Android录制WAV文件
来源:互联网 发布:美工设计的工作内容 编辑:程序博客网 时间:2024/05/21 10:16
实现思路:用AudioRecorder录制PCM数据以WAV格式保存
一)AudioRecord录制PCM数据
// default: mSampleRate = 8000int 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 blocke.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
2 0
- Android录制WAV文件
- Android录制WAV文件- 带去回声
- (8): 使用 TMediaPlayer 录制 wav 文件
- 03 ffmpeg调用声卡录制wav文件
- Android 手机录制wav格式音频文件实现
- Android AudioRecord录制wav格式的音频
- vc 录制和发送音频并保存wav文件
- WP8录制Wav音频文件
- WAV音频文件结构及录制
- 录制wav格式的音频
- android:使用audiotrack 类播放wav文件
- android录音程序之wav文件头
- android:使用audiotrack 类播放wav文件
- android录制声音写入文件
- wav文件
- WAV文件
- 声音的录制(VC)(保存为WAV文件) (转)
- Android || IOS录制mp3语音文件方法
- MySQL知识(七)——聚合函数、加密函数
- MySQL知识(八)——自定义函数
- Linux gcc使用
- 25个必须记住的SSH命令,你用过了吗?
- Python——类代码编写细节
- Android录制WAV文件
- Android 消息机制
- 命令行运行程序 解决 java “错误:编码GBK 的不可映射字符”
- 快速排序算法(c++)版
- iOS开发规范
- hdu 4734 数位dp
- Codeforces Round #258 (Div. 2) A. Game With Sticks
- 为什么频繁的跳槽
- LeetCode Repeated DNA Sequences