Skip to content

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 下面是解码前后的波形对比 img

根据上图可知,还原后的波形和原波形基本一致,是真较小,偏差主要来自预测的过程偏差

  1. dapcm压缩 - 16bit到3bit 先将16bit转换为8bit(不转换应该也行),再用adpcm算法压缩到3bit,高1位是符号位,低两位是差值索引. 这样压缩出来的码率是 3bit x 8k = 24kb = 3KB; 压缩比为16:3 这个时候因为差值索引只有2bit就是0~3,所以索引表要修改为:
    index_adjust = [-1,-1,2,4,-1,-1,2,4]
    
    step_table[] 表内容可以不改,长度要限制到30.

下图是按该方法生成的原数据-还原后数据的对比图: img 从上图看出,还原后数据和原始数据差异较小,效果和第一种差别不大。

  1. 频率插值法压缩

adpcm压缩到3bit已是极限,再压缩会严重失真,所以我们必须另辟蹊径。 目前的采样频率是8KHz,直接减少失真较大,所以考虑用插值法,在4K采样数据的中间补上一个中间值,生成8K的数据。 压缩过程:16bit 8K --> 4bit 8K --> 4bit 4K 解压过程: 4bit 4K --> 16bit 4K --> 插值为16bit 8K 这样生成的码率是:4bit x 4K = 16Kb = 2KB; 压缩比为8:1 img 上图是该方法下的数据对比图,可以看到波形轮廓一致,但相对上面两种差异较大,音损较多。

  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

比较和选择

  1. ROM固化音频播放 从上面的分析结果来看,要保证音质和压缩比,最适合低性能单片机的应该是16bit 8K压缩为4bit 4K的,兼具音质和空间占用,这样下来1秒的音频只需要2KB的ROM空间,也就是20KB空间可以存放10秒的音源。 如果选择3bit 3K极限压缩,20K空间可以存储17秒,但是每byte数据对应3bit的压缩值,操作起来要计算对齐。
  2. 录音存储和回放 录音数据既要采样又要存储,所以计算过程简单省时最好,所以还是推荐4bit 4K的压缩方式,然后每个block为128 BYTE。这样在流传输的过程中即使丢包也能正确播放下一个block. 而且码率只要大于16Kbit每秒即可.