IMA ADPCM

1.IMA是Interactive Multimedia Association的缩写,就是互动多媒体协会。IMA ADPCM就是说标准是IMA制定的,当然还有Microsoft ADPCM,标准就是MS制定的;
2.ADPCM自适应差分PCM编码,和PCM编码的差别就在于差分两个字。。如果已经了解的PCM编码,请继续往下看。

差分编码就是用下一个采样点与现在采样点的电平差进行编码。。而不是直接用一个二进制数表示当前的电平大小。。自适应的编码方式加上了预测,使得可以用比较少的位率完整的存储每个样本的电平值。。

比如8 Bit的PCM,编码从00H-FFH。现在有三个点,电平大小是零电平,正的-6dB,0dB。则对应的PCM编码是80H,C0H,FFH。这样需要三个Byte来存储。
而ADPCM会进行预测,它已知第一个点是零电平,并且也已知前一个点的电平,它就会根据之前的采样点和现在的采样点预测下一个点也就是第二个点的电平。当然预测不可能精准。。可能预测成了24H或者C3H之类,于是就一个较低位数的二进制数来描述实际值与预测值的差距。比如,用4Bit 或者5Bit。下一次预测可能预测成F0之类的。。解码的过程反之。。这样就能获得50%-62.5%的压缩率。。

所以,ADPCM算法的好坏,取决于预测的准确性。。。也只能用来压缩音频信号之类的有规律的信号,如果是随机信号,那就没得玩了。。
3.ADPCM(Adaptive Differential Pulse Code Modulation),是一种针对 16bits( 或8bits或者更高) 声音波形数据的一种有损压缩算法,它将声音流中每次采样的 16bit 数据以 4bit 存储,所以压缩比 1:4. 而且压缩/解压缩算法非常简单,所以是一种低空间消耗,高质量高效率声音获得的好途径。保存声音的数据文件后缀名为 .AUD 的大多用ADPCM 压缩。
  ADPCM 主要是针对连续的波形数据的,保存的是波形的变化情况,以达到描述整个波形的目的,由于它的编码和解码的过程却很简洁,列在后面,相信大家能够看懂。
  8bits采样的声音人耳是可以勉强接受的,而 16bit 采样的声音可以算是高音质了。ADPCM 算法却可以将每次采样得到的 16bit 数据压缩到 4bit 。需要注意的是,如果要压缩/解压缩得是立体声信号,采样时,声音信号是放在一起的,需要将两个声道分别处理。

ADPCM 压缩过程
  首先我们认为声音信号都是从零开始的,那么需要初始化两个变量
    int index=0,prev_sample=0;
  下面的循环将依次处理声音数据流,注意其中的 getnextsample() 应该得到一个 16bit 的采样数据,而 outputdata() 可以将计算出来的数据保存起来,程序中用到的 step_table[],index_adjust[] 附在后面:
    int index=0,prev_sample:=0;
    while (还有数据要处理)
    {
      cur_sample=getnextsample();        // 得到当前的采样数据
      delta=cur_sample-prev_sample;       // 计算出和上一个的增量
      if (delta<0) delta=-delta,sb=8;      // 取绝对值
      else sb = 0 ;               // sb 保存的是符号位
      code = 4*delta / step_table[index];    // 根据 steptable[]得到一个 0-7 的值
      if (code>7) code=7;            // 它描述了声音强度的变化量
      index += index_adjust[code] ;       // 根据声音强度调整下次取steptable 的序号
      if (index<0) index=0;           // 便于下次得到更精确的变化量的描述
      else if (index>88) index=88;
      prev_sample=cur_sample;
      outputode(code|sb);            // 加上符号位保存起来
    }
  有关ADPCM压缩过程更详细的信息,参见本站 ADPCM压缩过程演示程序

ADPCM 解压缩过程
  接压缩实际是压缩的一个逆过程,同样其中的 getnextcode() 应该得到一个编码,,而 outputsample() 可以将解码出来的声音信号保存起来。这段代码同样使用了同一个的 setp_table[] 和 index_adjust() 附在后面:
    int index=0,cur_sample=0;
    while (还有数据要处理)
    {
        code=getnextcode();                       // 得到下一个数据
        if ((code & 8) != 0) sb=1 else sb=0;
        code&=7;                            // 将 code 分离为数据和符号
        delta = (step_table[index]*code)/4+step_table[index]/8;     // 后面加的一项是为了减少误差
        if (sb==1) delta=-delta;
        cur_sample+=delta;                        // 计算出当前的波形数据
        if (cur_sample>32767) output_sample(32767);
        else if (cur_sample<-32768) output_sample(-32768);
        else output_sample(cur_sample);
        index+=index_adjust[code];
        if (index<0) index=0;
        if (index>88) index=88;
     }
  有关ADPCM解压过程更详细的信息,参见本站 ADPCM解压过程演示程序
附表
     int index_adjust[8] = {-1,-1,-1,-1,2,4,6,8};

     int step_table[89] =
     {
       7,8,9,10,11,12,13,14,16,17,19,21,23,25,28,31,34,37,41,45,
       50,55,60,66,73,80,88,97,107,118,130,143,157,173,190,209,230,253,279,307,337,371,
       408,449,494,544,598,658,724,796,876,963,1060,1166,1282,1411,1552,1707,1878,2066,
       2272,2499,2749,3024,3327,3660,4026,4428,4871,5358,5894,6484,7132,7845,8630,9493,
       10442,11487,12635,13899,15289,16818,18500,20350,22385,24623,27086,29794,32767
     }

特殊ADPCM压缩
  根据ADPCM压缩/解压原理,本站提供了 3bits ADPCM 和 4bits ADPCM 压缩程序,另外还提供 ADPCM系数表设计程序 下载。
AUD文件结构
  关于 WestWood 的 .AUD 文件,结构比较简单,这里顺带提一下,有兴趣可以自己写处理AUD文件的程序,其 8bit 的声音压缩算法尚不知晓,但用的最广泛的 16bit 声音正是用 ADPCM 压缩,每个 AUD 文件都有一个文件头,结构如下:
    struct
    {
      unsigned short int samplespersec ;    // 频率
      long int size;              // 除掉文件头的大小
      long int outsize;            // 输出数据大小 (通常是 4 倍)
      unsigned char flags;           // 位 0 描述是否立体声,位 1 描述是否 16 bit
      unsigned char type ;           // 1=WW 压缩,99=IMA ADPCM
    }
  AUD文件的声音信号是按块存放的,每块大约 512 字节,每一块都有一个块头结构:
    struct
    {
      unsigned short int size; // 压缩过的数据大小
      unsigned short int outsize; // 输出数据大小 (通常是 4 倍)
      long int id; // 永远是 0x0000DEAF
    }
IMA ADPCM(Adaptive Differential Pulse Code Modulation)是一种压缩音频编码方式,常用于减少音频数据量,同时保留较好的音质。实现 IMA ADPCM 解码的核心是理解其状态表(step size、index)和解码每个 nibble(4位)为一个 16 位 PCM 样本。 以下是一个基于 IMA ADPCM 的 Python 解码示例: ```python # IMA ADPCM step size 和 index 表 index_table = [ -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 ] step_size_table = [ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 ] def ima_adpcm_decode(data, num_channels=1): """ 解码 IMA ADPCM 数据为 PCM 样本 :param data: 原始 IMA ADPCM 数据(bytes) :param num_channels: 声道数(1=单声道,2=双声道) :return: 解码后的 PCM 样本列表 """ predictor = 0 # 初始预测值 step_index = 0 # 初始 step index step = step_size_table[step_index] decoded = [] # 存储解码后的样本 # 每个字节包含两个 nibble(高4位和低4位) for byte in data: for nibble in ((byte >> 4) & 0xF, byte & 0xF): # 解码 nibble sign = nibble & 0x8 delta = nibble & 0x7 diff = step >> 3 if delta & 4: diff += step if delta & 2: diff += step >> 1 if delta & 1: diff += step >> 2 if sign: predictor -= diff else: predictor += diff # 防止溢出 if predictor > 32767: predictor = 32767 elif predictor < -32768: predictor = -32768 decoded.append(predictor) # 更新 step index step_index += index_table[nibble] if step_index < 0: step_index = 0 elif step_index > 88: step_index = 88 step = step_size_table[step_index] # 处理双声道数据(交错排列) if num_channels == 2: left = decoded[::2] right = decoded[1::2] return list(zip(left, right)) # 返回 (left, right) 样本对 else: return decoded ``` ### 使用示例: ```python # 示例 IMA ADPCM 数据(每个字节包含两个 nibble) adpcm_data = bytes.fromhex("2c 14 0e 14 cf 13 47 13 22 12 ab 0f 5e 0a 20 ff 23 ed c3 ea 8b 02 5f 12 7f 0f 1c 12 ff 1d 8a 0a c4 ed 47 e2 a7 fa 28 f1 48 ee 97 20 7a 0c ab 01") # 解码为 PCM 样本(双声道) pcm_samples = ima_adpcm_decode(adpcm_data, num_channels=2) # 打印前10个样本 print(pcm_samples[:10]) ``` --- ### 说明: - `index_table` 和 `step_size_table` 是 IMA ADPCM 的标准表格。 - 每个 nibble(4位)解码为一个 16 位 PCM 样本。 - 双声道数据通常为交错排列,即 `LRLRLR...`,解码后需要按顺序分离左右声道。 - 你可以将解码后的 PCM 数据写入 `.wav` 文件进行播放测试。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值