Android录音上————AudioRecord实现录音功能

Android多媒体1————AudioRecord实现录音功能

一.前言

在百度实习的时候,导师让我负责语音助手SDK相关的东西,所以就一直想对其进行整理总结,就先从最基础,最简单AudioRecord类开始。

二.官方文档中的AudioRecord

想要了解一个类的具体说明,首先要看看官方文档:

1.概述

AndioRecordlei类的主要功能是让各种JAVA应用管理音频资源,方便从平台的音频输入硬件录制音频。此功能的实现是通过“pulling”(读取)AndioRecord对象的声音数据来完成。在录制过程中,应用所需要的是通过后面三个类方法中的一个区及时获取AudioRecord对象的录音数据。
开始录音时,AudioRecord需要一个初始化相关联的声音buffer,这个buffer主要用来存储新的声音数据,这个buffer的大小,我们可以在对象的构造期间去指定,它表明一个AudioRecord对象还没用被读取(同步)声音数据前能录多长的音。声音数据从音频硬件被读取出来,数据大小不超过整个录音数据的大小(可以分多次读取),即每次读取初始化buffer容量的数据。

2.实现Android录音的流程
  • 构造一个AudioRecord对象,其中需要的最小录音缓存buffer大小通过getMinBufferSize得到,如果buffer容量过小,将导致对象构造的失败
  • 初始化一个buffer,该buffer大于等于AudioRecord对象用于声音数据的buffer大小
  • 开始录音
  • 创建一个数据流,一边从AudioRecord中读取数据初始化的buffer,一边将buffer中的数据导入数据流中
  • 关闭数据流
  • 停止录音

三.相关的API

1.构造方法

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编码,Android支持的采用大小为16bit或者8bit。采样越大,信息量越多,音质也越高可以在getMinBufferSize()查看。
  • bufferSizeInBytes:采集数据需要缓存区的大小,如果不知道最小需要的大小
2.公共方法
  • int getAudioFormat():返回配置的音频数据格式
  • int getAudioSessionId():返回音频会话 id。
  • int getAudioSource():返回音频录制源。
  • int getChannelConfiguration():返回配置的通道配置。
  • int getChannelCount():返回配置的通道数。
  • static int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat):返回成功创建 audio 记录对象所需的最小缓冲区大小 (以字节为单位)。
  • int getNotificationMarkerPosition():返回以框架表示的通知标记位置。
  • int getPositionNotificationPeriod():返回以框架表示的通知更新期间。
  • int getRecordingState():返回音频记录实例的录制状态。
  • int getSampleRate():返回以 hz 为单位的配置音频数据采样率
  • int getState():返回音频记录实例的状态。
  • int read(short[] audioData, int offsetInShorts, int sizeInShorts):从音频硬件读取音频数据, 以便录制到缓冲区中。
  • int read(byte[] audioData, int offsetInBytes, int sizeInBytes):从音频硬件读取音频数据, 以便录制到缓冲区中。
  • int read(ByteBuffer audioBuffer, int sizeInBytes):从音频硬件读取音频数据, 以便录制到缓冲区中。
  • void release():释放本机AudioRecord资源
  • int setNotificationMarkerPosition(int markerInFrames)
  • int setPositionNotificationPeriod(int periodInFrames)
  • void setRecordPositionUpdateListener(AudioRecord.OnRecordPositionUpdateListener listener, Handler handler):设置AudioRecord通知的侦听器,当达到先前设置的标记时,或每次定期记录头位置更新时。
  • void startRecording():从AudioRecord实例开始记录。
  • void startRecording(MediaSyncEvent syncEvent):当指定的同步事件在指定的音频会话上发生时,从AudioRecord实例开始记录。
  • void stop():停止记录

四.使用示例

public class AudioRecordImpl {private static final String TAG = "AudioRecordImpl";// 采样率private static final int SAMPLE_RATE_HZ = 16000;private static final int BUFFER_SIZE = 640;private AudioRecord audioRecord;private Thread recordThread;//采样频率private int mAudioSampleRate = SAMPLE_RATE_HZ;//音频源private int mAudioSource = MediaRecorder.AudioSource.MIC;//编码大小private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;//选择声道private int mAudioChannel = AudioFormat.CHANNEL_IN_MONO;// 用于数据统计private volatile boolean isQueryLog;private volatile boolean isStartRecord = false;public AudioRecordImpl() {setAudio(SAMPLE_RATE_HZ, MediaRecorder.AudioSource.MIC, AudioFormat.ENCODING_PCM_16BIT,AudioFormat.CHANNEL_IN_MONO);}//默认设置public void setAudio(int sampleRate, int source, int format, int channel) {mAudioSampleRate = sampleRate;mAudioSource = source;mAudioFormat = format;mAudioChannel = channel;}//开始录音public v startRecord() {stopRecord();if (recordThread != null) {try {//t.join()方法阻塞调用此方法的线程(calling thread),// 直到线程t完成,此线程再继续recordThread.join();} catch (InterruptedException e) {e.printStackTrace();}}//设置线程优先级,android.os.Process.THREAD_PRIORITY_AUDIO-标准音乐播放使用的线程优先级android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);//获取最小bufferfinal int bufferSize = AudioRecord.getMinBufferSize(mAudioSampleRate, mAudioChannel, mAudioFormat);try {// 防止某些手机崩溃//创建audioRecord对象audioRecord = new AudioRecord(mAudioSource, mAudioSampleRate,mAudioChannel, mAudioFormat, bufferSize * 10);} catch (Exception e) {e.printStackTrace();LogUtil.dcf(TAG, "new AudioRecord() IllegalStateException ", e);}isStartRecord = true;recordThread = new Thread() {@Overridepublic void run() {super.run();try {// 防止某些手机崩溃if (audioRecord != null) {audioRecord.startRecording();}} catch (IllegalStateException e) {e.printStackTrace();LogUtil.dcf(TAG, "startRecording IllegalStateException ", e);isStartRecord = false;}isQueryLog = true;while (isStartRecord) {try {//读取语音数据byte[] buffer = new byte[BUFFER_SIZE];int readBytes = audioRecord.read(buffer, 0, buffer.length);if (readBytes > 0) {//处理语音数据fireData(buffer);}}} catch (Exception e) {e.printStackTrace();LogUtil.ecf(TAG, "audio recorder exception," + e);isStartRecord = false;}}// 释放资源try {if (audioRecord != null) {audioRecord.release();LogUtil.ic(TAG, "audioRecorder release ");}} catch (Exception e) {e.printStackTrace();LogUtil.wcf(TAG, "stop and release IllegalStateException ", e);} finally {audioRecord = null;}}};recordThread.start();}//停止录音public void stopRecord() {LogUtil.dc(TAG, "stopRecord");isStartRecord = false;}//释放资源public void release() {//释放资源LogUtil.dc(TAG, "release");stopRecord();}
}

五.参考资料

官方文档
Android 音视频开发(二):使用 AudioRecord 采集音频PCM并保存到文件


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部