Android 平台语音通话及回音消除、噪音消除研究
一 Android操作系统由来
Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平
板电脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用“安
卓”或“安致”。Android操作系统最初由Andy Rubin开发,主要支持手机。2005年8月由Google收购注资。
2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Androi
d系统。随后Google以Apache开源许可证的授权方式,发布了Android的源代码。第一部Android智能手机发
布于2008年10月。Android逐渐扩展到平板电脑及其他领域上,如电视、数码相机、游戏机等。2011年第
一季度,Android在全球的市场份额首次超过塞班系统,跃居全球第一。 2012年11月数据显示,Android
占据全球智能手机操作系统市场76%的份额,中国市场占有率为90%。2013年09月24日谷歌开发的操作系
统Android在迎来了5岁生日,全世界采用这款系统的设备数量已经达到10亿台。
二 Android平台语音通讯
正因为Android平台优越的性能、美观的界面,越来越多人使用Android手机,从而在Android平台上的
语音通话越来越多。语音通话大概流程如下:我认为一个语音通话系统至少有四个模块。分别是PCM(Pulse
Code Modulation,即 脉码编码调制)语音采集,编解码,网络传输以及语音播放。如果算上UI交互的话,
就是五个模块了。整体流程大概是:A打电话给B,A声音通过MIC被采集成PCM原始数据,然后经过编码压缩,
再通过网络(建立P2P连接)将编码后的数据传输出去;B端通过网络收到数据后进行解码处理,然后调用播
放模块,进行播放数据。如果想通话音质提供些,可以在编码前加入 噪音消除,回音消除。
三 录音、放音、编码、解码、网络发送、接收
1、语音采集模块
Android平台上的实现是通过AudioRecord接口来实现PCM数据的采集,这一步比较容易的。但需要注意的是
AudioRecord接口的使用方法。构造AudioRecord 实例需要参数 public AudioRecord (int audioSource, int
sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)
比如录音代码如下:
static final int frequency = 8000;
static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
int recBufSize,playBufSize;
AudioRecord audioRecord;
recBufSize = AudioRecord.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency,
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, recBufSize);
2、语音播放
当语音数据采集好了之后,接着可以实现语音播放模块。Android上实现PCM数据的播放也很简单,直接
使用AudioTrack这个接口就行了。同样需要注意该接口
的使用方法。AudioTrack的构造方式跟AudioRecord是对应的
static final int frequency = 8000;
static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
int recBufSize,playBufSize;
AudioTrack audioPlayer ;
playBufSize = AudioTrack.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
audioPlayer = new AudioTrack(AudioManager.STREAM_MUSIC,frequency,AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT,playBufSize,
AudioTrack.MODE_STREAM) ;
3、语音编解码
采集到的PCM数据是原始的语音数据,如果我们直接进行网络传输,那是不可取的。因此,要进行打包编码。
编码我们需要第三方的库,目前我使用的库是speex(http://www.speex.org)。我看到许多SIP语音电话都
使用到了这个库进行编解码。当然也有对这个库评 价不好的说法,但我觉得作为学习还是可取的,因为speex
使用起来很方便。把speex源码下载下来,写好JNI接口,在NDK环境编译一下,即可在java环境调用。
例如下面一个接口函数
jint
Java_com_audiocodec_talkdemo_AudioCodec_InitAudioEncodec( JNIEnv* env,
jobject thiz,jint sampling_rate,jint audioLevel)
{
if(nInitAudioCodecEncodeFlag == 1 || audioLevel < 3 || audioLevel > 8 )
return 0 ;
int frame_size ;
if(sampling_rate == 8000)
{
audio_Leval = 0 ;
capAudioLength = 160 ;
capAudioBitrate = 8000 ;
一 Android操作系统由来
Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平
板电脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用“安
卓”或“安致”。Android操作系统最初由Andy Rubin开发,主要支持手机。2005年8月由Google收购注资。
2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Androi
d系统。随后Google以Apache开源许可证的授权方式,发布了Android的源代码。第一部Android智能手机发
布于2008年10月。Android逐渐扩展到平板电脑及其他领域上,如电视、数码相机、游戏机等。2011年第
一季度,Android在全球的市场份额首次超过塞班系统,跃居全球第一。 2012年11月数据显示,Android
占据全球智能手机操作系统市场76%的份额,中国市场占有率为90%。2013年09月24日谷歌开发的操作系
统Android在迎来了5岁生日,全世界采用这款系统的设备数量已经达到10亿台。
二 Android平台语音通讯
正因为Android平台优越的性能、美观的界面,越来越多人使用Android手机,从而在Android平台上的
语音通话越来越多。语音通话大概流程如下:我认为一个语音通话系统至少有四个模块。分别是PCM(Pulse
Code Modulation,即 脉码编码调制)语音采集,编解码,网络传输以及语音播放。如果算上UI交互的话,
就是五个模块了。整体流程大概是:A打电话给B,A声音通过MIC被采集成PCM原始数据,然后经过编码压缩,
再通过网络(建立P2P连接)将编码后的数据传输出去;B端通过网络收到数据后进行解码处理,然后调用播
放模块,进行播放数据。如果想通话音质提供些,可以在编码前加入 噪音消除,回音消除。
三 录音、放音、编码、解码、网络发送、接收
1、语音采集模块
Android平台上的实现是通过AudioRecord接口来实现PCM数据的采集,这一步比较容易的。但需要注意的是
AudioRecord接口的使用方法。构造AudioRecord 实例需要参数 public AudioRecord (int audioSource, int
sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)
比如录音代码如下:
static final int frequency = 8000;
static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
int recBufSize,playBufSize;
AudioRecord audioRecord;
recBufSize = AudioRecord.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency,
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, recBufSize);
2、语音播放
当语音数据采集好了之后,接着可以实现语音播放模块。Android上实现PCM数据的播放也很简单,直接
使用AudioTrack这个接口就行了。同样需要注意该接口
的使用方法。AudioTrack的构造方式跟AudioRecord是对应的
static final int frequency = 8000;
static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
int recBufSize,playBufSize;
AudioTrack audioPlayer ;
playBufSize = AudioTrack.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
audioPlayer = new AudioTrack(AudioManager.STREAM_MUSIC,frequency,AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT,playBufSize,
AudioTrack.MODE_STREAM) ;
3、语音编解码
采集到的PCM数据是原始的语音数据,如果我们直接进行网络传输,那是不可取的。因此,要进行打包编码。
编码我们需要第三方的库,目前我使用的库是speex(http://www.speex.org)。我看到许多SIP语音电话都
使用到了这个库进行编解码。当然也有对这个库评 价不好的说法,但我觉得作为学习还是可取的,因为speex
使用起来很方便。把speex源码下载下来,写好JNI接口,在NDK环境编译一下,即可在java环境调用。
例如下面一个接口函数
jint
Java_com_audiocodec_talkdemo_AudioCodec_InitAudioEncodec( JNIEnv* env,
jobject thiz,jint sampling_rate,jint audioLevel)
{
if(nInitAudioCodecEncodeFlag == 1 || audioLevel < 3 || audioLevel > 8 )
return 0 ;
int frame_size ;
if(sampling_rate == 8000)
{
audio_Leval = 0 ;
capAudioLength = 160 ;
capAudioBitrate = 8000 ;