Android 灌音AudioRecord

打印 上一主题 下一主题

主题 557|帖子 557|积分 1671

AudioRecord是安卓多媒体框架中用于录制音频的工具。它支持录制原始音频数据,即PCM数据,PCM数据不能被播放器直接播放,必要编码压缩成常见音频格式才气被播放器识别。通常生成PCM文件之后可将PCM文件转成WAV文件一般的播放器便可直接播放了。
接下来处置惩罚AudioRecord操纵。
1.初始化AudioRecord
先相识几个概念:
  1. audioSource:音频来源
  2. sampleRateInHz:采样率,以赫兹为单位。目前,只有44100Hz是保证在所有设备上都可以使用的速率(最适合人耳的),但是其他速率(例如22050、16000和11025)可能在某些设备上可以使用;如果用于语音识别的话根据不同厂商需要采用不同的采样率
  3. channelConfig:音频通道的配置
  4. audioFormat:音频数据的格式
  5. bufferSizeInBytes:在录制期间写入音频数据的缓冲区的总大小(以字节为单位)
复制代码
初始化操纵:
  1. int mBufferSize = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)*2;
  2. AudioRecord mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
  3.         16000,
  4.         AudioFormat.CHANNEL_IN_MONO,//双声道
  5.         AudioFormat.ENCODING_PCM_16BIT,
  6.         mBufferSize);
复制代码
 2.开始灌音
  1. /**
  2.      * 录制pcm文件
  3.      * @param pcmFilePath pcm文件路径
  4.      */
  5.     public void startRecord(String pcmFilePath) {
  6.         if (isRecord) {
  7.             return;
  8.         }
  9.         this.mPcmFilePath=pcmFilePath;
  10.         isRecord = true;
  11.         RecordThread recordThread = new RecordThread();
  12.         mExecutorService.execute(recordThread);
  13.     }
  14. class RecordThread implements Runnable {
  15.         @Override
  16.         public void run() {
  17.             mAudioRecord.startRecording();
  18.             FileOutputStream fos = null;
  19.             try {
  20.                 Log.i(TAG, "文件地址: " + mPcmFilePath);
  21.                 fos = new FileOutputStream(mPcmFilePath);
  22.                 byte[] bytes = new byte[mBufferSize];
  23.                 while (isRecord) {
  24.                     mAudioRecord.read(bytes, 0, bytes.length);
  25.                     fos.write(bytes, 0, bytes.length);
  26.                     fos.flush();
  27.                 }
  28.                 Log.i(TAG, "停止录制");
  29.                 mAudioRecord.stop();
  30.                 fos.flush();
  31.             } catch (IOException e) {
  32.                 e.printStackTrace();
  33.             } finally {
  34.                 if (fos != null) {
  35.                     try {
  36.                         fos.close();
  37.                     } catch (IOException e) {
  38.                         e.printStackTrace();
  39.                     }
  40.                 }
  41.             }
  42.         }
  43.     }
复制代码
3.竣事灌音
  1. /**
  2.      * 停止录制
  3.      */
  4.     public void stopRecord() {
  5.         isRecord = false;
  6.     }
复制代码
4.将灌音生成的pcm文件转成wav文件
  1. /**
  2.      * pcm文件转wav文件
  3.      * @param pcmFile pcm文件
  4.      * @param wavFile wav文件
  5.      */
  6.     public void pcm2Wav(File pcmFile, File wavFile) {
  7.         if (!pcmFile.exists()){
  8.             throw new RuntimeException(pcmFile.getAbsolutePath()+",there is no pcm file");
  9.         }
  10.         mExecutorService.execute(new PcmToWavThread(pcmFile,wavFile));
  11.     }
  12.     class PcmToWavThread implements Runnable {
  13.         File pcmFile;
  14.         File wavFile;
  15.         public PcmToWavThread(File pcmFile, File wavFile) {
  16.             this.pcmFile = pcmFile;
  17.             this.wavFile = wavFile;
  18.         }
  19.         @Override
  20.         public void run() {
  21.             if (!wavFile.exists()){
  22.                 try {
  23.                     wavFile.createNewFile();
  24.                     PcmToWavUtil util=new PcmToWavUtil(mSampleRate,mChannel,mFormat);
  25.                     util.pcmToWav(pcmFile.getAbsolutePath(),wavFile.getAbsolutePath());
  26.                 } catch (IOException e) {
  27.                     e.printStackTrace();
  28.                 }
  29.             }
  30.         }
  31.     }
复制代码
 pcm文成wav文件方法如下:
  1. /**
  2.      * pcm文件转wav文件
  3.      *
  4.      * @param inFilename 源文件路径
  5.      * @param outFilename 目标文件路径
  6.      */
  7.     public void pcmToWav(String inFilename, String outFilename) {
  8.         FileInputStream in;
  9.         FileOutputStream out;
  10.         long totalAudioLen;//总录音长度
  11.         long totalDataLen;//总数据长度
  12.         long longSampleRate = mSampleRate;
  13.         int channels = mChannel == AudioFormat.CHANNEL_IN_MONO ? 1 : 2;
  14.         long byteRate = 16 * mSampleRate * channels / 8;
  15.         byte[] data = new byte[mBufferSize];
  16.         try {
  17.             in = new FileInputStream(inFilename);
  18.             out = new FileOutputStream(outFilename);
  19.             totalAudioLen = in.getChannel().size();
  20.             totalDataLen = totalAudioLen + 36;
  21.             writeWaveFileHeader(out, totalAudioLen, totalDataLen,
  22.                     longSampleRate, channels, byteRate);
  23.             while (in.read(data) != -1) {
  24.                 out.write(data);
  25.                 out.flush();
  26.             }
  27.             Log.e(TAG, "pcmToWav: 停止处理");
  28.             in.close();
  29.             out.close();
  30.         } catch (IOException e) {
  31.             e.printStackTrace();
  32.         }
  33.     }
  34.     /**
  35.      * 加入wav文件头
  36.      */
  37.     private void writeWaveFileHeader(FileOutputStream out, long totalAudioLen,
  38.                                      long totalDataLen, long longSampleRate, int channels, long byteRate)
  39.             throws IOException {
  40.         byte[] header = new byte[44];
  41.         // RIFF/WAVE header
  42.         header[0] = 'R';
  43.         header[1] = 'I';
  44.         header[2] = 'F';
  45.         header[3] = 'F';
  46.         header[4] = (byte) (totalDataLen & 0xff);
  47.         header[5] = (byte) ((totalDataLen >> 8) & 0xff);
  48.         header[6] = (byte) ((totalDataLen >> 16) & 0xff);
  49.         header[7] = (byte) ((totalDataLen >> 24) & 0xff);
  50.         //WAVE
  51.         header[8] = 'W';
  52.         header[9] = 'A';
  53.         header[10] = 'V';
  54.         header[11] = 'E';
  55.         // 'fmt ' chunk
  56.         header[12] = 'f';
  57.         header[13] = 'm';
  58.         header[14] = 't';
  59.         header[15] = ' ';
  60.         // 4 bytes: size of 'fmt ' chunk
  61.         header[16] = 16;
  62.         header[17] = 0;
  63.         header[18] = 0;
  64.         header[19] = 0;
  65.         // format = 1
  66.         header[20] = 1;
  67.         header[21] = 0;
  68.         header[22] = (byte) channels;
  69.         header[23] = 0;
  70.         header[24] = (byte) (longSampleRate & 0xff);
  71.         header[25] = (byte) ((longSampleRate >> 8) & 0xff);
  72.         header[26] = (byte) ((longSampleRate >> 16) & 0xff);
  73.         header[27] = (byte) ((longSampleRate >> 24) & 0xff);
  74.         header[28] = (byte) (byteRate & 0xff);
  75.         header[29] = (byte) ((byteRate >> 8) & 0xff);
  76.         header[30] = (byte) ((byteRate >> 16) & 0xff);
  77.         header[31] = (byte) ((byteRate >> 24) & 0xff);
  78.         // block align
  79.         header[32] = (byte) (2 * 16 / 8);
  80.         header[33] = 0;
  81.         // bits per sample
  82.         header[34] = 16;
  83.         header[35] = 0;
  84.         //data
  85.         header[36] = 'd';
  86.         header[37] = 'a';
  87.         header[38] = 't';
  88.         header[39] = 'a';
  89.         header[40] = (byte) (totalAudioLen & 0xff);
  90.         header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
  91.         header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
  92.         header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
  93.         out.write(header, 0, 44);
  94.     }
复制代码
5.开释资源
  1. /**
  2.      * 释放资源
  3.      */
  4.     public void release() {
  5.         if (mAudioRecord != null) {
  6.             mAudioRecord.release();
  7.         }
  8.         if (mExecutorService!=null){
  9.             mExecutorService.shutdown();
  10.         }
  11.     }
复制代码
至此灌音功能即可实现了,如果想要测试可以直接使用MediaPlayer方法举行灌音播放

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表