Android: Need to Record Mic Input

Android: Need to record mic input

To record and play back audio in (almost) real time you can start a separate thread and use an AudioRecord and an AudioTrack.

Just be careful with feedback. If the speakers are turned up loud enough on your device, the feedback can get pretty nasty pretty fast.

/*
* Thread to manage live recording/playback of voice input from the device's microphone.
*/
private class Audio extends Thread
{
private boolean stopped = false;

/**
* Give the thread high priority so that it's not canceled unexpectedly, and start it
*/
private Audio()
{
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
start();
}

@Override
public void run()
{
Log.i("Audio", "Running Audio Thread");
AudioRecord recorder = null;
AudioTrack track = null;
short[][] buffers = new short[256][160];
int ix = 0;

/*
* Initialize buffer to hold continuously recorded audio data, start recording, and start
* playback.
*/
try
{
int N = AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT);
recorder = new AudioRecord(AudioSource.MIC, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10);
track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10, AudioTrack.MODE_STREAM);
recorder.startRecording();
track.play();
/*
* Loops until something outside of this thread stops it.
* Reads the data from the recorder and writes it to the audio track for playback.
*/
while(!stopped)
{
Log.i("Map", "Writing new data to buffer");
short[] buffer = buffers[ix++ % buffers.length];
N = recorder.read(buffer,0,buffer.length);
track.write(buffer, 0, buffer.length);
}
}
catch(Throwable x)
{
Log.w("Audio", "Error reading voice audio", x);
}
/*
* Frees the thread's resources after the loop completes so that it can be run again
*/
finally
{
recorder.stop();
recorder.release();
track.stop();
track.release();
}
}

/**
* Called from outside of the thread in order to stop the recording/playback loop
*/
private void close()
{
stopped = true;
}

}

EDIT

The audio is not really recording to a file. The AudioRecord object encodes the audio as 16 bit PCM data and places it in a buffer. Then the AudioTrack object reads the data from that buffer and plays it through the speakers. There is no file on the SD card that you will be able to access later.

You can't read and write a file from the SD card at the same time to get playback/preview in real time, so you have to use buffers.

Capturing Raw Microphone Input on Android

OpenSL ES

To get the closest possible to unprocessed audio, I think the OpenSL ES API specification in the Android NDK is the best option. Google provide an example project of real-time recording and playback (with a delay to avoid feedback).

This is how the underlying implementation of AudioRecorder was built and it allows for much better optimization of your audio processing. Although it uses C++, it may be worthwhile knowing especially if you are planning on implementing any other audio processing apps in the future.

MediaRecorder

As mentioned previously there is an option to set the MediaRecorder.AudioSource to UNPROCESSED. However as mentioned in the documentation, this is not supported on all devices.

True Raw Input

To capture the real input the hardware actually receives, via an Android app, is a very unlikely achievable task (at least cross-platform). And even if you get it to work on one device, I would be amazed if it worked on several devices. At this level you would want to look at Android OS development, but then you start to limit yourself to the hardware you want to use.

As mentioned in your question's comments :

Your "mistake" is that each OEM can implement this differently. Even within the same company there might be different teams working on different models that don't do things exactly the same. IIRC, when I worked at Sony we didn't have any microphone setting that didn't use some preprocessing effect(s).

Which I'm sure is true in most OEMs.

Record audio and play it simultaneously

It is possible, to play the audio directly with a stream method. The data will be saved in background. To get basic knowledge I suggest to take a look at these examples, explained by the android-studio documentation. This is a taff project as a beginner. Start step by step. First try to record audio, then stream with mediaPlayer and saving it. And the final step is all together. Cheers.



Related Topics



Leave a reply



Submit