Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Клиент звукового драйвера использует свойство KSPROPERTY_AUDIO_POSITION для получения и задания текущей позиции в звуковом потоке. Свойство использует структуру KSAUDIO_POSITION для описания текущей позиции. Структура содержит два члена: PlayOffset и WriteOffset.
Члены PlayOffset и WriteOffset определяют границы области буфера клиента, зарезервированного в настоящее время для эксклюзивного использования звукового устройства. Клиент должен предположить, что устройство в настоящее время может получить доступ к любому из данных, содержащихся в этом регионе. Поэтому клиент должен получить доступ только к частям буфера, лежащим за пределами этого региона. Границы региона перемещаются по мере продвижения потока.
Если буфер клиента цикличен (то есть тип потока KSINTERFACE_STANDARD_LOOPED_STREAMING), PlayOffset и WriteOffset являются смещениями относительно буфера. То есть они указываются как смещения байтов с начала циклического буфера клиентского приложения. Если любой индекс увеличивается до конца буфера, он переносится к началу буфера. (Смещение в начале буфера равно нулю.) Таким образом, ни смещение никогда не превышает размер буфера.
Если буфер клиента не зациклен (т. е. тип потока KSINTERFACE_STANDARD_STREAMING), PlayOffset и WriteOffset являются смещениями относительно потока. То есть они указываются как смещения байтов с начала потока. Эти смещения можно рассматривать как смещения в идеализированный буфер, содержащий целый поток и являющийся непрерывным и последовательным от начала до конца.
В случае потока отрисовки член PlayOffset указывает положение воспроизведения потока, а член WriteOffset указывает положение записи потока. На следующем рисунке показаны позиции воспроизведения и записи в буфере клиента.
Позиция воспроизведения — это байтовое смещение образца, который в настоящее время воспроизводится (т. е. выборка, защепляемая при входе ЦАП (Цифрового-аналогового преобразователя)). Позиция записи — это положение, за пределами которого клиент может безопасно записывать данные в буфер. При воспроизведении потока позиции воспроизведения и записи перемещаются слева направо, как показано на предыдущем рисунке. Записи клиента должны оставаться впереди позиции записи. Кроме того, если буфер цикличен, запись клиента никогда не должна опережать позицию воспроизведения.
Хотя драйвер порта WaveCyclic или WavePci зависит от минипорт-драйвера для отслеживания позиции воспроизведения, позицию записи отслеживает драйвер порта. Драйверы портов WaveCyclic и WavePci обновляют позицию записи следующим образом:
WaveCyclic
Каждый раз, когда драйвер порта WaveCyclic вызывает IDmaChannel::CopyTo для копирования нового блока данных в циклический буфер (из буфера клиента), позиция записи перемещается в расположение (в буфере клиента) последнего байта в блоке данных.
WavePci
По умолчанию каждый раз, когда драйвер минипорта WavePci вызывает IPortWavePciStream::GetMapping для получения нового сопоставления (части буфера клиента) и вызов успешен, позиция записи перемещается на место последнего байта в новом сопоставлении в буфере клиента.
Если минипорт-драйвер WavePci переопределяет поведение по умолчанию, указав драйверу порта смещение предварительной выборки, текущая позиция записи всегда равна сумме текущей позиции воспроизведения и смещения предварительной выборки. Дополнительные сведения см. в разделе "Prefetch Offsets".
В случае потока записи член PlayOffset указывает позицию записи потока, а элемент WriteOffset указывает позицию чтения потока. На следующем рисунке показаны позиции записи и чтения в буфере клиента.
Позиция записи — это смещение байтов последнего образца, зафиксированного на выходе аналогово-цифрового преобразователя или ADC. (Эта позиция указывает расположение буфера, в которое подсистема DMA звукового устройства в конечном итоге записывает образец.) Позиция чтения — это положение, за пределами которого клиент не может безопасно считывать из буфера. В процессе записи потока позиции чтения и записи перемещаются слева направо на предыдущем рисунке. Операции чтения клиента должны соответствовать позиции чтения. Кроме того, если буфер цикличен, операции чтения клиента должны оставаться впереди позиции записи.
Несмотря на то, что драйвер порта WaveCyclic или WavePci зависит от драйвера минипорта для отслеживания позиции записи, драйвер порта отслеживает позицию чтения. Драйверы портов WaveCyclic и WavePci обновляют позицию чтения следующим образом:
WaveCyclic
Каждый раз, когда драйвер порта WaveCyclic вызывает IDmaChannel::CopyFrom , чтобы скопировать новый блок данных из циклического буфера (в буфер клиента), положение чтения перемещается к расположению (в буфере клиента) последнего байта в блоке данных.
WavePci
Каждый раз, когда минипорт-драйвер WavePci вызывает IPortWavePciStream::ReleaseMapping для освобождения ранее приобретенного сопоставления (части буфера клиента), положение чтения перемещается к расположению последнего байта в освобожденном сопоставлении (в буфере клиента).
Драйверы минипорта не должны реализовывать подпрограммы обработчика для запросов свойств KSPROPERTY_AUDIO_POSITION. Вместо этого драйверы портов WaveCyclic и WavePci обрабатывают эти запросы от имени драйверов минипорта. При обработке запроса get-property драйвер порта WaveCyclic или WavePci уже содержит все сведения, необходимые для вычисления значения WriteOffset, но по-прежнему требуются сведения от мини-драйвера для вычисления значения PlayOffset. Чтобы получить эти сведения, драйвер порта вызывает метод IMiniportWaveCyclicStream::GetPosition или IMiniportWavePciStream::GetPosition .
Для потока отрисовки метод GetPosition извлекает положение воспроизведения — смещение байтов семпла, который в настоящее время воспроизводится через ЦАП. Для потока захвата метод GetPosition извлекает позицию записи — байтовое смещение последнего образца, который был захвачен АЦП.
Обратите внимание, что значение смещения, полученное вызовом GetPosition , — это положение воспроизведения, соответствующее сигналу, передаваемого в данный момент через разъем динамика, или положение записи, соответствующее сигналу, полученному в данный момент через разъем микрофона. Это не позиция DMA. (Позиция DMA — это смещение байта образца, который движок DMA в звуковом устройстве в настоящее время передает в буфер DMA или из него.)
Некоторые звуковые оборудования содержат регистр положения для отслеживания смещения байта образца, которое в данный момент находится в каждом DAC или ADC, в этом случае метод GetPosition извлекает содержимое регистра положения для соответствующего потока. Другое звуковое оборудование может предоставлять драйверу только позицию DMA. В этом случае метод GetPosition должен обеспечить наилучшую оценку смещения байтового оффсета образца в ЦАП или АЦП, принимая во внимание текущую позицию DMA и внутренние задержки, вызванные буферизацией в устройстве.
Хотя обработчик свойств в портовом драйвере WaveCyclic или WavePci должен различать между зацикленными и незацикленными буферами, чтобы определить, следует ли предоставлять смещение в байтах относительно потока или буфера, эта информация о том, является ли буфер зацикленным или незацикленным, является прозрачной для минипорт-драйвера.
Метод IMiniportWaveCyclicStream::GetPosition всегда сообщает о позиционировании воспроизведения или записи относительно буфера, независимо от того, работает ли буфер клиента в циклическом или нециклическом режиме. Если буфер клиента цикличен, обработчик свойств преобразует позицию относительно буфера, сообщаемую минипорт-драйвером как смещение в циклическом буфере, в смещение в буфере клиента, которое затем записывает в член PlayOffset. Если буфер клиента не зациклен, обработчик свойств преобразует позицию воспроизведения относительно буфера в позицию воспроизведения относительно потока перед записью в член PlayOffset.
Метод IMiniportWavePciStream::GetPosition всегда сообщает о позиции воспроизведения или записи относительно потока, независимо от того, цикличен или нецикличен буфер клиента. Если буфер клиента цикличен, обработчик свойств преобразует позицию воспроизведения относительного потока в позицию воспроизведения относительно буфера (выраженную как смещение в буфер клиента), прежде чем записывать его в элемент PlayOffset в структуре KSAUDIO_POSITION в запросе свойства. Если буфер клиента не зациклен, обработчик свойств записывает положение относительно потока в элемент PlayOffset.
Позиция воспроизведения или записи равна нулю сразу после инициализации потока. Переход к состоянию KSSTATE_STOP (см. KSSTATE) сбрасывает позицию до нуля. Когда поток останавливается переходом от KSSTATE_RUN к KSSTATE_PAUSE или KSSTATE_ACQUIRE, позиция зависает. Он отменяет при переходе потока с KSSTATE_PAUSE или KSSTATE_ACQUIRE обратно в KSSTATE_RUN.
Примеры реализации методов GetPosition для драйверов мини-порта WaveCyclic и WavePci см. в примере звуковых драйверов в комплекте драйверов Windows (WDK).