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.)
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::SampleToRefTime
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.