在说这个话题之前需要知道几个重点:
1.mediaRecorder/audioRecord区别
mediaRecorder是系统提供常用的录音类,该类可以实现音频录音生成文件。audioRecord也是系统提供的录音类,但是他可以直接捕获音频流,开发者可以实时随意处理其内容。常见的场景比如语音聊天/tom猫/k歌。
2.riff/wav/pcm/raw/mp3
riff是一种文件描述格式,wav文件就采用了riff描述,其前44字节就是riff描述内容。pcm就是媒体数据的元数据,直接记录声音内容的。wav = riff + pcm,raw = pcm,而mp3是一种压缩编码,大概的意思就是将pcm通过算法压缩。
3.采样率,比特率,通道数,采样值
采样率是模拟信号采集频率(每秒样本数),采样率越高声音还原越真实;比特率是模拟信号转为数字信号后的采样率;采样值又称每样本数据位数,常见8位与16位;通道常见有单通道和双通道,单通道每样本占用8/16位,双通道每样本占用16/32位,且高8/16位是左声道,低8/16位是右声道;
然后我们再来讨论如何实现音频合成:
1.首先我们需要获得用户声音就需要录音类,需要同步处理数据就只能用audioRecord了
2.录制的声音是pcm即元数据,我们需要与另外一个声音文件合并,这样就必须将另外一个文件解码为pcm数据
3.获得录音与伴奏的pcm数据之后进行混合,混合算法后面再说,简单的来说就是算每位字节的平均值
4.得到混合后的音频pcm之后进行再编码,比如以最终生成wav格式为例,只需要在pcm数据前加入44字节的riff描述即可。
实现过程中遇到的问题:
1.录音失真:在测试的过程中发现录音文件播放速度非常快,经分析发现是wav文件头描述与文件实际内容不匹配导致,比如我采用44100采样率,单声道,16位采样值录音,但是riff中写的是双声道,因此算出来的播放时间比实际时间少了一半,所以播放速度加倍。得出来的结论就是riff描述内容一定要与pcm实际内容匹配,否则就会导致播放声音异常。----由此也可以推断只要文件能播,但是播放效果异常就说明多半是riff与pcm类型不匹配导致的.
2.部分文件不支持:出现概率很小,可能是文件本身编码问题。
3.录音过程耗时:audioRecord.read的时候会阻塞耗时,所以会出现mediaPlayer播放完了,录音只录到一半。
4.混合算法:理论上混合算法就是每位字节相加除以位数求平均数即可,但前提条件是两个文件的通道数&采样值必须一样。之前也解释过通道数与采样值的作用,所以很好推断如果采样值之前是8bit要合16bit,就先要byte转short再叠加求均数;如果是单通道要合双通道就写算法加在前半位或后半位;双通道转单通道就前半位与后半位叠加后算平均数之后再与单通道叠加算平均数.
5.Android设备只能以单声道的形式录制,即使传入双声道的参数运行不报错,也只能将生成的PCM当作单声道文件处理。
========================福利============源码========================
Android audioRecord录音Demo
http://download.csdn.net/detail/h3c4lenovo/4684011
Android音频混合 -- K歌合成
http://download.csdn.net/detail/h3c4lenovo/4684013