打印
[51单片机]

真正实现ADPCM音频解码[为播放流畅 振南提出"缓冲追随思想"]

[复制链接]
1951|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
znmcu|  楼主 | 2016-6-17 13:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 znmcu 于 2016-6-17 13:20 编辑

真正实现ADPCM音频解码与播放【为了边解码边播放的流畅度,振南提出了“追随策略”!】



振南电子网站 www.znmcu.cn  

振南电子 ZN-X开发板技术支持QQ群: 177856520

振南 SD卡、FAT32文件系统、嵌入式存储技术交流QQ群:
198521880
在前面作的 VS1003录音实验中,我们把录音数据(经过ADPCM编码)存到了AT45DB161中,我振南的ZN-X SHELL测试系统中我们可以通过mp3test flash 0xaddres len命令 使用VS1003再回头去播放它,也可以通过at45db161 up 0xaddres len命令将它上传到PC,存为WAV文件,通过播放器软件来播放。

总之,不论是使用VS1003去回放它,还是用PC上的播放器软件来播放WAV文件,都是使用外部的解码器(硬件或者软件)对ADPCM进行解码的。但是在实际应用中,可能并没有专用的解码芯片为我们完成硬件解码工作(可能因为成本的问题或其它原因),我们需要自己通过软件对ADPCM进行解码

振南在这里,将要实现的就是在ZN-X开发板上,通过单片机软件直接解码ADPCM音频数据,最终得到PCM数据,通过DACZN-X开发板上的TLC5615芯片)将声音还原播放出来!!

关于ADPCM编码的原理,以及WAV文件的数据格式,振南在前面花了很大篇幅进行了深入详尽的讲解。这些都是我们这里最终实现解码和播放的重要基础。

解码后的数据,是原始的PCM数据,说白了就是原始的音频信号的ADC采样值,它们是可以直接写入到DAC,从而还原出声音的!

有人问:“你在51单片机上作音频解码,还要播放出来!51速度跟得上吗?”振南ZN-X开发板(51版)上使用的51芯片是STC最新的1T增强51单片机STC15L2K60S2,它在主频、内存,甚至指令集都经过了提升和优化,还增加了定点乘除法指令,这使他的计算性能得到提高,可以作一些比较简单的解码,比如这里的ADPCM(但是想直接软件解码MP3这些音频还是算了!)

虽然ZN-X上的51芯片是比较强的,但是如果按照常规的“读取ADPCM数据块(256字节),解码完成(产生505个采样值,暂存于缓冲数组之中),最后再从缓冲中读取送入DAC(要按音频的原始采样率定时送给DAC,比如8KHZ,就是每隔125usDAC送一个数据)”这种方法,一边解码一边播放,最终出来的声音一定是断断续续的。因为读取ADPCM数据块(从AT45DB161中)解码以及存入缓冲,这起码也要20-30ms,这意味着声音中间有20-30ms的中断。
声音信号有一个重要的特点:就是它是连续的,不能有间隙。
如果声音中有“间隙”,那声音必然是断断续续,如果这种情况很严重,比如解码算法写得很烂,效率很低,占用了大量的时间,造成了声音信号的严重“断流”,此时我们甚至听不出播放的是什么?似乎跟噪音一样!

解码是一定需要时间的,有解码才会产生最终用于播放的原始音频数据,但是同时又不能让声音数据“断流”,这该如何来解决!!?
振南改变了解码和向DAC送数的策略,让他们可以同时协同工作,真正作到边解码边送数,同时还要保证规定的时间间隔(送快了,声音就变成快放了,送慢了,声音就变成“搅带”了!)
振南使用的方法,是振南针对音频和视频的解码和播放,为了保证其流畅度而经常用到的两种方法之一,我称这为“追随策略”。关于这一方法的思想和实现,振南不在这里详述,大家可以关注振南更多的**和实验的发布。

通过振南的“追随策略”(其实也很简单,只是能不能想到的问题)可以实现ADPCM解码同时流畅播放的目的。
不再啰嗦了!感觉自己像是长舌妇一样。

振南为ADPCM的解码和播放专门设计了一个SHELL命令(这一实验是振南SHELL整板测试的延续,一方面这可以提高整板测试的趣味性,同时通过这种比较复杂功能的测试,可以测试STC51单片机运行的稳定性。解码用到了很多的扩展RAM,即xdata,以及一些片内外设,比如定时器,所以它可以起到对STC51芯片自身进行测试的作用,如果芯片CPU、扩展RAM等工作不正常,或者是内部晶振不稳定,都可能造成解码和播放的错误,甚至直接死机!!)

ADPCM解码播放命令:tlc5615test wav 0xaddres is_save
因为声音最终由TLC5615播放出来,所以振南把这个命令放在了tlc5615test的命令集中。
参数wav说明要对FlashROM(AT45DB161)中存储的ADPCM数据(WAV文件)进行解码,并播放。
0xaddresADPCM音频数据块的开始地址(字节地址) 注:从开始地址默认读取125KB数据进行解码,即一共500ADPCM数据块!!
is_save:如果为1,则将解码后的数据存入到AT45DB161中,从扇区地址2050(字节地址1049600)开始。这样以便于我们对解码后的数据进行查看或上传。
注意:解码后的数据写入到AT45DB161中的开始地址是固定的,被设计为无法配置(为什么设计成这样?因为振南偷懒了!),所以在一开始向AT45DB161中下载或者是通过VS1003录音存入WAV文件的时候,不要超过扇区2050!!


我们可以使用命令at45db161test up 0x000000 205824将由VS1003录音的WAV文件上传到PC,再用at45db161test up 0x100400 131072,将解码后的数据也上传上来,然后通过Cooledit软件对两者的波形进行比较,看看我们是不是解码正确!(有时候声音听起来似乎没问题,但是在解码的时候,有一些小段的音频解码出错,通过比对,来确认我们的解码是没问题的!!)

相关帖子

沙发
望断云山| | 2016-6-22 00:40 | 只看该作者
啧啧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:振南的znFAT -- 单片机上上的FAT32文件系统 www.znmcu.cn

4474

主题

5195

帖子

33

粉丝