Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
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 reservada 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. Assim, o cliente deve acessar apenas as partes do buffer que estão fora dessa região. Os limites da região se movem à medida que o fluxo avança.
Se o buffer do cliente for de ciclo contínuo (ou seja, o tipo de fluxo for KSINTERFACE_STANDARD_LOOPED_STREAMING), PlayOffset e WriteOffset serão deslocamentos relativos ao respetivo buffer. Ou seja, eles são especificados como deslocamentos de byte desde o início do buffer do cliente em loop. Quando um deslocamento é incrementado até ao final do buffer, ele retorna ao início do buffer. (O deslocamento no início do buffer é zero.) Assim, nenhum dos deslocamentos excede o tamanho do buffer.
Se o buffer do cliente não estiver em "loop" (ou seja, se o tipo de fluxo for KSINTERFACE_STANDARD_STREAMING), então PlayOffset e WriteOffset serão deslocamentos relativos ao fluxo. Ou seja, eles são especificados como offsets de byte desde o início do fluxo de dados. Esses deslocamentos podem ser pensados como compensações em 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 desvio em bytes da amostra que está atualmente a ser reproduzida (ou seja, a amostra que está fixada na entrada do conversor digital-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 o stream é reproduzido, as posições de reprodução e escrita movem-se da esquerda para a direita na figura anterior. As escritas do cliente devem ficar à frente da posição de gravação. Além disso, se o buffer estiver em loop, as gravações do cliente nunca devem ultrapassar a posição de reprodução.
Embora o driver de porta WaveCyclic ou WavePci dependa do driver de miniporta para acompanhar a posição de reprodução, é o driver de porta que acompanha a 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, cada vez que o driver de miniporta 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 miniporta 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 do 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 de 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 registo é o offset de bytes da amostra mais recente a ser retida na saída do conversor analógico-digital, ou ADC. (Esta posição especifica o local do buffer no qual o mecanismo DMA do dispositivo de áudio eventualmente gravará a amostra.) A posição de leitura é a posição além da qual o cliente não pode ler com segurança a partir 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 acompanhar a posição de leitura. Além disso, se o buffer estiver em loop, as leituras do cliente devem ficar à frente da posição do registro.
Embora o driver de porta WaveCyclic ou WavePci dependa do driver de miniporta para manter o controle da posição de gravação, 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
Cada vez 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
Cada vez que o driver de miniporta WavePci chama IPortWavePciStream::ReleaseMapping para liberar um mapeamento adquirido anteriormente (de uma parte do buffer do cliente), a posição de leitura avança para o local (no buffer do cliente) do último byte no mapeamento liberado.
Os drivers de miniporta não precisam implementar rotinas de manipulador para solicitações de propriedade KSPROPERTY_AUDIO_POSITION. Em vez disso, os drivers de portas WaveCyclic e WavePci lidam com essas solicitações em nome de drivers de miniporta. Ao lidar com uma solicitação get-property, 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 miniporta para calcular o valor PlayOffset . Para obter essas informações, o driver de porta chama o método IMiniportWaveCyclicStream::GetPosition ou IMiniportWavePciStream::GetPosition do driver de miniporta.
Para um fluxo de renderização, o método GetPosition recupera a posição de reprodução - o deslocamento em bytes da amostra que está a ser reproduzida atualmente através 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 atualmente através do conector de alto-falante ou uma posição de gravação correspondente ao sinal que está sendo recebido atualmente através do conector de microfone. Não é a posição da DMA. (A posição DMA é o deslocamento de bytes da amostra que o mecanismo DMA no dispositivo de áudio está atualmente a transferir para ou a partir do buffer de DMA.)
Algum hardware de áudio contém um registo de posição para acompanhar o deslocamento de bytes da amostra atualmente em cada DAC ou ADC. Neste caso, o método GetPosition simplesmente recupera o conteúdo do registo de posição para o fluxo apropriado. Outros hardware de áudio só podem fornecer ao driver a posição DMA, caso em que o método GetPosition deve fornecer a melhor estimativa do deslocamento em bytes da amostra no DAC ou ADC, levando em consideração a posição DMA atual e os atrasos de buffering internos ao dispositivo.
Embora o manipulador de propriedades no driver de porta WaveCyclic ou WavePci deva distinguir entre buffers em loop e sem loop para determinar se deve fornecer um deslocamento de byte relativo ao fluxo ou relativo ao buffer, esse detalhe (ou seja, se um buffer é em loop ou não) é transparente para o driver de miniporta.
O método IMiniportWaveCyclicStream::GetPosition sempre relata uma posição de reprodução ou registro relativa ao buffer, independentemente de o buffer do cliente estar em loop ou sem loop. Se o buffer do cliente estiver em ciclo, o gestor de propriedades converte a posição relativa do buffer relatada pelo driver da miniporta, que é expressa como um deslocamento no buffer cíclico, para um deslocamento no buffer do cliente, o qual o gestor escreve no membro PlayOffset. Se o buffer do cliente não tiver loop, o manipulador de propriedades converte a posição de reprodução relativa ao buffer para uma posição de reprodução relativa ao fluxo antes de escrevê-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 ser em loop ou não. Se o buffer do cliente estiver em loop, o manipulador de propriedades converte a posição de reprodução relativa ao fluxo em uma posição de reprodução relativa ao buffer (expressa como um deslocamento no buffer do cliente) antes de gravá-la no membro PlayOffset na estrutura KSAUDIO_POSITION na solicitação de propriedade. Se o buffer do cliente não tiver loop, o manipulador de propriedades gravará 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 fluxo. Uma transição para o estado KSSTATE_STOP (ver KSSTATE) redefine a posição para 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 transita de KSSTATE_PAUSE ou KSSTATE_ACQUIRE de volta para KSSTATE_RUN.
Por exemplo, consulte os drivers de áudio de exemplo no Windows Driver Kit (WDK) para implementações dos métodos GetPosition nas miniportas WaveCyclic e WavePci.