Android audio recording, part 2

Download source code of this article.

My previous article was about recording audio using MediaRecorder class. This class is very easy to use and can be used for quick and simple audio recording, also this class saves the audio data either MPEG 4 or 3GPP compressed format. But if you need raw data that can be used to process audio data, then you cannot use MediaRecorder class but you have to use AudioRecord class. AudioRecord class provides you the raw data in uncompressed format. You can use this data to write to a file, display waveform, etc..

To record audio using AudioRecord class:

  1. Create an instance of AudioRecord
  2. Start recording using startRecording() method
  3. Read uncompressed data using AudioRecord.read() method
  4. Stop recording using stop() method.

Creating AudioRecord instance

The constructor of AudioRecord class is:

AudioRecord(
	int audioSource, int sampleRateInHz,
	int channelConfig, int audioFormat, int bufferSizeInBytes)

The first parameter is the audio source, this can be one of the AudioSource values. Second parameter is the sample rate in Hz. This can be 44100, 22050, 11025, 8000, etc.. Third parameter is channel value, this can be one of the AudioFormat values (normally CHANNEL_IN_MONO or CHANNEL_IN_STEREO). Third is the audio encoder format, this can be one of the following values:

  1. ENCODING_PCM_16BIT – 16 bit per sample
  2. ENCODING_PCM_8BIT – 8 bit per sample
  3. ENCODING_DEFAUL – default encoding

Forth parameter is the buffer size. This should be calculated using AudioRecord.getMinBufferSize() static method. The syntax of getMinBufferSize() method is:

public static int getMinBufferSize (
	int sampleRateInHz, int channelConfig, int audioFormat)

The parameters are same as that of the constructor. The method calculate the minimum buffer size needed to store one chunk of audio. Anything less than this number will result in failure while creating the AudioRecord object.

Start Recording

Once we create an instance of the AudioRecord object, startRecording() method is used to start recording audio.

Reading uncompressed data

Once the recording is started, it is the responsibility of the application to read the audio data and store it for further processing. We can read the audio data using one of the read method of AudioRecord class. The audio data will be raw PCM_16BIT or PCM_8BIT format depending on how you initialized the object. The application can use this data to do further processing of any sort. In our sample application we just save this data to a temporary file, further when the recording is stopped we read this data and write to WAV file. The application has to continuously read the data otherwise the previous chunk of data will be overwritten by the new one.

Stop recording

Recording can be stopped using stop() method. Remember to call release() method to release the AudioRecord object.

The following code snippet shows the typical usage:

AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
	44100, AudioFormat.CHANNEL_IN_STEREO,
	AudioFormat.ENCODING_PCM_16BIT, bufferSize);

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

Sample application

The sample application of this article records audio and save it to a WAV file. The WAV file will be placed in “/SDCard/AudioRecorder” folder with current millisecond as the file name.

Reference

Writing WAV file – RingDroid sample application, RehearsalAssist application

54 thoughts on “Android audio recording, part 2

  1. sudheer

    Hi,

    Thanks for sharing nice tutorial.

    I am also working on the similar application. Here I am trying to send the audio to an IP camera over http post method. I tried with media recorder but i am unable to play it in IP camera.

    IP camera have some supported formats like G711 and G726 audio compression formats. Now the question is how can i do it with your sample application. Kindly help me to do so.

    Thanks & Regards

     /  Reply

    1. Krishnaraj Varma Post author

      Sudheer, this is a complicated issue and I don’t have any specific solution for that. But this most probably happens because of the format difference. MediaRecorder uses AMR encoder and can save files in MPEG4, Raw AMR and 3GPP formats. I am not sure how you send the data to the remote player, when the recording is finished you are sending the file content?

      I suggest you to try AudioRecord and send the uncompressed data to the remote player.

      Update here your progress. Thanks.

      -Krishnaraj Varma

       /  Reply

  2. Ajit kumar

    Hi, I was able to record. but.. while playing, it sounds like it has been fast forwarded. can you suggest me of what to do on this. I am doing it on LG optimus. app is specifically for this device only. and one more thing, will the recording quality be fine even when device has reached time out on display? i tried with Media player but when it goes to time out, sound recording is not proceeding. please help me on this

     /  Reply

    1. Krishnaraj Varma Post author

      Ajit, I think the fast forward issue may be related to writing to WAV file, please check WAV header and see whether you are specifying correct values.

      Could you please explain the timeout issue you are getting, I didn’t get the correctly.

       /  Reply

      1. I also experienced high-pitched voices when testing this code. I made the recordings with settings configured for 8000Hz, Mono, 16Bit PCM. I discovered that the sample rate of the recordings was exactly 2x what I had configured it to be. For example, by adjusting the sample rate to 4000Hz, it sounded normal and had the correct length.

        I believe the problem exists due to the hard-coded values in copyWaveFile():

        int channels = 2;
        long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8;

        There is only a single channel being sampled with mono audio, and byteRate ends up being twice what it should be. This can be corrected by setting int channels = 1 for mono sources.

         /  Reply

        1. T-Money

          For future reference, you also need to change the “block align” bit that’s being written out at header[32]. It should be (channels * RECORDER_BPP / 8).

           /  Reply

  3. Radzell

    I been using this solution for a project. I am having two small problems one is that my voice seem distorted and i can figure out how to play the audio on my android device after i record it.

     /  Reply

    1. Krishnaraj Varma Post author

      Randzell, there could be so many reasons for the distorted voice, can you check weather the output file is in correct format (I assume it is a WAV file)?

      The file can be played by different desktop and mobile audio players including the default one in Nexus One.

       /  Reply

  4. Gi

    Does anyone know how to turn off dynamic range compression (http://en.wikipedia.org/wiki/Dynamic_range_compression)? I’m interested in processing raw signal, I mean – when there is a very quiet signal, I would like to record very low raw values. But I get a quiet signal amplified and the resulting raw value is a high value instead. Is it possible to turn this “feature” off? Or is it implemented in the hardware part without an “turn off” option?

     /  Reply

  5. sudheer

    Hi,
    Thanks for your reply. As the Audio Record class does support PCM 8 bit and 16 bit, Can we do our own encoding in other formats, especially I would like to format in ADPCM at 8Khz, Mono and 4 Bit. Is this possible in Android. Kindly help me if you have some ideas to do so.

    Kind Regards

     /  Reply

  6. david sun

    I am a beginner in android world, I just setup Eclipse, and I can run “hello android” with an emulator on my PC, this is my first Java app, this is fun. I’d like to try audiorecord.2 on my Eclipse environment, buy I have no idea how to setup a project linked to source code downloaded from SVN. could you please give me some hint( instruction) on how to build a Eclipse project with AudioRecoder2. any suggestions are appreciated. what I did is build a brand new project called audiorecoder, and copy sorce code to src directory, but when I run, it tells me “the public type RecorderActivity must be defined in its own file”, also it says” id can not be resolved or is not a field.”. “Applog can not be resolved”.

     /  Reply

  7. david sun

    Hi, after I play with Eclipse for a while, I can run audiorecorder2, the emulator pop up a window, “Sorry! The applicaion Audio Recorder(process com.varma.samples.audiorecorder)has stopped unexpectedly. please try again. “source not found”, after I open debug information, it shows ” the source attachment does not contain the source for the file AudioRecord.class. how to add AudioRecord.class to develop environment.

     /  Reply

  8. david sun

    my last question, and I think it is much easier to answer, could this Audiorecorder.1 or 2 run on Emulator? where will the data file be saved? I am using an IBM thinkpad T43. Windows XP.
    Eclipse Jave EE IDE for web developers, Version:Helios service release 2. build Id:20110218-0911

     /  Reply

  9. TC

    Thanks for the info. I have a follow up question… Now that we have a way to get raw PCM data. How would I be able to convert the PCM data to MPEG4 or 3GPP? Is there any API that allows me to feed it the PCM data file and it would spit out say 3GPP file?

    Thanks!

     /  Reply

  10. Tom N

    Thanks for posting this code, very useful, though I had to go into the debugger to understand why it was crashing on my phone (the original Motorola Droid). It turns out that AudioRecord.getMinBufferSize() was returning AudioRecord.ERROR_BAD_VALUE (in this case because AudioFormat.CHANNEL_IN_STEREO is apparently not supported). You may want to add a check for this.
    Thanks – Tom

     /  Reply

  11. I’ve used MediaRecorder class previously and found out that I can’t use pause method. Now I tried with your example to do AudioRecorder class too but couldn’t figure out how.

    could you please tell me how?? or some external resources??

     /  Reply

    1. Rathish

      Hi Mayu,
      Did you found the solution for pausing an audio recording. IF u hav got the solution means plz reply me back.
      rathish100@gmail.com tis is my id. So plz reply back, if u got the solution.

       /  Reply

  12. Leonardo

    Hello,
    This post was very usefull, it really works good.. Congrats.
    I’ve a question, do you know how to pause the recording? May be a temporal file to contain the previous recorded sound and then must do a binding of files?

     /  Reply

    1. Rathish

      Hi Mayu,
      Did you found the solution for pausing an audio recording. If u hav the solution means plz reply me back.
      rathish100@gmail.com tis is my id. So plz reply back, if u got the solution.

       /  Reply

  13. PenguinMan

    It looks good.
    But can anyone point me to an example that will just work.
    I want to read raw samples from the mic.
    But this example has errors in Eclipse such as: “R.id can not be resolved as a field”
    And after a few hours of playing with similar examples, the error is “AudioFlinger could not create record track : -1″
    This is a fairly simple thing to want to do;.. read some audio samples…I have done it 20 years ago on a PC..I have programmed for 20 years !! including Java. Android audio recording, must be the most complicated and convoluted mission ever devised. Perhaps I am the first person ever to want to record some bytes from a microphone on an android device ?, is that such a spectacular thing to ask for ?
    What is wrong with you all ?

     /  Reply

  14. PenguinMan

    I found the cause of my problem:

    This is the SECRET to getting audio recording to work if you are having problems starting audiorecord..
    The Manifest file needs the RECORD_AUDIO permission set

    That’s all !

    (It took me two days to work that out)

    (my last comment wasn’t helpful, if it was posted, please remove)

     /  Reply

  15. Nishant Rajput

    Hello Krishnaraj,

    Using Your Code m Converting Raw PCM Data to AAC using faac library through JNI. Its not difficult at all but m getting such humming sound in my converted AAC audio.

    Can you Work around it.? If u want i can send you my code.

    Thanks,
    Nishant Rajput

     /  Reply

  16. Mr. Varma,

    Thanks for your example of how to make the AudioRecord class work. I do have a problem, however when using your class. For some reason, the outputted WAV file has me sounding sped up, and also the pitch is that of a ‘chipmunk’. I have also done some conversion of the raw PCM file to MP3, without using the WAV headers, and it is the same result.

    I have read the AudioRecord API docs, and I can’t see anything that would resolve this problem.

    I’d be eternally grateful if you could help me figure out why this is happening.

    Thanks in advance.

     /  Reply

    1. Nevermind — it seems to be a problem with my rooted Vibrant running Ice Cream Sandwich. I tried on my wife’s unmodified phone, and it works just fine. Thanks for a great code example.

       /  Reply

  17. sky_lo

    i click record…
    then i click stop…
    then nothing. how/where can i view the file?
    how can i play it?
    has a file even been recorded??? no errors or feedback of anykind.
    this is on my G2 device by the way… deplyed via: ‘adb install AudioRecorder.2/AudioRecorder.2.apk’

    when the G2 device is mounted, will i be able to navigate to the dir and view the file as well?

    thx.
    sky

     /  Reply

  18. sky_lo

    okay, i was able to view the wavs in the SDCard/AudioRecorder folder…
    haven’t yet been able to play them tho

     /  Reply

  19. gangnith

    hi..in the link that you have put to download the source,.. i downloaded and executed..

    but i get a “force close” on my emulator.. and the error occurs on my “startRecording” function
    ,… are there are any pre-requisites for this ? can you pls help

     /  Reply

  20. Wendy

    Hi, this is really a great example, it helps me a lot, but how if i want to change pcm 16 bits to 8 bits?
    There is a buffer size error….
    thanks for ur helping!!

     /  Reply

  21. Subair

    Clicking on the record button results in a crash !!

    java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
    at android.media.AudioRecord.startRecording(AudioRecord.java:495)
    at com.demo.audiorecorder.AudioRecorderActivity.startRecording(AudioRecorderActivity.java:88)
    at com.demo.audiorecorder.AudioRecorderActivity.access$1(AudioRecorderActivity.java:84)
    at com.demo.audiorecorder.AudioRecorderActivity$1.onClick(AudioRecorderActivity.java:257)

     /  Reply

  22. Hello Ajith !
    Your Auido recording article is very helpful. I have some requirements like, I want to record audio with PCM_16 bit encoding type and 8000 sample rate in stereo mode and then separate the two channels data into two individual buffers from the main buffer which has raw PCM data of stereo audio. Can you please help me put with this

     /  Reply

  23. Sandeep

    Hi, nice example.Really helping thans a lot.
    Could you suggest or give some code or resouce to have pause button as well.
    that will pause recording .

    Thanks a lot.

     /  Reply

    1. Madhu Reddy

      Hi, Nice tutorial, i am able to record and playing back the recorded data. But How can i ensure like ‘there are no samples missing’ in my recording. i am having following issues

      1. difference between statRecording() and read() methods in functionality wise.

      2. For example i have started my recorder instance and by creating new thread i am reading samples using read() from device regularily. but in a case if i am not calling this read() regularly(since i am having other processing load) will i loose the data? and how this buffer pointer gets update?. what is the size difference to the recorder instance buffer and other audio buffer using in read().

      3. Why my recorder instance failing with 44.1 and 48k sampling rate?

      Thanks in Advance

       /  Reply

  24. Ruchi

    Hi,

    I want to implement pause and resume functionality while recording and playing using AndroidRecord.
    Kindly suggest how to do that. I am new to android programming.

    Thanks and regards.

     /  Reply

  25. Ruchi

    Hi,
    I executed the above souce code on Galaxy R(2.3.5 OS) and Sony Ericson (4.0 OS).
    My trouble is on Sony Ericson I can play the recorded file, but on Galaxy R I cant play it.
    The playing just finishes in less than a second on the later one.
    Please help.
    Thanks.

     /  Reply

  26. Murali

    Hi,
    It is nice example.Really helping thans a lot. The wav takes more size , so can you suggest me how to compress the wav file for reduce the size? please help me.

     /  Reply

  27. Meena

    I have created a file name “music_1.amr”.. When i recording audio it will capture and stored in “music_1.amr” . So i can do play, stop or save.. Now i wanna do is, whenever i create a new audio recording that previous recorded audio should be deleted automatically and this new audio capture must store it in same file name “music_1.amr”. What do i wanna do here . Can anyone suggest me?

     /  Reply

  28. Phalanx

    Hello ! Thanks for this code, very helpful !
    However, I still have a small problem with something and I can’t find any information about this : in the code, the sentence ” AppLog.logString” presents an error.

    AppLog is underlined in red with the explanation : AppLog cannot be resolved. The “help” menu gives me some option as usual “create variable, create filed, and so on…” but any of them implies that I will have to add some code for applog an I have no idea what to do!
    I can’t find anything about this by googling “applog”, this problem keeps me from doing any progress, so any help is highly expected!!

    Thanks in advance !

     /  Reply

  29. Chris

    Guys, I’m new to this but I spent a lot of time getting it to compile by copying/pasting the files into an existing empty package.. Is there a way to download the entire project into Eclipse in a single operation?

    I finally got it to compile, but it dies immediately on the phone:

    01-02 21:02:46.146: E/AndroidRuntime(4898): Uncaught handler: thread main exiting due to uncaught exception
    01-02 21:02:46.156: E/AndroidRuntime(4898): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.noiserecorder/com.example.noiserecorder.RecorderActivity}: java.lang.ClassNotFoundException: com.example.noiserecorder.RecorderActivity in loader dalvik.system.PathClassLoader@2fb24cd0
    01-02 21:02:46.156: E/AndroidRuntime(4898): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
    01-02 21:02:46.156: E/AndroidRuntime(4898): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
    01-02 21:02:46.156: E/AndroidRuntime(4898): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
    01-02 21:02:46.156: E/AndroidRuntime(4898): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
    01-02 21:02:46.156: E/AndroidRuntime(4898): at android.os.Handler.dispatchMessage(Handler.java:99)
    01-02 21:02:46.156: E/AndroidRuntime(4898): at android.os.Looper.loop(Looper.java:123)
    01-02 21:02:46.156: E/AndroidRuntime(4898): at android.app.ActivityThread.main(ActivityThread.java:4363)
    01-02 21:02:46.156: E/AndroidRuntime(4898): at java.lang.reflect.Method.invokeNative(Native Method)
    01-02 21:02:46.156: E/AndroidRuntime(4898): at java.lang.reflect.Method.invoke(Method.java:521)
    01-02 21:02:46.156: E/AndroidRuntime(4898): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:885)

    Any help would be greatly appreciated.

    Thanks.
    Chris

     /  Reply

  30. Chandan

    Hi,
    It is a nice tutorial. The code is working fine. The information on how to write mp3 and mp4 file using your code and on how to compress these file in mp3 or some other format will increase the beauty and completeness of this tutorial.

    Thanks!

     /  Reply

  31. Toleen

    Hello,

    I tried to integrate the recording function within a service, but the problem is that the conversion from raw to wav does not work perfectly.if the recording is more than 10 min the raw file is not converted completely.
    do u have any idea what would be the reason?

    thanks,
    Toleen

     /  Reply

  32. Carena Manznao

    hi ..can i ask question?
    How will you rename the file name. I mean file name for example should be: track 1 and so on after you have another recording.
    Please help me. thank you

     /  Reply

  33. Anil

    Sir I want to know how start recording when I speak and stop recording when stop speaking
    Just like “Talking tom cat”…
    I hope you will help me…

     /  Reply

  34. Omkar

    Hi there,
    I’m trying to make an app that controls the brightness of the screen through a plug-in device which can be connected to audio jack of mobile device.
    Any idea about that??

     /  Reply

  35. Eman

    hello,,, thank you so much for this article,,, but i just have one question… where is the code?! :O

     /  Reply

  36. jessy

    Hi,Thanks, a lot, but I have a question please, when I try to listen to what I have recorded , I heard nothing but a distorted sound and also the wave sample length is zero seconds although I recorded a sample of 8 scnds, Can anyone please help,
    Thanks

     /  Reply

  37. Amit Gauraw

    Hi ,

    I have to sream mic input over the http. Can you please help me how to achieve this task.

    Thanks in advance.

     /  Reply

  38. RKD

    Thank u so much!! I executed it at my first attempt! After browsing lots of sites, finally I got your link and it works perfectly.

     /  Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>