Compartir a través de


Posición de audio (propiedad)

El cliente de un controlador de audio usa la propiedad KSPROPERTY_AUDIO_POSITION para obtener y establecer la posición actual en una secuencia de audio. La propiedad usa una estructura KSAUDIO_POSITION para describir la posición actual. La estructura contiene dos miembros: PlayOffset y WriteOffset.

Los miembros PlayOffset y WriteOffset definen los límites de la región del búfer de cliente que está reservado actualmente para el uso exclusivo del dispositivo de audio. El cliente debe asumir que el dispositivo podría estar accediendo actualmente a cualquiera de los datos contenidos en esta región. Por lo tanto, el cliente debe tener acceso solo a las partes del búfer que se encuentran fuera de esta región. Los límites de la región se mueven a medida que avanza el flujo.

Si el búfer de cliente está en bucle (es decir, el tipo de secuencia es KSINTERFACE_STANDARD_LOOPED_STREAMING), PlayOffset y WriteOffset son desplazamientos relativos al búfer. Es decir, se especifican como desplazamientos de bytes desde el inicio del búfer de cliente en bucle. Cuando cualquiera de los incrementos de desplazamiento se incrementa al final del búfer, se ajusta alrededor del inicio del búfer. (El desplazamiento al principio del búfer es cero). Por lo tanto, ninguno de los desplazamientos supera el tamaño del búfer.

Si el búfer de cliente no está en bucle (es decir, el tipo de transmisión es KSINTERFACE_STANDARD_STREAMING), PlayOffset y WriteOffset son desplazamientos relativos a la transmisión. Es decir, se especifican como desplazamientos de bytes desde el inicio de la secuencia. Estos desplazamientos se pueden considerar como desplazamientos en un búfer idealizado que contiene toda la secuencia y es contiguo desde el principio hasta el final.

En el caso de una secuencia de representación, el miembro PlayOffset especifica la posición de reproducción de la secuencia y el miembro WriteOffset especifica la posición de escritura de la secuencia. En la siguiente ilustración se muestran las posiciones de reproducción y escritura en un buffer del cliente.

Diagrama que ilustra las posiciones de reproducción y escritura en un flujo de renderizado.

La posición de reproducción es el desplazamiento en bytes de la muestra que se está reproduciendo actualmente, es decir, la muestra retenida en la entrada del convertidor digital a analógico, o DAC. La posición de escritura es la posición más allá de la cual el cliente puede escribir de forma segura en el búfer. A medida que se reproduce la secuencia, las posiciones de reproducción y escritura se mueven de izquierda a derecha en la ilustración anterior. Las escrituras del cliente deben mantenerse por delante de la posición de escritura. Además, si el búfer tiene un ciclo continuo, las escrituras del cliente nunca deben superar la posición de reproducción.

Aunque el controlador de puerto WaveCíclico o WavePci se basa en el controlador de minipuerto para realizar un seguimiento de la posición de reproducción, el controlador de puerto realiza un seguimiento de la posición de escritura. Los controladores de puerto WaveCyclic y WavePci actualizan la posición de escritura de la siguiente manera:

  • WaveCyclic

    Cada vez que el controlador de puerto WaveCíclico llama a IDmaChannel::CopyTo para copiar un nuevo bloque de datos en el búfer cíclico (desde el búfer de cliente), la posición de escritura avanza a la ubicación (en el búfer de cliente) del último byte del bloque de datos.

  • WavePci

    De forma predeterminada, cada vez que el controlador de miniport de WavePci llama a IPortWavePciStream::GetMapping para adquirir una nueva asignación (de una parte del búfer de cliente) y la llamada se realiza correctamente, la posición de escritura avanza a la ubicación (en el búfer del cliente) del último byte de la nueva asignación.

    Si el controlador de miniporte WavePci invalida el comportamiento predeterminado especificando un desplazamiento de captura previa al controlador de puerto, la posición de escritura actual siempre es igual a la suma de la posición de reproducción actual y el desplazamiento de captura previa. Para obtener más información, vea Desplazamientos de Prefetch.

En el caso de una secuencia de captura, el miembro PlayOffset especifica la posición de registro de la secuencia y el miembro WriteOffset especifica la posición de lectura de la secuencia. En la ilustración siguiente se muestran las posiciones de registro y lectura en un búfer de cliente.

Diagrama que ilustra las posiciones de registro y lectura en un flujo de captura.

La posición del registro es el desplazamiento en bytes de la muestra más reciente que se va a retener en la salida del convertidor de analógico a digital o ADC. (Esta posición especifica la ubicación del búfer en la que el motor DMA del dispositivo de audio escribirá finalmente la muestra). La posición de lectura es la posición más allá de la cual el cliente no puede leer de forma segura desde el búfer. A medida que avanza la grabación de la secuencia, las posiciones de lectura y registro avanzan de izquierda a derecha en la ilustración anterior. Las lecturas del cliente deben seguir la posición de lectura. Además, si el buffer es cíclico, las lecturas del cliente deben permanecer delante de la posición del registro.

Aunque el controlador de puerto WaveCyclic o WavePci depende del controlador de miniport para realizar un seguimiento de la posición del registro, el controlador de puerto lleva un seguimiento de la posición de lectura. Los controladores de puerto WaveCíclico y WavePci actualizan la posición de lectura de la siguiente manera:

  • WaveCyclic

    Cada vez que el controlador de puerto WaveCíclico llama a IDmaChannel::CopyFrom para copiar un nuevo bloque de datos del búfer cíclico (al búfer de cliente), la posición de lectura avanza a la ubicación (en el búfer del cliente) del último byte del bloque de datos.

  • WavePci

    Cada vez que el controlador miniport WavePci llama a IPortWavePciStream::ReleaseMapping para liberar una asignación adquirida anteriormente (de una parte del búfer de cliente), la posición de lectura avanza hasta la posición (en el búfer del cliente) del último byte de la asignación liberada.

Los controladores de miniport no necesitan implementar rutinas de controlador para solicitudes de propiedad KSPROPERTY_AUDIO_POSITION. En su lugar, los controladores de puerto WaveCíclico y WavePci manejan estas solicitudes en nombre de los controladores miniport. Al gestionar una solicitud de obtención de propiedad, un controlador de puerto WaveCíclico o WavePci ya tiene toda la información que necesita para calcular el valor WriteOffset, pero todavía necesita información del controlador de miniport para calcular el valor PlayOffset. Para obtener esta información, el controlador de puerto llama al método IMiniportWaveCyclicStream::GetPosition o al método IMiniportWavePciStream::GetPosition del controlador de miniport.

Para una secuencia de renderizado, el método GetPosition recupera la posición de reproducción: el desplazamiento de bytes de la muestra que se está reproduciendo actualmente a través del DAC. Para una secuencia de captura, el método GetPosition recupera la posición del registro: el desplazamiento de bytes de la muestra más reciente que haya capturado el ADC.

Tenga en cuenta que el valor de desplazamiento recuperado por una llamada GetPosition es una posición de reproducción que corresponde a la señal que actualmente se está transmitiendo a través del conector del altavoz o una posición de grabación que corresponde a la señal que actualmente se está recibiendo a través del conector del micrófono. No es la posición DMA. (La posición DMA es el desplazamiento en bytes de la muestra que el motor DMA del dispositivo de audio está transfiriendo actualmente hacia el búfer DMA o desde él).

Algunas piezas de hardware de audio contienen un registro de posición para seguir el desplazamiento de bytes de la muestra que está actualmente en cada DAC o ADC, en cuyo caso el método GetPosition simplemente recupera el contenido del registro de posición para la secuencia adecuada. Otro hardware de audio solo puede proporcionar al controlador la posición DMA, en cuyo caso el método GetPosition debe proporcionar una mejor estimación del desplazamiento de bytes de la muestra en la DAC o ADC teniendo en cuenta la posición DMA actual y los retrasos de almacenamiento en búfer internos del dispositivo.

Aunque el controlador de propiedades del controlador de puerto WaveCíclico o WavePci debe distinguir entre los búferes en bucle y no en bucle para determinar si se debe proporcionar un desplazamiento de bytes relativo al flujo o al búfer, este detalle (es decir, si un búfer está en bucle o no en bucle) es transparente para el controlador de minipuerto.

El método IMiniportWaveCyclicStream::GetPosition siempre informa de una posición de reproducción o registro relativa al búfer, independientemente de si el búfer de cliente está en bucle o no está en bucle. Si el búfer de cliente está en bucle, el manejador de propiedades convierte la posición relativa al búfer que informa el controlador de miniporte, que se expresa como un desplazamiento en el búfer cíclico, en un desplazamiento en el búfer de cliente, el cual el manejador luego escribe en el miembro PlayOffset. Si el búfer del cliente no es cíclico, el controlador de propiedades convierte la posición de reproducción relativa al búfer en una relativa a la secuencia antes de escribirla en el miembro PlayOffset.

El método IMiniportWavePciStream::GetPosition siempre informa de una posición de reproducción o registro relativa a la secuencia, independientemente de si el búfer de cliente está en bucle o no. Si el búfer de cliente está en bucle, el controlador de propiedades convierte la posición de reproducción relativa a la secuencia en una posición de reproducción relativa al búfer (expresada como un desplazamiento en el búfer de cliente) antes de escribirla en el miembro PlayOffset en la estructura KSAUDIO_POSITION de la solicitud de propiedad. Si el búfer del cliente no es en bucle, el controlador de propiedades escribe la posición relativa al flujo en el miembro PlayOffset.

La posición de reproducción o registro es cero inmediatamente después de la inicialización de la secuencia. Una transición al estado de KSSTATE_STOP (vea KSSTATE) restablece la posición a cero. Cuando la secuencia se detiene mediante una transición de KSSTATE_RUN a KSSTATE_PAUSE o KSSTATE_ACQUIRE, la posición se bloquea. Descongela cuando la secuencia pasa de KSSTATE_PAUSE o KSSTATE_ACQUIRE a KSSTATE_RUN.

Para ver implementaciones de ejemplo de los métodos GetPosition para los controladores de miniporte WaveCíclico y WavePci, consulta los controladores de audio de ejemplo en el Kit de controladores de Windows (WDK).