struct audio_element {
/* Functions/RingBuffers */
el_io_func open;
ctrl_func seek;
process_func process;
el_io_func close;
el_io_func destroy;
io_type_t read_type;
union {
ringbuf_handle_t input_rb;
io_callback_t read_cb;
} in;
io_type_t write_type;
union {
ringbuf_handle_t output_rb;
io_callback_t write_cb;
} out;
audio_multi_rb_t multi_in;
audio_multi_rb_t multi_out;
/* Properties */
volatile bool is_open;
audio_element_state_t state;
events_type_t events_type;
audio_event_iface_handle_t iface_event;
audio_callback_t callback_event;
int buf_size;
char *buf;
char *tag;
int task_stack;
int task_prio;
int task_core;
xSemaphoreHandle lock;
audio_element_info_t info;
audio_element_info_t *report_info;
bool stack_in_ext;
audio_thread_t audio_thread;
/* PrivateData */
void *data;
EventGroupHandle_t state_event;
int input_wait_time;
int output_wait_time;
int out_buf_size_expect;
int out_rb_size;
volatile bool is_running;
volatile bool task_run;
volatile bool stopping;
};
audio_element_handle_t audio_element_init(audio_element_cfg_t *config)
audio_element_init用上层传入的audio_element_cfg_t去初始化audio_element的成员变量,包括audio_element的open、process、close、destroy、seek方法,audio_element任务的属性。
esp_err_t audio_element_setdata(audio_element_handle_t el, void *data)
audio_element_setdata用于将对象存入audio_element的私有数据,用作对象的上下文。
esp_err_t audio_element_run(audio_element_handle_t el)
audio_element_run创建一个Task用来处理audio_element的专有任务。
void audio_element_task(void *pv)
audio_element_task是audio_element_run创建的audio_element的处理专有业务的专有任务。调用audio_event_iface_waiting_cmd_msg等待命令,接受到命令后通过audio_element_process_running调用注册的process做element的业务处理。
audio_element_err_t audio_element_input(audio_element_handle_t el, char *buffer, int wanted_size)
audio_element_err_t audio_element_output(audio_element_handle_t el, char *buffer, int write_size)
audio_element_output将audio_element的输出放入输出ringbuffer。
esp_err_t audio_element_cmd_send(audio_element_handle_t el, audio_element_msg_cmd_t cmd)
audio_element_cmd_send通过audio_element的iface_event向audio_elment_task发送命令,支持的命令的如下:
typedef enum {
AEL_MSG_CMD_NONE = 0,
// AEL_MSG_CMD_ERROR = 1,
AEL_MSG_CMD_FINISH = 2,
AEL_MSG_CMD_STOP = 3,
AEL_MSG_CMD_PAUSE = 4,
AEL_MSG_CMD_RESUME = 5,
AEL_MSG_CMD_DESTROY = 6,
// AEL_MSG_CMD_CHANGE_STATE = 7,
AEL_MSG_CMD_REPORT_STATUS = 8,
AEL_MSG_CMD_REPORT_MUSIC_INFO = 9,
AEL_MSG_CMD_REPORT_CODEC_FMT = 10,
AEL_MSG_CMD_REPORT_POSITION = 11,
} audio_element_msg_cmd_t;
esp_err_t audio_pipeline_register(audio_pipeline_handle_t pipeline, audio_element_handle_t el, const char *name)
audio_pipeline_register将audio_element注册到pipeline,底层通过STAILQ_INSERT_TAIL向el_list插入链表元素。
esp_err_t audio_pipeline_link(audio_pipeline_handle_t pipeline, const char *link_tag[], int link_num)
在audio_pipeline_link中,遍历pipeline的el_list链表,将el_list链表上的audio_element的输入和输出的ringbuffer连接在一起。
esp_err_t audio_pipeline_run(audio_pipeline_handle_t pipeline)
audio_pipeline_run调用audio_element_run将el_list链表上的audio_element运行起来,这些audio_element是在audio_pipeline_register时插入el_list链表的元素,audio_element_run的底层是创建freeRTOS的Task,各个audio_element独立的在自己的Task里处理业务。
struct audio_event_iface {
QueueHandle_t internal_queue;
QueueHandle_t external_queue;
QueueSetHandle_t queue_set;
int internal_queue_size;
int external_queue_size;
int queue_set_size;
audio_event_iface_list_t listening_queues;
void *context;
on_event_iface_func on_cmd;
int wait_time;
int type;
};
esp_err_t audio_event_iface_waiting_cmd_msg(audio_event_iface_handle_t evt)
audio_event_iface_waiting_cmd_msg通过等待audio_event_iface_handle_t的internal_queue来处理事件。
esp_err_t audio_event_iface_cmd(audio_event_iface_handle_t evt, audio_event_iface_msg_t *msg)
audio_event_iface_cmd通过发送internal_queue触发等待internal_queue的任务,audio_element的audio_element_cmd_send通过调用audio_event_iface_cmd接口对内部internal_queue传递消息。