我想检查android中声音的响度

时间:2011-12-06 14:25:02

标签: android audio

我正在开发一个应用程序,我必须检测语音的响度。意味着移动设备上的一些呼喊,它将在屏幕上显示响度级别。

可以使用哪种API?

1 个答案:

答案 0 :(得分:8)

查看http://developer.android.com/reference/android/media/AudioRecord.html

当您读取缓冲区时,字节值将代表幅度。字节值越高声音就越大。

这是我在一段时间内写过的应用中使用的缩小版本:

将其添加到mainifest.xml中 <uses-permission android:name="android.permission.RECORD_AUDIO" />

<强> soundlevel.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ToggleButton
        android:id="@+id/togglebutton_record"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ToggleButton" />


    <ProgressBar
        android:id="@+id/progressbar_level"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

SoundLevel.java

import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.widget.CompoundButton;
import android.widget.ProgressBar;
import android.widget.ToggleButton;

public class SoundLevel extends Activity {

    private static final int sampleRate = 11025;
    private static final int bufferSizeFactor = 10; 

    private AudioRecord audio;
    private int bufferSize;

    private ProgressBar level;

    private Handler handler = new Handler();

    private int lastLevel = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.soundlevel);

        level = (ProgressBar) findViewById(R.id.progressbar_level);

        level.setMax(32676);

        ToggleButton record = (ToggleButton) findViewById(R.id.togglebutton_record);

        record.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // TODO Auto-generated method stub

                if (isChecked) {
                    bufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT) * bufferSizeFactor; 

                    audio = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);

                    audio.startRecording();

                    Thread thread = new Thread(new Runnable() {
                        public void run() {
                            readAudioBuffer();
                        }     
                      });

                    thread.setPriority(Thread.currentThread().getThreadGroup().getMaxPriority());

                    thread.start();

                    handler.removeCallbacks(update);
                    handler.postDelayed(update, 25);

                } else if (audio != null) {
                    audio.stop();
                    audio.release();
                    audio = null;
                    handler.removeCallbacks(update);
                }

            }
        });
    }

    private void readAudioBuffer() {

        try {
            short[] buffer = new short[bufferSize];

            int bufferReadResult;

            do {

                bufferReadResult = audio.read(buffer, 0, bufferSize);

                for (int i = 0; i < bufferReadResult; i++){

                    if (buffer[i] > lastLevel) {
                        lastLevel = buffer[i];  
                    }

                }

            } while (bufferReadResult > 0 && audio.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING);

            if (audio != null) {
                audio.release();
                audio = null;
                handler.removeCallbacks(update);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private Runnable update = new Runnable() {

        public void run() {

            SoundLevel.this.level.setProgress(lastLevel);

            lastLevel *= .5;

            handler.postAtTime(this, SystemClock.uptimeMillis() + 500);

        }

    };
}