I need to be able to create a WAV file using the mic in Android. Currently, I'm having a lot of trouble. So far, this is my situation. I'm using parts of the micDroid project code to record thus:
//read thread
int sampleRate = 44100;
int bufferSize = AudioRecord.getMinBufferSize(sampleRate,android.media.AudioFormat.CHANNEL_CONFIGURATION_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT);
AudioRecord ar = new AudioRecord(AudioSource.MIC,sampleRate,android.media.AudioFormat.CHANNEL_CONFIGURATION_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT,bufferSize);
short[] buffer = new short[bufferSize];
ar.startRecording();
while(isRunning){
try{
int numSamples = ar.read(buffer, 0, buffer.length);
queue.put(new Sample(buffer, numSamples));
} catch (InterruptedException e){
e.printStackTrace();
}
}
//write thread
int sampleRate = 44100;
WaveWriter writer = new WaveWriter("/sdcard","recOut.wav",sampleRate,android.media.AudioFormat.CHANNEL_CONFIGURATION_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT);
try {
writer.createWaveFile();
} catch (IOException e) {
e.printStackTrace();
}
while(isRunning){
try {
Sample sample = queue.take();
writer.write(sample.buffer, sample.bufferSize);
} catch (IOException e) {
//snip
}
}
Which appears to work fine, however the end result recognizably contains whatever I said, but it is horribly distorted. Here's a screen cap of audacity (WMP refuses to play the file).
Any help would be greatly appreciated, let me know if you need more code / info.
Update
Following markus's suggestions, here is my updated code:
int sampleRate = 16000;
writer = new WaveWriter("/sdcard","recOut.wav",sampleRate,android.media.AudioFormat.CHANNEL_IN_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT);
int bufferSize = AudioRecord.getMinBufferSize(sampleRate,android.media.AudioFormat.CHANNEL_IN_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT);
AudioRecord ar = new AudioRecord(AudioSource.MIC,sampleRate,android.media.AudioFormat.CHANNEL_IN_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT,bufferSize);
byte[] buffer = new byte[bufferSize]; //all references changed from short to byte type
...and another audacity screencap:
It's pretty clear, Audacity thinks that your file is floating point. Either the WAV header is screwed up or else it's how you opened it.
Make a recording. In Audacity, open it using Project / Import Raw Data Set the parameters for how you think that you recorded it. I'll bet it plays back ok.
You can set a buffer to be little-endian by using the following:
I have a lot of theories:
if not check queue.put and queue.take I think you don't need them because you stored your audio in and array that's enough. In the first while I would replace queue.put by a function to store the buffer in a huge array of bytes with all the bytes. Then you can put the header of the wav.
Remember a wav has the header and the bytes of the audio, maybe you have forgot the header and the program you are using is inventing a header to play it.
The other option is: you have the problem on the wav header of 44 bytes. check your WaveWriter function. if you write bad code on it, you can heard a lot of different sounds of your voice.
note: I had seen the function WaveWriter or similar on the source code of android but it had not been ready to use three months ago. Some new about waveheader?
CHANNEL_CONFIGURATION_MONO is deprecated as far as i know, use CHANNEL_IN_MONO. consider looking at rehearsalassistant project, afaik they use AudioRecord class, too. samplerates should be chosen to fit the standard sample rates like explained in this wikipedia article.