Latência WavePci
O driver de porta WavePci lida com buffering de um fluxo de áudio de forma diferente do driver WaveCyclic.
Se o driver de miniporta WavePci fornecer mixagem de hardware, o DirectSound enviará um IRP para o driver de porta WavePci que contém todo o fluxo de onda DirectSound em um único buffer cíclico. O DirectSound aloca o buffer como um bloco contíguo de memória virtual. Para evitar copiar o buffer DirectSound, a camada de streaming do kernel mapeia o buffer para a memória virtual do modo kernel e gera uma MDL (lista de descritores de memória) que especifica os endereços virtuais e físicos das páginas de memória no buffer cíclico. O driver de porta WavePci particiona o buffer cíclico em uma sequência de quadros alocadores (consulte Alocadores KS). O driver de miniporta especifica seu tamanho de quadro de alocador preferencial quando seu método IMiniportWavePciStream::GetAllocatorFraming é chamado pelo driver de porta durante a inicialização do fluxo. No entanto, o SysAudio, o construtor de gráficos do sistema, pode substituir as preferências do driver de miniporta para acomodar os requisitos dos outros componentes no gráfico de filtro de áudio.
O driver de porta WavePci expõe o buffer cíclico ao driver de miniporta como uma sequência de mapeamentos. Um mapeamento é um quadro de alocação inteiro ou uma parte de um quadro. Se um determinado quadro de alocação estiver completamente dentro de uma página, o driver de porta apresentará esse quadro ao driver de miniporta como um único mapeamento. Se um quadro de alocação ultrapassar um ou mais limites de página, o driver de porta dividirá o quadro em cada limite de página e o apresentará como dois ou mais mapeamentos. Cada chamada para IPortWavePciStream::GetMapping produz o próximo mapeamento sucessivo na sequência.
Em contraste com o caso WaveCyclic, onde o driver de miniporta tem pouco controle sobre quantos milissegundos de dados são armazenados em buffer no hardware, o driver de miniporta WavePci tem controle considerável sobre o número de mapeamentos que ele tem aberto a qualquer momento. O número de mapeamentos abertos aumenta em um a cada chamada para GetMapping e diminui em um a cada chamada para ReleaseMapping. (A chamada GetMapping pode falhar para que o driver tenha menos controle total sobre o número de mapeamentos.) Controlando o número de mapeamentos abertos e o tamanho cumulativo dos mapeamentos, o driver de miniporta pode determinar (dentro de uma tolerância dependente do tamanho do mapeamento) o número de milissegundos de buffer que estão disponíveis para o hardware. Seu driver de miniporta WavePci deve solicitar mapeamentos de página suficientes para reduzir as chances de inanição a níveis aceitáveis.
Se a política do driver de miniporta for armazenar em buffer até 50 milissegundos de dados, por exemplo, entre os ponteiros de leitura e gravação, lembre-se de que esse limite representa a quantidade máxima de dados que o driver acumulará, mas não representa e não deve representar a contribuição do driver para a latência do fluxo. Seu driver deve ser projetado para manter sua latência o menor possível. Quando um driver de miniporta obtém seu conjunto inicial de mapeamentos antes de começar a reproduzir um novo fluxo, o driver de miniporta pode continuar a solicitar mapeamentos até atingir seu limite de buffer (50 milissegundos neste exemplo) ou não houver mais mapeamentos imediatamente disponíveis. No último caso, no entanto, o driver de miniporta não deve esperar até que mais mapeamentos estejam disponíveis antes de começar a reproduzir o fluxo. Em vez disso, o driver deve começar a reproduzir imediatamente os mapeamentos que já obteve. Mais tarde, à medida que mais mapeamentos se tornam disponíveis, o driver pode continuar a adquirir mapeamentos adicionais até que atinja seu limite de tamanho de buffer ou nenhum outro mapeamento esteja imediatamente disponível.
Em geral, o hardware DMA de um dispositivo WavePci deve ser projetado para acessar diretamente quadros de áudio que são armazenados em alinhamentos de bytes arbitrários e que ultrapassam limites entre páginas não contíguas de memória física. Se você tiver um dispositivo que exija que os mapeamentos sejam um número integral de quadros de áudio, esse dispositivo será limitado nos tipos de formatos de áudio suportados. Um dispositivo com essa limitação ainda conseguirá com um tamanho de quadro de áudio que é uma potência de dois.
Por exemplo, um dispositivo com quatro canais e um tamanho de amostra de 16 bits requer um tamanho de quadro de áudio de oito bytes. Um número integral de quadros de áudio se encaixa perfeitamente em uma página (ou qualquer outro tamanho de quadro de alocação que seja um múltiplo de oito bytes). No entanto, no caso de um fluxo de 5.1 canais com amostras de 16 bits, o tamanho do quadro de áudio é de 12 bytes e um fluxo que excede o tamanho de uma única página necessariamente contém quadros de áudio que ultrapassam os limites da página. (Os números em Filtros de onda ilustram esse problema.) O hardware que não consegue resolver alinhamentos de bytes arbitrários e mapeamentos arbitrários de comprimento de bytes deve depender do driver para executar uma cópia intermediária, o que prejudica o desempenho.
O driver de adaptador de exemplo Ac97 no Microsoft Windows Driver Kit (WDK) implementa um método GetAllocatorFraming. O driver de miniporta usa esse método para comunicar seu tamanho de alocação de quadros preferencial. No Windows 2000 e Windows Me, o driver de porta chama esse método somente quando o driver de sistema de divisão (Splitter.sys) é instanciado acima do pino de saída. No Windows XP e versões posteriores, o driver de porta chama esse método para fluxos de entrada também. Lembre-se de que o SysAudio pode optar por ignorar as preferências do driver de miniporta ao decidir sobre um tamanho de alocação de quadros.