版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34272093/article/details/81703096
package com.example.administrator.speech; import android.content.Context; import android.media.AudioAttributes; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecord; import android.media.AudioTrack; import android.media.MediaRecorder; import android.os.Build; import android.os.Environment; import android.support.annotation.RequiresApi; import android.text.TextUtils; import android.util.Log; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class AudioRecordManager { //播放状态 status private boolean isRecording = false; //音频输入麦克风 private static final int AUDIO_INPUT = MediaRecorder.AudioSource.MIC; //录音对象 private AudioRecord record = null; //缓冲区 private int bufferSize = 0; //采样率 private final static int AUDIO_SAMPLE_RATE_IN_HZ = 16000; //单声道 private final static int AUDIO_CHANNEL_CONFIG = AudioFormat.CHANNEL_CONFIGURATION_MONO; //音频格式 private final static int AUTIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; private static final String TAG = "AudioRecordManager"; private Context context; //音频播放 private AudioTrack track; private FileInputStream fileInputStream; //pcm file wav file private File file,pcmFile,wavFile; //Thread private Thread recordThread = null; private ArrayList<byte[]> inBuffer = new ArrayList<>(); //构造方法 public AudioRecordManager(Context context) { this.context = context; bufferSize = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE_IN_HZ, AUDIO_CHANNEL_CONFIG, AUTIO_ENCODING); record = new AudioRecord(AUDIO_INPUT, AUDIO_SAMPLE_RATE_IN_HZ, AUDIO_CHANNEL_CONFIG, AUTIO_ENCODING, bufferSize); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ file = new File(Environment.getExternalStorageDirectory().getPath()+"/WAV/"); if (file.exists()){ file.delete(); } try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } pcmFile = new File(file, "test.pcm"); wavFile = new File(file, "test.wav"); Log.d("----->wavFile=",wavFile.getAbsolutePath()); if (wavFile.exists()){ wavFile.delete(); } } //创建录音对象 public void createAudio(String fileName, int audioSource, int sampleRateInHz, int channelConfig, int encoding) { bufferSize = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, encoding); record = new AudioRecord(audioSource, sampleRateInHz, channelConfig, encoding, bufferSize); // this.fileName = fileName; } // //创建默认的录音对象 // public void createDefaultAudio(String fileName) { // bufferSize = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE_IN_HZ, AUDIO_CHANNEL_CONFIG, AUTIO_ENCODING); // record = new AudioRecord(AUDIO_INPUT,AUDIO_SAMPLE_RATE_IN_HZ, AUDIO_CHANNEL_CONFIG, AUTIO_ENCODING,bufferSize); // rawFile = fileName+".raw"; // wavFile = fileName+".wav"; // startRecord(); // } /** * 开始录音 */ public void startRecord() { record.startRecording(); isRecording = true; recordThread = new Thread(new AudioRecordThread()); recordThread.start(); } public void stopRecord() { isRecording = false; inBuffer.clear(); } public void clearRecord() { if (record != null) { record.stop(); record.release(); record = null; } try { recordThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } class AudioRecordThread implements Runnable { @Override public void run() { writeDataToFile(); pcmToWav(pcmFile.getAbsolutePath(),wavFile.getAbsolutePath()); } } private void writeDataToFile() { try { byte[] audioData = new byte[bufferSize]; FileOutputStream outputStream = null; int readSize; if (pcmFile.exists()) pcmFile.delete(); outputStream = new FileOutputStream(pcmFile); while (isRecording) { readSize = record.read(audioData, 0, bufferSize); synchronized (inBuffer) { inBuffer.add(audioData.clone()); } if (AudioRecord.ERROR_INVALID_OPERATION != readSize) { outputStream.write(audioData); } } outputStream.flush(); outputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * pcm 转换成wav **/ private void pcmToWav(String pcmFile,String wavFile){ FileInputStream in; FileOutputStream out; long totalAudioLen; long totalDataLen; long longSampleRate = AUDIO_SAMPLE_RATE_IN_HZ; int channels = 1; long byteRate = 16 * AUDIO_SAMPLE_RATE_IN_HZ * channels / 8; byte[] data = new byte[bufferSize]; try { in = new FileInputStream(pcmFile); out = new FileOutputStream(wavFile); totalAudioLen = in.getChannel().size(); totalDataLen = totalAudioLen + 36; WriteWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate); while (in.read(data) != -1) { out.write(data); } in.close(); out.close(); }catch (IOException e) { e.printStackTrace(); } } private byte[] WriteWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate, int channels, long byteRate) throws IOException { byte[] header = new byte[44]; 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); header[8] = 'W'; header[9] = 'A'; header[10] = 'V'; header[11] = 'E'; header[12] = 'f'; // 'fmt ' chunk header[13] = 'm'; header[14] = 't'; header[15] = ' '; header[16] = 16; // 4 bytes: size of 'fmt ' chunk header[17] = 0; header[18] = 0; header[19] = 0; header[20] = 1; // format = 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); header[32] = (byte) (1 * 16 / 8); // block align header[33] = 0; header[34] = 16; // bits per sample header[35] = 0; 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); return header; } /** * 结束录制 */ /** * 播放 */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void playRecord() { final int minBufferSize = AudioTrack.getMinBufferSize(AUDIO_SAMPLE_RATE_IN_HZ, AUDIO_CHANNEL_CONFIG, AUTIO_ENCODING); track = new AudioTrack(new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build(), new AudioFormat.Builder() .setSampleRate(AUDIO_SAMPLE_RATE_IN_HZ) .setEncoding(AUTIO_ENCODING) .setChannelMask(AUDIO_CHANNEL_CONFIG) .build(), minBufferSize, AudioTrack.MODE_STREAM, AudioManager.AUDIO_SESSION_ID_GENERATE ); track.play(); File file = new File(Environment.getExternalStorageDirectory().getPath()+"/WAV/", "test.pcm"); try { fileInputStream = new FileInputStream(file); new Thread(new Runnable() { @Override public void run() { byte[] tempBuffer = new byte[minBufferSize]; int lenght = 0; try { lenght = fileInputStream.available(); } catch (IOException e) { e.printStackTrace(); } boolean is= lenght>0?true:false; while (is) { int readCount = 0; try { readCount = fileInputStream.read(tempBuffer); } catch (IOException e) { e.printStackTrace(); } if (readCount == AudioTrack.ERROR_INVALID_OPERATION || readCount == AudioTrack.ERROR_BAD_VALUE) { continue; } if (readCount != 0 && readCount != -1) { track.write(tempBuffer, 0, readCount); } } } }).start(); } catch (FileNotFoundException e) { e.printStackTrace(); } } }