android 获取录音时长_Android、iOS录音时音量大小计算
經常有人問我如何計算錄音時音量大小。iOS平臺是有api可以直接調用的,但是Android平臺上沒有比較好的辦法,因此我們就不得不自己計算了。
之所以有計算音量這個需求,是因為很多應用希望根據音量的大小實現一些動畫效果。因此,從這個需求出發,只要能根據說話時聲音的大小,獲取到的音量值有變化即可,而不必過分糾纏于到底范圍多少才是準確的。因為計算的方法有很多種,不同的方法計算出來的值肯定是不同的,但是只要能反映出大小變化,我們的目的就達到了。
下面我以Android錄音為例,介紹一下其中的一種計算方法。大家可以根據自己的需要重新計算,或者是對我這個計算出來的值做一些數學變換,從而滿足自己的需要。
需要提前說明的是,網上也有類似的一些計算方法,但是千萬不能照搬過來,因為這個和錄音的編碼和錄音數據的類型是有關系的。
錄音的編碼主要有兩種:8位pcm和16位pcm。8位pcm用一個字節表示語音的一個點,16位pcm用兩個字節,也就是一個short來表示語音的一個點。需要特別注意的是,如果你用的16位pcm編碼,而取錄音數據用的是byte的話,需要自己將兩個bye轉換成一個short。將兩個byte轉換成一個short,有小端和大端兩種,一般默認情況都是小端,但是有的開源庫,比如lamemp3需要的就是大端,這個要根據不同的情況進行不同的處理。
下面以Android為例,介紹一下用平均值計算音量的方法。
privatedouble calculateVolume(short[] buffer){
double sumVolume = 0.0;
double avgVolume = 0.0;
double volume = 0.0;
for(short b : buffer){
sumVolume += Math.abs(b);
}
avgVolume = sumVolume / buffer.length;
volume = Math.log10(1 + avgVolume) * 10;
return volume;
}
這個方法傳遞的是short類型的數據,所以錄音的編碼肯定是16位pcm,這樣可以直接計算而不需要轉換了。相信大家都聽過聲波這個東西,大家用音頻編輯軟件Adobe audition 打開一段聲音:
從這里我們可以看到,聲音是高低起伏變化的,有波峰波谷,說白了就是有正有負。因此在計算的時候,我們需要先求絕對值,要不然就上下抵消。求完絕對值然后進行累加,再除以整個數據的長度,就得到了這段語音數據的平均值了。
但是這樣直接計算出來的結果比較大,不利于我們使用,因此對它進行了取對數再乘以10:
volume = Math.log10(1 + avgVolume) * 10;
這些可以根據自己的需要進行運算,我這邊只是一個簡單的例子。
還有一個特別需要注意的問題是:如果你錄音的編碼是16為pcm,而錄音數據數據是byte,需要將兩個byte轉為一個short進行處理,建議用小端的方式。
privatedoublecalculateVolume(byte[] buffer){
double sumVolume = 0.0;
double avgVolume = 0.0;
double volume = 0.0;
for(int i = 0; i < buffer.length; i+=2){
int v1 = buffer[i] & 0xFF;
int v2 = buffer[i + 1] & 0xFF;
int temp = v1 + (v2 << 8);// 小端
if (temp >= 0x8000) {
temp = 0xffff - temp;
}
sumVolume += Math.abs(temp);
}
avgVolume = sumVolume / buffer.length / 2;
volume = Math.log10(1 + avgVolume) * 10;
return volume;
}
關于用小端的方式,將兩個byte轉為一個short的那些移位運算,應該不難,這里不做過多的解釋了。
以上就是用平均值的方法計算音量大小的方法,但是在iOS中,你自己不需要計算了,直接調用系統的api即可。
iOS獲取錄音是系統音量的步驟:
1、在開始錄音之前,要設置獲取系統音量的屬性
//設置獲取音量大小的屬性
UInt32 enabledLevelMeter = true;
AudioQueueSetProperty(_audioQueue, kAudioQueueProperty_EnableLevelMetering, &enabledLevelMeter, sizeof(UInt32));
2、調用系統api獲取音量,此方法可以在 緩沖器的回調函數中調用,也可以自己用一個定時器來調用
AudioQueueLevelMeterState levelMeter;
UInt32 levelMeterSize = sizeof(AudioQueueLevelMeterState);
AudioQueueGetProperty(_audioQueue, kAudioQueueProperty_CurrentLevelMeterDB, &levelMeter, &levelMeterSize);
double volume = levelMeter.mAveragePower
當然,你如果不想用系統的音量值,也可以像上面那樣自己計算,這取決于你的需要。
最后我把android的獲取錄音音量大小的demo上傳到附件中了,大家可以參考。
總結
以上是生活随笔為你收集整理的android 获取录音时长_Android、iOS录音时音量大小计算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu18.04安装Oracle1
- 下一篇: 连续状态空间模型离散化