Android:没有录音的示例麦克风可以获得实时幅度/电平?

时间:2011-01-23 22:42:28

标签: java android media record microphone

我试图在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,获得振幅,停止录制并重复?

最后,我是否必须录制到文件中?我不需要保存这个音频文件,我不能只是获取当前幅度或自上次调用当前直播麦克风输入以来没有录音的最高幅度?

感谢任何帮助,谢谢。

4 个答案:

答案 0 :(得分:14)

Toumal的解决方案有效,但我无法根据自己的需求获得足够高的刷新率。所以我最终使用了Toumal链接的SoundMeter.java类,但修改了它以使用此answer

中的代码

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

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;
    }

}

答案 1 :(得分:6)

是的,你必须先调用recorder.start(),你也不要忘记最后调用recorder.stop()!

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

答案 2 :(得分:2)

使用AudioRecord类而不是MediaRecorder

查看此网站:http://www.doepiccoding.com/blog/?p=195,它提供了一个很好的解释和工作代码:)

答案 3 :(得分:0)

您还可以使用mediaRecoder类,在UI上显示您需要使用Handler的实时数据:

    private Runnable pollTask = new Runnable() {
    @Override
    public void run() {
        double amplitude = soundMeter.getAmplitude();
        amplitudeTextView.setText("Amplitude: " + amplitude);

        handler.postDelayed(pollTask, 500);
    }
};

此部分显示UI上的数据:

handler.postDelayed(pollTask, 500);

不要忘记在onCreate方法中调用处理程序:

mediaRecorder.setOutputFile("/dev/null");

500是UI将更新的延迟(毫秒)

正如您在此处所见,如果您将输出目的地设置为如下所示,则无需将输出保存到文件:

{{1}}