Um coletor de ondas para sintetizadores de software Kernel-Mode

Conforme explicado em Sintetizadores e Coletores de Ondas, o driver de porta DMus implementa o coletor de ondas para um sintetizador de software que opera no modo kernel. O driver de miniporto para o sintetizador expõe uma interface ISynthSinkDMus ao driver de porta. O coletor de ondas do driver de porta usa essa interface para ler os dados de onda produzidos pelo sintetizador.

Para usar o coletor de ondas do driver de porta DMus, um driver de miniporto DMus deve definir um filtro DirectMusic com dois tipos de pino:

  • Um pin de entrada DirectMusic ou um pino de entrada MIDI. Esse pin é um coletor para um fluxo de renderização que contém mensagens MIDI.

  • Um pino de saída de onda. Esse pin é uma origem para um fluxo de renderização que contém exemplos de PCM.

A figura a seguir mostra um filtro DirectMusic contendo um nó de sintetizador (KSNODETYPE_SYNTHESIZER). Esse filtro atende aos requisitos anteriores para um sintetizador de software no modo kernel fornecendo um pin de entrada DirectMusic e um pino de saída de onda. (Além disso, um driver de miniporto DMus que dá suporte à síntese MIDI herdada pode fornecer um pin de entrada MIDI.)

Diagrama ilustrando um filtro DirectMusic para um sintetizador de software no modo kernel com pin de entrada DirectMusic e pino de saída de onda.

No lado esquerdo da figura, um fluxo MIDI insere o filtro por meio do pino de entrada DirectMusic. Esse pino tem uma interface IMXF que expõe ao driver de porta. O driver de porta obtém essa interface chamando o método IMiniportDMus::NewStream . O driver de porta alimenta mensagens MIDI para o pino chamando o método IMXF::P utMessage .

No lado direito da figura, um fluxo de onda sai do filtro através do pino de saída de onda e flui para o coletor de ondas do driver de porta. O driver de porta se comunica com o pino por meio de sua interface ISynthSinkDMus . O driver de porta obtém essa interface primeiro chamando IMiniportDMus::NewStream para obter um objeto de fluxo com uma interface IMXF e, em seguida, consultando o objeto para sua interface ISynthSinkDMus . O coletor de ondas extrai dados de onda do pino chamando o método ISynthSinkDMus::Render .

Embora um sintetizador de hardware possa, em princípio, contar com o coletor de ondas do driver de porta para renderização, a chamada para ISynthSinkDMus::Render adiciona latência suficiente ao fluxo MIDI para torná-lo pouco atraente para muitos aplicativos interativos. Para reduzir a latência do fluxo, é provável que os sintetizadores de hardware tenham conexões internas com a combinação e o hardware de renderização de ondas em vez de usar o coletor de ondas do driver de porta. Esse tipo de sintetizador substitui o pino de saída de onda no lado direito da figura anterior por uma conexão com fio (representada como um pino de ponte) para um mixer de hardware.

A interface ISynthSinkDMus fornece métodos para renderizar dados de onda por meio de um coletor de ondas, converter do tempo de referência para o tempo de exemplo e voltar e sincronizar com o relógio master:

ISynthSinkDMus::RefTimeToSample

ISynthSinkDMus::Render

ISynthSinkDMus::SampleToRefTime

ISynthSinkDMus::SyncToMaster

ISynthSinkDMus herda da interface IMXF . Para obter mais informações, consulte ISynthSinkDMus.

O driver de miniporto DMus na figura anterior identifica seu pino de entrada DirectMusic e o pino de saída de onda da seguinte maneira:

  • Para identificar seu pino de entrada DirectMusic, o driver de miniporto define o intervalo de dados do pino para ter um formato principal do tipo KSDATAFORMAT_TYPE_MUSIC e um subformulário do tipo KSDATAFORMAT_SUBTYPE_DIRECTMUSIC. Essa combinação indica que o pino aceita um fluxo MIDI com carimbo de data/hora. O descritor de intervalo de dados é uma estrutura do tipo KSDATARANGE_MUSIC. (Para obter um exemplo, consulte DirectMusic Stream Data Range.) O driver de miniporto define a direção do fluxo de dados do pino a ser KSPIN_DATAFLOW_IN. (O KsPinDescriptor da estrutura PCPIN_DESCRIPTOR. Membro do DataFlow indica a direção do fluxo de dados.) Ao chamar IMiniportDMus::NewStream para criar o objeto de fluxo para esse pino, o driver de porta define o parâmetro StreamType como DMUS_STREAM_MIDI_RENDER.

  • Para identificar seu pino de saída de onda, o driver de miniporto define o intervalo de dados do pino para ter um formato principal do tipo KSDATAFORMAT_TYPE_AUDIO e um subformulário do tipo KSDATAFORMAT_SUBTYPE_PCM. Essa combinação indica que o pino emite um fluxo de áudio de onda contendo exemplos de PCM. O descritor de intervalo de dados é uma estrutura do tipo KSDATARANGE_AUDIO. (Consulte o exemplo no Intervalo de Dados do Fluxo de PCM.) O driver de miniporte define a direção do fluxo de dados do pino a ser KSPIN_DATAFLOW_OUT. Ao chamar IMiniportDMus::NewStream para criar o objeto de fluxo para esse pino, o driver de porta define o parâmetro StreamType como DMUS_STREAM_WAVE_SINK.

Além disso, se o driver der suporte a um pin de entrada MIDI para o sintetizador, sua definição seria semelhante à do pino de entrada DirectMusic, mas a definição de pin especificaria um subformulário do tipo KSDATAFORMAT_SUBTYPE_MIDI e o pino aceitaria um fluxo MIDI bruto em vez de um fluxo MIDI com carimbo de data/hora.