BES音频框架分析---Audioflinger

Audioflinger模块

音频策略的执行者,负责输入输出流设备的管理及音频流数据的处理传输。 Audioflinger.c完成af创建及音频流管理。

 af_open()

函数的调用:app_init(void)--->af_open();

函数内流程:

(1)初始化struct af_stream_cfg_t *role相关参数

(2)创建af_thread,并使用信号量机制完成线程同步,同时af线程内af_thread_stream_handler()会对是否信号丢失、dma地址指针非法,语音数据处理回调超时等做判断。

af_thread_tid = osThreadCreate(osThread(af_thread), NULL);
af_default_priority = af_get_priority();
osSignalSet(af_thread_tid, 0x0);

(3)af_thread_tid信号量的产生过程参考af_stream_open()

 App_audio 模块

app_audio_open()

函数的调用:app_init(void)--->app_audio_open();

函数内流程:

(1)初始化提示音模块,调用app_prompt_list_init()完成了内存空间申请,app_prompt_list申请,app_prompt_handler_tid创建;

 if (NULL == app_prompt_request_mempool)
    {
        app_prompt_request_mempool = osPoolCreate(osPool(app_prompt_request_mempool));
    }
    app_prompt_list = list_new(app_prompt_list_free, NULL, NULL);
    app_prompt_handler_tid = osThreadCreate(osThread(app_prompt_handler_thread), NULL);

(2)设置APP_MODUAL_AUDIO模块的回调app_audio_handle_process(),根据当前设置的APP_BT_SETTING_T完成音频流的开启app_bt_stream_open或关闭app_bt_stream_close处理,其内部维护了一个audio队列,依赖于宏定义 __AUDIO_QUEUE_SUPPORT__;

app_set_threadhandle(APP_MODUAL_AUDIO, app_audio_handle_process);

enum APP_BT_SETTING_T {
    APP_BT_SETTING_OPEN = 0,
    APP_BT_SETTING_CLOSE,
    APP_BT_SETTING_SETUP,
    APP_BT_SETTING_RESTART,
    APP_BT_SETTING_CLOSEALL,
    APP_BT_SETTING_CLOSEMEDIA,
    APP_BT_SETTING_NUM,
};

app_audio_list_append(&aud_status)//打开一个流需将其加入队列
app_audio_list_rmv_callback(&a2ud_status, &next_status, APP_BT_SETTING_Q_POS_HEAD)//关闭一个流需将其从队列中删除

(3)bt流触发器初始化app_bt_stream_init(),创建定时器,在音乐或电话流开启时启动定时器回调app_bt_stream_trigger_timeout_cb()向模块APP_MODUAL_AUDIO发消息进入回调app_audio_handle_process完成相应操作

osTimerCreate(osTimer(APP_BT_STREAM_TRIGGER_TIMEOUT), osTimerOnce, NULL);
app_audio_sendrequest_param(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_RESTART, 0, 0)
app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_RESTART, 0);

(3) APP_BT_SETTING_T的产生过程参考bt_media_start()

 App_bt_media_manager模块

app_audio_manager_open()

函数的调用:app_init(void)--->app_audio_manager_open();

函数内流程:

(1)设置APP_MODUAL_AUDIO_MANAGE模块回调app_audio_manager_handle_process(),根据当前BT_MEDIA_MANAGER完成音乐、电话、提示音的开启bt_media_start或关闭bt_media_stop处理。

app_set_threadhandle(APP_MODUAL_AUDIO_MANAGE, app_audio_manager_handle_process);

enum APP_BT_MEDIA_MANAGER_ID_T {
    APP_BT_STREAM_MANAGER_START = 0,
    APP_BT_STREAM_MANAGER_STOP,
    APP_BT_STREAM_MANAGER_STOP_MEDIA,
    APP_BT_STREAM_MANAGER_UPDATE_MEDIA,
    APP_BT_STREAM_MANAGER_SWAP_SCO,
    APP_BT_STREAM_MANAGER_CTRL_VOLUME,
    APP_BT_STREAM_MANAGER_TUNE_SAMPLERATE_RATIO,
    APP_BT_STREAM_MANAGER_NUM,
};

(2) 通过调用audio_prompt_init_handler()---> memset((uint8_t *)&audio_prompt_env, 0, sizeof(audio_prompt_env));将提示音AUDIO_PROMPT_ENV_T初始化为0;

(3) APP_BT_SETTING_T的产生过程分音乐、电话、提示音三部分介绍

提示音流模块

app_voice_report()

函数的调用:在需要播放提示音的地方直接调用该接口

函数内流程:

(1) app_voice_report(APP_STATUS_INDICATION_T status, uint8_t device_id)是提示音总入口函数,APP_STATUS_INDICATION_T 枚举类型参数表示提示音序号,用来索引提示音ID  ,device_id  表示设备号,一般是0.

typedef enum APP_STATUS_INDICATION_T {
    APP_STATUS_INDICATION_POWERON = 0,
	APP_STATUS_INDICATION_AWAKEN,
              ······
}

(2)根据相关宏定义选择不同的提示音播放方式

void media_PlayAudio_locally(AUD_ID_ENUM id, uint8_t device_id)//仅本地播放
void media_PlayAudio_standalone_locally(AUD_ID_ENUM id, uint8_t device_id)//打断播放
void media_PlayAudio(AUD_ID_ENUM id,uint8_t device_id)//混合播放

(3) 如果是从耳发送命令给对端主耳播放app_tws_let_peer_device_play_audio_prompt()----->tws_ctrl_send_cmd(),如果是主耳发送提示音任务请求app_prompt_push_request()---->app_prompt_list_append(app_prompt_list, &req);---->osSignalSet(app_prompt_handler_tid, PROMPT_HANDLER_SIGNAL_NEW_PROMPT_REQ);

app_prompt_handler_thread()

函数的调用:app_prompt_list_init()--->app_prompt_handler_thread()

函数内流程: 

(1)收到信号PROMPT_HANDLER_SIGNAL_NEW_PROMPT_REQ后,根据当前是否有正在播放的提示音以及app_prompt_list是否为空,通过调用app_prompt_refresh_list来实现相关功能。

 (2)收到信号PPROMPT_HANDLER_SIGNAL_CLEAR_REQ后,先清除app_prompt_list,然后混合模式下发送PROMPT_HANDLER_SIGNAL_PLAYING_COMPLETED信号停止提示音,最后通过app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE, devId)---->app_audio_handle_process()完成提示音流的关闭。

(3)收到信号PROMPT_HANDLER_SIGNAL_PLAYING_COMPLETED,先标识当前没有正在播放的提示音,然后停止提示音保护定时器app_prompt_protector_timer,最后,调用app_prompt_refresh_list来实现相关功能。

app_prompt_refresh_list()

 函数的调用:app_prompt_handler_thread()--->app_prompt_refresh_list()

函数内流程: 

(1)如果当前有正在播放的提示音则退出,没有则继续判断app_prompt_list是否为空,如果为空则退出。

(2)如果app_prompt_list不为空,先标识当前有正在播放的提示音,然后调用app_prompt_

  • 15
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值