语音PCM

脉冲编码调制(Pulse Code Modulation, PCM)是语音信号的重要编码方式之一。语音编码是将模拟信号转为数字信号的语音通信技术,分为波形编码、参量编码和混合编码等类型。波形编码针对语音波形进行,在降低量化样本比特数的同时保持了良好的语音质量。

PCM编码就是一种波形编码方法,通过每隔一段时间对模拟语音信号采样,将其取整量化,用二进制码表示抽样量化的幅值,实现将语音数字化的编码调制。

PCM是现代数字传输系统普遍采用的调制方式。PCM可以向用户提供多种业务,包括2M~155 Mbit/s速率的数字数据专线业务和语音、图像、远程教学等业务,适用于传输速率要求高、需要更高带宽的应用,在语音信号处理中有着广泛的运用。

PCM分为抽样、量化和编码三个步骤,如下图所示。下面对此过程进行介绍

pcm的重采样 java_音视频

1.抽样

语音信号具有频率和振幅特征,频率对应于时间轴,振幅对应于电平轴,而由于存储空间有限,数字编码过程中,必须对正弦信号进行抽样。抽样是把模拟信号以其信号带宽2倍以上的频率提取样值,变为在时间轴上离散的抽样信号的过程。对一个正弦信号进行抽样获得的抽样信号是一个脉冲幅度调制信号,对抽样信号进行检波和平滑滤波,即可还原出原来的模拟信号。
抽样过程就是抽取某点的频率值的过程。显然,在1s内抽取的点越多,获取的频率信息越丰富。为了复原波形,一次振动中必须有2个点的采样,人耳能够感觉到的最高频率为20kHz,因此要满足人耳的听觉要求,则需要至少每秒进行40000次采样,即采样率为44. 1 kHz。光有频率信息是不够的,还必须获得该频率的能量值并量化,用于表示信号强度。量化电平数为2的整数次幂,常用16 bit的采样大小即26。例如对一个语音信号进行8次采样,采样点分别对应的能量值分别为Al~A8,使用2bit的采样大小只能保留Al ~A8中4个点,而进行3bit的采样则刚好记录下8点的所有信息。采样率和采样大小的值越大,记录的波形越接近原始信号。
抽样可以看作是周期性单位冲激脉冲和语音模拟信号的相乘,结果为一系列的周期性冲激脉冲,脉冲的高度与模拟信号的取值成正比。若抽样速率足够大,则离散的冲激脉冲可以完全代替模拟信号,即由这些离散信号可恢复出原信号。
抽样定理表述为:设有最高频率小于pcm的重采样 java_音视频_02的信号pcm的重采样 java_语音识别_03,将周期为pcm的重采样 java_pcm的重采样 java_04的冲激脉冲信号pcm的重采样 java_pcm的重采样 java_05与其相乘进行抽样,则pcm的重采样 java_语音识别_03被抽样信号完全确定。
pcm的重采样 java_非均匀量化_07

pcm的重采样 java_语音识别_03的傅里叶变换:
pcm的重采样 java_pcm的重采样 java_09
其中,
pcm的重采样 java_非均匀量化_10
由上可见,当频率间隔pcm的重采样 java_pcm的重采样 java_11时, pcm的重采样 java_pcm的重采样 java_12包含的每个原信号频谱间不重叠,这样就能用低通滤波器从抽样信号中恢复原信号。
由于实际的滤波器不够理想,边缘不够陡峭,因此实际抽样频率需要比pcm的重采样 java_pcm的重采样 java_13大些,如典型的电话信号最高频率限制在3400 Hz,而抽样频率一般取为8kHz

2.量化

抽样信号虽然是时间轴上离散的信号,但仍是模拟信号,其值在一定的取值范围内可有无限多个值。显然,对无限个样值给出数字码组来对应是不可能的。为了实现以数字码表示样值,必须采用四舍五入的方法把样值分级取整,使一定取值范围内的样值由无限多个值变为有限个值。这一过程称为量化。
量化后的抽样信号与量化前相比较有所失真,且不再是模拟信号。这种量化失真在接收端还原模拟信号时表现为噪声,称为量化噪声。量化噪声的大小取决于把样值分级取整的方式,分的级数越多,即量化级差或间隔越小,量化噪声也越小。
设模拟抽样信号为pcm的重采样 java_语音识别_14 ,抽样值仍为取值连续的变量。用pcm的重采样 java_pcm的重采样 java_15个不同的二进制数字码元来表示抽样值大小,则共有pcm的重采样 java_音视频_16个不同的抽样值。
将抽样范围划分为pcm的重采样 java_pcm的重采样 java_17个区间,每个区间用一个电平表示。这样,共有pcm的重采样 java_pcm的重采样 java_17个离散电平,成为量化电平。M个抽样区间等间隔划分,为均匀量化,否则为非均匀量化。量化信号表示为:
pcm的重采样 java_语音识别_19
若为均匀量化,量化值可取量化间隔的中点:
pcm的重采样 java_PCM_20

3.编码

量化后的抽样信号在一定范围内仅有有限个可取的样值,且信号正负幅度分布的对称性使正负样值个数相等,正负向的量化级对称分布。若将有限个量化样值绝对值从小到大排列,依次赋予十进制数字,以pcm的重采样 java_音视频_21pcm的重采样 java_语音识别_22号为前缀,则量化后的抽样信号就转化为按时序排列的十进制数字码流。将数字转换为二进制编码,根据十进制代码总个数确定二进制位数,即字长。这样把量化的抽样信号变换成给定字长的二进制码流的过程称为编码。
二进制码可经受较高的噪声电平的干扰,并且易于再生,因此PCM一般采用二进制码。
对于pcm的重采样 java_pcm的重采样 java_23个量化电平,可以用pcm的重采样 java_pcm的重采样 java_24位二进制码表示,其中每一种组合为一个码字。在点对点通信或短距离通信中,采用pcm的重采样 java_pcm的重采样 java_25位码已基本满足质量要求,而对于干线远程的全网通信,一般需要经过多次转接,有较高的质量要求,目前多采用8位编码PCM设备。

量化及代码

语音信号的特点就是小信号较重要,需要提高小信号的量化信噪比。所以需要对信号进行非线性压缩,改变大信号与小信号比例关系。

pcm的重采样 java_非均匀量化_26


pcm的重采样 java_语音识别_27


此时,pcm的重采样 java_语音识别_28就是[1/128,1/64,1/32,1/16,…,1/2]每段间隔都有一个重建值pcm的重采样 java_音视频_29

正负(1bit)段落码(3bit)段内电平码(4bit)

比如:输入x (-4096<x<4096)

正负(1bit):

大于零,1;小于零,0;

pcm的重采样 java_语音识别_30

%实验要求一:PCM编解码实验
clear all;
close all;
[x fs ]= audioread('C6_1_y.wav');  
v=1;
xx=x/v;
sxx=floor(xx*4096);
y=pcm_encode(sxx);
yy=pcm_decode(y,v)';

nq=sum((x-yy).*(x-yy))/length(x);
sq=mean(yy.^2);
snr=(sq/nq);
t=(1:length(x))/fs;
subplot(211)
plot(t,x/max(abs(x)))
axis tight
title('(a)编码前语音')
xlabel('时间/s')
ylabel('幅度')
subplot(212)
plot(t,yy/max(abs(yy)))
axis tight
title('(b)解码后语音')
xlabel('时间/s')
ylabel('幅度')
snrq=10*log10(mean(snr))
figure;
plot(t,abs(x-yy));
title('编码前后误差')

encoder

%PCM编码函数
function[out]=pcm_encode(x)
n=length(x);                                                     %-4096<x<4096
for i=1:n
    if x(i)>0
       out(i,1)=1;                                               %根据符号输出第1位量化结果
    else
       out(i,1)=0;
    end

    if abs(x(i))>=0 & abs(x(i))<32                               %根据输入范围输出后2-4位
         out(i,2)=0; out(i,3)=0; out(i,4)=0; step=2;st=0; 
    elseif 32<=abs(x(i)) & abs(x(i))<64
         out(i,2)=0; out(i,3)=0; out(i,4)=1; step=2;st=32; 
    elseif 64<=abs(x(i)) & abs(x(i))<128
         out(i,2)=0; out(i,3)=1; out(i,4)=0; step=4;st=64;
    elseif 128<=abs(x(i)) & abs(x(i))<256
         out(i,2)=0; out(i,3)=1; out(i,4)=1; step=8;st=128;
    elseif 256<=abs(x(i)) & abs(x(i))<512
         out(i,2)=1; out(i,3)=0; out(i,4)=0; step=16;st=256;
    elseif 512<=abs(x(i)) & abs(x(i))<1024
         out(i,2)=1; out(i,3)=0; out(i,4)=1; step=32;st=512;
    elseif 1024<=abs(x(i)) & abs(x(i))<2048
         out(i,2)=1; out(i,3)=1; out(i,4)=0; step=64;st=1024;
    elseif 2048<=abs(x(i)) & abs(x(i))<4096
         out(i,2)=1; out(i,3)=1; out(i,4)=1; step=128;st=2048;

    else
         out(i,2)=1; out(i,3)=1; out(i,4)=1; step=128;st=2048;
    end

    if(abs(x(i))>=4096)                                            %超出最大幅值的量化结果
       out(i,2:8)=[1 1 1 1 1 1 1];
    else                                                           %未超出,计算后四位
        tmp=floor((abs(x(i))-st)/step);
        t=dec2bin(tmp,4)-48;                                       %十进制转为4位二进制字符串
        out(i,5:8)=t(1:4);
    end
end
out=reshape(out',1,8*n);                                           %调整为长为8n的行向量

decoder

%PCM解码函数
function[out]=pcm_decode(ins,v)
n=length(ins);                         %输入为8位PCM采样信号

in=reshape(ins',8,n/8)';               %调整矩阵行列数
slot(1)=0;                             %量化幅值
slot(2)=32;
slot(3)=64;
slot(4)=128;
slot(5)=256;
slot(6)=512;
slot(7)=1024;
slot(8)=2048;

step(1)=2;                              %步长
step(2)=2;
step(3)=4;
step(4)=8;
step(5)=16;
step(6)=32;
step(7)=64;
step(8)=128;


for i=1:n/8
    ss=2*in(i,1)-1;                     %解码符号位
    tmp=in(i,2)*4+in(i,3)*2+in(i,4)+1;  %解码2-4位
    st=slot(tmp);
    dt=(in(i,5)*8+in(i,6)*4+in(i,7)*2+in(i,8))*step(tmp)+0.5*step(tmp);   %解码5-8位
out(i)=ss*(st+dt)/4096*v;               %解码结果相加,乘以量化电平
end

pcm的重采样 java_音视频_31


pcm的重采样 java_非均匀量化_32

Reference:梁瑞宇等. 语音信号处理实验教程[M]. 北京: 机械工业出版社, 2016.2.