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

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

Введение

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

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

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

  3. Частота дискретизации

  4. Выборки на систему координат (buffer size)

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

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

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

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

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

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

Измерение Задержки с 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 и частоты дискретизации. Можно добавить КИХ-фильтр линейной фазы цепь обработки, чтобы проверить, что измерения задержки как ожидалось. Кроме того, это обеспечивает способ проверить робастность обработки аудиоданных в реальном времени при данной рабочей нагрузке. Например,

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