【Matlab】PCM语音编解码
一.绪论
1.1 研究背景
?? 随着信息技术的快速发展,现代通信技术,特别是语音信号处理技术,已广泛应用于无线通信、军事通信、蓝牙通信等一系列专用通信系统。压缩编码技术是语音信号处理过程中非常重要的环节,可分为波形编码、参数编码和混合编码三类。脉冲编码调制(即脉冲编码)PCM,Pluse Code Modulation)波形编码在语音信号处理过程中应用最广泛,是数字通信系统发展的飞跃。
1.2 PCM技术研究现状
??脉冲编码调制的概念是1937年法国工程师AlecReeres最早提出的。随着集成电路技术的快速发展,超大型集成电路PCM编辑和解码器的出现使其在光纤通信、数字微波通信、卫星通信、信号处理、军事和民用电子技术领域发挥着越来越重要的作用。PCM它是一种数字化模拟语音信号的技术,也是一种语音波形编码。广泛应用于通信、计算机、数字仪表、遥控遥测等领域,其应用广度和深度也在不断扩大和深化。随着全球数字化和信息化的不断推进,脉冲编码调制将有更好的发展和应用前景。
??通常在语音通信中使用8位PCM编码可以保证令人满意的通信质量。典型电话信号的抽样频率为8万Hz。因此,当使用这种不均匀量化编码器时,典型的数字电话传输率为64 kb/s。
??在计算机应用中,能达到最高保真水平的是PCM编码广泛应用于材料保存和音乐欣赏,CD、DVD以及我们常见的 WAV应用于文件中。因此,PCM约定俗成无损编码,因为PCM代表数字音频中最好的保真水平,并不意味着PCM确保信号绝对保真,PCM只有最大限度的无限接近。要算一个PCM音频流的码率很容易,采样率值×采样大小值×声道数 bps。采样率为44.1KHz,采样大小为16bit,双声道的PCM编码的WAV文件的数据速率是 44.1K×16×2 =1411.2 Kbps。我们常见的Audio CD就采用了PCM光盘的容量只能容纳72分钟的音乐信息。
1.3 研究内容
??本设计针对PCM探讨编解码及其特点,并以编解码为基础MATLAB对PCM模拟通信系统的研究主要包括以下部分: ①利用Matlab编写PCM编解码相关函数程序,并调用PCM编解码函数,以正弦波和鸟的语音信号为输入信号,实现模拟和验证PCM编解码的正确性。 ②采用Matlab中的Simulink进行PCM编解码模拟、噪声影响和性能分析。 ③采用GUI语音输入完成界面操作,PCM编码,PCM解码、语音还原输出等一系列操作。这里调用①实现上述功能的程序。
二. PCM编解码的基本原理
2.1 PCM语音编码原理
??通常,我们将从模拟信号抽样、量化到转换为二进制符号的基本过程称为脉冲编码调制和脉冲编码调制。PCM编码过程实际上是抽样-量化-编码语音信号的过程。它是将模拟信号转换为二进制信号的常用方法。PCM编码的具体步骤如下: ??①根据信号本身的频率特征(如正弦信号根据采样定理以信号带宽2倍以上的频率提取抽样值,语音信号根据自身频率提取抽样值)Fs,为了准确表示信号,通常需要保留10kHz以下频谱成分,G.711标准中规定PCM的抽样频率为8kHz)进行抽样 ??②量化模拟信号的每个抽样值的本质是用数字量来表示时域中离散的每个抽样值。在这个过程中,量化精度会产生量化误差,量化精度越高,自然量化误差越小。常用的量化方法有两种:均匀量化和不均匀量化。 ??由于量化器信噪比公式均匀量化(S/N)=M由此可见,随着量化电平数M的增加,量化器的信噪比显著提高。当输入小信号时,量化间隔会变小,量化噪声的平均功率会变小。此时,小信号的量噪比难以满足要求;由于语音信号中小电压的可能性较大,且不均匀量化噪声对大小信号的影响大致相同,因此,采用不均匀量化来提高语音信号中小信号的量噪比。 ??在PCM语音编码主要是先压缩抽样值,然后均匀量化,实现不均匀量化,通常采用8位PCM编码来保证PCM编解码系统的通信质量。 ??③在PCM在编码中,一般采用A压缩法压缩抽样值,即具有以下特征的压缩法:
??y表示归一化压缩机的输出电压,x表示归一化压缩机的输入电压,A为了压缩和扩展系数,不同国家的标准值A的值也不同。在中国和欧洲被广泛使用A=87.56A压缩律(即13折线律)使曲线在原点附近的斜率等于16,使16折线简化为只有13段,每个转折点前后的1/2,而PCM的8位量化编码中就便用到了这一特性,其特性曲线如下图2-1所示:
??在上述编码方法中,虽然段内代码按量化间隔均匀编码,但不同段落的量化间隔因斜率和长度不同而不同。其中第1和2段最短,斜率最大,其横坐标x的归一化动态范围只有1/128。将其等分为16段后,每段的动态范围仅为(1/128) ? (1/16) = 1/2048。这是最小量化间隔,最小量化间隔(1/2048)称为一个量化单位。第八段最长,横坐标x的动态范围为1/2。每段长度为1/32度为1/32。若采用均匀量化,仍希望对小电压保持1/2048的动态范围,则需使用11位码组。现在不均匀量化只需要7位。
??如下图所示PCM编码原理框图,首先通过冲激脉冲对编码器中的模拟信号进行抽样,得到抽样时间上的信号抽样值。这个抽样值仍然是一个模拟量。在定量之前,通常使用保持电路进行短期保存,以便电路有时间定量。 ??在实际电路中,抽样和维护电路通常被称为抽样维护电路。图2-2中的量化器将模拟抽样信号转换为离散数字,然后在编码器中进行二进制编码。这样,每个二进制码组都代表一个定量的信号抽样值。常用的编码方法有逐步比较等。常用的二进制码包括天然二进制码和折叠二进制码。
2.2 PCM语音解码原理
??接收端实现PCM解码原理框图如图2-3所示,其主要原理是逐步比较A/D转换。
??输入本地译码器的记忆电路c7值后,恒流源产生下次比较所需的权值电流Iw。输出编码器c8值后,抽样值的编码已经完成,因此比较器需要等待下一个抽样值到达,不需要恒流源产生新的权值电流。 ??本地译码器部分仍保留在接收端的译码器中。由记忆电路接收发送的码组。当记忆电路接收码组的最后一个时c8后,恒流源产生另一个权值电流,相当于最后一个间隔的中间值。由于编码器中的比较器只是抽样的绝对值,当地的翻译器只产生正值电流,因此在接收器的翻译中,最后一步是基于接收码组的第一个c1值控制输出电流的正负极性。可获得接收端PCM语音解码。
三.软件设计
3.1信号生成和采样
??如图3-1所示(正弦波)信号生成和采样部分的代码。结合奈奎斯特采样定理产生的信号频率(2万Hz)确定信号的采样频率应大于4万Hz,这里选择的信号采样频率为8万Hz,采样前后对比代码和信号分别如图3-1和图3-2所示。此处选用max函数计算信号采样后幅度的极值PCM准备编码过程中的量化。
3.2 PCM编码
PCM编码的程序设计采用调用PCM编码函数的方法来实现。该编码函数分为三个部分:采样信号的量化,段落码判断和段内码判断,分别如图图3-4,图3-5及图3-6所示。通过如图3-7所示程序调用,结果如图3-8所示。
3.3 PCM解码
根据PCM解码的相关原理,可设计出PCM解码函数如图3-9所示,调用代码如图3-10所示,解码效果图如图3-11所示。
3.4 PCM编解码的Simulink实现
由PCM编解码原理,可设计出如图3-12所示的PCM编解码系统。
在图3-12中,我们以一个幅值为1,频率为1Hz的正弦波为例,先通过量化模块将正弦波量化,然后将量化后的信号通过对其进行编码,译码和解码,并设置其采样8位2进制编码,3位2进制解码,随后将解码过后的信号通过一个低通滤波器,滤除其中的高频噪声,从而将原来量化过后的信号在[0,1]区间上进行进行还原。
3.5 PCM编解码的GUI实现
此处采用GUI界面操作完成语音输入,PCM编码,PCM解码,语音还原输出,界面如图3-17所示,语音输入与语音还原输出后的对比图如图3-18所示。语音输入部分采用matlab内部自带的鸟叫声作为输入。
四.性能分析
4.1 具体信号分析
此处主要对该信号进行失真度分析的测试,如图3-19所示。可得到失真度的大小为0.002321,说明对应具体信号而言,PCM编解码后的输出信号还原度较高。
4.2 语音信号分析
根据图3-19所示程序,同样可以得到该语音信号的失真度为0.018,说明多频率混合信号的PCM编解码输出信号还原度比单频信号要略低。
附录代码
.m文件说明: 编解码函数: pcmcoding,pcmdecoding 运行顺序: xinhaocaiyang pcmbianma pcmjiema analysis 推荐直接GUI操作 project3e100.m是设计GUI界面的,直接点project3e100.fig就好了
注:simulink.slk是2018版的matlab编写的,要运行的话需要用2018以上的matlab版本
编码函数(pcmcoding.m)
function code=PCMcoding(S) z=sign(S); MaxS=max(abs(S)); S=abs(S/MaxS); %对采样信号S进行归一化 Q=2048*S; %对采样信号S进行量化,分为2048个区间, %采样13折线律作为压缩律进行非均匀量化 code=zeros(length(S),8); %代码存储
矩阵(全零) % 段落码判断程序 for i=1:length(S) if (Q(i)>=128)&&(Q(i)<=2048) code(i,2)=1; %对段位码的第一位进行判断 end if (Q(i)>32)&&(Q(i)<128)||(Q(i)>=512)&&(Q(i)<=2048) code(i,3)=1; %对段位码的第二位进行判断 end if (Q(i)>=16)&&(Q(i)<32)||(Q(i)>=64)&&(Q(i)<128)||(Q(i)>=256)&&(Q(i)<512)||(Q(i)>=1024)&&(Q(i)<=2048) code(i,4)=1; %对段位码的第三位进行判断 end end %段内码判断程序 N=zeros(length(S)); for i=1:length(S) N(i)=bin2dec(num2str(code(i,2:4)))+1; %判断该量化值所在的段位 end a=[0,16,32,64,128,256,512,1024]; b=[1,1,2,4,8,16,32,64]; for i=1:length(S) q=ceil((Q(i)-a(N(i)))/b(N(i))); %求段内码(10进制) if q==0 code(i,(5:8))=[0,0,0,0]; else k=num2str(dec2bin(q-1,4)); %进行段内码10进制与2进制之间的转换 code(i,5)=str2num(k(1)); code(i,6)=str2num(k(2)); code(i,7)=str2num(k(3)); code(i,8)=str2num(k(4)); end if z(i)>0 %判断编码的正负(8位码组的第1位) code(i,1)=1; elseif z(i)<0 code(i,1)=0; end end code = reshape(code', 1, []); end
解码函数(pcmdecoding.m)
function s=PCMdecoding(encode, max)
encode=(reshape(encode',8,length(encode)/8))'; %对码元进行重组,每8个为一组
l=size(encode,1);
a=[0,16,32,64,128,256,512,1024]; %量化区间
b=[1 1 2 4 8 16 32 64]; %段落量化间隔
c=[0 1.5:15.5]; %段内量化间隔
for i=1:l
x=encode(i,1);
T=bin2dec(num2str(encode(i,(2:4))))+1; %2进制与10进制之间转换,求所在段(10进制)
Y=bin2dec(num2str(encode(i,(5:8)))); %2进制与10进制之间转换,求段内所在位置(10进制)
if Y==0
k(i)=a(T)/2048;
else
k(i)=(a(T)+b(T)*c(Y))/2048;
end
if x==0
s(i)=-k(i);
else
s(i)=k(i);
end
end
s = s*max;
end
信号采样(xinhaocaiyang.m)
clear;clc;
T=0.0005;
t=-0.01:T:0.01;
fs=10000; %取采样频率为10000Hz
sdt=1/fs;
t1=-0.01:sdt:0.01;
xt=sawtooth(2*pi*50*t)+sawtooth(2*pi*100*t);
st=sawtooth(2*pi*50*t1)+sawtooth(2*pi*100*t1);
maximum = max(abs(st));
% 原始信号
figure;
subplot(2,1,1);plot(t,xt);title('原始信号');grid on;
subplot(2,1,2);stem(t1,st,'.');title('抽样信号');grid on;
PCM编码(pcmbianma.m)
pcm_encode = PCMcoding(xt);
figure;
stairs(pcm_encode);
axis([0 200 -2 2]);
title('PCM 编码');
grid on;
PCM解码(pcmjiema.m)
pcm_decode = PCMdecoding(pcm_encode, maximum);
figure;
subplot(2,1,1);plot(t, pcm_decode);
title('PCM 译码');grid on;
subplot(2,1,2);plot(t,xt);
title('原始信号');grid on;
结果分析(analysis.m)
da=0;
for i=1:length(t)
dc=(xt(i)-pcm_decode(i))^2/length(t);
da=da+dc;
end
fprintf('失真度是:%.6f\n',da);
GUI(project3e100.m)
左侧的PCM只是完成解码过程,输出需点击“PCM正弦波输出”按钮。 完整工程文件已上传到博客资源当中。