1

I am new to Android, and i am developing an audiometer on Android Studio. One of the steps is to see if the mic is receiving a sound that i am sending from the earphones, to check if they are working properly.

I am doing both things in the same activity, sending sound, and checking if there is any sound coming in.

I was able to send a tone of 1kHz of frequency for 2 seconds, using AudioTrack class, and the next step is to check if the mic is receiving something near that frequency. Since i wasn't able to even make the mic work, i am lowering my goals to just check if the microphone is receiving anything.

I've checked several links and none helped me, or because i am not familiar with android or because it wasn't what i needed, among others: Detect sound level, How to detect when a user stops talking into the microphone and Detect 'Whistle' sound in android

I've already put the permissions on the Manifest:

<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

And my CalibrationActivity.java is:

import android.content.Intent;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack; 
import android.media.MediaRecorder;    
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.io.IOException;

public class CalibrationActivity extends AppCompatActivity {

private MediaRecorder myRecorder;
private String outputFile = null;

private final int duration = 2; // seconds
private final int sampleRate = 4000;
private final int numSamples = duration * sampleRate;
private final double sample[] = new double[numSamples];
private final double freqOfTone = 1000; // hz

private final byte generatedSnd[] = new byte[2 * numSamples];

Handler handler = new Handler();

int getAmplitude = myRecorder.getMaxAmplitude();

public int result(){
    if (getAmplitude != 0) {
        return 1;
    }else {
        return 0;
    }
}


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

    outputFile = Environment.getExternalStorageDirectory().
        getAbsolutePath() + "/teste.3gpp";

    myRecorder = new MediaRecorder();
    myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    myRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    myRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
    myRecorder.setOutputFile(outputFile);


    Intent intent;
    if(result()==1){
        intent = new Intent(this, FirstTestActivity.class);
    }else{
        intent = new Intent(this, End1Activity.class);
    }

}

void start_recording() {
    try {
        myRecorder.prepare();
        myRecorder.start();
    } catch (IllegalStateException e) {
        // start:it is called before prepare()
        // prepare: it is called after start() or before setOutputFormat()
        e.printStackTrace();
    } catch (IOException e) {
        // prepare() fails
        e.printStackTrace();
    }
}

void stop_recording(){

    try {
        myRecorder.stop();
        myRecorder.release();
        myRecorder  = null;
    } catch (IllegalStateException e) {
        //  it is called before start()
        e.printStackTrace();
    } catch (RuntimeException e) {
        // no valid audio/video data has been received
        e.printStackTrace();
    }
}

@Override
protected void onResume() {
    super.onResume();
    // Use a new tread as this can take a while
    final Thread thread = new Thread(new Runnable() {
        public void run() {
            genTone();
            handler.post(new Runnable() {

                public void run() {
                    playSound();

                }
            });
        }
    });
    thread.start();
            start_recording();
            SystemClock.sleep(3000);
            stop_recording();
}


void genTone() {
    // fill out the array
    for (int i = 0; i < numSamples; ++i) {
        sample[i] = Math.sin(2 * Math.PI * i / (sampleRate / freqOfTone));
    }

    // convert to 16 bit pcm sound array
    // assumes the sample buffer is normalised.
    int idx = 0;
    for (final double dVal : sample) {
        // scale to maximum amplitude
        final short val = (short) ((dVal * 32767));
        // in 16 bit wav PCM, first byte is the low order byte
        generatedSnd[idx++] = (byte) (val & 0x00ff);
        generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);

    }
}

void playSound() {
    final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            sampleRate, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
            AudioTrack.MODE_STATIC);
    audioTrack.write(generatedSnd, 0, generatedSnd.length);
    audioTrack.play();
  }

  }

I wrote that based on examples that i found online, mostly from here, here and here, so there are a few parts of the code that i don't really understand.

The idea here is to send the sound from the earphones, and the user will be informed to put their earphones close to the mic. Then, the code should let the mic recording for 3 seconds and then check if the amplitude of the sound is different from 0, if that is the case, the application then goes to FirstTestActivity, else, to End1Activity. But once i try running the code, the aplication suddenly crashes, and i don't know why. I've been working on that for several weeks and i could not find a solution that probably is pretty simple. Thanks on advance.

Community
  • 1
  • 1

1 Answers1

-1

Based on your lack on knowledge on the subject it may be useful for you to just use a library instead like the one here

Intelli Dev
  • 156
  • 3
  • 15