虽然这篇笔记我厚着脸皮标成了原创,但是内容基本上是大神的博客以及开源项目的的阅读笔记,当然了,这些博文我也并无分享知识的心态,只是整理一下笔记便于以后翻看,如果有同学看到也不要说我抄袭哈:
大神的ID:Jhuster
大神的博客:http://ticktick.blog.51cto.com/823160/1748506
大神的git地址:https://github.com/Jhuster/AudioDemo
好,开始!
按顺序,哈哈哈,一 常识
常见的音频编码方式有:PCM 和 ADPCM,这些数据代表着无损的原始数字音频信号,添加一些文件头信息,就可以存储为WAV文件了。
常见的音频压缩格式自然就是MP3了,另外还有AAC,OGG,WMA等。音频压缩原理:
频谱掩蔽效应: 人耳所能察觉的声音信号的频率范围为20Hz~20KHz,在这个频率范围以 外的音频信号属于冗余信号。
时域掩蔽效应: 当强音信号和弱音信号同时出现时,弱信号会听不到,因此,弱音信号也属于冗余信号。
Android提供的相关API:
音频采集: MediaRecoder,AudioRecord 。前者是一个更加上层一点的API,它可以直接把手机麦克风录入的音频数据进行编码压缩(如AMR、MP3等)并存成文件,而后者则更接近底层,能够更加自由灵活地控制,可以得到原始的一帧帧PCM音频数据。如果想简单地做一个录音机,录制成音频文件,则推荐使用 MediaRecorder,而如果需要对音频做进一步的算法处理、或者采用第三方的编码库进行压缩、以及网络传输等应用,则建议使用 AudioRecord。
音频播放: SoundPool,MediaPlayer,AudioTrack 。MediaPlayer 更加适合在后台长时间播放本地音乐文件或者在线的流式资源; SoundPool 则适合播放比较短的音频片段,比如游戏声音、按键声、铃声片段等等,它可以同时播放多个音频; 而 AudioTrack 则更接近底层,提供了非常强大的控制能力,支持低延迟播放,适合流媒体和VoIP语音电话等场景。
音频编解码: MediaCodec
NDK API: OpenSL ES
二 音频录制与播放
AudioRecord录制
(1) 配置参数,初始化内部的音频缓冲区,需要配置的参数即AudioRecord的构造函数参数。
(2) 开始采集
(3) 需要一个线程,不断地从 AudioRecord 的缓冲区将音频数据“读”出来,注意,这个过程一定要及时,否则就会出现“overrun”的错误,该错误在音频开发中比较常见,意味着应用层没有及时地“取走”音频数据,导致内部的音频缓冲区溢出。
(4) 停止采集,释放资源
采集过程:当创建好了 AudioRecord 对象之后,就可以开始进行音频数据的采集了,通过下面两个函数控制采集的开始/停止:
AudioRecord.startRecording();
AudioRecord.stop();
一旦开始采集,必须通过线程循环尽快取走音频,否则系统会出现 overrun,调用的读取数据的接口是:
AudioRecord.read(byte[] audioData, int offsetInBytes, int sizeInBytes);
AudioTrack 播放,跟录制过程差不多
(1) 配置参数,初始化内部的音频播放缓冲区
(2) 开始播放
(3) 需要一个线程,不断地向 AudioTrack 的缓冲区“写入”音频数据,注意,这个过程一定要及时,否则就会出现“underrun”的错误,该错误在音频开发中比较常见,意味着应用层没有及时地“送入”音频数据,导致内部的音频播放缓冲区为空。
(4) 停止播放,释放资源
AudioTrack 提供了两种播放模式,一种是 static 方式,一种是 streaming 方式,前者需要一次性将所有的数据都写入播放缓冲区,简单高效,通常用于播放铃声、系统 提醒的音频片段; 后者则是按照一定的时间间隔不间断地写入音频数据,理论上它可用于任何音频播放的场景。