2011-01-23 5 views
12

나는과 같이 안드로이드에 마이크의 진폭 레벨을 얻으려고 노력했다 :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를 기록하고, 진폭을 얻고, 녹음을 중지하고 반복해야합니까?

마지막으로 파일에 녹음해야합니까? 이 오디오 파일을 저장할 필요가 없습니다. 녹음하지 않고 현재 라이브 마이크 입력의 마지막 호출 이후에 현재 진폭 또는 최대 진폭을 얻을 수 없습니까?

감사합니다. 감사합니다.

답변

6

그래, 먼저 recorder.start()를 호출해야하고, 마지막에 recorder.stop()도 반드시 호출해야합니다!

는 SoundMeter.java 및 NoiseAlert.java

Toumal에서이 솔루션은 작동
+1

분명히 한 대신, 필요 파일을 기록하지 않으려면 가지 audiorecord을 사용할 수 있습니다 – Tom

+1

당신은 리디렉션 할 수 있습니다 : N이 어디 저장하지 않습니다 아래로 당신이 출력 목적지를 설정하면 파일에 출력을 저장 할 필요가 없습니다 여기 참조 오디오/미디어 출력을/dev/null에 저장하고 실제 레코딩이 그런 식으로 진행되는 것을 방지합니다. 또한 recorder.prepare()를 사용했는지 확인하십시오. 그렇지 않으면 작동하지 않습니다. – kpax

10

에서 살펴 봐야 할 수 있습니다, 예를 들어 응용 프로그램에 대한 http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/를 참조하십시오, 그러나 나는 충분히 재생률 높은를 얻을 수 없습니다 내 필요. 그래서 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; 
    } 

} 
0

요를 제공합니다 에서 onCreate에서 핸들러를 호출하는

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

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

잊지 마세요 : UI에

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

이 부분 쇼 데이터 : u는 또한 당신이 핸들러 사용할 필요가 UI에 실시간으로 데이터를 표시, mediaRecoder 클래스를 사용할 수 있습니다 방법 :

handler.postDelayed(pollTask, 500); 

500 UI는 CA로

업데이트됩니다 밀리 초 지연이

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