您的位置:首页 > 移动开发 > Android开发

Android录制WAV文件

2016-02-20 13:33 477 查看
实现思路:用AudioRecorder录制PCM数据以WAV格式保存

一)AudioRecord录制PCM数据

// default: mSampleRate = 8000
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
minBufferSize = AudioRecord.getMinBufferSize(mSampleRate, channelConfig, audioEncoding);
Log.i(LOG_TAG, "minBufferSize: " + minBufferSize);

mRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION,
mSampleRate,
channelConfig,
audioEncoding,
minBufferSize*2);
mAudioSessionId = mRecord.getAudioSessionId();


二)保存WAV文件

File f = new File(mRecordfile);
if(f.exists()){
f.delete();
}

randomAccessWriter = new RandomAccessFile(mRecordfile, "rw");
initWavHeader(randomAccessWriter, (short)channelConfig, (int)mSampleRate, (short)16);
payloadSize = 0;


//初始化WAV文件头

static void initWavHeader(RandomAccessFile randomAccessWriter, short Channels, int SamplesPerSec, short BitsPerSample){
try {
randomAccessWriter.setLength(0);
// Set file length to 0, to prevent unexpected behavior in case the file already existed
randomAccessWriter.writeBytes("RIFF");
randomAccessWriter.writeInt(0); // Final file size not known yet, write 0
randomAccessWriter.writeBytes("WAVE");
randomAccessWriter.writeBytes("fmt ");
randomAccessWriter.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM
randomAccessWriter.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM
randomAccessWriter.writeShort(Short.reverseBytes((short) 1));// Number of channels, 1 for mono, 2 for stereo
randomAccessWriter.writeInt(Integer.reverseBytes(SamplesPerSec)); // Sample rate
randomAccessWriter.writeInt(Integer.reverseBytes(SamplesPerSec*BitsPerSample*Channels/8)); // Byte rate, SampleRate*NumberOfChannels*BitsPerSample/8
randomAccessWriter.writeShort(Short.reverseBytes((short)(Channels*BitsPerSample/8))); // Block align, NumberOfChannels*BitsPerSample/8
randomAccessWriter.writeShort(Short.reverseBytes(BitsPerSample)); // Bits per sample
randomAccessWriter.writeBytes("data");
randomAccessWriter.writeInt(0); // Data chunk size not known yet, write 0
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


//读取PCM写入WAV文件

byte[] pcmData = new byte[minBufferSize*2];
final Object threadLock = new Object();
Thread.currentThread().setPriority(MAX_PRIORITY);
Thread.currentThread().setName("AudioSourceMicr");
mRecord.startRecording();

synchronized (threadLock)
{
while (mThreadLoop && !Thread.currentThread().isInterrupted())
{
if (mPauseFlag) continue;

int bufferReadResult = mRecord.read(pcmData, 0, minBufferSize*2-512);
Log.i(LOG_TAG, "bufferReadResult = "+bufferReadResult);

if (bufferReadResult > 0){
saveWaveData(pcmData, bufferReadResult);
}
else{
Log.i(LOG_TAG, "Error to read pcm from AudioRecorder.");
}
}
}


//录制完成之后将数据长度回写到WAV文件头

randomAccessWriter.seek(4);
randomAccessWriter.write(Integer.reverseBytes(36+payloadSize));
randomAccessWriter.seek(40);
randomAccessWriter.write(Integer.reverseBytes(payloadSize));
randomAccessWriter.close();


三)回音消除&去噪(android4.1版本以上支持)

if (mAudioSessionId != 0 && android.os.Build.VERSION.SDK_INT >= 16)
{
if (NoiseSuppressor.isAvailable())
{
if (mNoiseSuppressor != null)
{
mNoiseSuppressor.release();
mNoiseSuppressor = null;
}

mNoiseSuppressor = NoiseSuppressor.create(mAudioSessionId);
if (mNoiseSuppressor != null)
{
mNoiseSuppressor.setEnabled(true);
}
else
{
Log.i(LOG_TAG, "Failed to create NoiseSuppressor.");
}
}
else
{
Log.i(LOG_TAG, "Doesn't support NoiseSuppressor");
}

if (AcousticEchoCanceler.isAvailable())
{
if (mAcousticEchoCanceler != null)
{
mAcousticEchoCanceler.release();
mAcousticEchoCanceler = null;
}

mAcousticEchoCanceler = AcousticEchoCanceler.create(mAudioSessionId);
if (mAcousticEchoCanceler != null)
{
mAcousticEchoCanceler.setEnabled(true);
// mAcousticEchoCanceler.setControlStatusListener(listener)setEnableStatusListener(listener)
}
else
{
Log.i(LOG_TAG, "Failed to initAEC.");
mAcousticEchoCanceler = null;
}
}
else
{
Log.i(LOG_TAG, "Doesn't support AcousticEchoCanceler");
}

if (AutomaticGainControl.isAvailable())
{
if (mAutomaticGainControl != null)
{
mAutomaticGainControl.release();
mAutomaticGainControl = null;
}

mAutomaticGainControl = AutomaticGainControl.create(mAudioSessionId);
if (mAutomaticGainControl != null)
{
mAutomaticGainControl.setEnabled(true);
}
else
{
Log.i(LOG_TAG, "Failed to create AutomaticGainControl.");
}

}
else
{
Log.i(LOG_TAG, "Doesn't support AutomaticGainControl");
}
}


源码工程:http://download.csdn.net/detail/hewenhao2014/9437513
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息