天天看點

(安卓自學筆記二)音量檢測的兩種方式

首先添加錄音權限

<uses-permission android:name="android.permission.RECORD_AUDIO"/>
           

方式一:MediaRecorder 

private MediaRecorder mediaRecorder;
           
private boolean isRecording;
           

設定存儲路徑

private final String FILE = Environment.getExternalStorageDirectory() + File.separator + "volomeDemo.aac";
           

初始化mediaRecorder

initMediaRecorder();

public void initMediaRecorder()
    {
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setOutputFile(FILE);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        Log.w("madiarecorder","初始化成功");
        try{
            mediaRecorder.prepare();
            mediaRecorder.start();
            isRecording=true;
            Log.w("madiarecorder","已啟動");
        }catch(Exception e)
        {
            Log.w("madiarecorder","異常");
        }
    }
           

利用

mediaRecorder.getMaxAmplitude();
           

得到目前某一時刻檢測到的音量,這個數值通常可以上萬

建立一個可視的繪圖線程,一會兒實時将音量繪制出來

class Draw_thread extends  Thread
    {
        @Override
        public void run(){
            while(true)
            {
                if (mediaRecorder == null) {
                    initMediaRecorder();
                }
                try{
                    myDraw();
                    Thread.sleep(30);
                }
                catch (Exception e) {
                    Log.w("線程", "異常");
                }
            }
        }
    }                initMediaRecorder();
                }
                try{
                    myDraw();
                    Thread.sleep(30);
                }
                catch (Exception e) {
                    Log.w("線程", "異常");
                }
            }
        }
    }      

利用

isRecording
           

記錄是否在監聽中

重寫銷毀方法

protected void onDestroy() {
        super.onDestroy();
        if (mediaRecorder!=null&&isRecording) {
            isRecording = false;
            mediaRecorder.stop();
            mediaRecorder.reset();
            mediaRecorder.release();
            mediaRecorder = null;
        }
    }
           

方法二:AudioRecord

聲明變量

    private AudioRecord audioRecord;
    private int bufferSize;
    private byte[] buffer;
           

初始化函數

public void initAudioRecord()
    {
        bufferSize = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_IN_MONO , AudioFormat.ENCODING_PCM_16BIT);
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 16000,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT, bufferSize);
        audioRecord.startRecording();
        // 用于讀取的 buffer
        buffer= new byte[bufferSize];
    }
           

在繪圖線程中擷取某一時刻音量,和mediaRecorder.getMaxAmplitude();作用差不多

try {
            int r = audioRecord.read(buffer, 0, bufferSize);
            int v = 0;
            // 将 buffer 内容取出,進行平方和運算
            for (int i = 0; i < buffer.length; i++) {
                // 這裡沒有做運算的優化,為了更加清晰的展示代碼
                v += buffer[i] * buffer[i];
            }
            // 平方和除以資料總長度,得到音量大小。可以擷取白噪聲值,然後對實際采樣進行标準化。
            // 如果想利用這個數值進行操作,建議用 sendMessage 将其抛出,在 Handler 裡進行處理。
            double dB = 10*Math.log10(v/(double)r);
           

得到的db就是目前音量大小

但是這個數值基本隻能用來判斷有沒有聲音,

而分别不出來音量大小,是以建議使用第一種方式

繪圖函數

            canvas.drawColor(Color.BLACK);//背景
            canvas.drawLine(200,250,200,250-6*(int)dB,paint);//子線程更新UI,如果是監聽器等調用的函數,是屬于主線程裡的!!!
            canvas.drawText(7*(int)dB+"",150,30,paint);

            int maxa=mediaRecorder.getMaxAmplitude();
            if(maxa<1600)
            {
                canvas.drawLine(100,250,100,250-maxa/8,paint);
            }
            else
            {
                canvas.drawLine(100,250,100,50,paint);
                paint.setColor(Color.RED);
                canvas.drawLine(150,250,150,250-maxa/100,paint);
                paint.setColor(Color.GREEN);
            }
            canvas.drawText(maxa+"",30,30,paint);
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    iv_audio.setImageBitmap(bitmap);
                }
            });                dB+"",150,30,paint);

            int maxa=mediaRecorder.getMaxAmplitude();
            if(maxa<1600)
            {
                canvas.drawLine(100,250,100,250-maxa/8,paint);
            }
            else
            {
                canvas.drawLine(100,250,100,50,paint);
                paint.setColor(Color.RED);
                canvas.drawLine(150,250,150,250-maxa/100,paint);
                paint.setColor(Color.GREEN);
            }
            canvas.drawText(maxa+"",30,30,paint);
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    iv_audio.setImageBitmap(bitmap);
                }
            });      

用了draw和paint展示了一下兩種方式的效果

(安卓自學筆記二)音量檢測的兩種方式

我将第一種方法獲得的音量用綠色(小數值時)+紅色(大數值時)顯示出來

    這個綠色随着聲音的增大,變化明顯

而第二種方式,基本隻要有點聲音,綠色就滿了

    沒聲音時數值,還可能為負值

是以第一種好用