Android 音频(一) _ 采样量化编码 & AudioRecord 录制音频

本文详细介绍了音频信号如何通过采样、量化和编码转换为计算机可处理的离散数据,重点讲解了AudioRecord在Android中的使用,包括其参数设置、录制过程和音频优化,以及与MediaRecorder的区别和应用场景。
摘要由CSDN通过智能技术生成

微信截图_20210613102553.png

计算机只能处理0和1,即离散值。音频这种模拟信号得转换成离散值才能被计算机处理。这个转化过程称为模拟信号数字化,分为三个步骤:

1. 采样

采样是对连续信号在时间上进行离散,即按照特定的时间间隔在原始的模拟信号上逐点采集瞬时值。采样的可视化效果如下图所示:

微信截图_20210613103146.png

原本连续的曲线被一根根离散的竖直线条代替。这些线条越密集,将它们相连后形成的曲线就越接近原始模拟信号。

物理中用采样频率来表示采样的密集程度,即每秒采样次数(采样数/秒),它用赫兹(Hz)表示

2. 量化

虽然连续值已被采样成若干离散值,但每个离散值的取值可能有无限多个。为了给每一个离散值都对应一个数字码,必须将无限种取值转化为有限种取值(对于只能处理二进制的计算机来说,取值的可能数应该是2的倍数)。物理中把这种通过四舍五入分级取整的方法称为量化。量化后的数字信号如下图所示:

微信截图_20210613111046.png

量化后的音频变得死板有棱角,就好像人类和机器人的差别。

3. 编码

模拟信号经过采样变成离散值,每一个离散值经过量化都对应一个二进制,将这些二进制按时间序列组合在一起就称为编码

经过采样量化编码形成的是音频的原始数据,这种原始数据格式称为PCM(Pulse Code Modulation),即是采样量化编码的英文表示。

.pcm 后缀的文件是非常非常大的,这增加了存储和网络传输的成本。遂 PCM 这样原始的无损音频还得经过一次压缩编码

音频存在冗余信息,才能被压缩。比如人耳能辨识的声音频率范围为20Hz~20KHz,该频率以外的声音都是冗余信息。再比如强弱信号同时出现,强弱差距过大,以至于弱信号完全被掩盖,弱信号就是冗余信息。

音频有很多压缩编码的格式,以下是 Android 官方支持的格式: 微信截图_20210613114558.png

在移动端最为常用的格式是 AAC,即 Advanced Audio Coding,是一种专为声音数据设计的文件压缩格式。它采用了更加高效的编码方式,使得它拥有和 MP3 相当的音质及更小的体积。

压缩编码由两种执行方式,交由 GPU 或是 CPU 执行,前者称为硬编码后者称为软编码,硬编码速度快,但兼容差,会存在编码失败的情况。软编码速度慢,但兼容性好。

录制 PCM 音频

Android 提供了两种录制音频的方式:1. MediaRecorder 2. AudioRecord

如果没有优化音频的需求,完全可以使用 MediaRecorder 直接输出 AAC 格式的音频。

而音频优化,比如降噪,增益算法都是基于 PCM 格式的。这就不得不使用 AudioRecord 来录制音频。

构建 AudioRecord 对象

AudioRecord 的构造函数包含 6 个参数:

  1. 音频源:表示从哪里采集音频,通常是麦克风。
  2. 采样频率:即每秒钟采用次数,44100 Hz是目前所有安卓设备都支持的采样频率。
  3. 声道数:表示声音由几个声道组成,单声道是目前所有安卓设备都支持的声道数。
  4. 量化精度:表示采用多少位二进制来表达一次量化的离散值,通常用 16 位。
  5. 缓冲区大小:表示在内存开辟一块多大的缓冲区用于存放硬件采集的音频数据。

构建 AudioRecord 的模板代码如下:

const val SOURCE = MediaRecorder.AudioSource.MIC //通过麦克风采集音频
const val SAMPLE_RATE = 44100 // 采样频率为 44100 Hz
const val CHANNEL_IN_MONO = AudioFormat.CHANNEL_IN_MONO // 单声道
const val ENCODING_PCM_16BIT = AudioFormat.ENCODING_PCM_16BIT //量化精度为 16 位

var bufferSize: Int = 0 // 音频缓冲区大小
val audioRecord by lazy {
// 计算缓冲区大小
bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_IN_MONO, ENCODING_PCM_16BIT)
// 构建 AudioRecord 实例
AudioRecord(SOURCE, SAMPLE_RATE, CHANNEL_IN_MONO, ENCODING_PCM_16BIT, bufferSize)
}

将构建 AudioRecord 的参数都常量化,以便在其他地方引用。其中缓冲区大小是通过AudioRecord.getMinBufferSize()动态计算的,计算的依据是采样平率、声道数、量化精度。

读取音频数据写入文件

有了 AudioRecord 实例,就可以调用它的方法从硬件设备中读取音频数据了。它提供了 3 个方法来控制音频数据的读取,分别是开始录制startRecording()、读一批音频数据read()、停止录制stop(),这 3 个方法通常用下面的模板来组合:

audioRecord.startRecording()
while(是否继续录制){ audioRecord.read() }
audioRecord.stop()

音频数据的大小以字节为单位,音频数据的读取是一批一批进行的,所以需要一个 while 循环持续不断地读取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值