Значение периода в ALSA

Я использую ALSA для и аудио приложения в Linux, я нашел, что большие документы объясняют, как его использовать: 1 и этот. хотя у меня есть некоторые проблемы, чтобы понять эту часть настройки:

 /* Set number of periods. Periods used to be called fragments. */ 
if (snd_pcm_hw_params_set_periods(pcm_handle, hwparams, periods, 0) < 0) {
  fprintf(stderr, "Error setting periods.\n");
  return(-1);
}

что означает установленное количество периодов, когда я использую режим ВОСПРОИЗВЕДЕНИЯ и:

/* Set buffer size (in frames). The resulting latency is given by */
/* latency = periodsize * periods / (rate * bytes_per_frame)     */
if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize * periods)>>2) < 0) {
  fprintf(stderr, "Error setting buffersize.\n");
  return(-1);
}

и тот же вопрос здесь о латентности, как я должен это понимать? Заранее благодарю за любую помощь!

Ответ 1

Я предполагаю, что вы прочитали и поняли этот раздел linux-journal. Вы также можете обнаружить, что этот блог разъясняет вещи в отношении выбора размера периода (или фрагмента в блоге) в контексте ALSA. Цитировать:

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

Задержка определяется размером буфера.
     Интервал пробуждения определяется размером фрагмента.

Уровень заполнения буфера будет колебаться между "полным буфером" и "полным буфер минус 1x размер фрагмента минус время ожидания планирования ОС". настройка меньшие размеры фрагментов увеличат нагрузку на процессор и уменьшат батарею время, когда вы вынуждаете процессор просыпаться чаще. OTOH увеличивается выйдите из безопасности, так как вы ранее заполняете буфер воспроизведения. Выбор размер фрагмента - это то, что вам нужно сделать, балансируя ваши потребности между потреблением энергии и безопасностью отсева. С современными процессоры и хороший планировщик ОС, такой как Linux, устанавливающий размер фрагмента на все, кроме половины размера буфера, не имеют смысл.

... (О, ALSA использует термин "период" для того, что я называю "фрагментом", выше. Это синоним)

Итак, как правило, вы должны установить period в 2 (как это было сделано в howto, на который вы ссылались). Тогда periodsize * period - ваш общий размер буфера в байтах. Наконец, latency - это задержка, вызванная буферизацией этого множества выборок, и ее можно вычислить, разделив размер буфера на скорость, с которой воспроизводятся образцы (т.е. согласно формуле latency = periodsize * periods / (rate * bytes_per_frame) в комментариях кода).

Например, параметры из howto:

  • period = 2
  • periodize = 8192 bytes
  • rate = 44100 Гц
  • 16 бит стереозвука (4 байта на кадр)

соответствуют суммарному размеру буфера period * periodsize = 2 * 8192 = 16384 байтов и задержке 16384/(44100 * 4) ~ 0,093` секунд.

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

Ответ 2

Когда приложение пытается записать образцы в буфер, если буфер уже заполнен, процесс переходит в режим сна. Он разбужается аппаратными средствами через прерывание; это прерывание поднимается в конце каждого периода.

В буфере должно быть не менее двух периодов; в противном случае буфер уже пуст, когда происходит пробуждение, что приводит к недоработку.

Увеличение количества периодов (т.е. уменьшение размера периода) увеличивает запас безопасности от недоработок, вызванных задержками планирования или обработки.

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