如何在Android上采样麦克风而不录音以获得实时振幅/电平?

我试图在Android上获得麦克风的振幅级别,如下所示:

MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);

Timer timer = new Timer();
timer.scheduleAtFixedRate(new RecorderTask(recorder), 0, 1000);

private class RecorderTask extends TimerTask {
    private MediaRecorder recorder;

    public RecorderTask(MediaRecorder recorder) {
        this.recorder = recorder;
    }

    public void run() {
        Log.v("MicInfoService", "amplitude: " + recorder.getMaxAmplitude());
    }
}

不幸的是,这始终只返回 0。

看来,要做到这一点,我必须真正开始录制。这是对的吗?

如果是这样,我是否需要录制500ms,获取振幅,停止录制并重复?

最后,我必须录制到文件吗?我不需要保存此音频文件,难道我不能只获得当前实时麦克风输入的当前振幅或最高振幅而不录音吗?

任何帮助是值得赞赏的,谢谢。


答案 1

Toumal的解决方案有效,但是我无法获得足够高的刷新率来满足我的需求。因此,我最终使用了SoundMeter.java类,Toumal链接了它,但对其进行了修改以使用此答案中的代码

以下是我使用的代码,它提供了更好的刷新率:

import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;

public class SoundMeter {

    private AudioRecord ar = null;
    private int minSize;

    public void start() {
        minSize= AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
        ar = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000,AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,minSize);
        ar.startRecording();
    }

    public void stop() {
        if (ar != null) {
            ar.stop();
        }
    }

    public double getAmplitude() {
        short[] buffer = new short[minSize];
        ar.read(buffer, 0, minSize);
        int max = 0;
        for (short s : buffer)
        {
            if (Math.abs(s) > max)
            {
                max = Math.abs(s);
            }
        }
        return max;
    }

}

答案 2

是的,你必须先调用recorer.start(),你一定不要忘记在最后调用recorer.stop()!

有关示例应用程序,请参阅 http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/,您可能希望查看SoundMeter.java和NoiseAlert.java


推荐