ADPCM 音频压缩算法
ADPCM(Adaptive Differential Pulse Code Modulation),是一种针对 16bits( 或8bits或者更高) 声音波形数据的一种有损压缩算法,它将声音流中每次采样的 16bit 数据以 4bit 存储,所以压缩比 1:4. 而且压缩/解压缩算法非常简单,是一种低空间消耗,高质量高效率声音获得的好途径。保存声音的数据文件后缀名为 .AUD 的大多用ADPCM 压缩。
ADPCM 主要是针对连续的波形数据的,保存的是波形的变化情况,以达到描述整个波形的目的。
8bits采样的声音人耳是可以勉强接受的,而 16bit 采样的声音可以算是高音质了。ADPCM 算法却可以将每次采样得到的 16bit 数据压缩到 4bit。需要注意的是,如果要压缩/解压缩得是立体声信号,采样时,声音信号是放在一起的,需要将两个声道分别处理。
以上文字摘自http://blog.csdn.net/lxc1014/article/details/9316381
自己写该算法时参考了上述博客中的内容。但后来才知道STM32官方也有该算法的文档和程序,于是自己基于上面两份资料写了关于该算法的代码。当然还有很多不懂的,不对处望博友指正。我用的是STM32的ADC、DAC,它是12Bit采样,所以我稍微将传统的ADPCM给改了下。
typedef __packed struct
{int16_t valprev;
int8_t index;
}_s_ADPCM;
int8_t index_adjust[16] = {-1,-1,-1,-1,2,4,6,8,-1,-1,-1,-1,2,4,6,8};
uint16_t 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
};
void ADPCM_Encoder(_s_ADPCM *state,int16_t* pInBuf,uint8_t *pOutBuf,uint8_t Len)
{
uint8_t i=0,j=0;
int16_t Index=0;
uint8_t code=0;
int32_t data=0,predata = 0 ,delta=0,prediff=0;
uint16_t step=0,tmpstep=0;
predata = (int32_t)state->valprev;
Index = (int16_t)state->index;
for(i=0;i<Len;i++)
{
data=(int32_t)*(pInBuf+i);
step = step_table[Index];
delta = data - predata;
if(delta<0)
{
delta=-delta;
code=8;
}
else
{
code=0;
}
#if 1
tmpstep = step;
prediff = (step >>3);
if(delta >= tmpstep)
{
code |= 0x04;
delta -= tmpstep;
prediff += step;
}
tmpstep = tmpstep>>1;
if(delta >= tmpstep)
{
code |= 0x02;
delta -= tmpstep;
prediff += (step >>1);
}
tmpstep = tmpstep>>1;
if(delta >= tmpstep)
{
code |= 0x01;
prediff += (step>>2);
}
#else
code = (delta<<2)/(step);
if(code >7)
code = 7;
prediff = (delta * step)>>2;
#endif
if(code & 8)
{
predata -= prediff;
}
else
{
predata += prediff;
}
if(predata > 2047)
{
predata =2047;
}
else if(predata < -2048)
{
predata =-2048;
}
Index+=index_adjust[code];
if(Index < 0)
Index=0;
else if(Index >59)
Index=59;
if(i&0x01)
{
*(pOutBuf+j) |=(uint8_t)((code&0x0f)<<4);
j++;
}
else
{
*(pOutBuf+j) = (uint8_t)(code&0x0f);
}
}
state->valprev = (int16_t)predata;
state->index =(int8_t)Index;
}
void ADPCM_Decoder(uint8_t *pInBuf,int16_t *pOutBuf,uint8_t Len,_s_ADPCM *state)
{
uint8_t i=0,j=0,tmp_data=0,inCode=0;
uint16_t step=0;
int16_t Index=0;
int32_t predsample=0,diffq=0;
predsample = (int32_t)state->valprev;
Index = (int16_t)state->index;
for(i=0;i<(Len<<1);i++)
{
tmp_data=pInBuf[i>>1];
if(i&0x01)
inCode=(tmp_data&0xf0)>>4;
else
inCode=tmp_data&0x0f;
step = step_table[Index];
diffq = step>>3;
if(inCode & 0x04)
diffq += step;
if(inCode & 0x02)
diffq += (step>>1);
if(inCode & 0x01)
diffq += (step>>2);
if(inCode & 8)
predsample-= diffq;
else
predsample+=diffq;
if(predsample > 2047)
predsample =2047;
else if (predsample <-2048)
predsample = -2048;
Index+= index_adjust[inCode];
if(Index < 0)
Index=0;
if(Index >59)
Index = 59;
pOutBuf[j++] = (int16_t)predsample;
}
state->valprev = (int16_t)predsample;
state->index = (int8_t)Index;
}
对上述代码进行简单说明下:
编码时将16Bit压缩成4Bit,输出时是8Bit的数据,先接到的数据放在8Bit的低4位,第二次接到的数据放在高4位。
其中在编码函数中采用了条件编译,现在采用的即为算法介绍中编码方式。算法参考文档:http://www.mp3-tech.org/programmer/docs/adpcm.pdf
(当然也是STM32 ADPCM编码采用的方式)。另一个条件选择是一种粗略算法,我感觉没有前面一种编码效果好(我只验证了第一种编码方式,第二种没有试验)。
解码时就要将压缩后的数据给分开来。即假如编码数量为32个16Bit的数据,经过压缩可得到16个8Bit的数据,再经过解压缩可得到32个16Bit数据。编解码局限性在于编码数量我只考虑了偶数情况,奇数情况我还没考虑。
当然上述算法还有待优化~~时间允许的话,一定仔细研究下,从而优化自己的代码。
ADPCM 音频压缩算法相关推荐
- ADPCM音频格式详解 ADPCM_IMA ADPCM_DIV4
网上帖子一大推,都是照搬adpcm音频算法代码,实际使用时需要注意没有相关细节,我在这里补充一片防止大家走弯路 //ADPCM-DIV4 音频帧标识头 struct adpcm_state { ...
- ADPCM音频编解码
前言 参考 所谓ADPCM编码是一种自适应差分脉码调制技术.它可以对音频数据在毫无损失的前提下,将数据量压缩为原来的1/4,这对于音频来说,意义是重大的. ADPCM源于微软的Windows,一般的W ...
- Zigbee音频, 6LowPAN, IEEE 802
http://antkillerfarm.github.io/ Zigbee音频 前言 本文是对Zigbee传输音频数据功能的一个资源汇总分析贴. 网上解决方案分析 基于MCF5213及Zigbee技 ...
- 第二部分 音频压缩编码
第二部分 音频压缩编码 一.有损 ( lossy )/无损 ( lossless )/未压缩 ( uncompressed )音频格式 未压缩音频是一种没经过任何压缩的简单音频.未压缩音频通常用 ...
- CSR867x — 说说蓝牙音频常用的编解码格式
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XX 作 者:文化人 XX 联系方式: XX 版权声明:原创文章,欢迎 ...
- CSR8670 — 说说蓝牙音频常用的编解码格式
SBC (Sub-band coding,子带编码) 最早的格式应该是SBC,SBC是A2DP(Advanced Audio DistribuTIon Profile,蓝牙音频传输协议)协议强制规定的 ...
- 音频处理与压缩的一些技术点和算法
音频处理的方法主要包括: 降噪.回声消除.自动增益.静音检测.噪声控制 音频压缩算法需要看音频编码的格式: G.7xx.iLBC.SILK.OPUS.AAC.AC3.apt-x(ADPCM)等等 降噪 ...
- 各种音频视频编码方法
编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...
- 蓝牙 A2DP 音频传输格式-全面解析
1. 蓝牙 A2DP 音频传输格式 达到 CD 音质需要 1411.2 kbit/s 的带宽,显然 A2DP 无法允许,所以音频数据需要经过压缩.我们知道同样的比特率下,不同的编码格式音质是不同的.A ...
- ADPCM编解码的使用
网上有很多讲解Adpcm编解码的,但是就没有详细说明其是需要如何使用的. 这里就记录下是如何使用代码的,即是函数的参数需要填写什么,要注意的要点. ADPCM(Adaptive Differentia ...
最新文章
- ES Segment Memory——本质上就是segment中加到内存的FST数据,因此segment越多,该内存越大...
- 如何在命令行模式下升级的你Visual Studio的Solution文件
- redis快照文件dump.rdb解析工具--redis-rdb-tools
- Latex 调整表格大小 表格过大 表格过小
- 7-8 字符串字母大小写转换 (15 分)
- 获取设备和 App 信息
- Android MediaPlayer的生命周期
- c语言程序原版PDF,正式版C语言程序设计.pdf
- 静态网页HTML知识点归纳
- 微信扫码跳转浏览器下载app
- drive翻译成中文_drive是什么意思_drive翻译_读音_用法_翻译
- 什么是设备管理系统,包括哪些内容?一文读懂
- SAP物料主数据编码范围配置
- django 发送邮件验证码
- 机器学习中的矩阵向量求导(五) 矩阵对矩阵的求导
- 7-13 大家一起来玩游戏 (20 分)
- thinkphp6 验证码总是提示不正确
- C#工控上位机——框架
- VS2015 0xc000007b应用程序无法正常启动 解决办法
- 2023青海大学计算机考研信息汇总
热门文章
- 经典算法详解(2):费氏数列
- Word 2003的基本使用
- 《你和你的研究》全文
- 基于单片机的心率监测系统设计(#0403)
- C++统计输入字符串各个大写字母的个数
- Android 项目使用 Jenkins 打包时的异常问题 AAPT: C:\Windows\System32\config\systemprofile\.gradle\caches
- 通过命令行安装egret引擎
- 计算机网络——数据从网卡到应用的过程
- 解决Word无响应崩溃的问题
- 04、CONSTANT-ROUND CZK PROOFS for NP--Alon Rosen[对于NP的常数轮CZK证明]