AudioRecorder 錄制pcm數(shù)據(jù)
1、定義 實(shí)例化一個(gè)AudioRecord類我們需要傳入幾種參數(shù)
- AudioSource:這里可以是MediaRecorder.AudioSource.MIC
- SampleRateInHz:錄制頻率,可以為8000hz或者11025hz等,不同的硬件設(shè)備這個(gè)值不同
- ChannelConfig:錄制通道,可以為AudioFormat.CHANNEL_CONFIGURATION_MONO和AudioFormat.CHANNEL_CONFIGURATION_STEREO
- AudioFormat:錄制編碼格式,可以為AudioFormat.ENCODING_16BIT和8BIT,其中16BIT的仿真性比8BIT好,但是需要消耗更多的電量和存儲(chǔ)空間
- BufferSize:錄制緩沖大?。嚎梢酝ㄟ^(guò)getMinBufferSize來(lái)獲取
- 這樣我們就可以實(shí)例化一個(gè)AudioRecord對(duì)象了
private int frequence = 8000; //錄制頻率,單位hz.這里的值注意了,寫的不好,可能實(shí)例化AudioRecord對(duì)象的時(shí)候,會(huì)出錯(cuò)。我開始寫成11025就不行。這取決于硬件設(shè)備
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
2、 實(shí)例化一個(gè)AudioRecord實(shí)例
//根據(jù)定義好的幾個(gè)配置,來(lái)獲取合適的緩沖大小
int bufferSize = AudioRecord.getMinBufferSize(frequence,channelConfig,audioEncoding);
//實(shí)力化audioRecord
AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC,frequence,channelConfig,audioEncoding,bufferSize);
//定義緩沖
short[]buffer = new short[bufferSize];
//開始錄制
record.startRecording();
3、創(chuàng)建一個(gè)文件,用于保存錄制的內(nèi)容 。然后打開一個(gè)輸出流,指向創(chuàng)建的文件
String fileStr = folder+fName;
audioFile = new File(fileStr);
if(!audioFile.getParentFile().exists()){
audioFile.getParentFile().mkdirs();
}
try {
if(audioFile.exists()){
audioFile.delete();
}
audioFile.createNewFile();
boolean ex = audioFile.exists();
Log.d(TAG,audioFile.getAbsolutePath()+" exist:"+ex);
}catch (Exception e){
e.printStackTrace();
}
//開通輸入流 到指定的文件
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(audioFile)));
4、現(xiàn)在就可以開始錄制了,我們需要?jiǎng)?chuàng)建一個(gè)字節(jié)數(shù)組來(lái)存儲(chǔ)從AudioRecorder中返回的音頻數(shù)據(jù)。 然后一個(gè)循環(huán),調(diào)用AudioRecord的read方法實(shí)現(xiàn)讀取
但是 注意,我們定義的數(shù)組要小于定義AudioRecord時(shí)指定的那個(gè)BufferSize
int r = 0;//存儲(chǔ)錄制進(jìn)度
while (isRecording){
//從bufferSize 中讀取字節(jié),返回讀取的short個(gè)數(shù)
int bufferReadResult = record.read(buffer,0,buffer.length);
for(int i = 0;i<bufferReadResult;i++){
dos.writeShort(buffer[i]);
}
publishProgress(new Integer(r));
r++;//自增進(jìn)度值
Log.d(TAG,"recoding "+r+",isRecording:"+isRecording);
}
//結(jié)束錄制
record.stop();
dos.close();
AudioTrack播放pcm數(shù)據(jù)
AudioTrack類允許我們播放原始的音頻數(shù)據(jù)
1、實(shí)例化一個(gè)AudioTrack同樣要傳入幾個(gè)參數(shù)
- StreamType:在AudioManager中有幾個(gè)常量,其中一個(gè)是STREAM_MUSIC;
- SampleRateInHz:最好和AudioRecord使用的是同一個(gè)值
- ChannelConfig:同上
- AudioFormat:同上
- BufferSize:通過(guò)AudioTrack的靜態(tài)方法getMinBufferSize來(lái)獲取
- Mode:可以是AudioTrack.MODE_STREAM和MODE_STATIC,關(guān)于這兩種不同之處,可以查閱文檔
2、打開一個(gè)輸入流,指向剛剛錄制內(nèi)容保存的文件,然后開始播放,邊讀取邊播放
isPlaying = true;
Log.d(TAG,"audioPlayer doInBackground");
int bufferSize = AudioTrack.getMinBufferSize(frequence,channelConfig,audioEncoding);
short[]buffer = new short[bufferSize/4];
try{
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(audioFile)));
//創(chuàng)建audioTrack track
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,frequence,channelConfig,audioEncoding,bufferSize,AudioTrack.MODE_STREAM);
track.play();
//由于AudioTrack播放的是流,所以,我們需要一邊播放一邊讀取
while (isPlaying && dis.available() >0){
int i = 0;
while (dis.available() > 0 && i < buffer.length){
buffer[i] = dis.readShort();
i++;
}
track.write(buffer,0,buffer.length);
Log.d(TAG,"audioPlayer while:");
}
track.stop();
dis.close();
}catch (Exception e){
e.printStackTrace();
}finally {
}
參考鏈接:
githubdemo:
https://github.com/feifei-123/MyExampleCode