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.自适应混音算法
    参与混音的多路音频信号自身的特点,以它们自身的比例作为权重,从而决定它们在合成后的输出中所占的比重。
    具体的原理可以参考这篇论文:快速实时自适应混音方案研究。
    这种方法对于音轨路数比较多的情况应该会比线性叠加后求平均法要好,但是可能会引入噪音。

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

猜你喜欢

转载自blog.csdn.net/shuangmu9768/article/details/125145341