Callback-функции PCM устройства
struct ado_pcm_hw {int32_t (*capabilities)( HW_CONTEXT_T *hw_context,snd_pcm_channel_info_t *info );int32_t (*aquire)( HW_CONTEXT_T *hw_context,PCM_SUBCHN_CONTEXT_T **PCM_SUBCHN_CONTEXT,ado_pcm_config_t *config,ado_pcm_subchn_t *subchn,uint32_t *why_failed );int32_t (*release)( HW_CONTEXT_T *hw_context,PCM_SUBCHN_CONTEXT_T *PCM_SUBCHN_CONTEXT,ado_pcm_config_t *config );int32_t (*prepare)( HW_CONTEXT_T *hw_context,PCM_SUBCHN_CONTEXT_T *PCM_SUBCHN_CONTEXT,ado_pcm_config_t *config );int32_t (*trigger)( HW_CONTEXT_T *hw_context,PCM_SUBCHN_CONTEXT_T *PCM_SUBCHN_CONTEXT,uint32_t cmd );uint32_t (*position)( HW_CONTEXT_T *hw_context,PCM_SUBCHN_CONTEXT_T *PCM_SUBCHN_CONTEXT,ado_pcm_config_t *config );int32_t (*reconstitute)( ado_pcm_config_t * config, int8_t *dmaptr,size_t size );} ado_pcm_hw_t;
Структура ado_pcm_hw_t
определяет callback-функции, которые драйвер должен предоставить для PCM устройства при осуществлении воспроизведения и/или захвата аудио данных.
Перечень callback-функций:
Прототип:
int32_t (*aquire)( HW_CONTEXT_T *hw_context,PCM_SUBCHN_CONTEXT_T **PCM_SUBCHN_CONTEXT,ado_pcm_config_t *config,ado_pcm_subchn_t *subchn,uint32_t *why_failed );
Вызывается при попытке клиентом открыть PCM поток.
![]() | Имя члена структуры написано с ошибками, но для совместимости со старыми драйверми эту опечатку приходится сохранять. |
Аргументы:
PCM_SUBCHN_CONTEXT_T
. ado_pcm_subchn_t
, описывающую субканал. Функция вызывается только если запрос клиента соответствует возможностям устройства. При этом опрашивается соответствующая структура, указанная при создании PCM устройства.
Основная задача callback-а в проверке способности устройства удовлетворить запрос. В этом случае драйвер должен выделить все необходимые ресурсы и DMA буферы для канала. Стоит учитывать, что устройство может поддерживать несколько субканалов, но число ресурсов при этом может оказаться ограниченным, что помешает удовлетворить запрос. В этом случае запрос должен быть отклонен, даже если имеются в достаточном количестве неактивные субканалы.
Пример: устройство с 8 преобразователями частоты дискретизации, поддерживающая до 24 потоков с исходной частотой дискретизации в 48 КГц. Если 9 клиентов попытаются воспроизвести данные с частотой 22 КГц, один из них потерпит неудачу, но пройдет до 16 запросов с частотой 48 КГц.
Возвращаемое значение:
Прототип:
int32_t (*release)( HW_CONTEXT_T *hw_context,PCM_SUBCHN_CONTEXT_T *PCM_SUBCHN_CONTEXT,ado_pcm_config_t *config );
Вызывается при завершении клиентской сессии с устройством, что является обратной процедурой к aquire(). При вызове следует освободить все ассоциированные ресурсы и DMA буферы.
Возвращаемое значение: EOK
.
Прототип:
int32_t (*prepare)( HW_CONTEXT_T *hw_context,PCM_SUBCHN_CONTEXT_T *PCM_SUBCHN_CONTEXT,ado_pcm_config_t *config );
Вызывается при подготовке оборудования к работе. Основное назначение в том, что поток может остановиться и перезапуститься в произвольное время, поэтому оборудование должно быть сброшено. Обычно функция просто сбрасывает DMA для перезапуска текущего буфера с начала.
Возвращаемое значение: EOK
.
Прототип:
int32_t (*trigger)( HW_CONTEXT_T *hw_context,PCM_SUBCHN_CONTEXT_T *PCM_SUBCHN_CONTEXT,uint32_t cmd );
Вызывается при необходимости остановить или начать операцию. Параметр cmd принимает значения:
Возвращаемое значение: EOK
.
Прототип:
uint32_t (*position)( HW_CONTEXT_T *hw_context,PCM_SUBCHN_CONTEXT_T *PCM_SUBCHN_CONTEXT,ado_pcm_config_t *config );
Функция должна сообщить состояние (положение) DMA движка относительно текущего фрагмента. Обычно используется для уведомления пользователя о состоянии воспроизведения.
Возвращается число байт, воспроизведенных от начала фрагмента.
Прототип:
int32_t (*reconstitute)( ado_pcm_config_t *config,int8_t *dmaptr,size_t size );
Данная функция является способом обхода особенностей оборудования с проблемной поддержкой форматов. Она используется для переформатирования данных в DMA буфере.
Пример: оборудование поддерживает 20-битное разрешение в 32-битном семпле. В драйвер поступает буфер со старшим битом в позиции 31, но оборудование ожидает, что старший бит будет в позиции 19. В callback-функции в этом случае придется выполнять побитовый сдвиг со всеми данными в потоке. Естественно, этот подход приводит к лишним накланым расходам и на практике стоит всячески избегать проблемного оборудования.
Возвращаемое значение: EOK
.
Прототип:
int32_t (*capabilities)( HW_CONTEXT_T *hw_context,snd_pcm_channel_info_t *info );
Вызывается при необходимости уведомить клиента о возможностях устройства в текущем экземпляре драйвера. При создании устройства драйвер уведомляет аудио стек о своих возможностях, но в последующем часть каналов может оказаться задействованными и часть из возможностей при этом окажется неактуальными.
Функция вызывается динамически в процессе работы драйвера и обычно должна удалить из структуры info некоторые опции, основываясь на уже задействованных ресурсах и состоянии оборудлвания. В худшем случае, если устройство поддерживает единственный субканал и он уже используется, функция должна удалить все доступные ресурсы из info.
Вызов ado_pcm_subchn_is_channel() применяется для определения типа субканала. Это позволяет использовать один callback и в логике воспроизведения и в логике захвата аудио потока.
Подробнее см. snd_pcm_channel_info_t и snd_pcm_channel_info().
Возвращаемое значение: EOK
.
ЗОСРВ «Нейтрино»
ado_pcm_config_t, ado_pcm_create(), snd_pcm_channel_info()
Предыдущий раздел: Библиотека libado