本篇项目地址,名字是AudioRecord录音(能暂停,将pch转换为wav),求star
https://github.com/979451341/Audio-and-video-learning-materials
先来段官方说明
html
AndioRecord类的主要功能是让各类JAVA应用可以管理音频资源,以便它们经过此类可以录制声音相关的硬件所收集的声音。此功能的实现就是经过”pulling”(读取)AudioRecord对象的声音数据来完成的。在录音过程当中,应用所须要作的就是经过后面三个类方法中的一个去及时地获取AudioRecord对象的录音数据. AudioRecord类提供的三个获取声音数据的方法分别是read(byte[], int, int), read(short[], int, int), read(ByteBuffer, int). 不管选择使用那一个方法都必须事先设定方便用户的声音数据的存储格式。
开始录音的时候,AudioRecord须要初始化一个相关联的声音buffer, 这个buffer主要是用来保存新的声音数据。这个buffer的大小,咱们能够在对象构造期间去指定。它代表一个AudioRecord对象尚未被读取(同步)声音数据前能录多长的音(即一次能够录制的声音容量)。声音数据从音频硬件中被读出,数据大小不超过整个录音数据的大小(能够分屡次读出),即每次读取初始化buffer容量的数据。
android
AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)
audioSource
音频源:指的是从哪里采集音频。这里咱们固然是从麦克风采集音频,因此此参数的值为MIC
sampleRateInHz
采样率:音频的采样频率,每秒钟可以采样的次数,采样率越高,音质越高。给出的实例是44100、22050、11025但不限于这几个参数。例如要采集低质量的音频就能够使用4000、8000等低采样率。
channelConfig
声道设置:android支持双声道立体声和单声道。MONO单声道,STEREO立体声
audioFormat
编码制式和采样大小:采集来的数据固然使用PCM编码(脉冲代码调制编码,即PCM编码。PCM经过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。) android支持的采样大小16bit 或者8bit。固然采样大小越大,那么信息量越多,音质也越高,如今主流的采样大小都是16bit,在低质量的语音传输的时候8bit足够了。
bufferSizeInBytes
采集数据须要的缓冲区的大小,若是不知道最小须要的大小能够在getMinBufferSize()查看。
AudioRecord.getMinBufferSize(sampleRateInHz,
channelConfig, channelConfig);
git
PCM
PCM是在由模拟信号向数字信号转化的一种经常使用的编码格式,称为脉冲编码调制,PCM将模拟信号按照必定的间距划分为多段,而后经过二进制去量化每个间距的强度。PCM表示的是音频文件中随着时间的流逝的一段音频的振幅。Android在WAV文件中支持PCM的音频数据。
WAV文件
WAV,MP3等是咱们比较常见的音频格式,不一样的编码格式对原始音频采用的编码方式也是不一样的,一般为了方便传输等问题,会对原始音频进行压缩,同时为了可以使得播放器可以识别该种格式,因此在每种格式的头文件都是特定的,有必定的规则,来让播放器识别出是该种格式,而后按着相应的解码算法去播放后面的音频文件。
github
首先是建立和配置AudioRecord算法
//音频输入-麦克风 private final static int AUDIO_INPUT = MediaRecorder.AudioSource.MIC; //采用频率 //44100是目前的标准,可是某些设备仍然支持22050,16000,11025 //采样频率通常共分为22.05KHz、44.1KHz、48KHz三个等级 private final static int AUDIO_SAMPLE_RATE = 16000; //声道 单声道 private final static int AUDIO_CHANNEL = AudioFormat.CHANNEL_IN_MONO; //编码 private final static int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; // 缓冲区字节大小 private int bufferSizeInBytes = 0; //录音对象 private AudioRecord audioRecord; /** * 建立默认的录音对象 * * @param fileName 文件名 */ public void createDefaultAudio(String fileName) { // 得到缓冲区字节大小 bufferSizeInBytes = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL, AUDIO_ENCODING); audioRecord = new AudioRecord(AUDIO_INPUT, AUDIO_SAMPLE_RATE, AUDIO_CHANNEL, AUDIO_ENCODING, bufferSizeInBytes); this.fileName = fileName; status = Status.STATUS_READY; }
开始录音,同时开个子线程将录音的数据放入pcm文件数组
audioRecord.startRecording(); new Thread(new Runnable() { @Override public void run() { writeDataTOFile(listener); } }).start();
如何将音频写入文件是重点,我写个伪代码,说明这个代码运行顺序
首先建立pcm文件,获得他的FileOutputStream,而后不断循环AudioRecord经过read将录音的数据放入字节数组里,当录音结束的时候要记得中止这个循环ide
// new一个byte数组用来存一些字节数据,大小为缓冲区大小 byte[] audiodata = new byte[bufferSizeInBytes]; FileOutputStream fos = null; int readsize = 0; try { File file = new File(currentFileName); if (file.exists()) { file.delete(); } fos = new FileOutputStream(file);// 创建一个可存取字节的文件 } catch (IllegalStateException e) { Log.e("AudioRecorder", e.getMessage()); throw new IllegalStateException(e.getMessage()); } catch (FileNotFoundException e) { Log.e("AudioRecorder", e.getMessage()); } while (true) { readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes); if (AudioRecord.ERROR_INVALID_OPERATION != readsize && fos != null) { try { fos.write(audiodata); } catch (IOException e) { Log.e("AudioRecorder", e.getMessage()); } } }
如何咱们要实现可以暂停录音,只要AudioRecord.stop就行,而后当继续录音时在AudioRecord.start就行了,可是要另建立一个pcm记录,当录音结束时咱们要将这些pcm一块儿转换为一个wav,
至于pcm转换为wav的代码是固定的,我就不贴出,你们在文章首部代码地址自取吧
参考文章
http://blog.csdn.net/hellofeiya/article/details/8968534
http://blog.csdn.net/JenseaChen/article/details/46883319
this