alsa: задержка увеличивается при каждом опустошении - PullRequest
0 голосов
/ 25 мая 2018

Я пишу типичный цикл захвата-воспроизведения-воспроизведения.Захват с использованием snd_pcm_readi(), немного дешевого аудио процесса, а затем воспроизведение через snd_pcm_writei().Однопоточный.При размере 128 периодов и 96000 кГц я не чувствую задержки.Хорошо.

Периодически я получаю переполнение буфера (snd_pcm_writei() возвращает -EPIPE);Все в порядке, у меня обычный рабочий стол Ubuntu 16.04, не настроенный на низкую задержку звука.

После некоторых недогрузок задержка становится ощутимой.Я не понимаю, почему.

это моя конфигурация устройства захвата:

Plug PCM: Linear Integer <-> Linear Float conversion PCM (S32_LE)
Its setup is:
  stream       : CAPTURE
  access       : RW_INTERLEAVED
  format       : FLOAT_LE
  subformat    : STD
  channels     : 1
  rate         : 96000
  exact rate   : 96000 (96000/1)
  msbits       : 32
  buffer_size  : 4096
  period_size  : 128
  period_time  : 1333
  tstamp_mode  : NONE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 128
  period_event : 0
  start_threshold  : 0
  stop_threshold   : 4096
  silence_threshold: 0
  silence_size : 0

И это конфигурация устройства воспроизведения:

Plug PCM: Linear Integer <-> Linear Float conversion PCM (S32_LE)
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : FLOAT_LE
  subformat    : STD
  channels     : 1
  rate         : 96000
  exact rate   : 96000 (96000/1)
  msbits       : 32
  buffer_size  : 384
  period_size  : 128
  period_time  : 1333
  tstamp_mode  : NONE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 128
  period_event : 0
  start_threshold  : 384
  stop_threshold   : 384
  silence_threshold: 0
  silence_size : 0
  boundary     : 6917529027641081856

, когда происходит опустошениеЯ запускаю snd_pcm_recover() и забываю об аудио периоде, который был просто отклонен snd_pcm_writei().По моему мнению, следующий аудио период будет воспроизведен, как только я запусту snd_pcm_writei(), и я снова буду в петле с низкой задержкой.Но это неправильно, задержка увеличивается.

Нет ошибок со стороны захвата моего цикла.

Что происходит?Что я делаю неправильно?

Спасибо.

1 Ответ

0 голосов
/ 25 мая 2018

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

Чтобы устройства захвата и воспроизведения не теряли синхронизацию, либо

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