Partilhar via


Latência WavePci

O driver de porta WavePci lida com buffering de um fluxo de áudio de maneira 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. 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 na 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 KS Allocators). O driver de miniporta especifica seu tamanho de quadro de alocador preferido quando seu método IMiniportWavePciStream::GetAllocatorFraming é chamado pelo driver de porta durante a inicialização do fluxo. No entanto, SysAudio, o criador dos gráficos do sistema, pode sobrepor as preferências do driver de miniporta para satisfazer os requisitos dos outros componentes no gráfico de filtro de áudio.

O driver de porta WavePci expõe o buffer cíclico para o 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 abranger um ou mais limites de página, o controlador de porta dividirá o quadro em cada um dos limites 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 com cada chamada para GetMapping e diminui em um com cada chamada para ReleaseMapping. (Uma chamada GetMapping pode falhar, é claro, para que o driver tenha menos controle total sobre o número de mapeamentos.) Controlando o número de mapeamentos abertos e controlando 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 buffering 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 fome para níveis aceitáveis.

Se a política do controlador de miniporta for armazenar em buffer até 50 milissegundos de dados, por exemplo, entre os ponteiros de leitura e de escrita, lembre-se de que esse limite representa a quantidade máxima de dados que o controlador irá acumular, mas não representa, nem deve representar, a contribuição do controlador 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 haver mais mapeamentos imediatamente disponíveis. Neste ú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 imediatamente a reproduzir os mapeamentos que já obteve. Mais tarde, à medida que mais mapeamentos ficam disponíveis, o driver pode continuar a adquirir mapeamentos adicionais até atingir o limite de tamanho do buffer ou não haver mais mapeamentos disponíveis imediatamente.

Em geral, o hardware DMA de um dispositivo WavePci deve ser projetado para acessar diretamente quadros de áudio armazenados em alinhamentos arbitrários de bytes e que ultrapassam os 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. Claro, um dispositivo com esta limitação ainda deve ser capaz de lidar com um tamanho de quadro de áudio que é uma potência de 2.

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 inteiro de quadros de áudio encaixa-se perfeitamente numa página (ou em 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 contém necessariamente quadros de áudio que ultrapassam os limites da página. (As figuras nos Filtros de Onda ilustram este problema.) O hardware que não pode lidar com alinhamentos arbitrários de bytes e mapeamentos arbitrários de comprimento de bytes deve depender do driver para executar uma cópia intermediária, o que degrada o desempenho.

O driver de exemplo do adaptador Ac97 no Microsoft Windows Driver Kit (WDK) implementa um método GetAllocatorFraming. O driver de miniport utiliza este método para comunicar o seu tamanho preferido de alocação de quadros. No Windows 2000 e Windows Me, o controlador de porta chama este método somente quando o driver do sistema Splitter (Splitter.sys) é instanciado acima do pino de saída. No Windows XP e posterior, o driver de porta chama esse método para fluxos de entrada também. Lembre-se de que o SysAudio pode ignorar as preferências do driver de miniport ao decidir sobre o tamanho de alocação de quadros.