• 【esp32-adf】pipeline源码分析


    一、pipeline介绍

    1.1 介绍

    1.2 代码结构

    二、pipleline源码分析

    2.1 audio_element

    2.1.1 数据结构

    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;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    2.1.2 api

    2.1.2.1 audio_element_init
    audio_element_handle_t audio_element_init(audio_element_cfg_t *config)
    
    • 1

    audio_element_init用上层传入的audio_element_cfg_t去初始化audio_element的成员变量,包括audio_element的open、process、close、destroy、seek方法,audio_element任务的属性。

    2.1.2.2 audio_element_setdata
    esp_err_t audio_element_setdata(audio_element_handle_t el, void *data)
    
    • 1

    audio_element_setdata用于将对象存入audio_element的私有数据,用作对象的上下文。

    2.1.2.3 audio_element_run
    esp_err_t audio_element_run(audio_element_handle_t el)
    
    • 1

    audio_element_run创建一个Task用来处理audio_element的专有任务。

    2.1.2.4 audio_element_task
    void audio_element_task(void *pv)
    
    • 1

    audio_element_task是audio_element_run创建的audio_element的处理专有业务的专有任务。调用audio_event_iface_waiting_cmd_msg等待命令,接受到命令后通过audio_element_process_running调用注册的process做element的业务处理。

    2.1.2.5 audio_element_input
    audio_element_err_t audio_element_input(audio_element_handle_t el, char *buffer, int wanted_size)
    
    • 1
    2.1.2.6 audio_element_output
    audio_element_err_t audio_element_output(audio_element_handle_t el, char *buffer, int write_size)
    
    • 1

    audio_element_output将audio_element的输出放入输出ringbuffer。

    2.1.2.7 audio_element_cmd_send
    esp_err_t audio_element_cmd_send(audio_element_handle_t el, audio_element_msg_cmd_t cmd)
    
    • 1

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.2 audio_pipeline

    2.2.1 数据结构

    2.2.2 api

    2.2.2.1 audio_pipeline_register
    esp_err_t audio_pipeline_register(audio_pipeline_handle_t pipeline, audio_element_handle_t el, const char *name)
    
    • 1

    audio_pipeline_register将audio_element注册到pipeline,底层通过STAILQ_INSERT_TAIL向el_list插入链表元素。

    2.2.2.2 audio_pipeline_link
    esp_err_t audio_pipeline_link(audio_pipeline_handle_t pipeline, const char *link_tag[], int link_num)
    
    • 1

    在audio_pipeline_link中,遍历pipeline的el_list链表,将el_list链表上的audio_element的输入和输出的ringbuffer连接在一起。

    2.2.2.3 audio_pipeline_run
    esp_err_t audio_pipeline_run(audio_pipeline_handle_t pipeline)
    
    • 1

    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里处理业务。

    2.3 audio_event_iface

    2.3.1 数据结构

    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;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.3.2 api

    2.3.2.1 audio_event_iface_waiting_cmd_msg
    esp_err_t audio_event_iface_waiting_cmd_msg(audio_event_iface_handle_t evt)
    
    • 1

    audio_event_iface_waiting_cmd_msg通过等待audio_event_iface_handle_t的internal_queue来处理事件。

    2.3.2.2 audio_event_iface_cmd
    esp_err_t audio_event_iface_cmd(audio_event_iface_handle_t evt, audio_event_iface_msg_t *msg)
    
    • 1

    audio_event_iface_cmd通过发送internal_queue触发等待internal_queue的任务,audio_element的audio_element_cmd_send通过调用audio_event_iface_cmd接口对内部internal_queue传递消息。

    2.4 主要的数据处理流程

    2.4.1

    2.5 pipeline处理流程–以play_bt_music_example举例

    三、参考

  • 相关阅读:
    [数据集][目标检测]猕猴桃检测数据集VOC+YOLO格式1838张1类别
    洛谷刷题C语言:SKOCIMIS、JACK、TIMSKO、TRIK、OKUPLJANJE
    《Weisfeiler and Leman Go Neural Higher-order Graph Neural Networks》阅读笔记
    18. 从零开始编写一个类nginx工具, 主动式健康检查源码实现
    java导出功能(多个sheet页数据导出)
    常见的旅游类软文类型分享
    初出茅庐的小李博客之根据编译时间生成软件版本号
    YOLOv5-调用官方权重进行检验(目标检测)
    MCP2515调试心得
    Linux 设置cd后自动ls、快捷键自动跳转指定目录或操作
  • 原文地址:https://blog.csdn.net/weixin_43810563/article/details/127738081