Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O cliente de um driver de áudio usa a propriedade KSPROPERTY_AUDIO_POSITION para obter e definir a posição atual em um fluxo de áudio. A propriedade usa uma estrutura KSAUDIO_POSITION para descrever a posição atual. A estrutura contém dois membros: PlayOffset e WriteOffset.
Os membros PlayOffset e WriteOffset definem os limites da região do buffer do cliente que está atualmente reservado para o uso exclusivo do dispositivo de áudio. O cliente deve assumir que o dispositivo pode estar acessando qualquer um dos dados contidos nessa região. Portanto, o cliente deve acessar apenas as partes do buffer que estão fora dessa região. Os limites da região se movem conforme o fluxo avança.
Se o buffer do cliente estiver em loop (ou seja, o tipo de fluxo será KSINTERFACE_STANDARD_LOOPED_STREAMING), PlayOffset e WriteOffset serão deslocamentos relativos ao buffer. Ou seja, eles são especificados como deslocamentos de bytes desde o início do buffer do cliente em loop. Quando o deslocamento atinge o final do buffer, ele volta para o início do buffer. (O deslocamento no início do buffer é zero.) Portanto, nenhum deslocamento excede o tamanho do buffer.
Se o buffer do cliente não for em ciclo (ou seja, quando o tipo de fluxo for KSINTERFACE_STANDARD_STREAMING), PlayOffset e WriteOffset serão deslocamentos relativos ao fluxo. Ou seja, eles são especificados como deslocamentos em bytes desde o início do fluxo de dados. Esses deslocamentos podem ser considerados como deslocamentos para um buffer idealizado que contém todo o fluxo e é contíguo do início ao fim.
No caso de um fluxo de renderização, o membro PlayOffset especifica a posição de reprodução do fluxo e o membro WriteOffset especifica a posição de gravação do fluxo. A figura a seguir mostra as posições de reprodução e gravação em um buffer de cliente.
A posição de reprodução é o deslocamento de bytes do exemplo que está sendo reproduzido no momento (ou seja, o exemplo que está travado na entrada do conversor digital para analógico, ou DAC). A posição de gravação é a posição além da qual o cliente pode gravar com segurança no buffer. À medida que a transmissão é reproduzida, as posições de reprodução e gravação se movem da esquerda para a direita na figura anterior. As operações de escrita do cliente devem anteceder a posição de escrita. Além disso, se o buffer estiver em loop, as gravações do cliente nunca deverão ultrapassar a posição de reprodução.
Embora o driver de porta WaveCyclic ou WavePci dependa do driver de miniporto para manter o controle da posição de reprodução, o driver de porta mantém o controle da posição de gravação. Os drivers de porta WaveCyclic e WavePci atualizam a posição de gravação da seguinte maneira:
WaveCyclic
Cada vez que o driver de porta WaveCyclic chama IDmaChannel::CopyTo para copiar um novo bloco de dados para o buffer cíclico (do buffer do cliente), a posição de gravação avança para o local (no buffer do cliente) do último byte no bloco de dados.
WavePci
Por padrão, sempre que o driver de miniporto WavePci chama IPortWavePciStream::GetMapping para adquirir um novo mapeamento (de uma parte do buffer do cliente) e a chamada é bem-sucedida, a posição de gravação avança para o local (no buffer do cliente) do último byte no novo mapeamento.
Se o driver de miniporto WavePci substituir o comportamento padrão especificando um deslocamento de pré-busca para o driver de porta, a posição de gravação atual será sempre igual à soma da posição de reprodução atual e ao deslocamento de pré-busca. Para obter mais informações, consulte Deslocamentos de pré-busca.
No caso de um fluxo de captura, o membro PlayOffset especifica a posição do registro do fluxo e o membro WriteOffset especifica a posição de leitura do fluxo. A figura a seguir mostra as posições de registro e leitura em um buffer de cliente.
A posição do registro é o deslocamento em bytes da amostra mais recente a ser registrada na saída do conversor analógico para digital, ou ADC. (Essa posição especifica o local do buffer no qual o mecanismo de DMA do dispositivo de áudio eventualmente gravará o exemplo.) A posição de leitura é a posição além da qual o cliente não pode ler com segurança do buffer. À medida que a gravação do fluxo progride, as posições de leitura e registro avançam da esquerda para a direita na figura anterior. As leituras do cliente devem seguir a posição de leitura. Além disso, se o buffer estiver em loop, as leituras do cliente deverão ficar à frente da posição do registro.
Embora o driver de porta WaveCyclic ou WavePci dependa do driver de miniporto para manter o controle da posição do registro, o driver de porta mantém o controle da posição de leitura. Os drivers de porta WaveCyclic e WavePci atualizam a posição de leitura da seguinte maneira:
WaveCyclic
Sempre que o driver de porta WaveCyclic chama IDmaChannel::CopyFrom para copiar um novo bloco de dados do buffer cíclico (para o buffer do cliente), a posição de leitura avança para o local (no buffer do cliente) do último byte no bloco de dados.
WavePci
Sempre que o driver de miniporto WavePci chama IPortWavePciStream::ReleaseMapping para liberar um mapeamento adquirido anteriormente (de uma porção do buffer do cliente), a posição de leitura avança para o local (na memória de buffer do cliente) do último byte no mapeamento liberado.
Os drivers de miniporto não precisam implementar rotinas de manipulador para solicitações de propriedade KSPROPERTY_AUDIO_POSITION. Em vez disso, os drivers de porta WaveCyclic e WavePci lidam com essas solicitações em nome de drivers de miniporto. Ao lidar com uma solicitação de obtenção de propriedade, um driver de porta WaveCyclic ou WavePci já tem todas as informações necessárias para calcular o valor WriteOffset, mas ainda precisa de informações do driver de miniporto para calcular o valor do PlayOffset. Para obter essas informações, o driver de porta chama o método IMiniportWaveCyclicStream::GetPosition ou IMiniportWavePciStream::GetPosition do driver de miniport.
Para um fluxo de renderização, o método GetPosition recupera a posição de reprodução - o deslocamento de bytes da amostra que está sendo reproduzida atualmente por meio do DAC. Para um fluxo de captura, o método GetPosition recupera a posição de gravação - o deslocamento de bytes da amostra mais recente a ser capturada pelo ADC.
Observe que o valor de deslocamento recuperado por uma chamada GetPosition é uma posição de reprodução correspondente ao sinal que está sendo transmitido pelo alto-falante ou uma posição de registro correspondente ao sinal que está sendo recebido no momento por meio da tomada de microfone. Não é a posição do DMA. (A posição de DMA é o deslocamento de bytes da amostra que o mecanismo de DMA no dispositivo de áudio está transferindo no momento para ou do buffer de DMA.)
Algum hardware de áudio contém um registrador de posição para acompanhar o deslocamento de byte da amostra atualmente em cada DAC ou ADC, nesse caso, o método GetPosition simplesmente recupera o conteúdo do registrador de posição para o fluxo correto. Outros hardwares de áudio só podem fornecer ao driver a posição de DMA, nesse caso, o método GetPosition deve fornecer uma melhor estimativa do deslocamento de bytes da amostra no DAC ou ADC, considerando a posição atual do DMA e os atrasos de buffer internos do dispositivo.
Embora o manipulador de propriedades no driver de porta WaveCyclic ou WavePci deva distinguir entre buffers em loop e não conectados para determinar se deseja fornecer um deslocamento de bytes relativo a um fluxo ou buffer, esse detalhe (ou seja, se um buffer está em loop ou não conectado) é transparente para o driver de miniporto.
O método IMiniportWaveCyclicStream::GetPosition sempre informa uma posição de reprodução ou gravação relativa ao buffer do cliente, independentemente de o buffer estar em loop ou não. Se o buffer do cliente estiver em loop, o manipulador de propriedades converterá a posição relativa ao buffer relatada pelo driver de miniporto, que é expressa como um deslocamento no buffer cíclico, para um deslocamento no buffer do cliente e o grava no membro PlayOffset. Se o buffer do cliente não for em loop, o manipulador de propriedades converterá a posição de reprodução relativa ao buffer em uma posição de reprodução relativa ao fluxo antes de gravá-la no membro PlayOffset.
O método IMiniportWavePciStream::GetPosition sempre relata uma posição de reprodução ou registro relativa ao fluxo, independentemente de o buffer do cliente estar em loop ou não. Se o buffer do cliente estiver em loop, o manipulador de propriedades converterá a posição de reprodução relativa ao fluxo em uma posição de reprodução relativa ao buffer (expressa como um deslocamento dentro do buffer do cliente) antes de gravá-la no PlayOffset no membro da estrutura KSAUDIO_POSITION na solicitação de propriedade. Se o buffer do cliente não for circular, o manipulador de propriedades grava a posição relativa ao fluxo no membro PlayOffset.
A posição de reprodução ou gravação é zero imediatamente após a inicialização do stream. Uma transição para o estado KSSTATE_STOP (ver KSSTATE) redefine a posição como zero. Quando o fluxo é interrompido por uma transição de KSSTATE_RUN para KSSTATE_PAUSE ou KSSTATE_ACQUIRE, a posição congela. Ele descongela quando o fluxo faz a transição de KSSTATE_PAUSE ou KSSTATE_ACQUIRE de volta para KSSTATE_RUN.
Para implementações de exemplo de métodos GetPosition para drivers de miniporto WaveCyclic e WavePci, veja os drivers de áudio de exemplo no Windows Driver Kit (WDK).