Как работает пример Echo

[Функция, связанная с этой страницей, Медиаплеер Windows SDK, является устаревшей функцией. Он был заменен MediaPlayer. MediaPlayer оптимизирован для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует по возможности использовать MediaPlayer вместо пакета SDK для Медиаплеер Windows. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]

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

размер буфера = время задержки * частота выборки / 1000 * выравнивание блока

Время задержки — в миллисекундах. Значения частоты дискретизации и выравнивания блоков задаются в структуре WAVEFORMATEX. Частота выборки в выборках в секунду; деление на 1000 урожаев выборок на миллисекунды. Выравнивание блока равно произведению числа каналов (1 для моно, 2 для стерео) и количества битов на выборку (8 или 16), разделенных на 8 (битов на байт).

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

После того как буфер задержки существует и Медиаплеер Windows выделяет входной буфер для предоставления звуковых данных и выходной буфер для получения обработанных звуковых данных, обработка эха выполняется следующим образом:

  1. Введите цикл, который позволяет обрабатывать каждый пример звука во входном буфере.
  2. Получение примера из входного буфера. Затем переместите указатель входного буфера вперед к следующему образцу, чтобы подготовиться к итерации следующего цикла.
  3. Получение примера из буфера задержки.
  4. Скопируйте образец из входного буфера в то же место в буфере задержки, из которого был получен последний образец задержки.
  5. Переместите указатель буфера задержки вперед к следующему образцу. Если указатель перемещается за конец буфера, переместите его в начало буфера.
  6. Объедините образец из входного буфера с примером из буфера задержки.
  7. Скопируйте результат в выходной буфер. Затем переместите указатель буфера вывода вперед на следующий урок, чтобы подготовиться к итерации следующего цикла.
  8. Повторяйте, пока не будут обработаны все примеры.

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

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

Обзор примера Echo