PCM格式音频

PCM(Pulse Code Modulation)编码,即通过脉冲编码调制方法生成数字音频数据的技术或格式,是一种无损编码格式,是音频模拟信号数字化的一种方法,需要经过采样、量化和编码过程,以实现音频模拟信号数字化。

  • 可以从6个方面描述PCM:
    1.采样率;
    2.符号:表示样本数据是否是有符号位,比如用一字节表示的样本数据,有符号的话表示范围为-128 … 127,无符号就是0 … 255;
    3.字节序:字节序分为大端与小端;
    4.样本大小:决定了每个样本由多少位组成,即前面说到的量化深度,一般16位是最常见的;
    5.声道数:常见的有单声道与双声道。
    6.整形或浮点型:大多数格式的PCM样本数据使用整形表示,然而在一些对精度要求高的应用方面,使用浮点类型表示PCM样本数据。

  • 音调、音量、音色
    音调:声音频率的高低。表示人的听觉分辨一个声音的调子高低的程度。音调主要由声音的频率决定,同时也与声音强度有关
    音量:人主观上感觉声音的大小,由“振幅”(amplitude)和人离声源的距离决定,振幅越大响度越大,人和声源的距离越小,响度越大。(单位:分贝dB)
    音色:又称声音的品质,波形决定了声音的音色。声音因不同物体材料的特性而具有不同特性,音色本身是一种抽象的东西,但波形是把这个抽象直观的表现。音色不同,波形则不同。典型的音色波形有方波,锯齿波,正弦波,脉冲波等。不同的音色,通过波形,完全可以分辨的。

  • 有符号数与无符号数互转(内存中存储的值不变,只是改变了解释这些位置的方式)

    有符号byte转无符号int:
    byte b= -120;
    int a= b & 0xff

    无符号byte转有符号byte:
    byte a=(byte)无符号数 #直接强转

  • 采样精度转换

    无符号8位PCM转有符号16位:
    方式一:((byte)(val+128))<<8
    方式二:(val-128)<<8

    有符号16位PCM转无符号8位:
    方式一:parseInt(255 / (65535 / (val + 32768))
    方式二:(val>>8)+128
    方式三:((val + 32768)>>8) & 0xFF

  • 分贝计算
    dB = 20 * log(A1 / A2) #以无符号16位的数值即可计算出大致的分贝,96.32dB=20*lg(65535);
    A1 = A2 * pow(10 , db/20)
    计算得知:每增大2个分贝,则在原振幅的基础上扩大约1.2589倍;

  • 混音算法
    1.线性叠加后求平均
    优点:不会产生溢出,噪音较小;
    缺点:衰减过大,影响通话质量;
    2.归一化混音(自适应加权混音算法)
    思路:使用更多的位数(32 bit)来表示音频数据的一个样本,混完音后在想办法降低其振幅,使其仍旧分布在16 bit所能表示的范围之内,这种方法叫做归一法;
    方法:为避免发生溢出,使用一个可变的衰减因子对语音进行衰减。这个衰减因子也就代表语音的权重,衰减因子随着音频数据的变化而变化,所以称为自适应加权混音。当溢出时,衰减因子较小,使得溢出的数据在衰减后能够处于临界值以内,而在没有溢出时,又让衰减因子慢慢增大,使数据较为平缓的变化。
    3.从newlc上找到的一个关于PCM脉冲编码的音频信号的混音实现:
    if( data1 < 0 && data2 < 0)
    date_mix = data1+data2 - (data1 * data2 / -(pow(2,16-1)-1));
    else
    date_mix = data1+data2 - (data1 * data2 / (pow(2,16-1)-1));
    4.切割时间片,重采样算法
    可以把各个通道的声音叠到一起,让声音的采样率按倍增加,如果提高声音的播放频率,声音可以正常的播放,声音实现了叠加;如果不想修改声音的播放输出频率,可以通过声音的重采样后输出自己想要的输出频率;
    5.自适应混音算法
    参与混音的多路音频信号自身的特点,以它们自身的比例作为权重,从而决定它们在合成后的输出中所占的比重。
    具体的原理可以参考这篇论文:快速实时自适应混音方案研究。
    这种方法对于音轨路数比较多的情况应该会比线性叠加后求平均法要好,但是可能会引入噪音。

  • 大端模式和小端模式的区别
    大端模式中字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中;
    而与大端存储模式相反,在小端存储模式中,低地址中存放的是字数据的低字节,高地址存放的是字数据的高字节。
    定义数组时,其元素的地址从低到高紧密排列。

### PCM 格式音频的定义和相关技术信息 PCM(Pulse Code Modulation,脉冲编码调制)是一种将模拟音频信号转换为数字信号的基本方法,广泛应用于音频录制、通信系统以及各种多媒体应用中。它通过对模拟信号进行采样、量化和编码三个步骤,生成原始的数字音频数据[^3]。 #### 采样与量化过程 在 PCM 编码过程中,模拟信号首先通过**采样**转化为离散时间信号。采样频率决定了每秒采集信号的次数,常见的如 44.1 kHz(CD 音质)、22.05 kHz(广播音质)、8 kHz(电话音质)等。采样后的信号再经过**量化**处理,将连续幅度值映射到有限数量的离散值上。例如,16 位量化表示每个采样点可以有 65536 个不同的取值范围[^2]。 #### 数据存储格式与容量计算 一个完整的 PCM 文件由多个采样点组成,其文件大小取决于以下几个关键参数:采样频率、采样位数(比特深度)、声道数以及音频时长。具体公式如下: ``` 存储量 = (采样频率 × 采样位数 × 声道数) × 时间 / 8 (单位:字节) ``` 例如,一段 CD 音质音频(44.1kHz、16bit、立体声),其一分钟的数据量为: ``` (44100 × 16 × 2) × 60 / 8 = 10,584,000 字节 ≈ 10.58 MB ``` 这种原始 PCM 数据通常以 `.pcm` 文件扩展名保存,也可以封装在容器格式如 WAV 中[^2]。 #### 声道排列方式 在多声道 PCM 数据中,存在两种主要的排列方式:**交错排列**(Interleaved)和**平面排列**(Planar)。交错排列是指左右声道交替存放,适用于大多数播放器;而平面排列则是先存储所有左声道数据,再存储右声道数据,常见于某些专业音频处理库中。若使用错误的排列方式播放音频,可能导致声音失真或单声道无声的情况[^4]。 #### 示例代码:读取和写入 PCM 数据 以下是一个简单的 C++ 示例,展示如何从二进制文件中读取 PCM 数据并将其转换为可播放的数组形式。 ```cpp #include <fstream> #include <vector> int main() { std::ifstream file("input.pcm", std::ios::binary); if (!file.is_open()) return -1; // 读取整个文件内容到缓冲区 std::vector<int16_t> pcm_data((std::istreambuf_iterator<char>(file)), {}); file.close(); // 此处可以添加音频处理逻辑,例如混音、滤波等操作 // 写回新的 PCM 文件 std::ofstream output("output.pcm", std::ios::binary); output.write(reinterpret_cast<const char*>(pcm_data.data()), pcm_data.size() * sizeof(int16_t)); output.close(); return 0; } ``` #### 应用场景与兼容性 由于 PCM 是未经压缩的原始音频数据,因此它具有极高的保真度,但也占用大量存储空间。WAV 文件本质上就是封装了 PCM 编码的一种容器格式,支持多种采样率和比特深度[^2]。正因为如此,PCM 广泛用于高质量音频处理、语音识别、VoIP 等对延迟敏感但需要高清晰度的应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值