Измерьте аудио задержку

Этот пример показывает, как измерить задержку аудио устройства. Пример использует audioLatencyMeasurementExampleApp, который в свою очередь использует audioPlayerRecorder наряду с тестовым сигналом и взаимной корреляцией, чтобы определить задержку. Чтобы избежать интерференции доступа к диску, тестовый сигнал загружается в dsp. Объект AsyncBuffer сначала и кадры передаются потоком от того объекта до аудио устройства.

Введение

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

  1. Оборудование (включая A/D и преобразование D/A)

  2. Драйверы аудио, которые связываются со звуковой картой системы

  3. Выборка уровня

  4. Выборки на кадр (buffer size)

  5. Алгоритмическая задержка (например, задержка, введенная фильтром или звуковым эффектом)

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

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

Аппаратная задержка

Меньшие форматы кадра и более высокие уровни выборки уменьшают задержку туда и обратно. Однако компромисс является более высоким шансом уволенных, происходящих (переполнения/недогрузки).

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

Измерение Задержки с audioLatencyMeasurementExampleApp.m

Функция audioLatencyMeasurementExampleApp вычисляет задержку туда и обратно в миллисекундах для данной настройки. Переполнения и недогрузки также представлены. Если переполнения/недогрузки не являются нулем, результаты, вероятно, недопустимы. Например:

audioLatencyMeasurementExampleApp('SamplesPerFrame',64,'SampleRate',48e3)

% The measurements in this example were done on macOS. For most
% measurements, a Steinberg UR22 external USB device was used. For the
% measurements with custom I/O channels, an RME Fireface UFX+ device was
% used. This RME device has lower latency than the Steinberg device for a
% given sample rate/frame size combination. Measurements on Windows using
% ASIO drivers should result in similar values.
Trial(s) done for frameSize 64. 
ans =
  1×5 table
    SamplesPerFrame    SampleRate_kHz    Latency_ms    Overruns    Underruns
    _______________    ______________    __________    ________    _________
      64                 48                8.3125        0           0        

Некоторые советы при измерении задержки

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

  1. Закройте все другие программы

  2. Гарантируйте, что никакие недогрузки/переполнения не происходят

  3. Используйте достаточно большой buffer size (SamplesPerFrame), чтобы гарантировать сопоставимое поведение без уволенных

  4. Гарантируйте, что ваши аппаратные настройки (buffer size, выбирая уровень) совпадают с входными параметрами к measureLatency

На Windows можно использовать функцию asiosettings, чтобы запустить диалоговое окно, чтобы управлять аппаратными настройками. На macOS необходимо запустить Аудио Setup MIDI.

При использовании ASIO (или CoreAudio с Mac OS), измерения задержки сопоставимы, пока никакие уволенные не происходят. Для небольших буферных размеров возможно получить чистое измерение в одном экземпляре и уволенных следующее. Опция Ntrials может использоваться, чтобы гарантировать сопоставимое поведение уволенного при измерении задержки. Например, чтобы выполнить 3 измерения, используйте:

audioLatencyMeasurementExampleApp('SamplesPerFrame',96,...
    'SampleRate',48e3,'Ntrials',3)
Trial(s) done for frameSize 96. 
ans =
  3×5 table
    SamplesPerFrame    SampleRate_kHz    Latency_ms    Overruns    Underruns
    _______________    ______________    __________    ________    _________
      96                 48                10.312        0           0        
      96                 48                10.312        0           0        
      96                 48                10.312        0           0        

Измерения для различных буферных размеров

На macOS также возможно попробовать различные форматы кадра, не изменяя аппаратные настройки. Чтобы сделать это удобным, можно задать вектор SamplesPerFrame:

BufferSizes = [64;96;128];
t = audioLatencyMeasurementExampleApp('SamplesPerFrame',BufferSizes)

% Notice that for every sample increment in the buffer size, the additional
% latency is 3*SamplesPerFrameIncrement/SampleRate (macOS only).
Trial(s) done for frameSize 64. 
Trial(s) done for frameSize 96. 
Trial(s) done for frameSize 128. 
t =
  3×5 table
    SamplesPerFrame    SampleRate_kHz    Latency_ms    Overruns    Underruns
    _______________    ______________    __________    ________    _________
       64                48                8.3125        0           0        
       96                48                10.312        0           0        
      128                48                12.312        0           0        

А именно, в предыдущем примере шаг

3*[128-96, 96-64]/48e3

% In addition, notice that the actual buffering latency is also determined
% by 3*SamplesPerFrame/SampleRate. Subtracting this value from the measured
% latency gives a measure of the latency introduced by the device (combined
% effect of A/D conversion, D/A conversion, and drivers). The numbers above
% indicate about 4.3125 ms latency due to device-specific factors.

t.Latency_ms - 3*BufferSizes/48
ans =
    0.0020    0.0020
ans =
    4.3125
    4.3125
    4.3125

Определение Пользовательских Каналов ввода-вывода

Измерения, выполняемые до сих пор, принимают, что канал № 1 используется для обоих вводов и выводов. Если вашему устройству соединили петлевой кабель с другими каналами, можно задать их использующий опцию IOChannels для measureLatency. Это задано как вектор с 2 элементами, соответствуя каналам ввода и вывода, которые будут использоваться (измерение всегда находится на моно сигнале). Например, для RME Fireface UFX +:

audioLatencyMeasurementExampleApp('SamplesPerFrame',[32 64 96],...
    'SampleRate',96e3,'Device','Fireface UFX+ (23767940)',...
    'IOChannels',[1 3])
Trial(s) done for frameSize 32. 
Trial(s) done for frameSize 64. 
Trial(s) done for frameSize 96. 
ans =
  3×5 table
    SamplesPerFrame    SampleRate_kHz    Latency_ms    Overruns     Underruns 
    _______________    ______________    __________    _________    __________
      32                 96                2.6458        0           32       
      64                 96                3.6458        0            0       
      96                 96                4.6458        0            0       

Алгоритмическая задержка

Измерения до сих пор не включали задержку алгоритма. Поэтому они представляют минимальную задержку туда и обратно, которая может быть достигнута для данного устройства, buffer size и уровня выборки. Можно добавить, что линейная фаза FIR фильтрует цепочку обработки, чтобы проверить, что измерения задержки как ожидалось. Кроме того, это обеспечивает способ проверить робастность обработки аудиоданных в реальном времени при данной рабочей нагрузке. Например,

L  = 961;
Fs = 48e3;
audioLatencyMeasurementExampleApp('SamplesPerFrame',128,...
    'SampleRate',Fs,'FilterLength',L,'Ntrials',3)

% The latency introduced by the filter is given by the filter's
% group-delay.

GroupDelay = (L-1)/2/Fs

% The group delay accounts for the 10 ms of additional latency when using a
% 961-tap linear-phase FIR filter vs. the minimal achievable latency.
Trial(s) done for frameSize 128. 
ans =
  3×6 table
    SamplesPerFrame    SampleRate_kHz    FilterLength    Latency_ms    Overruns    Underruns
    _______________    ______________    ____________    __________    ________    _________
      128                48                961             22.312        0           0        
      128                48                961             22.312        0           0        
      128                48                961             22.312        0           0        
GroupDelay =
    0.0100

Графический вывод исходного и записанного сигнала

%The latency measurements are determined by cross-correlating a source
%audio signal with a delayed version of the signal that results after
%loopback through the audio device. You can use the Plot option in
%measureLatency to plot the original and delayed signal along with the
%cross correlation:
audioLatencyMeasurementExampleApp('SamplesPerFrame',128,'Plot',true)

% If the optional FIR filtering is used, the waveforms are not affected
% because the filter used has a broader bandwidth than the test audio
% signal.
Trial(s) done for frameSize 128. 
Plotting... 
ans =
  1×5 table
    SamplesPerFrame    SampleRate_kHz    Latency_ms    Overruns    Underruns
    _______________    ______________    __________    ________    _________
      128                48                12.312        0           0