android 录音原始文件_音频采集:Android基于AudioRecord的实现
前言
這篇文章簡單介紹下移動端Android系統(tǒng)下利用AudioRecord進行音頻采集方法。
按照慣例開始前先提供一份源碼 AudioRecordLib 。
AudioRecord采集的核心實現(xiàn)在于 AudioRecordCore.java 這個文件。
權(quán)限申請
想要使用AudioRecord這個API,需要在AndroidManifest.xml的配置文件里面增加錄音權(quán)限:
初始化
AudioRecord的初始化需要先創(chuàng)建一個AudioRecord實例。
構(gòu)造函數(shù)原型如下:
public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig,
int audioFormat,int bufferSizeInBytes)
具體參數(shù)說明:
audioSource 這個參數(shù)指的是音頻采集的輸入源,接受的值定義在MediaRecorder.AudioSource里面,一般來說使用DEFAULT或者MIC即可。
sampleRateInHz 指定采集音頻的采樣頻率,比較通用的是44100(44.1kHz),這個值是科學(xué)家們通過奈葵斯特采樣定理得出的一個人能接受最佳的采樣頻率值。
channelConfig 指定AudioRecord采集幾個聲道的聲音,預(yù)設(shè)值定義在AudioFormat中,常用值有 CHANNEL_CONFIGURATION_MONO(單聲道) 和 CHANNEL_CONFIGURATION_STEREO(雙聲道)。
audioFormat 指定采樣PCM數(shù)據(jù)的采樣格式,預(yù)設(shè)值定義在也AudioFormat中,常用值有 ENCODING_PCM_8BIT、ENCODING_PCM_16BIT和ENCODING_PCM_FLOAT,值得強調(diào)的是ENCODING_PCM_16BIT可以保證兼容大部分Andorid手機。
bufferSizeInBytes 配置AudioRecord內(nèi)部的音頻數(shù)據(jù)緩沖區(qū),一般來說緩存區(qū)越小,產(chǎn)生的音頻延遲也越小;值得注意的是,我們可以利用AudioRecord.getMinBufferSize()這個方法幫我們算出最小的緩存區(qū)大小,這個數(shù)值最好不要自己計算,畢竟不同廠商可能有不同的緩存區(qū)采集實現(xiàn)。
檢測AudioRecord當(dāng)前狀態(tài)
由于可能存在權(quán)限問題導(dǎo)致配置AudioRecord失敗,所以我們需要在開始采集前檢查一下AudioRecord的狀態(tài):
if (mAudioRecord.getState() == AudioRecord.STATE_INITIALIZED) {
//todo start
}
如果getState()不等于AudioRecord.STATE_INITIALIZED說明創(chuàng)建AudioRecord失敗,這時候應(yīng)該給用戶反饋信息。
完整代碼如下:
//獲取最低AudioRecord內(nèi)部音視頻緩沖區(qū)大小,此大小依賴于各產(chǎn)商實現(xiàn),最好不要自己計算
mRecordBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
//初始化AudioRecord實例
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, channelConfig, audioFormat, mRecordBufSize);
//檢測AudioRecord初始化是否成功
if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
mAudioRecord = null;
mRecordBufSize = 0;
return false;
}
else {
//創(chuàng)建一個位置用于存放后續(xù)的PCM數(shù)據(jù)
mPcmData = new byte[mRecordBufSize];
mState = INIT;
return true;
}
開始采集
創(chuàng)建好了AudioRecord實例,調(diào)用如下的方法即可開始麥克風(fēng)采集:
mAudioRecord.startRecording();
提取數(shù)據(jù)
調(diào)用了開始采集后,我們需要另起一條線程進行PCM數(shù)據(jù)提取。
我們需要循環(huán)不斷從AudioRecord的緩沖區(qū)里面將數(shù)據(jù)讀取出來,值得注意的是這個過程一定要及時,不然會出現(xiàn)“overrun”的錯誤,也就是沒有及時取走音頻數(shù)據(jù)導(dǎo)致音頻緩存區(qū)溢出了。
private Thread mReadDataThread = new Thread() {
@Override
public void run() {
int read;
while (mState == RECORDING) {
//讀取mRecordBufSize長度的音頻數(shù)據(jù)存入mPcmData中
read = mAudioRecord.read(mPcmData, 0, mRecordBufSize);
//如果讀取音頻數(shù)據(jù)沒有出現(xiàn)錯誤 ===> read 大于0
if (read >= AudioRecord.SUCCESS) {
synchronized (AudioRecordRecord.class){
if (mCallback != null)
mCallback.onPCMDataAvailable(mPcmData, read);
}
}
}
}
};
停止采集,釋放資源
停止錄音我們可以調(diào)用AudioRecord的stop方法來實現(xiàn)。
mAudioRecord.stop();
但是我們存在采集(音頻提取)線程,所以我們需要更改一個狀態(tài)變量讓線程結(jié)束
mState = INIT;
使得 while (mState == RECORDING) 退出循環(huán)邏輯。
接著我們需要釋放錄制器的資源,以便設(shè)備的其他應(yīng)用可以正常使用錄音器,我們可以調(diào)用AudioRecord的release方法。
mAudioRecord.release();
這樣就完整的結(jié)束了AudioRecord的采集業(yè)務(wù)。
播放PCM文件
Audacity這個工具可以導(dǎo)入pcm原始文件,并且提供了波形圖查看和播放功能。
操作流程是:
文件 => 導(dǎo)入 => 原始數(shù)據(jù) => 設(shè)置PCM數(shù)據(jù)格式 => 導(dǎo)入
具體效果圖如下:
p1.png
結(jié)語
下一篇博客會介紹一下Android利用OpenSL ES進行錄音導(dǎo)出PCM數(shù)據(jù)。
本文同步發(fā)布于簡書、CSDN。
End!
總結(jié)
以上是生活随笔為你收集整理的android 录音原始文件_音频采集:Android基于AudioRecord的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 输入数字变成密码_如何在p
- 下一篇: 渭南治疗无精症最好的医院推荐