嵌入式 ADPCM压缩算法

本文介绍了ADPCM(Adaptive Differential Pulse Code Modulation)压缩算法,这是一种用于声音波形数据的有损压缩技术,能将16bit声音数据压缩至4bit,压缩比为1:4。ADPCM算法简单,适用于低空间需求和高音质场景。文中详细阐述了ADPCM的压缩和解压缩过程,并提供了相关附表。
摘要由CSDN通过智能技术生成
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 (还有数据要处理)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一段8051单片机上实现ADPCM编码的示例代码: ```c #include <reg51.h> #include <stdio.h> #include <intrins.h> #define SCLK P1_0 #define RCLK P1_1 #define DATA P1_2 #define ADPCM_STEPS 89 #define ADPCM_STEP_SHIFT 7 // ADPCM编码表 code int8_t ADPCM_StepSizeTable[16] = {1, 3, 5, 7, 9, 11, 13, 15, 16, 16, 16, 16, 16, 16, 16, 16}; code int16_t ADPCM_SampleTable[16] = {-1, -1, -1, -1, 2, 4, 6, 8, 1, 3, 5, 7, 9, 11, 13, 15}; // ADPCM编码函数 int8_t ADPCM_Encode(int16_t sample, int16_t* prev_sample, int8_t* prev_index) { int8_t code = 0; int8_t diff = 0; int8_t step = ADPCM_StepSizeTable[*prev_index]; // 计算预测值和预测误差 int16_t pred_sample = (*prev_sample * 127 + 64) >> 7; diff = sample - pred_sample; if (diff >= 0) { code = 0; } else { code = 8; diff = -diff; } // 计算量化步长 int8_t tmp_step = step; for (int i = 0; i < ADPCM_STEP_SHIFT; i++) { if (diff >= tmp_step) { code |= (1 << i); diff -= tmp_step; } tmp_step >>= 1; } // 更新前一采样值和量化器状态 if (code & 8) { pred_sample -= (ADPCM_SampleTable[*prev_index] * step) >> 3; step = (step * ADPCM_StepSizeTable[*prev_index]) >> 6; } else { pred_sample += (ADPCM_SampleTable[*prev_index] * step) >> 3; step = (step * ADPCM_StepSizeTable[*prev_index]) >> 6; } if (step < 1) { step = 1; } else if (step > ADPCM_STEPS) { step = ADPCM_STEPS; } *prev_sample = pred_sample; *prev_index = code & 0x0f; return code; } // 主函数 void main() { int16_t prev_sample = 0; int8_t prev_index = 0; int16_t sample = 0; int8_t code = 0; while (1) { // 读取采样值 sample = read_adc(); // ADPCM编码 code = ADPCM_Encode(sample, &prev_sample, &prev_index); // 输出编码结果 DATA = code; RCLK = 1; _nop_(); RCLK = 0; } } ``` 该示例代码实现了一个简单的ADPCM编码器,将输入的采样值进行ADPCM压缩,并将压缩后的编码通过并行输出到外部设备。在主函数中,通过不断读取ADC采样值,调用ADPCM_Encode函数进行编码,并将编码结果输出到外部设备中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值