Componentes MIDI e DirectMusic
Os programas de aplicativo dependem de uma combinação de componentes do modo de usuário e kernel para capturar e reproduzir fluxos MIDI e DirectMusic.
Um aplicativo pode usar qualquer uma das seguintes interfaces de software para reprodução e captura midi:
Funções midiOutxxx e midiInxxx do Microsoft Windows
DirectMusic API
O comportamento das funções midiOutXxx e midiInXxx baseia-se nos recursos de drivers e dispositivos MIDI herdados. A partir do Windows 98, o driver do sistema WDMAud converte chamadas para essas funções em comandos para drivers de áudio WDM. No entanto, ao emular o comportamento de software e hardware mais antigos, as funções midiOutXxx e midiInXxx sacrificam o tempo de precisão e a funcionalidade aprimorada que agora estão disponíveis por meio da API DirectMusic. Para obter mais informações sobre o DirectMusic e as funções MIDI do Windows Multimídia, consulte a documentação do SDK do Microsoft Windows.
O DirectMusic e as funções MIDI multimídia do Windows são clientes do driver do sistema SysAudio, que cria os grafos de filtro de áudio que processam os fluxos MIDI e DirectMusic. A criação de grafo é transparente para os aplicativos que usam essas interfaces de software.
Componentes MIDI
A figura a seguir mostra os componentes do modo de usuário e do modo kernel que um aplicativo MIDI usa para reproduzir dados MIDI. Esse aplicativo interfaces para os drivers de áudio WDM por meio das funções midiOutXxx , que são implementadas no componente do sistema WinMM, Winmm.dll.
O aplicativo MIDI na figura anterior lê eventos MIDI com carimbo de data/hora de um arquivo MIDI e os reproduz. Os drivers de miniporto MIDI e DMus são mostrados como caixas escurecidos para indicar que eles podem ser componentes fornecidos pelo fornecedor. Se apropriado, um fornecedor pode optar por usar um dos drivers de miniporto fornecidos pelo sistema – FMSynth, UART ou DMusUART – em vez de escrever um driver de miniporte personalizado. Todos os outros componentes na figura são fornecidos pelo sistema.
O loop main de um aplicativo típico de reprodução MIDI chama timeSetEvent para agendar o próximo evento de anotação ou anotação. Essa chamada usa como um de seus parâmetros um ponteiro de função para a rotina de retorno de chamada do aplicativo. Quando o evento ocorre e o sistema operacional chama a rotina de retorno de chamada, essa rotina chama midiOutShortMsg para ativar ou desativar uma ou mais anotações agendadas. A função midiOutShortMsg armazena as mensagens MIDI em buffers de dados bloqueados por página para eliminar a necessidade de paginar essa memória durante uma chamada. Para obter mais informações sobre as chamadas timeSetEvent e midiOutShortMsg, consulte a documentação do SDK do Microsoft Windows.
O WDMAud, que consiste em componentes do modo kernel e do usuário (Wdmaud.drv e Wdmaud.sys), registra os horários em que as mensagens MIDI brutas das chamadas midiOutShortMsg chegam. O WDMAud combina esses carimbos de data/hora com as mensagens MIDI para gerar o fluxo MIDI que ele envia para um dos componentes do modo kernel que aparecem abaixo de WDMAud na figura.
Ao criar o grafo de filtro de áudio para o aplicativo MIDI, sysAudio seleciona apenas uma das três conexões possíveis -- com SWMidi, a porta MIDI ou o driver de porta DMus -- que aparecem na figura anterior. Se o aplicativo selecionar o dispositivo MIDI padrão, o SysAudio primeiro procurará um dispositivo sintetizador cujo driver de miniporto MIDI ou DMus tenha um pino MIDI. Se ele não encontrar esse dispositivo no registro, o SysAudio usará o driver do sistema SWMidi (Swmidi.sys). SWMidi é um filtro KS que implementa um sintetizador de tabela de ondas no software e requer apenas um dispositivo que pode renderizar um fluxo de áudio de onda.
SWMidi mistura todas as suas vozes para produzir um fluxo PCM de onda única, que ele gera para o driver do sistema KMixer. O KMixer, por sua vez, passa um fluxo de onda formatado por PCM para um dispositivo WaveCyclic ou WavePci, cujos drivers de porta e miniporta aparecem no canto inferior esquerdo da figura. Como alternativa, o KMixer pode passar seu fluxo de saída para um dispositivo de áudio USB controlado pelo driver do sistema de classes USBAudio (não mostrado na figura).
Na figura anterior, o driver de porta MIDI usa o fluxo MIDI com carimbo de tempo do WDMAud e o converte em mensagens MIDI brutas, que o driver de miniporto MIDI reproduz por meio do dispositivo sintetizador. O driver de porta MIDI contém um sequenciador, que é implementado no software e é capaz de agendar as mensagens MIDI brutas com uma resolução de temporizador de um milissegundo.
O driver de porta DMus poderá obter uma precisão de tempo muito maior do que o driver de porta MIDI se o dispositivo sintetizador contiver um sequenciador de hardware. Nesse caso, o driver de miniporto DMus deve especificar um buffer de hardware grande o suficiente para absorver a tremulação resultante da concorrência por tempo de CPU com ISRs (rotinas de serviço de interrupção) e outras operações de alta prioridade. Os carimbos de data/hora no fluxo MIDI que o driver de porta DMus gera para o driver de miniporto são valores de 64 bits com resolução de 100 nanossegundos.
Se o sintetizador DMusic não tiver um sequenciador de hardware, ele deverá contar com o sequenciador de software do driver de porta DMus, que, como o do driver de porta MIDI, tem uma resolução de temporizador de um milissegundo.
Um driver de adaptador cria um driver de porta MIDI ou DMus chamando PcNewPort com um valor GUID de CLSID_PortMidi ou CLSID_PortDMus, respectivamente. No Windows XP e posterior, os drivers de porta MIDI e DMus compartilham a mesma implementação de software.
Aparecendo na parte inferior da figura anterior estão os nomes dos drivers de miniporto fornecidos pelo sistema FMSynth, UART e DMusUART, que estão incluídos em Portcls.sys. Um driver de adaptador cria um desses drivers de miniporte chamando PcNewMiniport. FMSynth e UART fornecem interfaces IMiniportMidi e dMusUART fornece uma interface IMiniportDMus . Observe que o UART agora está obsoleto (após o Windows 98 Gold) e tem suporte apenas para drivers existentes. Em vez disso, os novos drivers de adaptador devem usar dMusUART (no Windows 98 SE e posterior e no Windows 2000 e posterior), que implementa um superconjunto da funcionalidade do UART. DMusUART é um exemplo de um driver de miniporto DMus que não dá suporte a downloads de DLS nem sequenciamento de hardware. O código-fonte para os drivers de miniporte FMSynth e DMusUART está disponível nos drivers de áudio de exemplo no WDK (Kit de Driver do Windows).
A figura a seguir mostra os componentes do modo de usuário e do modo kernel que um programa de aplicativo MIDI usa para capturar dados MIDI. Esse aplicativo interfaces para os drivers de áudio WDM por meio das funções midiInXxx .
Na figura anterior, os drivers de miniport de MIDI e DMus são mostrados como caixas escurecidos para indicar que eles podem ser componentes fornecidos pelo fornecedor. Se apropriado, um fornecedor pode optar por usar um dos drivers de miniporto fornecidos pelo sistema, UART ou DMusUARTCapture. Todos os outros componentes na figura são fornecidos pelo sistema.
A origem dos dados MIDI normalmente é um dispositivo MPU-401. Ao chamar PcNewMiniport, um driver de adaptador pode criar um dos drivers de miniporto fornecidos pelo sistema, UART ou DMusUARTCapture, para capturar dados MIDI de um dispositivo MPU-401. Novamente, o UART é obsoleto e os novos drivers devem usar DMusUARTCapture (no Windows 98 SE e posterior e no Windows 2000 e posterior).
Sempre que ocorre um evento de anotação ou anotação MIDI, o driver de miniporto de captura MIDI ou DMusic (na parte inferior da figura anterior) adiciona um carimbo de data/hora à mensagem MIDI antes de adicioná-lo ao fluxo MIDI que flui para o driver de porta MIDI ou DMus.
O driver de porta de captura MIDI ou DMusic gera um fluxo MIDI com carimbo de data/hora para Wdmaud.sys, a metade do modo kernel do driver do sistema WDMAud. A metade do modo de usuário, Wdmaud.drv, gera o fluxo MIDI com carimbo de data/hora para o programa de aplicativos por meio das funções midiInXxx , que são implementadas em Winmm.dll.
O aplicativo MIDI na parte superior da figura grava eventos MIDI com carimbo de data/hora em um arquivo MIDI. No momento em que o aplicativo chama midiInOpen para abrir o fluxo de entrada MIDI, ele passa um ponteiro de função para sua rotina de retorno de chamada. Quando ocorre um evento de anotação ou anotação, o sistema operacional chama a rotina de retorno de chamada com um bloco de dados que inclui uma ou mais mensagens MIDI com carimbo de data/hora. Os carimbos de data/hora nessas mensagens são essencialmente os mesmos gerados originalmente pelo driver de miniporto MIDI ou DMus.
Componentes DirectMusic
A figura a seguir mostra os componentes do modo kernel e do usuário que são usados por um programa de aplicativo DirectMusic para reproduzir ou capturar dados MIDI.
Os componentes de reprodução são mostrados na metade esquerda da figura anterior e os componentes de captura aparecem à direita. Os drivers de miniporto DMus são mostrados como caixas escurecidos para indicar que eles podem ser componentes fornecidos pelo fornecedor. Se apropriado, um fornecedor pode usar um dos drivers de miniporto fornecidos pelo sistema, DMusUART ou DMusUARTCapture. Os outros componentes na figura são fornecidos pelo sistema.
No canto superior esquerdo da figura, um aplicativo DirectMusic direciona um fluxo MIDI com carimbo de data/hora de um arquivo para o componente do sistema DirectMusic no modo de usuário (DMusic.dll), que, por sua vez, direciona o fluxo para um driver de porta DMus. Esse driver pode ser associado ao driver de miniporto para um sintetizador DirectMusic ou dispositivo MPU-401, se houver um disponível. Como alternativa, o driver de porta pode ser associado ao driver do sistema DMusic (Dmusic.sys), que é um driver de miniporto DMus fornecido pelo sistema que implementa um sintetizador de tabela de onda compatível com DLS no software e que requer apenas um dispositivo que pode renderizar um fluxo de áudio de onda.
Como SWMidi, o driver DMusic, Dmusic.sys, mistura todas as suas vozes para produzir um único fluxo de onda formatado por PCM, que ele gera para kMixer. O KMixer, por sua vez, pode passar um fluxo de onda para um dispositivo de onda, cuja porta e os drivers de miniporta aparecem no canto inferior esquerdo da figura ou para um dispositivo de áudio USB controlado pelo driver do sistema USBAudio, que não aparece na figura.
Os componentes de captura DirectMusic aparecem na metade direita da figura anterior. O driver de miniporto de captura DMusic no canto inferior direito da figura controla o hardware de captura e os carimbos de data/hora de cada mensagem MIDI que ele registra. O driver de porta DMus direciona o fluxo MIDI com carimbo de data/hora para o componente DirectMusic no modo de usuário, DMusic.dll. O aplicativo acessa esse fluxo por meio da API DirectMusic e grava os dados MIDI com carimbo de data/hora em um arquivo.
Um driver de adaptador pode usar o driver de miniporto DMusUARTCapture fornecido pelo sistema para controlar um dispositivo de captura MPU-401. O driver do adaptador cria esse driver de miniporte chamando PcNewMiniport com o valor guid CLSID_DMusUARTCapture. O objeto de driver de miniporto resultante dá suporte a uma interface IMiniportDMus . O código-fonte do driver de miniporto DMusUARTCapture está disponível nos drivers de áudio de exemplo no WDK (Kit de Driver do Windows).
Um aplicativo DirectMusic também pode ser executado por meio de um dispositivo MidiOutXxx , como SWMidi (Swmidi.sys) se optar por. Para simplificar, esse caminho é omitido da figura anterior. O driver DMusic (Dmusic.sys) requer um download DLS inicial para operar corretamente; usar SWMidi evita esse requisito.