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 ...
随机推荐
- Ecstore安装篇-2.单机部署【linux】
单机部署实施-linux 单机部署实施-linux author :James,jimingsong@vip.qq.com since :2015-03-02 系统环境需求 软件来源 底层依赖 1. ...
- setcookie 设置无效
转载请署名 achieverain,谢谢 经常见人问PHP程序无法设置cookie.下面把我遇见过的情况都说一遍 1 PHP程序在执行setcookie之前有输出. 解决 : 把setcooki ...
- 关于PHPAPI ZEND_API TSRM_API宏的定义
在PHP源码中,我们可以见到诸如PHPAPI ZEND_API TSRM_API等xxx_API(当然还有其他格式的)这样的宏 关于它们的定义都是类似于 #if defined(__GNUC__) & ...
- imx6平台qt锯齿原因分析
gbl_alpha:全局alpha 就是设置整个界面的alpha值 loc_alpha 本地alpha 就是图片里面自带的alpha值 color_key color Key 要把界面透出来,就要设置 ...
- 快乐编程学ruby
人们常说:不忘初心,方得始终.所以,code除了完成工作任务,在最初还应该是富于乐趣的,正所谓,宅男配女仆,我们来了解了解我们的ruby 萌妹子吧:-). ...
- win10 Qt 调试器未设置
安装win10后一直用vs调试,没有用qt调试,这次启动调试,发现提示调试器未设置. 解决办法: 需要重新安装wdk 10 https://developer.microsoft.com/zh-cn/ ...
- Users is not mapped(Hibernate实体类采用注解)
今天做简单的登陆验证web应用时,用HQL语句查询数据表时 总是出现Users is not mapped [from Users u where u.username=? and u.passwor ...
- Unity 5 Game Optimization
2. Scripting Strategies 2.1 Cache Component references (缓存组件引用) 使用 Rigidbody rigidbody = GetComponen ...
- 使用minidom来处理XML的示例(Python 学习)(转载)
作者网站:http://www.donews.net/limodou/archive/2004/07/15/43609.aspx 一.XML的读取.在 NewEdit 中有代码片段的功能,代码片段分 ...
- Oracle查询和解锁表
一些ORACLE中的进程被杀掉后,状态被置为"killed",但是锁定的资源很长时间不释放,有时实在没办法,只好重启数据库.现在提供一种方法解决这种问题,那就是在ORACLE中杀不 ...