蓝牙HFP协议推荐的语音丢包补偿算法浮点实现的定点化

最近在做蓝牙的宽带语音通话。相对于蓝牙窄带语音,主要变化是把采样率从8k变到16k,以及编解码器从CVSD变成mSBC(modified SBC,改进的SBC)等。蓝牙语音通话相关的HFP(Hand Free Profile)强烈建议在宽带语音通话时要用上语音丢包补偿(packet lost concealment,PLC)算法来保证丢包时的语音质量,也给出了推荐的PLC算法的浮点实现。由于是在ADSP上做,算力有限,浮点实现是不能直接用的,因此要把浮点实现定点化。下面就讲讲我是怎么来做定点化的。

1,  理解算法的浮点实现

算法实现是基于paper “Waveform Substitution Techniques for Recovering Missing Speech Segments in Packet Voice Communications”的。 函数不多,API主要有三个:InitPLC()是初始化,PLC_good_frame()是正常帧处理,PLC_bad_frame()是丢包帧处理。内部函数也有三个:CrossCorrelation()算互相关,PatternMatch()算最匹配的起始位置,AmplitudeMatch()根据最匹配的位置算比例因子(scale factor),这些函数均在处理丢包帧时调用。

2, 结合mSBC实现做一个丢包补偿的demo

先前只有用于蓝牙音乐播放的SBC编解码demo(基于blueZ)。 为了支持mSBC, 对SBC代码做了修改(核心算法不变,对外围代码做了修改以支持mSBC)。现在又要结合PLC做丢包补偿,需要把PLC代码嵌到mSBC解码程序里。做丢包补偿demo的大致步骤如下:

1) 把一段16k采样的语音PCM用mSBC编码程序编码成sbc码流

2) 用mSBC解码程序把sbc码流解码成PCM

3) 在mSBC的解码程序里嵌入PLC代码。假设每20帧丢一帧(即丢包率为5%),用PLC算法去补偿丢的一帧,看补偿效果。补偿后的语音听起来无异样才算OK。这个PLC算法以及实现是HFP里推荐的,理论上不会有问题。如果补偿后声音有异样,一般是API没用好。

3, PLC算法的定点化

做定点化前需要找到做的点。我通过梳理代码发现有三处需要做定点化,下面看看这三处是怎么做定点化的。

1) 余弦表的定点化

代码中有一个浮点的余弦表,如下:

需要变成定点的表。看了表中值的范围,绝对值都是小于1的,因此在定点表示时适合用Q0.15。这样浮点的表就变成了定点的表,如下:

代码中用到余弦表时都是与PCM值相乘。两个short值相乘,要注意溢出,因此乘前要把一个值强制转换成int型。相乘后要做移位操作(右移15位),在移位前使值更接近浮点值,要做四舍五入(加上 1<<14,即加上0.5)处理。示例代码如下:

2) 算互相关时的定点化

代码中算互相关的代码如下:

从代码看出,用的算式如下:

既涉及到求平方根,又涉及到除法。以前做代码优化时知道求平方根可以用牛顿迭代法,于是我就在AMR-WB的参考代码(主要是basic operation的相关代码)里找有没有现成的可以用。不仅找到了,而且还是算平方根的倒数的(Word32 Isqrt(Word32 L_x),输入是一个32位的值,输出是Q0.31的值),这样除法就变成了乘法。我用几个值(比如100)带进函数Isqrt()试试,Q0.31的结果跟浮点值是对得上的。算式也就变成了如下的:

代码中可以看出x2,y2均是32位的,相乘后很可能超出32位,而Isqrt()的输入是32位的,不能直接使用,需要做些变形,变成 m * 2^{2n}(m为16位以内的整数,n为正整数)的形式。

这时m1 * m2是一个32位以内的数,就可以用函数Isqrt()了。

用Isqrt()求,

就是就是右移(n1 + n2)位。结果再乘以num就可求出定点的Cn了。

3) 做除法时的定点化

浮点实现中在算比例因子时用到了除法,代码如下:

看了AMR-WB参考代码,也有除法实现,即Word16 div_s (Word16 var1, Word16 var2)。不过是16位的除法,输出也是一个Q0.15的16位值。使用时还有其他限制条件:被除数和除数要都是正数,且被除数小于等于除数。在浮点代码中被除数和除数均可能是32位的正值,因此不能直接用,需要做些改进,变成 m * 2^{n}(m为16位以内的正整数,n为正整数)的形式。

 用div_s()求出m1/m2,2^{n_{1} - n_{2}}就是移位(左移、右移或者不移)。从浮点代码看出比例因子范围在0.75~1.2,要用Q1.14表示,因此要把用div_s()算出来的Q0.15值转换成Q1.14形式。最后再加一个限幅,范围是0.75~1.2,用Q1.14表示就是12288~19661。经过以上处理后就可求出定点的比例因子了。

在定点化的过程中,每一步定点化时都要比较定点的结果和浮点的结果,确保误差在很小的范围内,通常不超过1。做完后还要比较最终的误差,即最后的PCM值的误差。下图给出了浮点实现和定点实现最终的部分PCM值比较:

从图上可以看出,在做丢包补偿时,定点的和浮点的实现部分PCM值有误差,但误差都是在1范围内,这是可以接受的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/490844.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【线段树】第十三届蓝桥杯省赛C++ A组 Java C组 Python A组/B组《最长不下降子序列》(C++)

【题目描述】 给定一个长度为 N 的整数序列&#xff1a;,,⋅⋅⋅,。 现在你有一次机会&#xff0c;将其中连续的 K 个数修改成任意一个相同值。 请你计算如何修改可以使修改后的数列的最长不下降子序列最长&#xff0c;请输出这个最长的长度。 最长不下降子序列是指序列中的…

报道 | 2024年4月-2024年6月国际运筹优化会议汇总

封面图来源&#xff1a; https://www.pexels.com/zh-cn/photo/1181406/ 2023年2月-2024年6月召开会议汇总&#xff1a; The 24th European Conference on Evolutionary Computation in Combinatorial Optimisation (EvoCOP) Location: Aberystwyth, Wales, UK Important Date…

鸿蒙HarmonyOS应用开发——组件级配置

在开发应用时&#xff0c;需要配置应用的一些标签&#xff0c;例如应用的包名、图标等标识特征的属性。本文描述了在开发应用需要配置的一些关键标签。 应用包名配置 应用需要在工程的AppScope目录下的 app.json5配置文件 中配置bundleName标签&#xff0c;该标签用于标识应用…

STM32F4x7标准库带操作系统移植LWIP

上一篇解读了使用STM的标准库&#xff0c;移植不带操作系统版本的LWIP。 这里再梳理一下&#xff0c;带操作系统版本的差异。 main()函数 初始化部分跟之前的基本相同。 不同的是&#xff0c;不需要在主循环里调用LwIP_Periodic_Handle(LocalTime); LWIP驱动 ethernetif.c要…

React项目打包优化-包体积分析

1、什么是包体积分析&#xff1f; 通过可视化的方式&#xff0c;直观的看到各种包打包之后的体积大小&#xff0c;方便后续针对体积情况做优化 2、怎么分析包&#xff1f; 借助插件 source-map-explorer&#xff0c; 1、先安装插件 npm install source-map-explorer 2、在p…

代码随想录刷题day35|柠檬水找零根据身高重建队列最少的箭引爆气球

文章目录 day35学习内容一、柠檬水找零1.1、思路1.2、代码-正确写法 二、根据身高重建队列2.1、思路2.2、正确写法12.2.1、 如何理解上面这段代码2.2.2、 如何理解 que.add(p[1], p)&#xff1f;2.2.3、这段代码贪心在哪里呢&#xff1f; 三、最少的箭引爆气球3.1、思路3.2、正…

YOLOv5s处理二维牙齿数据集

一、网络结构 二、输入输出 1、输入 640x640的图像 2、输出 权重文件 测试图像 三、数据预处理 在github上下载YOLOv5的模型&#xff0c;并安装模型所需环境 pip install -U -r requirements.txt 四、训练&测试 对数据集进行训练 python train.py --img 640 --batc…

mybatis 实验报告1

文章目录 新建数据库新建项目&#xff0c;并导入jar包添加配置文件conf.xml定义实体类定义操作表user的sql的映射文件 userMapper.xml注册&#xff1a;将mapper.xml文件注册到conf.xml配置文件中一共6步&#xff0c;这个只是测试类&#xff0c;这个不算 新建数据库 命名是 随便…

4、事件修饰符、过滤器、自定义指令、生命周期

一、事件修饰符 按键别名enter 回车 delete 删除键 esc取消键 space 空格键 <script> export default {name: "KeyUp",methods:{keyUp(e){ console.log(e) }},skip(){window.location.href "http:www.xx.com"} } </script> <template>…

BUUCTF-Misc14

[WUSTCTF2020]find_me1 1.打开附件 是一个学校的校徽 2.盲文解密 发现图片属性里的备注是一串盲文 用在线盲文解密 3.得到flag

第三十一天-Flask-ORM-sqlalchemy

目录 1.什么是ORM 2.flask-sqlalchemy 1安装 2.配置 3.数据库模型设计 ​编辑 4.插入修改删除 5.查询 1.什么是ORM 2.flask-sqlalchemy 1安装 2.配置 3.数据库模型设计 4.插入修改删除 5.查询

001_Python(PyCharm,Anaconda,Jupyter更改工作目录)

# 整理笔记&#xff0c;记录一下Python学习过程&#xff0c;希望对像我一样的初学者有所帮助&#xff01; 一、Python三个基本概念 1、解释器 Python解释器&#xff0c;是将高级语言解析为二进制机器语言的工具。 通常说的安装python就是指安装python解释器。 目前最新的P…

基于springboot+vue调用百度ai实现车牌号识别功能

百度车牌号识别官方文档 结果视频演示 后端代码 private String getCarNumber(String imagePath, int count) {// 请求urlString url "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate";try {byte[] imgData FileUtil.readFileByBytes(imagePath);Stri…

【如何安装odl: 1.0.0.dev0】

【如何安装odl: 1.0.0.dev0】 ODL官网 pip install odl可能容易报错&#xff0c;建议使用下述命令安装 pip install https://github.com/odlgroup/odl/archive/master.zip检查是否安装成功 conda list

练习二 霍格沃兹登录页面

1.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>教务系统管理页面</title><link rel"stylesheet" href"./教务管路系统页面.css"> </head> <body&g…

Spring Data Elasticsearch 与ES版本对应关系记录

参考&#xff1a; Versions :: Spring Data Elasticsearch

cpp第二次作业

现象&#xff1a; 源码&#xff1a; #include <iostream>using namespace std;class Rectangle{ private:int length;int width; public:void set_l(int l);void set_w(int w);int get_l();int get_w();void show(); };void Rectangle::set_l(int l) {lengthl; }void Re…

javaWeb健康管理系统

一、引言 1.1 设计背景 紧张的工作节奏、教学和科研的压力、个人不良的工作生活习惯、以及伴随工作压力而来的家庭关系、人际关系紧张等因素使得高校群体成为慢性病的高发群体[1]。学生入学的定期体检&#xff0c;教职工人入职体检&#xff0c;以及所有学生和教职工的定期体检…

使用小皮【phpstudy】运行Vue+MySql项目

现在的情况是我扒到了一个开源的项目&#xff0c;现在想要实现一下前端对应的功能&#xff0c;后端是完备的&#xff0c;但是需要调用数据库将数据跑起来&#xff0c;这里可以使用到MySql数据库&#xff0c;这里我还发现了一个比较好用的软件小皮【phpStudy】 官网 一 安装软件…

前端面试拼图-数据结构与算法(二)

摘要&#xff1a;最近&#xff0c;看了下慕课2周刷完n道面试题&#xff0c;记录下... 1. 求一个二叉搜索树的第k小值 二叉树(Binary Tree) 是一棵树 每个节点最多两个子节点 树节点的数据结构{value, left?, right?} 二叉树的遍历 前序遍历&#xff1a;root→left→right 中…