AudioRecord是安卓多媒体框架中用于录制音频的工具。它支持录制原始音频数据,即PCM数据,PCM数据不能被播放器直接播放,必要编码压缩成常见音频格式才气被播放器识别。通常生成PCM文件之后可将PCM文件转成WAV文件一般的播放器便可直接播放了。
接下来处置惩罚AudioRecord操纵。
1.初始化AudioRecord
先相识几个概念:
- audioSource:音频来源
- sampleRateInHz:采样率,以赫兹为单位。目前,只有44100Hz是保证在所有设备上都可以使用的速率(最适合人耳的),但是其他速率(例如22050、16000和11025)可能在某些设备上可以使用;如果用于语音识别的话根据不同厂商需要采用不同的采样率
- channelConfig:音频通道的配置
- audioFormat:音频数据的格式
- bufferSizeInBytes:在录制期间写入音频数据的缓冲区的总大小(以字节为单位)
复制代码 初始化操纵:
- int mBufferSize = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)*2;
- AudioRecord mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
- 16000,
- AudioFormat.CHANNEL_IN_MONO,//双声道
- AudioFormat.ENCODING_PCM_16BIT,
- mBufferSize);
复制代码 2.开始灌音
- /**
- * 录制pcm文件
- * @param pcmFilePath pcm文件路径
- */
- public void startRecord(String pcmFilePath) {
- if (isRecord) {
- return;
- }
- this.mPcmFilePath=pcmFilePath;
- isRecord = true;
- RecordThread recordThread = new RecordThread();
- mExecutorService.execute(recordThread);
- }
- class RecordThread implements Runnable {
- @Override
- public void run() {
- mAudioRecord.startRecording();
- FileOutputStream fos = null;
- try {
- Log.i(TAG, "文件地址: " + mPcmFilePath);
- fos = new FileOutputStream(mPcmFilePath);
- byte[] bytes = new byte[mBufferSize];
- while (isRecord) {
- mAudioRecord.read(bytes, 0, bytes.length);
- fos.write(bytes, 0, bytes.length);
- fos.flush();
- }
- Log.i(TAG, "停止录制");
- mAudioRecord.stop();
- fos.flush();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (fos != null) {
- try {
- fos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
复制代码 3.竣事灌音
- /**
- * 停止录制
- */
- public void stopRecord() {
- isRecord = false;
- }
复制代码 4.将灌音生成的pcm文件转成wav文件
- /**
- * pcm文件转wav文件
- * @param pcmFile pcm文件
- * @param wavFile wav文件
- */
- public void pcm2Wav(File pcmFile, File wavFile) {
- if (!pcmFile.exists()){
- throw new RuntimeException(pcmFile.getAbsolutePath()+",there is no pcm file");
- }
- mExecutorService.execute(new PcmToWavThread(pcmFile,wavFile));
- }
- class PcmToWavThread implements Runnable {
- File pcmFile;
- File wavFile;
- public PcmToWavThread(File pcmFile, File wavFile) {
- this.pcmFile = pcmFile;
- this.wavFile = wavFile;
- }
- @Override
- public void run() {
- if (!wavFile.exists()){
- try {
- wavFile.createNewFile();
- PcmToWavUtil util=new PcmToWavUtil(mSampleRate,mChannel,mFormat);
- util.pcmToWav(pcmFile.getAbsolutePath(),wavFile.getAbsolutePath());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
复制代码 pcm文成wav文件方法如下:
- /**
- * pcm文件转wav文件
- *
- * @param inFilename 源文件路径
- * @param outFilename 目标文件路径
- */
- public void pcmToWav(String inFilename, String outFilename) {
- FileInputStream in;
- FileOutputStream out;
- long totalAudioLen;//总录音长度
- long totalDataLen;//总数据长度
- long longSampleRate = mSampleRate;
- int channels = mChannel == AudioFormat.CHANNEL_IN_MONO ? 1 : 2;
- long byteRate = 16 * mSampleRate * channels / 8;
- byte[] data = new byte[mBufferSize];
- try {
- in = new FileInputStream(inFilename);
- out = new FileOutputStream(outFilename);
- totalAudioLen = in.getChannel().size();
- totalDataLen = totalAudioLen + 36;
- writeWaveFileHeader(out, totalAudioLen, totalDataLen,
- longSampleRate, channels, byteRate);
- while (in.read(data) != -1) {
- out.write(data);
- out.flush();
- }
- Log.e(TAG, "pcmToWav: 停止处理");
- in.close();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 加入wav文件头
- */
- private void writeWaveFileHeader(FileOutputStream out, long totalAudioLen,
- long totalDataLen, long longSampleRate, int channels, long byteRate)
- throws IOException {
- byte[] header = new byte[44];
- // RIFF/WAVE header
- header[0] = 'R';
- header[1] = 'I';
- header[2] = 'F';
- header[3] = 'F';
- header[4] = (byte) (totalDataLen & 0xff);
- header[5] = (byte) ((totalDataLen >> 8) & 0xff);
- header[6] = (byte) ((totalDataLen >> 16) & 0xff);
- header[7] = (byte) ((totalDataLen >> 24) & 0xff);
- //WAVE
- header[8] = 'W';
- header[9] = 'A';
- header[10] = 'V';
- header[11] = 'E';
- // 'fmt ' chunk
- header[12] = 'f';
- header[13] = 'm';
- header[14] = 't';
- header[15] = ' ';
- // 4 bytes: size of 'fmt ' chunk
- header[16] = 16;
- header[17] = 0;
- header[18] = 0;
- header[19] = 0;
- // format = 1
- header[20] = 1;
- header[21] = 0;
- header[22] = (byte) channels;
- header[23] = 0;
- header[24] = (byte) (longSampleRate & 0xff);
- header[25] = (byte) ((longSampleRate >> 8) & 0xff);
- header[26] = (byte) ((longSampleRate >> 16) & 0xff);
- header[27] = (byte) ((longSampleRate >> 24) & 0xff);
- header[28] = (byte) (byteRate & 0xff);
- header[29] = (byte) ((byteRate >> 8) & 0xff);
- header[30] = (byte) ((byteRate >> 16) & 0xff);
- header[31] = (byte) ((byteRate >> 24) & 0xff);
- // block align
- header[32] = (byte) (2 * 16 / 8);
- header[33] = 0;
- // bits per sample
- header[34] = 16;
- header[35] = 0;
- //data
- header[36] = 'd';
- header[37] = 'a';
- header[38] = 't';
- header[39] = 'a';
- header[40] = (byte) (totalAudioLen & 0xff);
- header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
- header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
- header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
- out.write(header, 0, 44);
- }
复制代码 5.开释资源
- /**
- * 释放资源
- */
- public void release() {
- if (mAudioRecord != null) {
- mAudioRecord.release();
- }
- if (mExecutorService!=null){
- mExecutorService.shutdown();
- }
- }
复制代码 至此灌音功能即可实现了,如果想要测试可以直接使用MediaPlayer方法举行灌音播放
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |