Поделиться через


Синхронизация времени

Критически важной задачей приемника волны является разрешение смещения времени между кристаллами эталонных и контрольных часов. Это делается с помощью программного эквивалента цикла фазовой блокировки.

Приемник волны отслеживает номер выборки в буфере, в который он может записать следующий. Таким образом, несмотря на то, что он знает, что он включен, например, в выборке 20, приемник волны по-прежнему должен проверка master часы, чтобы получить эталонное время. Он имеет поток, который просыпается примерно каждые 20 миллисекунд и запрашивает master часов для текущего времени. Например, master часы могут сообщать о том, что текущее время (в миллисекундах) равно 420.

Приемник волн также поддерживает часы задержки, которые показывают смещение между текущим временем в соответствии с master часами и временем выборки. Эта информация используется для вычисления ожидаемого времени master часов и сравнивает их с фактическими master считывания часов, чтобы увидеть, смещение двух часов.

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

Часы задержки сообщают приложению самое раннее время, когда можно запланировать воспроизведение новой заметки. Время задержки — это время master часов плюс смещение, представляющее задержку синтезатора. Эта задержка представляет собой минимальную задержку с момента, когда приложение отправляет новую воспроизводимую заметку, до момента, когда синтезатор фактически воспроизводит заметку. В любой момент приложение может запланировать воспроизведение заметки со временем текущей задержки или позже, но не раньше текущего времени задержки.

Например, если master часы в настоящее время находятся на момент времени 420 и приложение имеет заметку о том, что оно хочет воспроизвести как можно скорее, часы задержки сообщают, что это самое раннее время воспроизведения заметки. Если программный синтезатор имеет задержку в 100 миллисекундах, в следующий раз он сможет воспроизвести заметку в 520.

Предположим, что событие помечено для воспроизведения в время 520 в исходное время. Синтезатор выполняет свою работу, отрисовывая заметки в образцы и выполняя все вычисления во время выборки. Поэтому ему необходимо знать, во что преобразуется эталонное время 520 во время выборки. В пользовательском режиме приемник волны предоставляет две функции, используемые синтезатором:

IDirectMusicSynthSink::SampleToRefTime и IDirectMusicSynthSink::RefTimeToSample**

Чтобы выполнить преобразование в этом случае, синтезатор вызывает IDirectMusicSynthSink::RefTimeToSample в приемнике волн.

Затем приемник волны возвращает время выборки (например, 600). Соответствующее примечание отображается во время выборки 600. Затем, когда метод synth IDirectMusicSynth::Render вызывается приемником волны для отрисовки следующей части потока (например, от 600 до 800), заметка отображается в буфере во время выборки 600.

Примечание Время выборки хранится в виде 64-разрядного числа, чтобы избежать смены. (Значение DWORD переворачено в течение 27 часов.)

Подводя итоги, синтезатор выполняет все свои внутренние вычисления во время выборки, а приемник волны выполняет преобразование в время выборки из времени отсчета и наоборот. Приемник волн также управляет синхронизацией с master часами и предоставляет сведения о задержке. Скрытие этой функции в приемнике волн упрощает запись синтезатора.