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

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

任何帮助表示赞赏,谢谢。

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

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

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

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

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

使用AudioRecord类而不是MediaRecorder

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

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

 public class SoundMeter { private MediaRecorder mediaRecorder; public void start(){ if(started){ return; } if (mediaRecorder == null){ mediaRecorder = new MediaRecorder(); mediaRecorder.setAudioSource( MediaRecorder.AudioSource.MIC); mediaRecorder.setOutputFormat( MediaRecorder.OutputFormat.THREE_GPP); mediaRecorder.setAudioEncoder( MediaRecorder.AudioEncoder.AMR_NB); mediaRecorder.setOutputFile("/dev/null"); try{ mediaRecorder.prepare(); }catch (IllegalStateException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } mediaRecorder.start(); started = true; } } } public double getAmplitude(){ return mediaRecorder.getMaxAmplitude(); } } 

此部分显示UI上的数据:

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

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

 handler.postDelayed(pollTask, 500); 

500是UI将更新的延迟(以毫秒为单位)

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

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