文章

03.音频数据源之PCM

03.音频数据源之PCM

PCM 基础

声音与音频

声音是波,成为声波,而声波的三要素是频率振幅波形

频率代表音阶的高低(女高音、男低音)单位赫兹(Hz),人耳能听到的声波范围:频率在 20Hz~20kHz 之间;振幅代表响度(音量);波形代表音色。而我们音频处理就是对声波采集成数字信号后进行处理。

音频采集与关键名词

音频采集的过程主要是通过设备设置采样率、采样数,将音频信号采集为pcm(Pulse-code modulation,脉冲编码调制)编码的原始数据(无损压缩),然后编码压缩成 mp3aac 等封装格式的数据。

音频关键知识:

  • 采样率: 一段音频数据中单位时间内(每秒)采样的个数。
  • 位宽: 一次最大能传递数据的宽度,可以理解成放单个采集数据的内存。常有 8 位和 16 位,而 8 位:代表着每个采集点的数据都使用 8 位(1 字节)来存储;16 位:代表着每个采集点的数据都使用 16 位(2 字节)来存储。
  • 声道数: 扬声器的个数,单声道、双声道等。每一个声道都占一个位宽。
![image.png500](https://raw.githubusercontent.com/hacket/ObsidianOSS/master/obsidian/20240602222328.png)

一段时间内的数据大小如何计算?

采样率 x (位宽 / 8) x 声道数 x 时间 = 数据大小(单位:字节)

比如 2 分钟的 CD(采样率为:44100,位宽:16,声道数:2)的数据大小:44100 x (16 / 8) x 2 x 120 = 20671.875 Byte 约为 20.18M。

PCM 数据的基本使用

PCM 数据是如何组成(存储)?

举个例子,分别使用不同的方式存储一段采集数据 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 总共 8 个字节。

  • 8 位单声道: 按照数据采集时间顺序存储,即:0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88
  • 8 位双声道: L声道-R声道-L声道-R声道形式存储,即:0x11(L) 0x22(R) 0x33(L) 0x44(R) ……
  • 16 位单声道: 首先从 维基多媒体:pcm 了解到位宽大于 8 位时,字节的排序方式是有差别的;当使用一个以上的字节表示 PCM 样本时,必须知道字节顺序(大端与小端)。由于低端字节 Intel CPU 的广泛使用,低端字节 PCM 往往是最常见的字节方向。所以: big-endian 存储方式:0x1122 0x3344 0x5566 0x7788; little-endian 存储方式:0x2211 0x4433 0x6655 0x8877。

举个栗子:当位宽为 16 位(2 字节)存储一个采集数据时,如:0x12ab,大端和小端分别是: big-endian: 0x12 0xab; little-endian: 0xab 0x12

  • 16 位双声道: L 声道 -R 声道 -L 声道 -R 声道形式存储:
    • big-endian:0x1122(L) 0x3344(R) 0x5566(L) 0x7788(R)
    • little-endian: 0x2211(L) 0x4433(R) 0x66550(L) 0x8877(R)

Android 终端音频采样介绍

1
2
3
4
5
6
7
8
9
10
11
12
/** 
* @param audioSource 音频来源{@link MediaRecorder.AudioSource};如指定麦克风:MediaRecorder.AudioSource.MIC
* @param sampleRateInHz 采样率{@link AudioFormat#SAMPLE_RATE_UNSPECIFIED},单位Hz;安卓支持所有的设备是:44100Hz
* @param channelConfig 声道数{@link AudioFormat#CHANNEL_IN_MONO};
* @param audioFormat 位宽{@link AudioFormat#ENCODING_PCM_8BIT}
* @param bufferSizeInBytes 采集期间缓存区的大小
*/
public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat,
            int bufferSizeInBytes)

//获取最小缓存区,参数跟AudioRecord保持一致
int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {}

PCM 音频采样数据处理

音频采样数据在视频播放器的解码流程中的位置如下图所示:

![image.png500](https://raw.githubusercontent.com/hacket/ObsidianOSS/master/obsidian/20240602231809.png)
本文由作者按照 CC BY 4.0 进行授权