携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第32天,点击查看活动详情
1. AudioRecord介绍
AndioRecord类的主要功能是让各种JAVA应用能够管理音频资源,以便它们通过此类能够录制平台的声音输入硬件所收集的声音。此功能的实现就是通过”pulling同步”(reading读取)AudioRecord对象的声音数据来完成的。在录音过程中,应用所需要做的就是通过read方法去及时地获取AudioRecord对象的录音数据。AudioRecord类提供的三个获取声音数据的方法分别是read(byte[], int, int), read(short[], int, int), read(ByteBuffffer, int)。无论选择使用那一个方法都必须事先设定方便用户的声音数据的存储格式。 开始录音的时候,一个AudioRecord需要初始化一个相关联的声音buffffer, 这个buffffer主要是用来保存新的声音数据。这个buffffer的大小,我们可以在对象构造期间去指定。它表明一个AudioRecord对象还没有被读取(同步)声音数据前能录多长的音(即一次可以录制的声音容量)。声音数据从音频硬件中被读出,数据大小不超过整个录音数据的大小(可以分多次读出),即每次读取初始化buffffer容量的数据。 一般情况下录音实现的简单流程如下:
-
创建一个数据流。
-
构造一个AudioRecord对象,其中需要的最小录音缓存buffffer大小可以通过
getMinBufffferSize方法得到。如果buffffer容量过小,将导致对象构造的失败。
-
初始化一个buffffer,该buffffer大于等于AudioRecord对象用于写声音数据的buffffer大小。
-
开始录音。
-
从AudioRecord中读取声音数据到初始化buffffer,将buffffer中数据导入数据流。
-
停止录音。
-
关闭数据流
2. getMinBufffferSize流程解析
程序示例:
int bufferSize = AudioRecord.getMinBufferSize(
m_InSampleRate
, AudioFormat.CHANNEL_IN_STEREO
, AudioFormat.ENCODING_PCM_16BIT);
getMinBufffferSize时序图:
根据最小的framecount计算最小的buffersize。音频中最常见的是frame这个单位,一个frame就是1个采样点的字节数*声道。为啥搞个frame出来?因为对于多//声道的话,用1个采样点的字节数表示不全,因为播放的时候肯定是多个声道的数据都要播出来//才行。所以为了方便,就说1秒钟有多少个frame,这样就能抛开声道数,把意思表示全了。getMinBufSize函数完了后,我们得到一个满足最小要求的缓冲区大小。这样用户分配缓冲区就有了依据。
- 函数原型:
publicstaticintgetMinBufferSize(intsampleRateInHz,int
channelConfig,intaudioFormat)
- 作用:
返回成功创建AudioRecord对象所需要的最小缓冲区大小;
- 参数:
sampleRateInHz:默认采样率,单位Hz,这里设置为44100,44100Hz是当前唯一能保证在所有设备上工作的采样率;
channelConfig:描述音频声道设置,这里设置为AudioFormat.CHANNEL_CONFIGURATION_MONO,CHANNEL_CONFIGURATION_MONO保证能在所有设备上工作;
audioFormat:音频数据的采样精度,这里设置为AudioFormat.ENCODING_16BIT;
- 返回值:
返回成功创建AudioRecord对象所需要的最小缓冲区大小。注意:这个大小并不保证在负荷下的流畅录制,应根据预期的频率来选择更高的值,AudioRecord实例在推送新数据时使用此值。如果硬件不支持录制参数,或输入了一个无效的参数,则返回ERROR_BAD_VALUE(-2),如果硬件查询到输出属性没有实现,或最小缓冲区用byte表示,则返回ERROR(-1)。