概述
【Matlab】PCM语音编解码
一.绪论
1.1 研究背景
随着信息技术的高速发展,现代通信技术,尤其是语音信号处理技术已经在日常生活中得到十分广泛的运用,如无线通信,军事通信,蓝牙通信等一系列专用通信系统等。而在语音信号处理的过程中十分重要的一环便是压缩编码技术,可分为三类:波形编码,参数编码及混合编码等。其中以脉冲编码调制(即PCM,Pluse Code Modulation)为代表的波形编码在语音信号处理的过程中应用最为广泛,是数字通信系统发展的一次飞跃。
1.2 PCM技术的研究现状
脉冲编码调制的概念是1937年由法国工程师AlecReeres最早提出来的。随着集成电路技术的飞速发展,超大规模集成电路的PCM编、解码器出现,使它在光纤通信、数字微波通信、卫星通信、信号处理、军事及民用电子技术领域发挥着越来越重要的作用。PCM是一种将模拟语音信号进行数字化的技术,同时也是语音波形编码的一种。目前广泛应用于通信、计算机、数字仪表、遥控遥测等领域,其应用广度和深度也在不断地扩展和深化。随着全球数字化、信息化的不断推进,脉冲编码调制会有更加良好的发展、应用前景。
在语音通信中,通常采用8位的PCM编码就能够保证满意的通信质量。典型电话信号的抽样频率是8000Hz。故在采用这类非均匀量化编码器时,典型的数字电话传输比特率为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.56的A压缩律(即13折线律),它使得曲线在原点附近的斜率等于16,使16段折线简化成只有13段,且每一段转折点前后A律曲线的斜率比值为1/2,而PCM的8位量化编码中就便用到了这一特性,其特性曲线如下图2-1所示:
在13折线律中采用的折叠码有8位。其中第一位c1表示量化值的极性正负。后面的7位分为段落码和段内码两部分,用于表示量化值的绝对值。其中第2至4位(c2 c3 c4)是段落码,共计3位,可以表示8种斜率的段落;其他4位(c5 ~ c8)为段内码,可以表示每一段落内的16种量化电平。段内码代表的16个量化电平是均匀划分的。所以,这7位码总共能表示27 = 128种量化值。在下面的表2-1中给出了段落码和段内码的编码规则。
在上述编码方法中,虽然段内码是按量化间隔均匀编码的,但是因为各个段落的斜率不等,长度不等,故不同段落的量化间隔是不同的。其中第1和2段最短,斜率最大,其横坐标x的归一化动态范围只有1/128。再将其等分为16小段后,每一小段的动态范围只有(1/128) (1/16) = 1/2048。这就是最小量化间隔,后面将此最小量化间隔(1/2048)称为1个量化单位。第8段最长,其横坐标x的动态范围为1/2。将其16等分后,每段长度为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所示(正弦波)。由奈奎斯特采样定理结合所产生的信号的频率(2000Hz)确定信号的采样频率要大于4000Hz,此处选取的信号采样频率为8000Hz,代码和信号采样前后对比分别如图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('失真度是:%.6fn',da);
GUI(project3e100.m)
GUI设计网上教程很多,这里贴1张效果图。
左侧的PCM只是完成解码过程,输出需点击“PCM正弦波输出”按钮。
完整工程文件已上传到博客资源当中。
最后
以上就是细心小土豆为你收集整理的【Matlab】基于A律13折线的PCM语音编解码系统(GUI设计、simulink、附完整代码)的全部内容,希望文章能够帮你解决【Matlab】基于A律13折线的PCM语音编解码系统(GUI设计、simulink、附完整代码)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复