1.什么是 PCM ?
PCM 全称 Pulse-Code Modulation,就是脉冲调制编码。简单来说就是一种用数字表示采样模拟信号的方法。
2.PCM 数据的三个重要步骤 ?
采样(Sampling) 量化(Quantization) 编码(Coding)
2.1 采样
通常自然界的声音可以通过一条曲线在坐标中显示连续的模拟信号表示.
g) 为了更加容易理解 PCM,选取其中的一个波形,假设这一个波形表示一秒的音频模拟信号。则采样可以如下图所示:
其中红色的曲线表示原始信号;蓝色垂直线段表示是当前时间点对原始信号的一次采样。采样是一系列基于振幅的样本;这也是为什么采样过程被称为 PAM 的原因。 PAM(Pulse Amplitude Modulation)是一系列离散样本的结果。
采样率(Sample rate)每秒钟采样次数,单位 Hz. 根据场景的不同,采样率也会有所不同,采样率越高,那么采样的声音就更加的接近原始声音,声音的还原度就越高,质量越好,同时占用的空间也会越大。例如,通话时的采样率为 8000Hz,常用的媒体采样率为 44100Hz.
2.2 量化
原始信号采样后,需要通过量化来描述采样数据的大小.
量化处理过程,就是将时间连续的信号,处理成时间离散的信号,并用实数表示。这些实数将被转换为二进制数用于模拟信号的存储和传输.
在图例中,如果说采样是画垂直线段的话,那么量化就是画水平线,用于衡量每次采样的数字指标:
每条横线表示一个等级(level),为了更好的描述量化过程.引入**位深(bit-depth)**概念:用来描述存储数字信号值的 bit 数.
常用的模拟信号位深有:
8-bit:2^8 = 256 levels,有 256 个等级可以用于衡量真实的模拟信号.
16-bit:2^16 = 65,536 levels,有 65,536 个等级可以用于衡量真实的模拟信号.
32-bit:2^32 = 4294967296 levels,有 4294967296 个等级可以衡量真实的模拟信号. 其中 16-bit 的最常见。显而易见位深越大对模拟信号的描述将越真实,对声音的描述更加准确.
量化的过程就是将一个平顶(同一个高度)样本四舍五入到一个可用最近 level 描述的过程。如图中黑色加粗梯形折线。量化过程中,我们将尽量让每个采样和一个 level 匹配,因为每个 level 都是表示一个 bit 值。
2.3 编码
编码就是将每个 sample 数据转换成二进制数据,该数据就是 PCM 数据。PCM 数据可以直接存储在介质上,也可以在经过编解码处理后进行存储或传输。
PCM 数据常用量化指标: 采样率、位深、声道数、采样数据是否有符号(有符号的采样数据不能使用无符号的方式播放)、字节序(表示 PCM 数据是用大端存储还是小端存储,通常是小端存储). 例如: ffmpeg 常见的 PCM 数据格式 s16le,它表示有符号的 16 位小端pcm 数据.
3.PCM 数据的存储结构
例如一段有符号的 8-bit 的 pcm 数据:
+---------+-----------+-----------+----
binary | 0010 0000 | 1010 0000 | ...
decimal | 32 | -96 | ...
+---------+-----------+-----------+----
其表示的采样范围是 -128 ~ 127. 当含有多通道时候 PCM 数据就会交叉排列(通常)以双声道为例:
+---------+-----------+-----------+-----------+-----------+----
FL | FR | FL | FR | FL |
+---------+-----------+-----------+-----------+-----------+----
对于 8-bit 有符号的 PCM 数据而言,上图表示第一个字节存放第一个左声道数据(FL),第二个字节放第一个右声道数据(FR),第三个字节放第二个左声道数据(FL)…
不同的驱动程序对于多声道数据的排列方式可能稍有区别,下面是常用的声道排列地图:
2: FL FR (stereo)
3: FL FR LFE (2.1 surround)
4: FL FR BL BR (quad)
5: FL FR FC BL BR (quad + center)
6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR)
7: FL FR FC LFE BC SL SR (6.1 surround)
8: FL FR FC LFE BL BR SL SR (7.1 surround)
知道了 PCM 数据的结构,我们可以分离出左右声道的数据,进而算出左右声道的音量大小.完成如下图示功能(红色圈出部分):
4.音量的调整
音量的表示实际上就是量化过程中每个采样数据的 level 值,只要适当的增大或者缩小采样的 level 就可以达到更改音量的目的。但需要说明的是,并不是将 level 值*2 就能得到两倍于原声音的音量.
数据溢出: 我们都知道每个采样数据的取值范围是有限制的,例如一个 signed 8-bit 样本,取值范围为-128 ~ 127,值为 125 时,放大两倍后的值为 250,超过了可描述的范围,此时发生了数据溢出。这个时候就需要我们做策略性的裁剪处理,使放大后的值符合当前格式的取值区间.
对数描述: 平时表示声音强度我们都是用分贝(db)作单位的,声学领域中,分贝的定义是声源功率与基准声功率比值的对数乘以 10 的数值。根据人耳的心理声学模型,人耳对声音感知程度是对数关系,而不是线性关系。人类的听觉反应是基于声音的相对变化而非绝对的变化。对数标度正好能模仿人类耳朵对声音的反应。所以用分贝作单位描述声音强度更符合人类对声音强度的感知。前面我们直接将声音乘以某个值,也就是线性调节,调节音量时会感觉到刚开始音量变化很快,后面调的话好像都没啥变化,使用对数关系调节音量的话声音听起来就会均匀增大.
如下图,横轴表示音量调节滑块,纵坐标表示人耳感知到的音量,图中取了两块横轴变化相同的区域,音量滑块滑动变化一样, 但是人耳感觉到的音量变化是不一样的,在左侧也就是较安静的地方,感觉到音量变化大,在右侧声音较大区域人耳感觉到的音量变化较小:
对此我们可以使用 tan 函数来模拟对数变换,达到近似效果,比如 x * tan(x/100);其中 x 表示当前的分贝值.
至于音频采集可以查看此篇文章.音频采集
更多多媒体文章欢迎关注我的公众号 CodeEngine
- END -