Каково время задержки (или задержки) для обратных вызовов из метода waveOutWrite API? - PullRequest
1 голос
/ 20 августа 2009

У меня есть спор с некоторыми разработчиками на другом форуме о точной генерации событий MIDI (примечание к сообщениям и т. Д.). Человеческое ухо довольно чувствительно к небольшим временным неточностям, и я думаю, что их основная проблема заключается в использовании таймеров с относительно низким разрешением, которые квантовывают свои события с интервалами в 15 миллисекунд (что достаточно велико, чтобы вызвать заметные неточности).

Около 10 лет назад я написал пример приложения (Visual Basic 5 для Windows 95), которое представляло собой комбинированный программный синтезатор и MIDI-плеер. Основной предпосылкой была система воспроизведения с подпрыгивающим буфером, где каждый буфер представлял собой длительность шестнадцатой ноты (пример: при 120 четвертных нотах в минуту каждая четвертная нота составляла 500 мс, и, следовательно, каждая шестнадцатая нота составляла 125 мс, поэтому каждая буфер составляет 5513 образцов). Каждый буфер воспроизводился с помощью метода waveOutWrite, а функция обратного вызова из этого метода использовалась для постановки в очередь следующего буфера, а также для отправки MIDI-сообщений. Это обеспечивало синхронизацию звука на основе WAV и звука MIDI.

На мой взгляд, этот метод работал отлично - ноты MIDI не звучали даже немного не в ногу (тогда как если вы используете обычный таймер с точностью до 15 мс для воспроизведения ноты MIDI, они будут звучать заметно не в ногу).

Теоретически, этот метод будет производить синхронизацию MIDI с точностью до сэмпла, или 0,0227 миллисекунд (так как на миллисекунду приходится 44,1 сэмпла). Я сомневаюсь, что это истинная задержка этого подхода, так как, вероятно, существует небольшая задержка между завершением буфера и уведомлением обратного вызова waveOutWrite. Кто-нибудь знает, насколько велика будет эта задержка?

Ответы [ 3 ]

5 голосов
/ 23 августа 2009

Планировщик Windows по умолчанию работает с интервалами 10 или 16 мс в зависимости от процессора. Если вы используете API timeBeginPeriod (), вы можете изменить этот интервал (при довольно значительной стоимости энергопотребления).

В Windows XP и Windows 7 волновые API-интерфейсы работают с задержкой около 30 мс, в Windows Vista волновые API-интерфейсы имеют задержку около 50 мс. Затем вам нужно добавить в аудио движок задержки.

К сожалению, у меня нет цифр для задержки двигателя в одном направлении, но у нас есть некоторые цифры относительно задержки двигателя - мы выполнили тест, который воспроизводил тональный сигнал, возвращенный через аудиоустройство USB, и измерил задержку прохождения сигнала в оба конца. (сделать, чтобы захватить). На Vista задержка прохождения туда и обратно составляла около 80 мс с вариацией около 10 мс. На Win7 задержка в оба конца составляла около 40 мс с вариацией около 5 мс. Однако, YMMV, поскольку величина задержки, вносимая аудиооборудованием, различна для каждого компонента оборудования.

Я абсолютно не представляю, какова была задержка для звукового движка XP или звукового стека Win9x.

1 голос
/ 08 октября 2011

Чтобы добавить к отличным ответам выше.

Ваш вопрос о латентности Windows ни пообещал, ни позаботился. И как таковой, он может быть совершенно другим в зависимости от версии ОС, аппаратного обеспечения и других факторов. WaveOut API и DirectSound тоже (не уверен насчет WASAPI, но я полагаю, что это верно и для этого последнего Vista + аудио API) - все они настроены для буферизованного вывода звука. Определенная точность обратного вызова не требуется, если вы вовремя ставите в очередь следующий буфер, пока текущий еще воспроизводится.

Когда вы начинаете воспроизведение звука, у вас есть несколько предположений, таких как отсутствие потерь во время воспроизведения, и весь вывод непрерывен, а частота звука точно соответствует ожидаемой, например, 44100 Гц. Затем вы делаете простую математику, чтобы запланировать выход волны во времени, преобразовав время в сэмплы, а затем в байты.

К сожалению, эффективная скорость воспроизведения не является точной, например, Представьте, что реальная аппаратная частота дискретизации может составлять 44,100 Гц -3%, и в долгосрочной перспективе математика времени до байта может вас подвести. Была предпринята попытка компенсировать этот эффект, например, сделать аудиоаппаратуру тактовой частотой воспроизведения и синхронизировать видео с ней (так работают плееры), а также использовать метод согласования скорости, чтобы согласовать скорость входящих данных с фактической скоростью воспроизведения на аппаратном уровне. И то, и другое делает измерения абсолютного времени и задержки весьма спекулятивным знанием.

Более того, задержки API 20 мс, 30 мс, 50 ​​мс и так далее. С давних пор waveOut API - это слой поверх других API. Это означает, что некоторая обработка выполняется до того, как данные действительно достигают аппаратного обеспечения, и эта обработка требует, чтобы вы заблаговременно убрали руки с очередей, иначе данные не достигнут аппаратного обеспечения. Допустим, если вы попытаетесь поставить в очередь свои данные в 10 мс буферах непосредственно перед временем воспроизведения, API примет эти данные, но сам опоздает с передачей этих данных в нисходящем направлении, и на громкоговорителях будет тихий или комфортный шум.

Теперь это также относится к обратным вызовам, которые вы получаете. Вы можете сказать, что вас не волнует задержка буферов, и для вас важно точное время обратного вызова. Однако, поскольку API является многоуровневым, вы получаете обратный вызов с точностью синхронизации внутреннего уровня, такой второй внутренний уровень уведомляет о свободном буфере, и первый внутренний уровень обновляет свои записи и проверяет, может ли он также освободить ваш буфер (эй, эти буферы не не должно совпадать). Это делает ожидания точности обратного вызова очень слабыми и ненадежными.

При условии, что я не касался API waveOut в течение достаточно долгого времени, если бы возник такой вопрос о точности синхронизации, я бы, вероятно, прежде всего подумал о двух вещах:

  • Windows обеспечивает доступ к звуковым аппаратным часам (я знаю об интерфейсе IReferenceClock, доступном через DirectShow, и, вероятно, это происходит из-за другой вещи более низкого уровня, которая также доступна), и имея такую ​​доступность, я попытался бы синхронизироваться с ней

  • Новейший аудио API от Microsoft, WASAPI, предоставляет специальную поддержку для аудио с малой задержкой, добавляя новые интересные вещи, такие как улучшенное планирование потоков мультимедиа, потоки в эксклюзивном режиме и задержка <10 мс для PCM - это то, где лучше синхронизировать смотреть на </p>

1 голос
/ 20 августа 2009

На самом базовом уровне Windows - многопоточная ОС. И это планирует потоки с 100 мсек. Это означает, что, если нет конфликта ЦП, задержка между концом буфера и обратным вызовом waveOutWrite может быть сколь угодно короткой. Или, если есть другие занятые потоки, вы должны ждать до 100 мс на поток. В лучшем случае, однако ... тактовые частоты процессора сейчас на ГГц. Это ставит абсолютную нижнюю границу того, как быстро может быть вызван обратный вызов с точностью до 0,000,000,000,1 второго порядка.

Если вы не можете определить максимальное количество обратных вызовов waveOutWrite, которое вы можете обработать за одну секунду, что может означать задержку каждого вызова, я думаю, что на самом деле задержка будет на несколько порядков ниже предустановки большинства время, если нет слишком много занятых потоков, и в этом случае все будет идти ужасно, ужасно неправильно.

...