0

I am trying to have my application start to record sound from the microphone when a button is pressed. I want it to print out the amplitude of the sound recorded while the microphone is on to my TextView object.

Here is my code for the RecordSound class:

import android.media.MediaRecorder;

public class RecordSound {
private MediaRecorder mRecorder = null;

public void start() {
    if (mRecorder == null) {
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mRecorder.setOutputFile("/dev/null");

        try {
            mRecorder.prepare();
        } catch (Exception e) {
            e.printStackTrace();
        }

        mRecorder.start();
    }
}

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

public double getAmplitude() {
    if (mRecorder != null) {
        return mRecorder.getMaxAmplitude();
    }
    else {
        return 0;
    }
}

public boolean isOn() {
    if (mRecorder == null) {
        return false;
    }
    else {
        return true;
    }
}
}

Here is my code for the MainActivity class:

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
private RecordSound mRecorder = null;
private TextView tv = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button recordButton = (Button) findViewById(R.id.bRecord);
    tv = (TextView)findViewById(R.id.data);
    mRecorder = new RecordSound();

    recordButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mRecorder.isOn()) {
                mRecorder.stop();
            }
            else {
                mRecorder.start();
            }

            if (mRecorder.isOn()) {
//                  long t= System.currentTimeMillis();
//                  long end = t+15000;
//                  while(System.currentTimeMillis() < end) {
//                      tv.setText(String.valueOf(mRecorder.getAmplitude()));
//                  }
//                  
                tv.setText(String.valueOf(mRecorder.getAmplitude()));
            }
        }
    });

    while (mRecorder != null && mRecorder.isOn()) {
        tv.setText(String.valueOf(mRecorder.getAmplitude()));
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}

The code that is commented out is my attempt at making the microphone record and print the amplitude for the first fifteen seconds that the microphone is on.

Currently I am able to press the button to start recording. It will then print out the amplitude value to the TextView, but it is always 0.0. I've tried a while statement several different places, both in and out of the onClick() method. I can't seem to get the TextView to update dynamically while the microphone is recording sound.

Jack
  • 131
  • 1
  • 3
  • 13
  • You have to explain your issue to provide suggestion/fix – Libin Apr 15 '14 at 00:16
  • @Jack Rather than linking to a third party website like codeshare, you should embed the most relevant code into your posts. Also, there isn't any code provided in the second link. – adneal Apr 15 '14 at 00:30

1 Answers1

0

I didn't really try to run your code and I don't know much about MediaRecoder in Android. But I guess the problem of your code is that your while loop is inside onCreate() method, and so the loop only runs when the onCreate() is called (in case of you haven't understood when Android system calls onCreate() method of your app, I suggest reading the Activity Lifecycle document). Clearly, your media recorder hasn't been started when the while loop runs, so this statment:

tv.setText(String.valueOf(mRecorder.getAmplitude()));

is not runned at all.

Then when you press the button for the first time, the media recoder is started and right after that, you get the amplitude, set the TextView value also for the first and only one time. The document of MediaRecorder.getMaxAmplitude() says that it returns

the maximum absolute amplitude measured since the last call, or 0 when called for the first time

That's why you always get 0.0 display on the TextView.

In order to update the TextView dynamically while the microphone is on, you should maintain a background thread that check the media recoder and get amplitude periodically. For this purpose, you can consider using Timer and TimerTask. But since Android system doesn't allow you to update the UI from any thread other than the main thread, you may have to use Handler. I found this answer is useful for you.

Community
  • 1
  • 1
theman
  • 598
  • 1
  • 7
  • 19