最近在做蓝牙的宽带语音通话。相对于蓝牙窄带语音,主要变化是把采样率从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 * 22n(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 * 2n(m为16位以内的正整数,n为正整数)的形式。

用div_s()求出m1/m2,2(n1-n2就是移位(左移、右移或者不移)。从浮点代码看出比例因子范围在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范围内,这是可以接受的。

蓝牙HFP协议推荐的语音丢包补偿算法浮点实现的定点化的更多相关文章

  1. 深入剖析iLBC的丢包补偿技术(PLC)

    转自:http://blog.csdn.net/wanggp_2007/article/details/5136609 丢包补偿技术(Packet Loss Concealment——PLC)是iLB ...

  2. TCP传输协议中如何解决丢包问题

    TCP在不可靠的网络上实现可靠的传输,必然会有丢包.TCP是一个“流”协议,一个详细的包将会被TCP拆分为好几个包上传,也是将会把小的封裝成大的上传,这就是说TCP粘包和拆包难题. 但是许多人有不同的 ...

  3. 【转】使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?

    使用TCP协议连续传输大量数据时,是否会丢包,应如何避免? 比如发送文件.记得有人提过可能会发生什么堆栈溢出.怎样避免呢?是不是可以收到数据后发送确认包,收到确认包后再继续发送.或是发送方发送了一些数 ...

  4. QUIC协议详解之Initial包的处理

    从服务器发起请求开始追踪,细说数据包在 QUIC 协议中经历的每一步.大量实例代码展示,简明易懂了解 QUIC. 前言 本文介绍了在 QUIC 服务器在收到 QUIC 客户端发起的第一个 UDP 请求 ...

  5. 丢包 ICMP

    小结: 1.ICMP 常见网络丢包故障分析及处理 云极安 云极安 2019-12-25 我们在管理维护网络的过程中经常会遇到数据包丢失的现象.使用Ping命令进行连通性测试,则会发现Ping包延时远远 ...

  6. luogu题解 P2419 【牛大赛Cow Contest】传递丢包

    题目链接: https://www.luogu.org/problemnew/show/P2419 分析: "在交际网络中,给定若干元素和若干对二元关系,且关系具有传递性. 通过传递性推导出 ...

  7. 蓝牙 BLE 协议学习: 000-有关概念介绍

    背景 在学校内就用过蓝牙技术参加过比赛(并拿了奖):而蓝牙作为物联网中比较常见的协议,有必要进行深入的学习.此后的文章会以 ble(v4.0) 进行学习. 介绍 蓝牙技术最初由电信巨头爱立信公司于 1 ...

  8. UDP主要丢包原因及具体问题分析

    UDP主要丢包原因及具体问题分析 一.主要丢包原因   1.接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来 ...

  9. UDP丢包和无序 问题的解决方法

    最近在做一个项目,在这之前,做了个验证程序. 发现客户端连续发来1000个1024字节的包,服务器端出现了丢包现象. 纠其原因,是服务端在还未完全处理掉数据,客户端已经数据发送完毕且关闭了. 我用过s ...

  10. 用clumsy模拟丢包测试socket库的失败重传

    用python的socket库写了通信小程序,现在我需要通过软件模拟出在网络极差的情况下,socket底层解决丢包问题的能力怎么样,我一开始想的是分别在linux和windowns下分别测试,后来一想 ...

随机推荐

  1. CF-925(已更新:D-F)

    CF 925 补题ing 待更新 后面打算更新D题和power oj上一道区间合并的题(现在才知道是一道洛谷上的原题--) D 分析 ​ 涉及到关于取模的知识,我们的答案要满足三个条件: ai-aj≡ ...

  2. 从零开始的react入门教程(十),快速上手react-redux,相对于redux它究竟简化了什么?

    壹 ❀ 引 在前面两篇文章中,我们介绍了redux与context部分概念与基本用法,这里我们做个简单复习. redux属于应用数据流框架,主要用于应用状态的管理,比如react中的state.其数据 ...

  3. Python list 中删除元素的方法

    在python列表中删除元素主要分为以下3种场景: 根据目标元素所在的索引位置进行删除,可以使用del关键字或pop()方法:根据元素本身的值进行删除,可使用列表(list类型)提供的remove() ...

  4. XTW100编程器在Win10下的安装

    XTW100 这是一个淘宝上卖得很多的经典编程器, 用于写入24和25系列的存储芯片. 最初使用的是stm32f103c8t6, 因为f103价格飞涨, 市面上大都换成国产的兼容mcu了, 软件和使用 ...

  5. 我的小程序之旅八:基于weixin-java-mp实现微信公众号被动回复消息

    在微信里有这样一个公众号[华为运动健康],当点击最新排行的时候,公众号就会发送今天最新的运动步数给你.如下图: 这里有两种格式的消息 1.有头像框,有聊天框--普通消息 2.消息有样式.颜色等--模板 ...

  6. C++ STL学习

    C++ STL学习 目录 C++ STL学习 容器库概览 对可以保存在容器中的元素的限制 容器支持的操作 所有容器都支持的操作或容器成员 迭代器 迭代器的公共操作 迭代器的类型 迭代器的const属性 ...

  7. 【Azure Logic App】使用Outlook.com发送邮件遇到429报错

    问题描述 在Logic App中使用 Outlook.com组件发送邮件,遇见了outlook connection报429的错误 {"error":{"code&quo ...

  8. 【Azure 环境】如果Azure中的某一个资源被删除后是否可以查看到删除的记录呢?如Resource Group

    问题描述 当一个资源从Azure中删除后,是否有地方可以查看到这些操作的记录呢?如操作人,操作时间等. 问题解答 可以的.通过 Azure订阅页面的活动日志,可以查看所有对订阅下资源的操作记录,包含D ...

  9. 初识JavaScript逆向——以网易云音乐和招标网站为例

    前言:需要掌握一定的JavaScript基础,能看懂基础的JavaScript代码. 我们平常在浏览网站的时候会看到许多加密的参数,如果需要知道它的原始数据,就需要知道整个加密过程,所以本篇文章就来介 ...

  10. 基于Ant Design设计语言的WinForm UI界面库

    前言 经常在技术群里看到有小伙伴提问:WinForm有什么好看.开源的UI库推荐的吗?,今天大姚给大家分享一款基于Ant Design(使用Ant Design 5.0)设计语言.开源(Apache ...