Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AudioRecord - writing PCM file

I' m trying to record some voice using AudioRecord class and then write it to output .pcm file. I want my program to keep recording until the stop button is pressed. Unfortunatelly no matter how long I' m recording, output file size is always 3528 bytes and it lasts for about 20 ms. Also according to Toolsoft Audio Tools, properies of that file are: 44100Hz, 16 bits, stereo, even if I' m using mono with completely different sampling frequency.

Thread recordingThread;
boolean isRecording = false;


int audioSource = AudioSource.MIC;
int sampleRateInHz = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);

byte Data[] = new byte[bufferSizeInBytes];

AudioRecord audioRecorder = new AudioRecord(audioSource,
                                            sampleRateInHz, 
                                            channelConfig, 
                                            audioFormat, 
                                            bufferSizeInBytes);
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);   
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}    

public void startRecording(View arg0) {
    audioRecorder.startRecording();
    isRecording = true;
    recordingThread = new Thread(new Runnable() {
        public void run() {
            String filepath = Environment.getExternalStorageDirectory().getPath();
            FileOutputStream os = null;
            try {
                os = new FileOutputStream(filepath+"/record.pcm");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            while(isRecording) {
                audioRecorder.read(Data, 0, Data.length);
                try {
                    os.write(Data, 0, bufferSizeInBytes);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    });
    recordingThread.start();
}

public void stopRecording(View arg0) {
    if (null != audioRecorder) {
        isRecording = false;
        audioRecorder.stop();
        audioRecorder.release();
        audioRecorder = null;
        recordingThread = null;
    }
}

May I kindly ask you to tell me what's wrong? I'm hoping the answer won't be 'everything' :)

like image 422
Arxas Avatar asked Nov 27 '12 12:11

Arxas


2 Answers

try {
                os.write(Data, 0, bufferSizeInBytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

This is the issue. You are closing the FileOutputStream (os.close()) after just a single write. Move it out of the while loop:

while(isRecording) {
            audioRecorder.read(Data, 0, Data.length);
            try {
                os.write(Data, 0, bufferSizeInBytes);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
      try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
like image 113
Sid Sarasvati Avatar answered Oct 18 '22 11:10

Sid Sarasvati


Change your sample rate to 8000, because in emulator you cant test with 44100 sample rate.

use AudioRecord source as shown to play in emulator

private static final int RECORDER_SAMPLERATE = 8000;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

AudioRecord audio_record = new AudioRecord(MediaRecorder.AudioSource.MIC,
            RECORDER_SAMPLERATE, RECORDER_CHANNELS,
            RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement);


int BufferElements2Play = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
int BytesPerElement = 2; // 2 bytes in 16bit format

If it din't get worked, then go to this blog. It will work fine for recording and storing the data in .pcm file.

like image 30
Rahul Baradia Avatar answered Oct 18 '22 12:10

Rahul Baradia