Измерение задержки звука

Этот пример показов, как измерить задержку аудио устройства. Пример использует 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 Audio 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