天天看點

android 實時擷取 麥克風 音量大小

Android 上有一些很有趣的應用,例如《吹裙子》、《吹氣球》之類的。利用的是實時擷取麥克風輸入音量,然後進行相應的處理。錄音過程中怎樣獲得聲音的大小呢?網上也不少人問如何處理這個事情,也有一些解答,不過都沒有實際的代碼。簡單摸索了一下,寫了個小 Demo 試了試,果然可以。給大家共享一下。

不解釋代碼了,大家看注釋。

package com.xxiyy.spl;  

import android.media.AudioFormat;  

import android.media.AudioRecord;  

import android.media.MediaRecorder;  

import android.util.Log;  

public class RecordThread extends Thread {  

    private AudioRecord ar;  

    private int bs;  

    private static int SAMPLE_RATE_IN_HZ = 8000;  

    private boolean isRun = false;  

    public RecordThread() {  

        super();  

        bs = AudioRecord.getMinBufferSize(SAMPLE_RATE_IN_HZ,  

                AudioFormat.CHANNEL_CONFIGURATION_MONO,  

                AudioFormat.ENCODING_PCM_16BIT);  

        ar = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_IN_HZ,  

                AudioFormat.ENCODING_PCM_16BIT, bs);  

    }  

    public void run() {  

        super.run();  

        ar.startRecording();  

                // 用于讀取的 buffer  

        byte[] buffer = new byte[bs];  

        isRun = true;  

        while (isRun) {  

            int r = ar.read(buffer, 0, bs);  

            int v = 0;  

                        // 将 buffer 内容取出,進行平方和運算  

            for (int i = 0; i < buffer.length; i++) {  

                // 這裡沒有做運算的優化,為了更加清晰的展示代碼  

                v += buffer[i] * buffer[i];  

            }  

            // 平方和除以資料總長度,得到音量大小。可以擷取白噪聲值,然後對實際采樣進行标準化。  

            // 如果想利用這個數值進行操作,建議用 sendMessage 将其抛出,在 Handler 裡進行處理。  

            Log.d("spl", String.valueOf(v / (float) r));  

        }  

        ar.stop();  

    public void pause() {  

                // 在調用本線程的 Activity 的 onPause 裡調用,以便 Activity 暫停時釋放麥克風  

        isRun = false;  

    public void start() {  

                // 在調用本線程的 Activity 的 onResume 裡調用,以便 Activity 恢複後繼續擷取麥克風輸入音量  

        if (!isRun) {  

            super.start();  

}  

轉評:

原文中提到“平方和除以資料總長度,得到音量大小”,有些文章中提到這個音量值在不同的手機中表現得不一樣,同樣的發聲,但出來的值相差很大。進而有通過一些計算,調整“音量”的算法,其中有兩個,分别是:

1、計算了噪音,對音量進行調整:

value 的 值 控制 為 0 到 100 之間 0為最小 》= 100為最大!!

 int value = (int) (Math.abs((int)(v /(float)r)/10000) >> 1);

2、計算分貝值:

那個值應該是聲音的振幅,并不是音量的大小,

聲音的大小應該是用分貝為機關的吧,

double dB = 10*Math.log10(v/(double)r);

即:經傅立葉變化後得到的複數數組是個二維數組,實部和虛部的平方和取對數後乘以10就大緻等于我們通常表示音量的分貝了。