Когда обновлять указатель буфера аудиодрайвера ALSA

Я пишу драйвер USB Audio Playback, используя ALSA APIs. Для этого я пытался понять существующие звуковые драйверы в Linux ядре. Но я не понимаю, когда обновлять указатель звукового буфера ядра. Мы знаем, что ядро ​​помещает новые аудиоданные в кольцевой буфер, а задача нашего драйвера — брать новые данные из кольцевого буфера, передавать их по USB и обновлять указатель буфера ядра.

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

Но я не понимаю, почему они так уверены, что к моменту завершения передачи URB в буфере ядра будет 4096 байт новых данных? Новый объем данных в буфере ядра может быть меньше 4096 байт? Тогда почему он всегда обновляет указатель буфера на 4096 байт. Я думаю, что должно быть некоторое знание того, сколько новых байтов находится в буфере ядра, и драйвер должен обновляться только на эту сумму, или, может быть, я что-то неправильно понял? Любое предложение или руководство ценны.


person azizulhakim    schedule 15.06.2015    source источник


Ответы (1)


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

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

Аудиодрайверы USB используют точно такой же механизм для обнаружения опустошения, т. е. функция snd_pcm_period_elapsed() проверяет, не находится ли текущая позиция (возвращенная вашим обратным вызовом .pointer) слишком далеко вперед.

person CL.    schedule 16.06.2015
comment
Спасибо КЛ. Это отвечает на мой вопрос. Просто нужно прояснить несколько вещей. Вы сказали, что USB-драйверы используют функцию snd_pcm_period_elapsed(), чтобы проверить, не находится ли текущая позиция слишком далеко впереди. Итак, если это слишком далеко впереди, как это решает эту проблему? Должны ли мы что-то делать с нашим драйвером, чтобы решить эту проблему, или ALSA позаботится об этом? - person azizulhakim; 18.06.2015
comment
ALSA позаботится об остановке потока или выполнении любых других настроек. - person CL.; 18.06.2015