Wednesday, January 1, 2014

How to: Record audio from MIC and save raw PCM values into a file (in Android)

Note: I have been working on some audio processing related projects at work and thought I could share some code which others find useful. This one is the first in the series. Please let me know if you find this useful; I can do share more reusable code.
First thing to remember is that it is better to run the audio recording code in a background thread or in an AysnTask. You can set the priority of that thread to THREAD_PRIORITY_URGENT_AUDIO.
Below is the code snippet; code is pretty self-explanatory.

public static final int SAMPLING_RATE = 44100;
public static final int AUDIO_SOURCE = MediaRecorder.AudioSource.MIC;
public static final int CHANNEL_IN_CONFIG = AudioFormat.CHANNEL_IN_MONO;
public static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
public static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLING_RATE, CHANNEL_IN_CONFIG, AUDIO_FORMAT);
public static final String AUDIO_RECORDING_FILE_NAME = "recording.raw";

@Override
public void run() {
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
    Log.v(LOGTAG, "Starting recording…");

    byte audioData[] = new byte[BUFFER_SIZE];
    AudioRecord recorder = new AudioRecord(AUDIO_SOURCE,
                SAMPLING_RATE, CHANNEL_IN_CONFIG,
                AUDIO_FORMAT, BUFFER_SIZE);
    recorder.startRecording();

    String filePath = Environment.getExternalStorageDirectory().getPath()
                + "/" + AUDIO_RECORDING_FILE_NAME;
    BufferedOutputStream os = null;
    try {
        os = new BufferedOutputStream(new FileOutputStream(filePath));
    } catch (FileNotFoundException e) {
        Log.e(LOGTAG, "File not found for recording ", e);
    }

    while (!mStop) {
        int status = recorder.read(audioData, 0, audioData.length);

        if (status == AudioRecord.ERROR_INVALID_OPERATION ||
            status == AudioRecord.ERROR_BAD_VALUE) {
            Log.e(LOGTAG, "Error reading audio data!");
            return;
        }

        try {
            os.write(audioData, 0, audioData.length);
        } catch (IOException e) {
            Log.e(LOGTAG, "Error saving recording ", e);
            return;
        }
    }

    try {
        os.close();

        recorder.stop();
        recorder.release();

        Log.v(LOGTAG, "Recording done…");
        mStop = false;

    } catch (IOException e) {
        Log.e(LOGTAG, "Error when releasing", e);
    }
}

You will need to add the following permissions in AndroidManifest.xml.
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

3 comments:

  1. May I knwo is it possible to store the value/information of PCM into file?

    ReplyDelete
  2. How do i store in .pcm format and not in .raw format ?

    ReplyDelete
  3. I am getting the following errors saying :

    AudioFormat cannot be resolved to a variable MainActivity.java /helloworld/src/com/example/helloworld line 13 Java Problem

    Like this I am getting 4 errors. Please let me know how to solve it.

    ReplyDelete