Um dissipador de onda para sintetizadores de software Kernel-Mode

Como explicado em Sintetizadores e Wave Sinks, o driver de porta DMus implementa o coletor de onda para um sintetizador de software que opera no modo kernel. O driver de miniporta para o sintetizador expõe uma interface ISynthSinkDMus para o driver de porta. O coletor de onda do driver de porta usa essa interface para ler os dados de onda que são produzidos pelo sintetizador.

Para fazer uso do coletor de onda do driver de porta DMus, um driver de miniporta DMus deve definir um filtro DirectMusic com dois tipos de pino:

  • Um pino de entrada DirectMusic ou um pino de entrada MIDI. Este pino é um ponto de entrada para um fluxo de renderização contendo mensagens MIDI.

  • Um pino de saída de onda. Este pino é uma fonte para um fluxo de renderização contendo amostras de PCM.

A figura a seguir mostra um filtro DirectMusic contendo um nó de sintetizador (KSNODETYPE_SYNTHESIZER). Este filtro atende aos requisitos anteriores para um sintetizador de software de modo kernel, fornecendo um pino de entrada DirectMusic e um pino de saída de onda. (Além disso, um miniport driver DMus que suporta síntese MIDI herdada pode disponibilizar um pino de entrada MIDI.)

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

No lado esquerdo da figura, um fluxo MIDI entra no filtro através do pino de entrada do DirectMusic. Este 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 o pino com mensagens MIDI chamando o método IMXF::PutMessage.

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 dissipador de onda do driver de porta. O controlador da porta comunica-se com o pino através da sua interface ISynthSinkDMus. O driver de porta obtém essa interface chamando primeiro IMiniportDMus::NewStream para obter um objeto de fluxo com uma interface IMXF e, em seguida, consultando o objeto para sua interface ISynthSinkDMus . O módulo de receção de ondas recolhe dados de onda do pino chamando o método ISynthSinkDMus::Render.

Embora um sintetizador de hardware possa, em princípio, confiar no coletor de onda 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, os sintetizadores de hardware tendem a ter conexões internas com hardware de mistura e renderização de onda em vez de usar o sumidouro de onda do driver de porta. Este 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 misturador de hardware.

A interface ISynthSinkDMus fornece métodos para renderizar dados de onda através de um coletor de onda, converter de tempo de referência para tempo de amostra e vice-versa, e sincronizar com o relógio mestre:

ISynthSinkDMus::RefTimeToSample

ISynthSinkDMus::Renderizar

ISynthSinkDMus::SampleToRefTime

ISynthSinkDMus::SyncToMaster

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

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

  • Para identificar seu pino de entrada DirectMusic, o driver de miniporta define o intervalo de dados do pino para ter um formato principal do tipo KSDATAFORMAT_TYPE_MUSIC e um subformato do tipo KSDATAFORMAT_SUBTYPE_DIRECTMUSIC. Esta combinação indica que o pino aceita um fluxo MIDI marcado com data e hora. O descritor do intervalo de dados é uma estrutura do tipo KSDATARANGE_MUSIC. (Para obter um exemplo, consulte DirectMusic Stream Data Range.) O driver de miniporta define a direção do fluxo de dados do pino como KSPIN_DATAFLOW_IN. (A estrutura PCPIN_DESCRIPTOR tem o membro KsPinDescriptor.DataFlow que 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 miniporta define o intervalo de dados do pino para ter um formato principal do tipo KSDATAFORMAT_TYPE_AUDIO e um subformato do tipo KSDATAFORMAT_SUBTYPE_PCM. Esta combinação indica que o pino emite um fluxo de áudio de onda contendo amostras de PCM. O descritor do intervalo de dados é uma estrutura do tipo KSDATARANGE_AUDIO. (Consulte o exemplo em PCM Stream Data Range.) O driver de miniporta define a direção do fluxo de dados do pino como 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 suportasse um pino de entrada MIDI para o sintetizador, sua definição seria semelhante à do pino de entrada do DirectMusic, mas a definição do pino especificaria um subformato do tipo KSDATAFORMAT_SUBTYPE_MIDI, e o pino aceitaria um fluxo MIDI bruto em vez de um fluxo MIDI com carimbo de data/hora.