问题描述
- 个人当前实现的声波通讯程序原理是:采用两个不同频率的声波表示0和1,按照所需传输数据的二进制编码生成一段声波进行播放,音频接收端使用快速傅里叶算法解析采集到的音频数据,通过解析出的两个特定频率的排列顺序还原出二进制数据。
- 问题:音频频率并不是一个sample的音频就可以解析出,使用快速傅里叶算法解析,需要多个sample的音频数据才能表示一个频率,假设是每40个sample表示一个频率(即一个二进制位0或1),音频接收端也需要以同样的sample个数作为一个解析窗口,由于发送和接收的时间不一定同步,就会产生一个窗口对齐的问题,如下:
* 假设发送数据是0和1交替,窗口是4个sample的音频数据
发送端:000011110000111100001111000011110000111
接收端:0000111100001111....
可能是: 000111100001111....
也可能是:00111100001111....
也可能是: 0111100001111....
- 如上图,如果接收解析端也按照4个sample去解析,窗口没对齐时,4个sample中就会混杂0和1,这样解析出的数据就可能是错的,或者全部是乱七八糟的数据。
问题解决
- 之前公司老员工给的解决方案是:创建多个解析处理,每个处理间隔一定时间,这样总有一个解析是完全正确的。
- 经过一定时间的思考,有了一个更好的办法。
有利条件
- 判断一个窗口音频数据的频率时,可以采用判断两种特定频率的快速傅里叶运算值,哪个高就认为是哪个频率,这样的话窗口并不需要完全对齐,只要窗口中正确的频率超过另外一个频率,即正确的sample数据占比大于50%就能解析出正确的数据,如下:
* 如果数据是0
接收到的音频sample数据:0000 (可以正确解析)
0001(可以正确解析)
0011(不能正确解析)
现实场景
- 如上,只要解析窗口不正好和发送窗口相差一半窗口的时长就不会出错,这种情况出现的概率也比较小,这样的话,理论上大部分情况都能解析出正确的答案;但是实际测试中发现,不做其它处理,解析出正确的结果的几率很低,原因是:发送和接收端都有可能丢失sample。
- 正确解析方案:解析窗口越靠近发送窗口的开始或者结束,得到正确结果的可能越大。
如何实现
- 我们无法保证单个解析窗口与发送窗口的时差,因此我们需要创建额外解析窗口,只需要再创建一个就好了,不需要多个,与第一个解析窗口的时差控制在半个窗口的时长,如下:
发送端:000011110000111100001111000011110000111
* 情况1:第一个窗口解析错误,第二个窗口就能解析正确
接收端窗口1:00111100001111....
接收端窗口2: 111100001111.... (与第一个窗口相差半个窗口时长)
* 情况1:第一个窗口解析正确,第二个窗口就会解析错误
接收端窗口1:000111100001111....
接收端窗口2: 0111100001111.... (与第一个窗口相差半个窗口时长)