昨天学习了图片的绘制,今天轮到了音频的采集和播放。java
Android 在音频的采集上有提供相应的 API,就是 AudioRecord。git
AudioRecord 是为 Java 应用程序提供管理音频资源功能的类,使应用程序可能经过此类可以获取声音相关硬件所收集的声音。github
录音是 Input 行为,因此这个功能的实现就是经过读取硬件的数据来完成录音的过程。缓存
构造一个 AudioRecord 对象,并指定须要的最小的缓存 buffer 大小。微信
这个缓存是用来存储未读取的声音数据的,他代表声音数据没有被读取前,能录多久的音(即一次能够录制的声音容量)。markdown
初始化一个 buffer,这个 buffer 和 上一步指定的 buffer 不一样,这是用来表示每次读取声音数据读取多少的。oop
开始录音。学习
建立一个数据流,将从 AudioRecord 读取到声音数据存储在数据流中。spa
关闭数据流。code
中止录音。
从上面的步骤就能够看出录音其实和普通的文件 I/O 的思想是一致的。说到这里,其实计算机里就是计算和 I/O,掌握这个模型后,大部分的逻辑都能理通。
AudioRecord 须要的参数有如下几个:
接下来对各个参数进行详细说明:
音频源指的是从哪里采集音频,也就是指定硬件设备。下面是 Android 所支持的音频源,在 MediaRecorder.AudioSource
中定义:
/**默认声音**/ public static final int DEFAULT = 0; /**麦克风声音*/ public static final int MIC = 1; /**通话上行声音*/ public static final int VOICE_UPLINK = 2; /**通话下行声音*/ public static final int VOICE_DOWNLINK = 3; /**通话上下行声音*/ public static final int VOICE_CALL = 4; /**根据摄像头转向选择麦克风*/ public static final int CAMCORDER = 5; /**对麦克风声音进行声音识别,而后进行录制*/ public static final int VOICE_RECOGNITION = 6; /**对麦克风中相似ip通话的交流声音进行识别,默认会开启回声消除和自动增益*/ public static final int VOICE_COMMUNICATION = 7; /**录制系统内置声音*/ public static final int REMOTE_SUBMIX = 8; 复制代码
采样率指的是音频的采样率,每秒钟可以采样的次数,采样率越高,音质越高。此处推荐的采样率是 44100、22050、11025,可是并不局限于这几个。
Android 支持双声道立体声和单声道,这部分在 AudioFormat
中定义
public static final int CHANNEL_IN_MONO = CHANNEL_IN_FRONT; public static final int CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT); 复制代码
经过 AudioRecoder 采集到的声音数据是 PCM 格式的,在计算机中采样位数通常有 8 位和 16 位之分。这个参数是用来衡量声音波动变化的一个参数,相似于分辨率的概念,他的数值越大,录制的颗粒度越细,声音就更精细。
须要注意的是: 8 位不是说将纵轴分割成 8 份,而是分红 2 的 8 次方,即 256 份。同理,16 位是把纵轴分割成 2 的 16 次方 65536 份。
在录制的时候并不须要存储量这个参数,可是已经知道了这些参数,就能够计算出录制文件的存储大小了。声音最重要的三个参数就是:声道、采样位数、采样频率,因此由如下公式能够计算出录制文件的大小:
存储量= (采样频率 · 采样位数 · 声道 · 时间)/8 (单位:字节数)
上半部分讲了怎么录制声音,下半部分聊一下怎么把录制的声音播放出来。
播放录制的声音须要用到 AudioTrack 这个类。
其实和录制几乎同样,只是流程是相反的。毕竟一个是 input,一个是 output。仍是标准的 I/O 思路,参数也一致。
最后确定要放代码的,代码太长了,就不在文章中贴出来了。感兴趣的能够去 GitHub 仓库看看。
最新更新请关注微信公众号