Modo de usuário versus modo kernel
Um sintetizador personalizado pode ser gravado para ser executado no modo de usuário ou no modo kernel. Em geral, os sintetizadores de software são mais fáceis de implementar no modo de usuário, mas frequentemente podem obter menor latência no modo kernel. Os componentes de hardware só podem ter suporte no modo kernel. No entanto, existem bons motivos para iniciar o desenvolvimento no modo de usuário, mesmo que a implementação final seja executada no modo kernel.
Criar sintetizadores de software (e coletores de onda) é muito mais simples no modo de usuário. As interfaces do modo de usuário são fáceis de usar e a depuração é simplificada. Outro benefício é que o componente resultante é um arquivo executável do Microsoft Windows. Como esse arquivo executável é um objeto COM, instalá-lo é simplesmente uma questão de auto-registro da linha de comando com regsvr32.exe. (O aplicativo do sistema RegSvr32 chama a função DllRegisterServer da DLL. Para obter mais informações, consulte a documentação do SDK do Microsoft Windows.)
Se uma implementação de modo de usuário for tudo o que você precisa, você poderá entregar seu produto com um programa de aplicativo em vez de um driver. O usuário evita um processo complicado de instalação de driver e nenhuma reinicialização é necessária após a instalação. O componente de modo de usuário pode então ser enumerado como uma das portas disponíveis, dependendo se você deseja que outros aplicativos possam usá-lo. Para obter mais informações, consulte Registrando seu sintetizador.
A vantagem de uma implementação de software no modo kernel é a menor latência. Com o advento de mensagens com carimbo de data/hora, no entanto, essa vantagem não é tão grande quanto costumava ser. AS APIs MIDI herdadas não tinham carimbo de data/hora, portanto, quando você reproduziu uma nota, isso foi exatamente quando ela foi enfileirada para ser reproduzida. O carimbo de data/hora possibilita a reprodução de anotações na fila em horários especificados no futuro. Usar carimbo de data/hora significa que a anotação é reproduzida no momento correto, a menos que o aviso prévio seja menor do que a latência inerente ao sistema.
A latência é apenas um problema quando os sons são enfileirados para serem reproduzidos com pouco ou nenhum aviso prévio. Portanto, as implementações de modo kernel são recomendadas somente quando há uma limitação indesejável para uma implementação de software no modo de usuário ou ao dar suporte à aceleração de hardware.
Se você decidir fazer uma implementação no modo kernel, a melhor abordagem ainda será iniciar o desenvolvimento no modo de usuário. O código-fonte do sintetizador de modo de usuário da Microsoft é fornecido no WDK (Microsoft Windows Driver Kit), portanto, você não precisa escrever um novo sintetizador do zero. Você pode usar o código existente para entender como os downloads de DLS (sons baixáveis) são analisados. Em seguida, você pode adicionar qualquer nova funcionalidade (como analisar partes adicionais) e depurar essa lógica no modo de usuário primeiro, eliminando as rotinas que acessam o hardware. (Uma rotina fragmentada não pode fazer nada ou emular a função de hardware no software.) Para obter mais informações sobre o DLS, consulte a documentação do SDK do Windows.
Quando sua implementação estiver funcionando no modo de usuário, você poderá movê-la para o modo kernel e fazê-la funcionar lá. Depois que a versão do software estiver funcionando no modo kernel, a próxima etapa será começar a mover a funcionalidade para o hardware. Os sintetizadores de software no modo de usuário e no modo kernel servem como etapas intermediárias úteis no processo de colocar o sintetizador de hardware em execução.
Para resumir as recomendações acima:
Para componentes somente de software, implemente os componentes primeiro no modo de usuário (para resolver os problemas de design com interfaces fáceis, depuração, instalação e remoção) e, em seguida, converta para o modo kernel, se necessário, devido à latência ou outras considerações.
Para componentes de hardware, primeiro implemente uma versão de software no modo de usuário (para resolver os problemas de design com interfaces fáceis, depuração, instalação e remoção), depois converta-a em uma versão de software no modo kernel. Por fim, conecte o componente do modo kernel ao hardware, um recurso de cada vez, até que tudo funcione conforme desejado.