Audio Recording In .Wav Format In Android Programming

This example will help you to record audio in .wav format The WAV file will be placed in “/SDCard/AudioRecorder” folder with current millisecond as the file name.

Algorithm:

1.) Create a new project by File-> New -> Android Project name it SoundRecordingExample2.

2.) Write following into res/values/strings.xml:

 

<resources>

<string name="app_name">SoundRecordingExample2</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_sound_recording_example2">SoundRecordingExample2</string>

<string name="app_info">This is a sample application to record audio.nnTo start recording press &quot;Record&quot; button, to stop recording press &quot;Stop&quot; button.</string>
<string name="choose_format_title">Choose Audio Format</string>
<string name="start_recording">Record</string>
<string name="stop_recording">Stop</string>
<string name="audio_format">Format</string>
</resources>

 

 

3.) Write following into main.xml:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="20dip">

<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
android:scaleType="fitCenter"/>

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/app_info"
android:layout_weight="1.0"
android:textSize="20dip"/>

<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnStart"
android:text="@string/start_recording"
android:layout_weight="1.0"/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnStop"
android:text="@string/stop_recording"
android:layout_weight="1.0"/>
</LinearLayout>
</LinearLayout>

 

 

4.) Write following into AndroidManifest.xml:

 

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.soundrecordingexample2"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".SoundRecordingExample2"
android:label="@string/title_activity_sound_recording_example2" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

 

 

5.) Create and Write following into srcAppLog.java:

 

package com.example.soundrecordingexample2;

import android.util.Log;

public class AppLog {
private static final String APP_TAG = "AudioRecorder";

public static int logString(String message){
return Log.i(APP_TAG,message);
}
}

 

 

6.) Run for output.

Steps:

1.) Create a project named SoundRecordingExample2 and set the information as stated in the image.

Build Target: Android 4.0
Application Name: SoundRecordingExample2
Package Name: com. example. SoundRecordingExample2
Activity Name: SoundRecordingExample2
Min SDK Version: 2.2

2.) Open SoundRecordingExample2.java file and write following code there:

 

package com.example.soundrecordingexample2;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;

public class SoundRecordingExample2 extends Activity {
private static final int RECORDER_BPP = 16;
private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

private AudioRecord recorder = null;
private int bufferSize = 0;
private Thread recordingThread = null;
private boolean isRecording = false;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

setButtonHandlers();
enableButtons(false);

bufferSize = AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
}

private void setButtonHandlers() {
((Button)findViewById(R.id.btnStart)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btnStop)).setOnClickListener(btnClick);
}

private void enableButton(int id,boolean isEnable){
((Button)findViewById(id)).setEnabled(isEnable);
}

private void enableButtons(boolean isRecording) {
enableButton(R.id.btnStart,!isRecording);
enableButton(R.id.btnStop,isRecording);
}

private String getFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);

if(!file.exists()){
file.mkdirs();
}

return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + AUDIO_RECORDER_FILE_EXT_WAV);
}

private String getTempFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);

if(!file.exists()){
file.mkdirs();
}

File tempFile = new File(filepath,AUDIO_RECORDER_TEMP_FILE);

if(tempFile.exists())
tempFile.delete();

return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
}

private void startRecording(){
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize);

int i = recorder.getState();
if(i==1)
recorder.startRecording();

isRecording = true;

recordingThread = new Thread(new Runnable() {

@Override
public void run() {
writeAudioDataToFile();
}
},"AudioRecorder Thread");

recordingThread.start();
}

private void writeAudioDataToFile(){
byte data[] = new byte[bufferSize];
String filename = getTempFilename();
FileOutputStream os = null;

try {
os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

int read = 0;

if(null != os){
while(isRecording){
read = recorder.read(data, 0, bufferSize);

if(AudioRecord.ERROR_INVALID_OPERATION != read){
try {
os.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}

try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

private void stopRecording(){
if(null != recorder){
isRecording = false;

int i = recorder.getState();
if(i==1)
recorder.stop();
recorder.release();

recorder = null;
recordingThread = null;
}

copyWaveFile(getTempFilename(),getFilename());
deleteTempFile();
}

private void deleteTempFile() {
File file = new File(getTempFilename());

file.delete();
}

private void copyWaveFile(String inFilename,String outFilename){
FileInputStream in = null;
FileOutputStream out = null;
long totalAudioLen = 0;
long totalDataLen = totalAudioLen + 36;
long longSampleRate = RECORDER_SAMPLERATE;
int channels = 2;
long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8;

byte[] data = new byte[bufferSize];

try {
in = new FileInputStream(inFilename);
out = new FileOutputStream(outFilename);
totalAudioLen = in.getChannel().size();
totalDataLen = totalAudioLen + 36;

AppLog.logString("File size: " + totalDataLen);

WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
longSampleRate, channels, byteRate);

while(in.read(data) != -1){
out.write(data);
}

in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

private void WriteWaveFileHeader(
FileOutputStream out, long totalAudioLen,
long totalDataLen, long longSampleRate, int channels,
long byteRate) throws IOException {

byte[] header = new byte[44];

header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte) (totalDataLen & 0xff);
header[5] = (byte) ((totalDataLen >> 8) & 0xff);
header[6] = (byte) ((totalDataLen >> 16) & 0xff);
header[7] = (byte) ((totalDataLen >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) channels;
header[23] = 0;
header[24] = (byte) (longSampleRate & 0xff);
header[25] = (byte) ((longSampleRate >> 8) & 0xff);
header[26] = (byte) ((longSampleRate >> 16) & 0xff);
header[27] = (byte) ((longSampleRate >> 24) & 0xff);
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
header[32] = (byte) (2 * 16 / 8); // block align
header[33] = 0;
header[34] = RECORDER_BPP; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte) (totalAudioLen & 0xff);
header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
header[43] = (byte) ((totalAudioLen >> 24) & 0xff);

out.write(header, 0, 44);
}

private View.OnClickListener btnClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnStart:{
AppLog.logString("Start Recording");

enableButtons(true);
startRecording();

break;
}
case R.id.btnStop:{
AppLog.logString("Start Recording");

enableButtons(false);
stopRecording();

break;
}
}
}
};
}

 

 

3.) Compile and build the project.

Note: – For better results check on device.

Output

Leave a Comment:

18 comments
muhammad yar says November 8, 2012

Dear Sir this is very good code and you did work very hard for this but when i use same code and start recording it create a folder and file of 44 byte.(it will store empty file) don not record the voice please can you help me

thanx in advance

Reply
    Himanshu says June 22, 2015

    Take Permission to Write_External_Storage in Apps Mainfest.java.

    Reply
John Wells says December 6, 2012

Hi, Same problem Here, did you ever get it to work.

Thanks John.

john.wells@andrewjackson.co.uk

Reply
Bilal says December 27, 2012

hi,
i am having the same problem, when i open the file after recording i cannot hear the recorded voice, please help.

Thanks

Reply
What codec is used for audiodata from AudioRecord.read() in android : Android Community - For Application Development says January 29, 2013

[…] No codec is used. It reads raw samples. If you want to save to .wav file you should first write a .wav header to file.Look at this example […]

Reply
Joey says February 18, 2013

I am having the same problem as “muhammad yar”. The wav files are unreadable and all 44 bytes in size. I did notice that it never gets inside the while loop in the following code but I couldn’t figure out why. I like the code and totally would like to use it. Thanks.

Method: copyWaveFile(…)
Lines: 187-189

while (in.read(data) != -1) {
out.write(data);
}

Reply
Android 99 says February 21, 2013

Same problem of 44 byte wav file

Reply
Nemo says March 2, 2013

Hey!
Pretty Job here!

Reply
bitto says April 22, 2013

This is very good ,simple code and easy to understand.

However, to people cant get data of wav file like @muhammad (and like me) because the loop never get into “os.write(data);” in line 127. There is an error at “AudioRecord.ERROR_INVALID_OPERATION != read” in line 125 because there is not properly initial “recorder” in line 87

Thus, what i have done to make this code work for me are

line 24 change RECORDER_CHANNELS from AudioFormat.CHANNEL_IN_STERIO to AudioFormat.CHANNEL_IN_MONO

line 40 change sample rate from 8000 to 44100 same as RECORDER_SAMPLERATE in line 23

line 41 change from AudioFormat.CHANNEL_CONFIGURATION_MONO to CHANNEL_IN_MONO

Now you can hear your voice but the voice look like fast forward. The last thing you have to change is in line 171 change channel from 2 to 1

All done!! Happy recording your sound….

Reply
451smile says May 21, 2013

try to change “MediaRecorder.AudioSource.MIC” on “MediaRecorder.AudioSource.VOICE_RECOGNITION”

Reply
law says June 17, 2013

Hi! I tried this one and i work. The problem is i cannot see the folder via PC. But i can see from the device the the folder is created and there is a file. And the file can be played.
But from my PC, i cannot see it. What could be the possible problem?

Reply
Rohit says June 25, 2013

Error: recoder is uninitialised coming ….
It is unable to initialize recorder with these configuration … Why so ?

Reply
Rohit says June 25, 2013

Error: recoder is uninitialised coming ….
It is unable to initialize recorder with these configuration … Why so ??

Reply
Sylvie says June 26, 2013

Thanks a lot for sharing…
I want to ask something… If I want to get ONLY data from the audio (withour header, etc) since I need to process it again later, which array I need to call ?

and how do I call that array ??
Thanks before…

Reply
Joze says August 11, 2013

Hi
thanks for code, but on my HTC desire C also record only WAV header (44bytes)!
why?

Reply
Krack says August 27, 2013

Same as muhammad yar i face the same problem could you please advice !!??

Reply
indira says October 21, 2013

Hello,
I am using your code.when i was recording the voice its not recording the voice and error occuring,it is stored 0size in sdcard.

Reply
Huseyin says November 6, 2013

Hi,
Thanks for tutorial.
I try your code
But I got that error.How can I fix that?
Error creating AudioRecord instance: initialization check failed.
E/AudioRecord-Java(6182): [ android.media.AudioRecord ] Error code -20 when initializing native AudioRecord object.

Thanks

Reply
Add Your Reply