标签:
1. http://www.leiphone.com/news/201406/record.html
本文作者是科通芯城的何顺义工程师。
想必大家都有这样的经历:接到朋友从火车站、地铁、会场、KTV等场合打来的电话,有时候很难听清楚,有时候却听得很清晰。这是为什么?
通常我们会认为是对方信号不稳定,所以通话质量有好有坏。其实不然,这种环境下能否听清对方讲话,主要取决于对方手机录音和降噪功能的优劣。同时,这也是高端手机和普通手机的一个重要区别。
任何功能的差别,归根到底,都是硬件和软件的差别。在本文中,笔者将花较长的篇幅和网友们分享一下手机的录音、降噪的原理;所需要的硬件、算法;以及不同的硬件、算法,在使用体验上的差别。希望对大家能有些帮助。
首先说一下为什么要强调手机的录音功能。
很简单,手机是用来通话的。通话的过程,首先要把说话的人的声音录下来,然后听者才可以听得到。所以,录音功能对于通话,是基础而重要的。
对于手机的录音过程,简单地讲,需要经过三个阶段,两个环节。三个环节是:“声音——模拟电信号——数字电信号”。两个环节是:“麦克风”和“ADC(analog digital converter/数字模拟转换器)”。麦克风负责把“声音”转化为“模拟电信号”,ADC负责把“模拟电信号”转化为“数字电信号”。所以说,麦克风和ADC的品质直接决定录音功能的品质。
麦克风大家比较熟悉,这里不再赘述,主要讲一下ADC。
如何衡量一个ADC的品质?简单点讲,看两个参数:采样速度和量化位数。什么是采样速度和量化位数?可以这么理解,采样速度代表速度,而量化位数代表精度。这两个数值都是越大越好。
那么,怎么知道手机中ADC的“采样速度”和“量化位数”呢?办法是有的:
先下载一个叫“RecForg”的免费APP,安装运行之后,找到“设置”菜单,进入后界面如下图所示▼
上图中,有两个红色方框:“采样率”和“音频格式”。这两个子菜单分别对应ADC的“采样速度”和“量化位数”。
可以看出,有三个档位是灰色不可选的:12kHz、24kHz、 48kHz。而其它所有档位都可以选择。这说明笔者手机ADC的“采样速率”有5个档位,最高为44kHz。同时,笔者也测试过朋友的小米2,发现其最高的采样速率是48kHz。这说明小米2使用的ADC要比笔者手机的ADC高一个等级。
在“设置”菜单界面,点击“音频格式”子菜单进入之后,会看到下图▼
上图说明,笔者手机的ADC的“量化位数”是16位。
很简单吧?需要说明的是,笔者发现APP“RecForg”只在android平台手机上可以找到,而在IOS里是没有的。如果大家想查看Iphone的ADC的参数,可以尝试找一些类似的录音软件,碰碰运气,说不准会有发现呢。
在“录音过程和硬件”部分,讲到了录音需要的硬件,以及硬件性能对于录音质量的影响。
如果在安静的环境中,软件对于通话的影响并不大。然而,手机是移动通信设备,通话场景不确定,很可能是在嘈杂环境中的。在这种情况下,降噪算法对于通话质量就至关重要了。
降噪是怎么回事?简单点说,就是通过算法,从接收到的声音中分离出人声和噪声,把人声加强,把噪声抑制,从而提高通话质量。道理很简单,但在具体实现上,算法非常复杂,各手机公司一般都不会自己做降噪算法,而是采用相关专业公司的方案。
说到降噪,不得不提audience公司。这是一家专门从事移动通信音频技术的全球领导公司,通俗点说,就是做音频降噪算法的公司。苹果、三星、HTC、Google、LG、华为、夏普、魅族、小米等都是audience的客户,如果要列举采用audience芯片的机型,将会是一张非常长的名单。
那么,不同的降噪算法,体现用户体验上,会有什么区别呢?
我们可以在嘈杂的环境中,可以进行两种试验。(一)、在嘈杂环境中,使用“免提通话”,对方可以听很清楚的条件下,说话者和手机的最大距离是多远?(二)、在嘈杂环境中,手机可以语音识别的最大距离是多远?笔者测试过一些高端手机和普通手机,结果差别还蛮大。大家如果有兴趣,也可以试一试。
上面是从体验方面来说降噪性能。那么除了主观感受,是否可以有一个客观的、直观的展现呢?答案也是肯定的。见下图▼
上图是iphone4s和小米2播放通道的频率响应曲线。可以明显地看出,iphone4s在低频(<80Hz)和高频段(>1.4Hz)都做了相应的降噪处理,只保留和人声频段。而小米2只在高频段有降噪处理。这也说明和iphone4s相比,小米在一些细节上还是有一定提升空间。
2. http://blog.163.com/l1_jun/blog/static/143863882013517105217611/
前文书咱们说到IOS下如何录制一个wav格式的音频,然而现在的情况确实安卓不支持wav格式,于是有看官说了,你个二百五,就不能选个安卓支持的格式录制么,我很负责任的说,苹果和谷歌掐架,苦的就是我们这帮苦逼的技术人员。。。安卓的格式苹果全不支持,看好是全不,不是全部,反过来苹果的格式,安卓也不惯着。。。。
当然上有政策下有对策是万年不变的真理,Ios与安卓的音频互通是难不倒我们伟大的程序员的,而目前解决这个问题方案有很多种但大致以下3种方式,且听我细细道来。
第一种方案对于服务器负荷较大,不论是安卓端亦或是IOS端都将音频传输到服务器,通过服务器进行转换再进行转发。这种做法可以不受系统限制,但是信息量较大时对服务器负荷较大,对服务器端的要求很高。据传闻,微信就是采用这种方式进行的语音IM交互
第二种方案是不论IOS端还是安卓端都统一使用相同的第三方音频库进行编解码处理,然后再进行网络传输,优点是可供选择的音频库非常多,可以根据自己不同的需求选择各种各样的音频格式,但是因为不论是IOS端还是安卓端都需要对其进行i编码解码处理,而项目初期并没有设计这方面的需求所以如果双端都进行修改修改量实在太大。同样据传闻,同为语音IM的成熟案例微米就是依靠Speex的三方开源库来完成的,这种格式体积小,能降噪,是目前比较受推崇的方式。
我采用的是第三种方式,amr格式的音频文件是安卓系统中默认的录音文件,也算是安卓支持的很方便的音频文件,IOS系统曾经是支持这种格式的文件,自4.3以后才取消了对amr的支持(原因应该不需要我多说。。。),可见,amr格式的音频文件并非IOS处理不了的,因为有了这样的概念和潜意识的植入,我就开始一门心思在网络上找寻各种各样的实例以及demo,我要做的就是把问题尽量都解决在IOS端。终于功夫不负有心人,最终让我得以成功的在IOS端成功的转换出安卓端可以使用的amr文件。接下来,我们就说说如何在IOS端完成wav与amr文件的互转。
首先推荐给大伙提供一个demo在下面的连接下载。此demo转载自中国开源社区,本人发自内心的向发布者Jeans大人致以最崇高的敬意。
http://www.oschina.net/code/snippet_562429_12400
demo下载打开项目后将如下四个源码文件以及两个库文件拖入自己的项目,引用AudioToolbox.framework、CoreAudio.framework以及AVFouncation.framework即可完成类库的导入
打开我们导入的头文件就会发现有又大量的struct,而在开启ARC项目中是禁止使用struct和union的,而我们的项目确实可以开启ARC的,这里涉及到一个知识点,之前也在网络上看到有人提问在开启ARC后改如何使用struct,我也是接触这个项目之后开始涉及混编才了解该如何解决这个问题, 只要将Compile Sources As(设置编译源)的设置为Ojbective-C++或者将包含到声名struct和union头文件的实作文件的扩展名改为.mm就可以在项目中使用struct和union了,但是请注意此时你编写的代码不再是纯粹的Objective-C语言了,而是涉及到Objective-C++,此处涉及到混编的问题,我们再后面还会再讲解混编相关的内容,但并不会很多,感兴趣的看官可以自己查找资料。回到原题,如果在导入文件后遇到了编译错误,请点击项目的TARGETS下的Build Settings找到以下编译设置并按照图内容修改
注意,如果是新建空项目Compile Sources As的设置在According to File Type(依照文件类型选择编译源)的模式下应该也可以正常编译,尽量不要设置为Ojbective-C++进行编译,我是因为项目中含有其他的SDK需要用到所以才如此设置,一旦设置成Ojbective-C++会和我们之后讲的网络传输篇中所使用的SDK产生一定冲突很那解决。所以此最好保持According to File Type。
文件正常导入之后就可以直接使用转换方法了,和常规的SDK不同,这个库并非以累的形式封装的,而是数个功能函数,所以并不需要我们去构造对象,接下来我们说一下转换时具体用到的方法,虽然这些方法简单易用,但是我还是愿意为大家提供一点便利,所谓帮人到底送佛送到西,下面我每一个方法的名称、功能、参数说明以及使用示例贴出以供大家参考~。
哦~对了不要忘记,我们的第一步永远都是导入头文件
#import “amrFileCodec.h”;
接下来我们开始第一个函数EncodeWAVEFileToAMRFile从函数名称中就可看出,此方法是将WAV转换为AMR文件的,我们先来看一下示例
参数列表也并不是很复杂4个参数分别问:1.WAV的文件地址,2.AMR的文件地址,3.音频通道数,也就是我们上篇文章中所提到录制音频的最后一个参数,声道数量。4.编码位数,同样在上一篇文章中我们也已经介绍过不再赘述。
接下来第二个函数,DecodeAMRFileToWAVEFile这个参数与前一个功能正好相反,是从amr转换为WAV,下面是具体代码示例
这个参数可以说较上一个更加简单,第一个参数是需要一个AMR的文件地址也就是源,第二个参数则是目标地址也就是一个WAV文件的地址,简单的两个参数就可完成调用了。需要注意的是,此处所使用的地址和之前我们再使用AVFouncation的时候又不同了,它既不是要NSString的字符串,也不是NSURL对象而是一个const char的指针,但是这并不是问题,实例代码中所转换的方法并不是最简的只是急于演示所以拖拽出来的,希望有心的看官可以自行过滤,过眼不过心是编程大忌。
相对于导入可以说使用的方法简单的一塌糊涂,并不需要我们多少功夫,也没有那么高深莫测,但是测试还是要下一定功夫的,经过实机检测IOS下录制出的WAV转换为AMR之后放到安卓平台可以正常播放,而安卓录制的AMR文件拿到IOS下转换出WAV一样可以播放完全没有任何问题。但是这个方法也是有一定的弊端,音频转换的速度较慢,如果是时间较长的音频文件转换起来会有短时间顿卡,但是用来实现语音IM聊天是完全可以满足的
至此我们本地音频处理篇的内容全部完结,也算是告一段落,但是我们现在只是在本地机器上实现了正确的音频转换以及播放,想要完成语音IM聊天我们还差关键的环节就是与服务器的交互,详细的内容,我们将在下一篇文章中介绍,尽请关注IOS、安卓IM语音聊天开发初探部分心得——异步Socket传输篇
标签:
原文地址:http://www.cnblogs.com/lushengcao/p/4954366.html