WAV压缩算法探讨
压缩格式
wav压缩格式有很多种,结合单片机的特性,adpcm方式是最简单有效的,所以以下探讨均基于该格式。 Adpcm格式又有不同的打包标准,比如MS,IMA等,主要是分包定义不同
压缩率
一般的adpcm压缩都是把16bit的数据压缩到4bit(高1位符号,表示正/负向偏差;低三位为差值表索引);所以一般情况下压缩率为4:1。
因为单片机的内部ROM空间一般都很小,所以我们会在降低部分音质的情况下追求极致压缩比,所以我进行了以下尝试:
原始数据:单声道,16bit宽,8K采样率,4秒长度
1. adpcm压缩 - 16bit到4bit
16bit压缩到4bit,这样出来的码率就是4bit x 8K = 32Kb = 4KB; 压缩比为4:1
下面是解码前后的波形对比
根据上图可知,还原后的波形和原波形基本一致,是真较小,偏差主要来自预测的过程偏差
- dapcm压缩 - 16bit到3bit
先将16bit转换为8bit(不转换应该也行),再用adpcm算法压缩到3bit,高1位是符号位,低两位是差值索引.
这样压缩出来的码率是 3bit x 8k = 24kb = 3KB; 压缩比为
16:3
这个时候因为差值索引只有2bit就是0~3,所以索引表要修改为:step_table[]
表内容可以不改,长度要限制到30.
下图是按该方法生成的原数据-还原后数据的对比图: 从上图看出,还原后数据和原始数据差异较小,效果和第一种差别不大。
- 频率插值法压缩
adpcm压缩到3bit已是极限,再压缩会严重失真,所以我们必须另辟蹊径。
目前的采样频率是8KHz,直接减少失真较大,所以考虑用插值法,在4K采样数据的中间补上一个中间值,生成8K的数据。
压缩过程:16bit 8K --> 4bit 8K --> 4bit 4K
解压过程: 4bit 4K --> 16bit 4K --> 插值为16bit 8K
这样生成的码率是:4bit x 4K = 16Kb = 2KB; 压缩比为8:1
上图是该方法下的数据对比图,可以看到波形轮廓一致,但相对上面两种差异较大,音损较多。
- 极限压缩测试 结合上述方法,我们可以尝试多种组合来取得更高的压缩比
原数据 | 压缩后数据 | 还原后数据 | 压缩比 |
---|---|---|---|
16bit 8K | 4bit 8K | 16bit 8K | 4:1 32Kb/4KB |
16bit 8K | 4bit 4K | 16bit 8K | 8:1 16Kb/2KB |
16bit 8K | 4bit 3K | 16bit 6K | 8:1 12Kb/1.5KB |
16bit 8K | 3bit 4K | 8bit 8K | 5.3:1 12Kb/1.5KB |
16bit 8K | 3bit 3K | 8bit 6K | 5.3:1 9Kb/1.1KB |
比较和选择
- ROM固化音频播放 从上面的分析结果来看,要保证音质和压缩比,最适合低性能单片机的应该是16bit 8K压缩为4bit 4K的,兼具音质和空间占用,这样下来1秒的音频只需要2KB的ROM空间,也就是20KB空间可以存放10秒的音源。 如果选择3bit 3K极限压缩,20K空间可以存储17秒,但是每byte数据对应3bit的压缩值,操作起来要计算对齐。
- 录音存储和回放 录音数据既要采样又要存储,所以计算过程简单省时最好,所以还是推荐4bit 4K的压缩方式,然后每个block为128 BYTE。这样在流传输的过程中即使丢包也能正确播放下一个block. 而且码率只要大于16Kbit每秒即可.