I wrote a simple Android code to capture audio from a my HTC HD Desire Android Mobile, and wriite it into an audio file on my SD Card. My code wrote the audio file, but I can't open the file. I suspect that the audio file format is not right.
This is the code that I wrote, with some explanation how it work. I appreciate any hints on how to debug my code. Thank you.
Code
The recorder class has one method, StartRecording(), that is responsible for capturing sound from the microphone for 20 seconds.
package com.audio;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder.AudioSource;
public class Recorder {
private short[] recordedAudioBuffer;
private int bufferRead;
public short[] startRecording() {
int recorderBufferSize = AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT) * 2;
AudioRecord recorder = new AudioRecord(AudioSource.DEFAULT, 8000,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
recorderBufferSize);
recordedAudioBuffer = new short[recorderBufferSize];
recorder.startRecording();
bufferRead = recorder.read(recordedAudioBuffer, 0, recorderBufferSize);
synchronized (this) {
try {
this.wait(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
recorder.stop();
recorder.release();
return recordedAudioBuffer;
}
public int getBufferRead() {
return bufferRead;
}开发者_运维百科
}
I drive the recorder code with the AudioRecorderActivity. This class uses the a simple FileOutputStream wrapped inside a BufferedOUtputStream, and write the audio buffer array from the recorder into a file.
package com.audio;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
public class AudioRecorderActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create a file to dump the recording
File f = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/test.raw");
try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Record audio
Recorder recorderInstance = new Recorder();
short[] recordedAudioBuffer = recorderInstance.startRecording();
// Write the audio to the file
BufferedOutputStream bufferedStreamInstance = null;
try {
bufferedStreamInstance = new BufferedOutputStream(
new FileOutputStream(f));
} catch (FileNotFoundException e) {
throw new IllegalStateException("Cannot Open File", e);
}
DataOutputStream dataOutputStreamInstance = new DataOutputStream(
bufferedStreamInstance);
try {
for (int idxBuffer = 0; idxBuffer < recordedAudioBuffer.length; idxBuffer++) {
dataOutputStreamInstance
.writeShort(recordedAudioBuffer[idxBuffer]);
}
} catch (IOException e) {
throw new IllegalStateException(
"dataOutputStreamInstance.writeShort(curVal)");
}
}
}
And this is my android manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.audio"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="9" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AudioRecorderActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
The data produced by AudioRecord consists of PCM samples. This is the "raw" form of the sound. In the example above you will get 8,000 16-bit (two byte) samples per second. Writing this data to a file just creates a file with this raw data.
What you probably want is for the data to be in some standard file format where it has some sort of header, and possibly some compression (aka encoding).
The easiest route to record audio in a known format is to use the MediaRecorder class. The doc for MediaRecorder has a short sample that I won't bother repeating here.
You can use an intent too if you dont want to implement this on your app
final Intent audioIntent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
File audioFile = new File(Environment.getExternalStorageDirectory(), "videoTest.mp4");
audioFileUri = Uri.fromFile(audioFile);
audioIntent.putExtra(MediaStore.EXTRA_OUTPUT, audioFileUri);
startActivityForResult(audioIntent, TAKE_AUDIO);
audioFileUri is the uri of the file in the SD card
精彩评论