Nikolar
Nikolar

Reputation: 11

Create custom listeners

I want to create an Android app in which I have to react if the amplitude of the microphone reaches a definite level.

Right now I'm using this Code:

MediaRecorder soundRecorder = new MediaRecorder();
soundRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
soundRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
soundRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
soundRecorder.setOutputFile("/dev/null");
soundRecorder.prepare();
soundRecorder.start();

int amplitude = 0;
while (amplitude < MyApp.this.ampToReact) {
    amplitude = soundRecorder.getMaxAmplitude();
}

But I know that this is very bad programming (and my app keeps crashing).

So I would like to create a listener with an onAmplitudeReachedDefiniteLevel() method to replace this ugly while loop.

Upvotes: 0

Views: 107

Answers (1)

Sanjay Manohar
Sanjay Manohar

Reputation: 7026

Listener will only work if some code exists to detect the event. But you'll need to do this manually as far as I can tell. Rather, if you are repetitively sampling for something crossing a threshold, it may be best to poll using a timer.

What is the sample rate?

What is the lowest latency you need?

for example, at 44100 kHz, if you want to react with 1ms precision, then you only need to check every 44 samples.

Why don't you set a timer / callback, which is called every 1 ms? Then cancel the timer after you've 'reacted'? There are several ways of doing this. Here's one of them, using android Handler (untested - sorry if it needs tweaking!)

final int POLL_INTERVAL = 100; // milliseconds
Handler h = new Handler(); // this is where you feed in messages
OnClickListener startbuttonListener = new OnClickListener() {
  // for example, if you want to start listening after a button press:
  public void onClick(View v) { 
    h.postDelayed(poll, POLL_INTERVAL); // start running the poll loop
  }
};
Runnable poll = new Runnable() {
  public void run() {
    if(soundRecorder.getMaxAmplitude() > MyApp.this.ampToReact){
      h.postDelayed(soundTrigger, 0); // run your sound trigger if criterion met
    }else h.postDelayed(this, POLL_INTERVAL); // post this Runnable (i.e. poll) again
  }
}
Runnable soundTrigger = new Runnable() {
  public void run(){
    // TRIGGERED!
  }
}

Upvotes: 1

Related Questions