Как использовать ALSA snd_pcm_writei ()? - PullRequest
4 голосов
/ 02 февраля 2010

Может кто-нибудь объяснить, как snd_pcm_writei

snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer,
                                 snd_pcm_uframes_t size)

работает

Я использовал это так:

for (int i = 0; i < 1; i++) {
   f = snd_pcm_writei(handle, buffer, frames);

   ...
}

Полный исходный код на http://pastebin.com/m2f28b578

Значит ли это, что я не должен давать snd_pcm_writei() число все кадры в buffer, но только

sample_rate * latency = frames

Так что, если я, например, иметь: sample_rate = 44100 задержка = 0,5 [с] all_frames = 100000

Количество кадров, которое я должен дать snd_pcm_writei(), будет

sample_rate * latency = frames 44100 * 0,5 = 22050

а количество итераций цикла for должно быть?:

(int) 100000/22050 = 4; с рамками = 22050

и один дополнительный, но только с

100000 мод 22050 = 11800

кадров

Это так работает?

Louise

http://www.alsa -project.org / ALSA-док / ALSA Пб / группа ___ p_c_m.html # gf13067c0ebde29118ca05af76e5b17a9

Ответы [ 4 ]

6 голосов
/ 02 февраля 2010

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

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

Чтобы уменьшить задержку на стороне приложениявам нужно написать наименьший буфер, который будет работать для вас.Если ваше приложение выполняет задачу DSP, это, как правило, ценность данных одного окна.

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

Длядизайн, который делает создание данных в непрерывном режиме с помощью звукового драйвера относительно легким, посмотрите на гнездо (http://jackaudio.org/), которое основано на регистрации функции обратного вызова с помощью механизма воспроизведения звука. На самом деле, вам, вероятно, лучше использовать гнездовместо того, чтобы пытаться сделать это самостоятельно, если вы действительно беспокоитесь о задержке.

3 голосов
/ 08 марта 2013

Я думаю, что причина «преждевременного» закрытия устройства заключается в том, что вам нужно позвонить snd_pcm_drain(handle); до snd_pcm_close(handle);, чтобы убедиться, что все данные воспроизводятся до закрытия устройства.

3 голосов
/ 18 ноября 2012

Я провел некоторое тестирование, чтобы определить, почему snd_pcm_writei() не работает для меня, используя несколько примеров, которые я нашел в руководствах ALSA, и я пришел к выводу, что простые примеры выполняли snd_pcm_close () до того, как звуковое устройство могло воспроизвести весь поток, отправленный на него.

Я установил скорость на 11025, использовал 128-байтовый случайный буфер и для петли snd_pcm_writei() для 11025/128 для каждой секунды звука. Две секунды потребовали 86 * 2 вызовов snd_pcm_write(), чтобы получить две секунды звука.

Чтобы дать устройству достаточно времени для преобразования данных в аудио, я использовал цикл for после цикла snd_pcm_writei(), чтобы задержать выполнение функции snd_pcm_close().

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

0 голосов
/ 21 сентября 2014

Если порог запуска драйвера ALSA не установлен должным образом (если в вашем случае он составляет около 2 с), то вам нужно вызвать snd_pcm_start (), чтобы начать рендеринг данных сразу после snd_pcm_writei (). Или вы можете установить соответствующий порог в параметрах программного обеспечения устройства ALSA.

исй:

...