ADPCM编码和解码
原文:http://www.znmcu.cn/znx_51_alltest_shell_fj_adpcm1.html
ADPCM音频解码,其实放在这里有些不太合适。
在编写ZN-X开发板整板测试程序的后期,振南开始转向专注于ADPCM音频的解码算法。对于音视频的编解码,振南一直是很感兴趣的。
VS1003录音向外输出的数据是经过ADPCM编码的,所谓ADPCM编码是一种自适应差分脉码调制技术。它可以对音频数据在毫无损失的前提下,将数据量压缩为原来的1/4,这对于音频来说,意义是重大的。我很想深入去研究一下ADPCM,但因为没有时间,一直被搁置。
ADPCM源于微软的Windows,一般的WAV文件就是使用它来编码的,WAV是Windows上的标准音频格式。ADPCM算法已经被标准化了,现行使用的是IMA-ADPCM,即IMA组织制订的ADPCM算法。这种算法比较简单,但却有较高的压缩比。


ADPCM编码的原理(我会尽量说的通俗的):
如果我们对一个声音信号进行采样,采用16位量化,比如采集53个点,如下图:

如果我们直接存储每一个点的16位的采样值,这样就需要53X16=848个位,大约是106字节。但我们换个思路,我们不存储采样值,而存储采样点两两之间的差值(采样值可能会很大,需要更多的位数来表达,比如16个位,但是两点之间一般来说是比较连续的,差值不会太大,所以这个差值只需要很少的几个位即可表达,比如4个位)。这样,我们只需要知道前一个点的值,又知道它与下一个点的差值,就可以计算得到下一个点了。这个差值就是所谓的“差分”!
这就是DPCM的主要思想精髓!!
“什么?DPCM?我们不是说ADPCM吗?”是的,DPCM是差分脉码调制,多一个A,就是自适应!为什么要自适应?
你有没有考虑到一个问题?如果取两点之差,这个差值超过了4个位可以表达的范围,该如何处理?音频信号虽然具有很高的连续性,但是我们并不能保证两点之间产生突变的可能!

前面的差值可能是3、5、8、12,后面突然变成20、40,甚至更大,这时4个位还够用吗?数据量的减少,不能以数据丢失和失真作为代价!!
如果有一种方法,可以把两点之间的差值变换到固定的几个位即可表达的范围内,那就好了!而且这种变换是实时的,并且具有自适应性和预测能力的。这就是ADPCM的基本思想。它定义了一些因子,这种算法如果发现两点之间差值变大之后,就会用差值去和相应的因子作除法,从而减小了差值,让它可以减少到几个位可表达的数值范围内。而选择哪一个因子来除它,这就是ADPCM编码要作的事情了。
ADPCM算法巧妙的利用了音频信号的特点,也就是音频信号上的点与它前面的若干个点是有一定的相关性的,从而可以对下一个点进行预测,从而预先估计这个差值,从而选取相应的除数因子,去把差值归化到数值范围内!!
以上就是ADPCM对音频信号进行编码大体思想和过程!!
我们从VS1003中读取到的,就是经过ADPCM编码后的数据,也就是音频信号采样点之间的差值!(只是这些差值并不能直接用来去计算下一个采样点,而需要与因子相乘,计算得到真正的差值,这与编码是一个相逆的过程。乘数因子就是编码时用的那个除数因子,解码时要根据当前的音频信号去预判,以便取合适的因子!!)
以上是对ADPCM编码音频的解码的方法,它适用于VS1003输出的音频数据,同样适用于使用ADPCM编码的WAV文件,以及所有使用ADPCM编码的声音数据!!!
【比如一些语音产品,像数字对讲机、数字广播等等,也都可以使用ADPCM编码,这样可以很好的降低数据带宽要求!!】
ADPCM编码和解码的更多相关文章
- java编码原理,java编码和解码问题
java的编码方式原理 java的JVM的缺省编码方式由系统的“本地语言环境”设置确定,和操作系统的类型无关 . 在JAVA源文件-->JAVAC-->Class-->Java--& ...
- IO(六)--- 编码和解码
编码: 把看得懂的字符变成看不懂码值这个过程我们称作为编码. 解码: 把码值查找对应的字符,我们把这个过程称作为解码. 注意: 以后编码与解码一般我们都使用统一的码表.否则非常容易出乱码. 常用码表: ...
- RapidJSON 代码剖析(三):Unicode 的编码与解码
根据 RFC-7159: 8.1 Character Encoding JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32. The defa ...
- BASE64编码和解码(VC源代码) 并 内存加载 CImage 图像
BASE64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本.完整的BASE64定义可见 RFC1421和 RFC2045.编码后的数据比原始数据略长,为原来的4/3.在电子 ...
- Android 中的编码与解码
前言:今天遇到一个问题,一个用户在登录的时候,出现登录失败.但是其他用户登录都是正常的,经过调试发现登录失败的用户的密码中有两个特殊字符: * .# . 特殊符号在提交表单的时候,出现了编码不一样的 ...
- base64编码、解码的C语言实现
转自:http://www.cnblogs.com/yejianfei/archive/2013/04/06/3002838.html base64是一种基于64个可打印字符来表示二进制数据的表示方法 ...
- android Java BASE64编码和解码二:图片的编码和解码
1.准备工作 (1)在项目中集成 Base64 代码,集成方法见第一篇博文:android Java BASE64编码和解码一:基础 (2)添加 ImgHelper 工具类 package com.a ...
- android Java BASE64编码和解码一:基础
今天在做Android项目的时候遇到一个问题,需求是向服务器上传一张图片,要求把图片转化成图片流放在 json字符串里传输. 类似这样的: {"name":"jike&q ...
- Web开发须知:URL编码与解码
通常如果一样东西需要编码,说明这样东西并不适合传输.原因多种多样,如Size过大,包含隐私数据,对于Url来说,之所以要进行编码,是因为Url中有些字符会引起歧义. 例如,Url参数字符串中使用key ...
随机推荐
- mysql bit类型数据库中无法显示
表an_bit bit类型字段id select bin(id+0) from an_bit显示二进制 select id+0 from an_bit显示十进制 http://blog.csdn.ne ...
- React添加自定义属性
使用‘data-’前缀即可,代码举例 render(){ return ( <ul className={css.forUl}> { this.props.todo.map(functio ...
- sqlserver判断字符串是否是数字
sql2005有个函数ISNUMERIC(expression)函数:当expression为数字时,返回1,否则返回0.这只是一个菜鸟级的解决办法,大多数情况比较奏效. eg: ') --结果为1 ...
- php 常用的调试方法
file_put_contents("c:\1.log","输出字符串",FILE_APPEND);第三个参数是防止前面的内容被覆盖 error_log(pri ...
- 使用Pycharm 安装三方库
除了使用easy_insatll和pip工具安装Python第三方库外还可以使用pycharm安装Python第三方库,步骤如下: 1.打开pycharm,点击File,再点击settings 2.点 ...
- ITest
渗透测试入门 我很简单,请不要欺负我 网站综合渗透实验: 真的很简单: 你是会员吗: 2015中国网络安全大赛 一.代码执行: 同DZ漏洞全家桶中的"又见DZ,我能那你怎么办". ...
- 【第五篇】androidEventbus源代码阅读和分析之发送粘性事件和接收粘性事件代码分析
代码里面发送粘性事件代码如下: // 发送Sticky事件 EventBus.getDefault().postSticky(new User("soyoungboy", &quo ...
- Linux权限解释
从左至右,第一位数字代表文件所有者的权限,第二位数字代表同组用户的权限,第三位数字代表其他用户的权限. 而具体的权限是由数字来表示的,读取的权限等于4,用r表示:写入的权限等于2,用w表示:执行的权限 ...
- team viewer - rollback framework could not be initialized
rollback framework could not be initialized, 在安装team viewer 的时候出现的这个错误信息,求大师帮忙 https://zhidao.baidu. ...
- Java Lambda表达式入门[转]
原文链接: Start Using Java Lambda Expressions http://blog.csdn.net/renfufei/article/details/24600507 下载示 ...