PCM介绍
PCM(Pulse Code Modulation),脉冲编码调制。人耳听到的是模拟信号,PCM是把声音从模拟信号转化为数字信号的技术。原理是用一个固定的频率对模拟信号进行采样,采样后的信号在波形上看就像一串连续的幅值不一的脉冲(脉搏似的短暂起伏的电冲击),把这些脉冲的幅值按一定精度进行量化,这些量化后的数值被连续的输出、传输、处理或记录到存储介质中,所有这些组成了数字音频的产生过程(抽样、量化、编码三个过程)。
播放音乐时,应用程序从存储介质中读取音频数据(MP3、WMA、AAC…),经过解码后,最终送到音频驱动程序中的就是PCM数据,反过来,在录音时,音频驱动不停地把采样所得的PCM数据送回给应用程序,由应用程序完成压缩、存储等任务。所以,音频驱动的两大核心任务就是:
playback:如何把用户空间的应用程序发过来的PCM数据,转化为人耳可以辨别的模拟音频
capture:把mic拾取到得模拟信号,经过采样、量化,转换为PCM信号送回给用户空间的应用程序。
WAV介绍
WAV,MP3等是我们比较常见的音频格式,不同的编码格式对原始音频采用的编码方式也是不同的,通常为了方便传输等问题,会对原始音频进行压缩,同时为了能够使得播放器能够识别该种格式,所以在每种格式的头文件都是特定的,有一定的规则,来让播放器识别出是该种格式,然后按着相应的解码算法去播放后面的音频文件。
wav文件分为两个部分,第一个部分是wav头文件,第二个部分是PCM编码的音频数据部分。
android 原声录音
1. AndioRecord介绍
AndioRecord类的主要功能是让各种JAVA应用能够管理音频资源,以便它们通过此类能够录制声音相关的硬件所收集的声音。此功能的实现就是通过”pulling”(读取)AudioRecord对象的声音数据来完成的。在录音过程中,应用所需要做的就是通过后面三个类方法中的一个去及时地获取AudioRecord对象的录音数据. AudioRecord类提供的三个获取声音数据的方法分别是read(byte[], int, int), read(short[], int, int), read(ByteBuffer, int). 无论选择使用那一个方法都必须事先设定方便用户的声音数据的存储格式。
代码如下
//录音对象
private AudioRecord audioRecord;
public void createAudio(String fileName, int audioSource, int sampleRateInHz, int channelConfig, int audioFormat) {
// 获得缓冲区字节大小
bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,
channelConfig, channelConfig);
audioRecord = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes);
//this.fileName = fileName;
}
参数解释一下
audioSource:数据采集源,当然是麦克风了
sampleRateInHz:采样频率,设备一秒钟内对模拟信号的采样次数,在主流的采集卡上分为
(8Khz的电话采样率就可以达到人的对话程度)
22.05KHz:无线电广播;
44.1KHz:音频 CD,MP3等;
48KHz:miniDV、数字电视、DVD、电影和专业音频。
人耳能够感觉到的最高频率为20kHz,要满足人耳的听觉要求,则需要每秒进行40k次采样,即40kHz。我们常见的CD采样率为44.1kHz。(也比如我对接过硬件的扬声器最高是16KHz,则手机MIC采样率就不用太高,节省传输带宽)
channelConfig:声音在录制或播放时在不同空间位置采集或回放的相互独立的音频信号。
单声道 采样数据为8位的短整数(short);
双声道 采样数据为16位的整数,(int),高八位(左声道)和低八位(右声道)分别代表两个声道。
audioFormat:编码制式和采样大小:采集来的数据当然使用PCM编码(脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。) android支持的采样大小16bit 或者8bit。当然采样大小越大,那么信息量越多,音质也越高,现在主流的采样大小都是16bit,在低质量的语音传输的时候8bit足够了。
2. 主要源码
public class AudioRecorder {
private static AudioRecorder audioRecorder;
//音频输入-麦克风
private final static int AUDIO_INPUT = MediaRecorder.AudioSource.MIC;
//采用频率
//44100是目前的标准,但是某些设备仍然支持22050,16000,11025