BES(恒玄) 提示音解析_筱谙的博客-程序员宅基地

技术标签: BES 开发讲解  

今天,继续讲解BES平台 UI 最后模块--- 提示音.

提示音这一块比较繁琐,也很容易出问题,我们就 提示音实现机制,问题点 做个全面的讲解。

BES 提示音分为两种 触发模式 ,第一种是打断的 ,第二种是mix类型的 。

首先,说下 BES单机模式下 提示音执行流程和机制。

一、单机模式下的提示音流程

BES 提示音的 总入口 是 :app_voice_report(APP_STATUS_INDICATION_T status, uint8_t device_id)

其中 :APP_STATUS_INDICATION_T 枚举类型数据 提示音序号,用来索引提示音ID  ,device_id  表示设备号,一般是0.

通过“void trigger_media_play(AUD_ID_ENUM id, uint8_t devicSe_id, uint16_t aud_pram)”向主线程发出提示音任务请求.

然后跳转到 “app_audio_manager_handle_process”执行.

最后所有的提示音都会跑到“int app_play_audio_onoff(bool onoff, APP_AUDIO_STATUS* status)”里面,在这个函数里面可以设置提示音声道 /采样率 等属性。

最后在函数 “void media_Play_init_audio(uint16_t aud_id)”获取 SBC 数据(media_runtime_audio_prompt_update).

这个修改项一般 相对简单,对应ID 修改SBC原文件就好,例如:

在 res_audio_data.h 里面 找到对用的 提示音源文件并修改。

提示音SBC源文件在工程文件 目录下/config/_default_cfg_src_/res/en 里面

TWS 模式下的 提示音播放 就是在 提示音消息发出之前 增加 一些条件判断和同步等待。

二 、Merge 提示音

上面说的 都是 打断的提示音(会中断当前的音乐/通话),现在说下 mixer的提示音。

和SBC数据不一样,Merge提示音需要PCM(3:1) 格式的数据,所以需要占用更多的存储空间,源文件一般保存在/config/_default_cfg_src_/ring 里面

由于打断类型的提示音需要重复开关codec ,在通话的时候容易产生电流声进而传输带远端,所有在BES2300系列的软件里面需要用到merge提示音.

在WT230U 2300IU  2300IU1 2300ZP 系列早期的SDK 都需要关闭混合提示音的宏。

export MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED ?= 0
export TWS_PROMPT_SYNC ?= 0

使用接口函数 :merge_startint app_ring_merge_start(void);merge_stop :int app_ring_merge_stop(void);

需要注意的是,这个接口都是单边有效,如果在TWS模式,需要自己添加提示音同步机制

当然后面出来的 2500系类 和 2300YP 后期SDK 已经解决了打开混合 提示音宏定义 导致的 死机或者卡顿问题,可以在target.mk里面直接打开

export MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED ?= 1 也就不需要用到以上接口了 .

 

三、提示音常见问题:

1. 播放提示音没有声音

a. 设置声音过小导致:

早期代码在 Tgt_hardware.c里面配置提示音音量大小(第一个)

后面SDK更新后 提示音大小设置到了 app_media_player.cpp 里面设置

b.无法找到相关SBC数据文件,

一般我会在media_runtime_audio_prompt_update 函数最后添加打印“TRACE(1,"media_runtime_audio_prompt_update,current id is %d\n",id);”确认是否关联到了对应的SBC文件。

c.其他原因被打断的,根据上述提示音播放流程逐步跟踪。

d.merge提示音无法播放:

通话或者音乐播放的函数里面确认app_ring_merge_more_data 是否被执行。

2.TWS 提示音播放不同步 或者 副耳无提示音的问题

a. 单边播放问题 :检查当前提示音是否为 单边播放或只设置了单声道

b. 由于延迟偏差不同步导致的副耳无法播放:修改提示音TWS播放等待延迟.在app_ibrt_voice_report_trigger_init 函数里面修改 延迟.(具体数值以实际调试为准,下面数值仅作参考)

例如 :

 if (report_role == VOICE_REPORT_MASTER){
            app_ibrt_voice_report_info_t voice_report_info;

			switch(aud_id){  /**Different prompt tone delays adjust for TWS sync by sanke**/
				case AUD_ID_BT_MIC_MUTE:
				case AUD_ID_BT_MIC_UNMUTE:
				case AUD_ID_BT_CONNECTED:
					tg_tick = curr_ticks + US_TO_BTCLKS(APP_PLAY_CONNECTED_AUDIO_SYNC_DELAY_US);
					tg_tick_tiemout = APP_PLAY_CONNECTED_AUDIO_SYNC_TRIGGER_TIMEROUT;
					break;

				case AUD_ID_BT_PAIRING:
					tg_tick = curr_ticks + US_TO_BTCLKS(APP_PLAY_AUDIO_SYNC_DELAY_US*2);
					tg_tick_tiemout = APP_PLAY_AUDIO_SYNC_TRIGGER_TIMEROUT*2;
					break;

				 default:
				 	tg_tick = curr_ticks + US_TO_BTCLKS(APP_PLAY_AUDIO_SYNC_DELAY_US);
					tg_tick_tiemout=APP_PLAY_AUDIO_SYNC_TRIGGER_TIMEROUT;
				 	break;
			}
}
....///
else if (report_role == VOICE_REPORT_SLAVE){
            tg_tick = app_ibrt_voice_tg_tick;
            if (curr_ticks < tg_tick && tg_tick != 0)
            {
				switch(aud_id){  /**Different prompt tone delays adjust for TWS sync by sanke**/
					case AUD_ID_BT_MIC_MUTE:
					case AUD_ID_BT_MIC_UNMUTE:
					case AUD_ID_BT_CONNECTED:
						tg_tick_tiemout = APP_PLAY_CONNECTED_AUDIO_SYNC_TRIGGER_TIMEROUT;
						break;

					case AUD_ID_BT_PAIRING:
						tg_tick_tiemout = APP_PLAY_AUDIO_SYNC_TRIGGER_TIMEROUT*2;
						break;

					 default:
					 	tg_tick_tiemout = APP_PLAY_AUDIO_SYNC_TRIGGER_TIMEROUT;
					 	break;
				}
//......
}

 

修改函数app_ibrt_voice_report_set_trigger_time为如下:

static void app_ibrt_voice_report_set_trigger_time(uint32_t tg_tick,uint32_t tg_tick_timeout)
{
    if (tg_tick){
        ibrt_ctrl_t *p_ibrt_ctrl = app_ibrt_if_get_bt_ctrl_ctx();
        btif_connection_role_t connection_role =  app_tws_ibrt_get_local_tws_role();
        btdrv_syn_trigger_codec_en(0);
        btdrv_syn_clr_trigger(0);
        btdrv_enable_playback_triggler(ACL_TRIGGLE_MODE);
        if (connection_role == BTIF_BCR_MASTER){
            bt_syn_set_tg_ticks(tg_tick, p_ibrt_ctrl->tws_conhandle, BT_TRIG_MASTER_ROLE,0);
        }else if (connection_role == BTIF_BCR_SLAVE){
            bt_syn_set_tg_ticks(tg_tick, p_ibrt_ctrl->tws_conhandle, BT_TRIG_SLAVE_ROLE,0);
        }
        btdrv_syn_trigger_codec_en(1);
        app_ibrt_voice_report_trigger_checker_start(tg_tick_timeout);
        TRACE_VOICE_RPT_I("[TRIG] set trigger tg_tick:%08x", tg_tick);
    }else{
        btdrv_syn_trigger_codec_en(0);
        btdrv_syn_clr_trigger(0);
        bt_syn_cancel_tg_ticks(0);
        app_ibrt_voice_report_trigger_checker_stop();
        TRACE_VOICE_RPT_I("[TRIG] trigger clear");
    }
}

3.混合提示音 声音大小:(audio_prompt_sbc.cpp)

在较新SDK里面打开 MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED 后 如果在音乐播放状态容易出现 提示音播放导致声音忽大忽小的问题,请调整以下参数

DEFAULT_COEFF_FOR_MIX_PROMPT_FOR_MUSIC  

4. 固定提示音采样率(需要与SBC源文件采样率匹配)

5. 由于音频中断但merge_prompt还在运行播放导致的死机问题:

在int bt_sco_player(bool on, enum APP_SYSFREQ_FREQ_T freq) 和 int bt_sbc_player(enum PLAYER_OPER_T on, enum APP_SYSFREQ_FREQ_T freq) 处添加:

if(app_ring_merge_isrun()){
			app_ring_merge_stop();
} /***To slove painc case ,while call or music stop but tone is merge start !sanke***/

 

以上大致就是BES提示音 讲解和 常见问题点分析,有不当之处,请指正,谢谢!

后续会更新 IRBT对耳通讯和 EQ/ANC调试,敬请期待!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_34990604/article/details/115085798

智能推荐

SpringMVC-特性annotation-程序员宅基地

@InitBinder日期参数绑定通常我们使用它,来解决日期类型参数绑定的问题:private SimpleDateFormat yMd = new SimpleDateFormat(&amp;amp;amp;amp;amp;amp;quot;yyyy-MM-dd&amp;amp;amp;amp;amp;amp;quot;); @InitBinder public void initBinder(WebDataBinder binder) { binder.registerC

Linux进程通信之消息队列-项目实践_将进程做成队列-程序员宅基地

消息队列的基本概念:消息队列 (也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一。另外两种是信号灯和共享内存。这些IPC机制使用共同的授权方法。只有通过系统调用将标志符传递给核心之后,进程才能存取这些资源。这种系统IPC对象使用的控制方法和文件系统非常类似。使用对象的引用标志符作为资源表中的索引。 上面是到别的地方copy的一些蛋疼的基本概念,看一百遍都是那么回事,_将进程做成队列

AWVS登录界面显示“无法访问”解决办法(附图)_awvs为什么提示系统无效呢_看我的眼色行事的博客-程序员宅基地

AWVS不能正常登录解决办法前言一、问题详情二、解决办法前言几天没用awvs忽然登录就连接不上了,不过百度一下发现是小问题,两三分钟就解决了,希望这个分享也可以帮助到你。一、问题详情打开Acunetix快捷键时,连接浏览器后,报“无法访问”错误。二、解决办法按Windows+R键输入services.msc打开服务界面查看Acunetix服务是否开启,一般是两个服务..._awvs为什么提示系统无效呢

java 普通switch与增强型switch_enhanced switch-程序员宅基地

switchint tag = 3;switch (tag){ case 1: System.out.println("111"); break; case 2: System.out.println("222"); break; case 3, 4: System.out.println("3 or 4"); break; default: System.out.println("else");}tag 可以是byte, _enhanced switch

win7系统64位系统怎么计算机配置,电脑装64位系统有什么要求|64位系统安装条件是什么...-程序员宅基地

装64位系统有什么要求?我们知道操作系统对电脑硬件是有一定的要求,电脑有32位和64位两种,64位系统对电脑要求比较高,所以我们在安装64位系统之前,需要知道64位系统的安装要求。那么64位系统安装要求是怎样的呢?这边系统城小编以win7 64位系统的要求为例,跟大家介绍64位系统安装条件以及检测方法。相关教程:相关说明:1、操作系统分32位和64位两种,电脑也有32位和64位之分,电脑位数一般取..._64位操作系统

将superset的元数据库从sqlite修改为mysql_superset 怎么不用sqllite_滕颛的博客-程序员宅基地

在使用superset过程中,查看superset看板时经常会出现报错sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) database is locked,要多次刷新才能成功查看到看板,在网上查了一下原因,说是sqlite的问题,切换为mysql后不再出现这个问题,所以决定直接切换superset元数据库为mysql。标题测试环境Superet 0.35.1MySQL 5.7.28Navicat Premium 12.0.19_superset 怎么不用sqllite

随便推点

mysql的update条件语句_简单了解标准SQL的update语句三种用法_张恒平的博客-程序员宅基地

一、环境:MySQL-5.0.41-win32Windows XP professional二、建立测试环境:DROP TABLE IF EXISTS t_test;CREATE TABLE t_test (bs bigint(20) NOT NULL auto_increment,username varchar(20) NOT NULL,password varchar(20) default...

第七版辅导书和第六版 通信原理_通信原理(第七版)同步辅导及习题全解-程序员宅基地

通信原理(第七版)同步辅导及习题全解作 者:王颖惠,牛丽英出版时间:2015丛编项:九章丛书-高校经典教材同步辅导丛书内容简介《通信原理(第七版)同步辅导及习题全解(新版)》是与 出版,樊昌信、曹丽娜编*的《通信原理》(第七版)一书配套的同步辅导及习题全解辅导书。《通信原理(第七版)同步辅导及习题全解(新版)》共有13章,分别介绍绪论、通知信号、随机过程、信道、模拟调制系统、数字基带传输系统、数字..._通信原理第六版和第七版

Ubuntu系统安装钉钉(史上最简单高效方法)_ubuntu安装钉钉_MINI_XY_Wang的博客-程序员宅基地

在各个博主的论坛上看到大多数是推进他们提供的安装包,但我在按照别人的方式安装总是不能够成功,后来才发现dingding官网已经提供了十分权威和简单的安装方法了,具体请看官网连接和以下内容。..._ubuntu安装钉钉

Pandas 数据查找及修改操作 iloc() & loc() bool类型索引_df.loc查询并修改数据-程序员宅基地

代码运行基于jupyter notebook文章目录一、数据加载二、.iloc() 用位置查找、修改数据查找数据修改数据三、.loc() 用标签查找、修改数据查找数据修改数据三、bool类型索引四、参考资料一、数据加载import pandas as pdimport picklewith open('titanic.pickle', 'rb') as file: df = pickle.load(file)二、.iloc() 用位置查找、修改数据df = df.set_inde._df.loc查询并修改数据

c语言pow立方根,C#math.pow立方根计算(C# math.pow cube root calculation)_柯布西耶的博客-程序员宅基地

有三个担心,我有。你在你的表达式中的一部分利用Math.Pow(),但是,你会想在谈话过程中,后来给出的表达式的第一部分使用Math.Sqrt()。其次,与表达中的括号分组导致表达的错误评价的问题第三,你将需要你没有一个十进制值,以评估预期的结果数值后使用“d”字符后缀。以下方程:(0.3D *((0.0015d *(0.793700526d + Math.Sqrt(0.7071068)))+(0..._c#计算立方

docker nginx 访问404_运维(1) Jenkinsfile+Dockerfile+Nginx实现前端Vue自动化部署-程序员宅基地

一、前言本文将基于以下环境通过Dockerfile+Jenkinsfile+Nginx 以jenkins流水线的方式实现前端Vue自动化部署Docker version 1.13.1, build 4ef4b30/1.13.1Jenkins 2.235.2Nginx 1.19.1node 12.18.3npm 6.14.7cnpm 6.1.1二、编写配置文件在vue项目中新增如下配置文件...