上一篇介绍了如何将音频直接录制到文件。但如果希望在将音频数据录制到文件之前,对它进行一定得处理,该怎么办?Android提供了一个名为AudioRecord的类来满足这些需要。当设置AudioRecord对象时,android将确保音频数据写入AudioRecord的内部缓冲区,然后应用程序可对音频数据执行想要的操作。
示例代码:
该应用程序没有界面,当进入程序就开始进行录音。然后读取这些音频数据进行处理。
package com.example.audiorecord;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
protected static final String TAG = "AudioRecord";
private int mAudioBufferSize;
private int mAudioBufferSampleSize;
private AudioRecord mAudioRecord;
private boolean inRecordMode = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initAudioRecord();
}
@Override
protected void onResume() {
super.onResume();
Log.v("TAG", "Resuming");
inRecordMode = true;
Thread t = new Thread(){
@Override
public void run() {
getSamples();
};
};
t.start();
}
@Override
protected void onPause() {
Log.v("TAG", "Pausing");
inRecordMode = false;
super.onPause();
}
protected void getSamples() {
if(mAudioRecord == null)return;
short[] audioBuffer = new short[mAudioBufferSampleSize];
System.out.println("-----开始录制-----");
mAudioRecord.startRecording();
int audioRecordingState = mAudioRecord.getRecordingState();
if(audioRecordingState != AudioRecord.RECORDSTATE_RECORDING)
{
Log.e("", "AudioRecord没有在录音");
finish();
}
else
{
Log.v("TAG", "AudioRecord开始录音。");
}
while(inRecordMode)
{
int samplesRead = mAudioRecord.read(audioBuffer, 0, mAudioBufferSampleSize);
Log.v("", "Got samples: "+ samplesRead);
Log.v("TAG", "First few sample values: "+
audioBuffer[0]+","+
audioBuffer[1]+","+
audioBuffer[2]+","+
audioBuffer[3]+","+
audioBuffer[4]+","+
audioBuffer[5]+","+
audioBuffer[6]+","+
audioBuffer[7]+","+
audioBuffer[8]+","+
audioBuffer[9]+",");
mAudioRecord.stop();
Log.v("TAG", "AudioRecord has stopped recording");
}
}
private void initAudioRecord() {
int sampleRate = 8000;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
mAudioBufferSize = 2 * AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
mAudioBufferSampleSize = mAudioBufferSize / 2;
mAudioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, //音频源
sampleRate, //采样频率
channelConfig, //声道配置
audioFormat, //音频编码格式
mAudioBufferSize);//内部缓冲区大小
Log.v("TAG", "Setup of AudioRecord okay.Buffer size = "+mAudioBufferSampleSize);
int audioRecordState = mAudioRecord.getState();
if(audioRecordState != AudioRecord.STATE_INITIALIZED)
{
Log.e("TAG", "AudioRecord is not properly initialized");
finish();//结束该activity
}
}
}
需要在清单文件中添加android权限android.permission.RECORD_AUDIO。
AudioRecord类有一个名为getMinBufferSize()的静态帮助器类,它将获取想要的参数设置,返回为恰当初始化AudioRecord而应该指定的最小的缓冲区。此缓冲区无法供直接访问,但在处理以前获取的音频数据期间,AudioRecord需要拥有足够的内部空间来存储音频数据。当然可以使用缓冲区的最小值,或者可以稍微进行一下存储。绝不应尝试将缓冲区大小设置为比此帮助器方法建议使用的值更小。在本例中,我们选择的缓冲区大小为最小值的两倍。
在本例中,使用一个子线程进行音频数据采样。