【Matlab】PCM语音编解码


一.绪论

1.1 研究背景

  随着信息技术的高速发展,现代通信技术,尤其是语音信号处理技术已经在日常生活中得到十分广泛的运用。而在语音信号处理的过程中十分重要的一环便是压缩编码技术,可分为三类:波形编码,参数编码及混合编码等。其中以脉冲编码调制(即PCM,Pluse Code Modulation)为代表的波形编码在语音信号处理的过程中应用最为广泛,是数字通信系统发展的一次飞跃。

1.2 PCM技术的研究现状

  脉冲编码调制的概念是1937年由法国工程师AlecReeres最早提出来的。随着集成电路技术的飞速发展,超大规模集成电路的PCM编、解码器出现,使它在光纤通信、数字微波通信、卫星通信、信号处理、军事及民用电子技术领域发挥着越来越重要的作用。

  PCM 即脉冲编码调制 (Pulse Code Modulation)。在PCM 过程中,将输入的模拟信号进行采样、量化和编码,用二进制进行编码的数来代表模拟信号的幅度 ;接收端再将这些编码还原为原来的模拟信号。即数字音频的 A/D 转换包括三个过程 :采样,量化,编码。

  话音PCM的抽样频率为8kHz,每个量化样值对应一个8位二进制码,故话音数字编码信号的速率为8bits×8kHz=64kbps = 8kb/s。量化噪声随量化级数的增多和级差的缩小而减小。量化级数增多即样值个数增多,就要求更长的二进制编码。因此,量化噪声随二进制编码的位数增多而减小,即随数字编码信号的速率提高而减小。

  自然界中的声音非常复杂,波形极其复杂,所以我们常采用的就是脉冲代码调制编码,即PCM编码。在计算机应用中,能够达到最高保真水平的就是PCM编码。需要说明的是,PCM约定俗成了无损编码,因为PCM代表了数字音频中最佳的保真水准,并不意味着PCM就能够确保信号绝对保真,PCM也只能做到最大程度的无限接近。

  目前PCM编码广泛应用于通信、计算机、数字仪表、遥控遥测等领域,其应用广度和深度也在不断地扩展和深化。随着全球数字化、信息化的不断推进,脉冲编码调制会有更加良好的发展、应用前景。

1.3 研究内容

  本次设计针对PCM的编解码及其特点进行探究,并基于MATLAB对PCM通信系统进行仿真,其研究内容主要有以下几个部分:
  ①利用Matlab编写PCM编解码相关函数程序,并调用PCM编解码函数,分别以一个正弦波和三种不同的语音信号(锣声、哈利路亚、笑声)作为输入信号,实现仿真,验证PCM编解码的正确性。
  ②采用Matlab中的Simulink进行PCM编解码仿真,噪声影响与性能分析。
  ③采用GUI界面操作完成语音输入,PCM编码,PCM解码,语音还原输出等一系列操作。


二. PCM编解码的基本原理

2.1 PCM语音编码原理

  通常我们把从模拟信号抽样、量化,直到变换成为二进制符号的基本过程,称为脉冲编码调制,简称脉码调制。PCM编码的过程,实际上就是将一个语音信号进行“抽样-量化-编码”的一个过程。它是将模拟信号变换成二进制信号的一种常用方法。PCM编码的具体步骤如下:
  1)对模拟信号按信号自身的频率特点(如正弦信号依据采样定理以其信号带宽2倍以上的频率提取抽样值,语音信号依据其自身的频率Fs,为精确表示信号,一般要保留10kHz以下的频谱成分,G.711标准中规定PCM的抽样频率为8kHz)进行抽样
  2)对该模拟信号的各个抽样值进行量化,其实质是能够用数字量来表示在时域上离散的各个抽样值。在该过程中,会因为量化精度而产生量化误差,量化精度越高自然量化误差也就越小。而常用的量化方式有均匀量化和非均匀量化两种。
  由于在均匀量化时,由量化器信噪比公式(S/N)=M可得量化器的信噪比随着量化电平数M的增加而显著提高,当小信号输入时,量化间隔也会变小,其量化噪声的平均功率也会变小,此时小信号量噪比便难以达到要求;而由于语音信号中小电压出现的概率较大,并且非均匀量化噪声对大小信号的影响大致相同,因此采用非均匀量化来改善语音信号中小信号的量噪比。

  在PCM语音编码中,主要是对抽样值先进行压缩再进行均匀量化来实现非均匀量化,并通常采用8位PCM编码来保证PCM编解码系统的通信质量。

  在本实验中,我们选择15折线压缩律进行实验。μ律压缩特性由下式表示:

  对上式作一些修正。在μ律中,修正后的表示式如下:

  由上式可以看出:满足当 x = 0时,y = 0;当x = 1时,y = 1。但是,在其它点上自然存在一些误差。不过,只在小电压(x < 1/128)时,才有稍大误差。通常用参数μ表示上式中的常数255。其特性曲线如下图2-1所示:

图2-1 μ律15折线律的特性曲线
  由于其第一段和第二段的斜率不同,不能合并为一条直线,故当考虑到信号的正负电压时,仅正电压第一段和负电压第一段的斜率相同,可以连成一条直线。所以,得到的是15段折线,称为15折线压缩特性。
  μ律不易用电子线路准确实现,所以目前实用中是采用特性近似的15折线代替μ律。这时,和A律一样,也把纵坐标 y 从0到1之间划分为8等份。对应于各转折点的横坐标 x 值可以按照下式计算:

  计算结果列于下表中: 表2-1 μ律折线的斜率


  在15折线律中采用的折叠码与13折线律相同也有8位。其中第一位c1表示量化值的极性正负。后面的7位分为段落码和段内码两部分,用于表示量化值的绝对值。其中第2至4位(c2 c3 c4)是段落码,共计3位,可以表示8种斜率的段落;其他4位(c5 ~ c8)为段内码,可以表示每一段落内的16种量化电平。段内码代表的16个量化电平是均匀划分的。

  所以,这7位码总共能表示27 = 128种量化值。在下面的表2-1中给出了段落码和段内码的编码规则。

表2-2 段落码和段内码的编码规则


  在上述编码方法中,虽然段内码是按量化间隔均匀编码的,但是因为各个段落的斜率不等,长度不等,故不同段落的量化间隔是不同的。其中第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位就够了。

  如下图2-2所示为PCM编码的原理框图,它首先在编码器中由冲激脉冲对模拟信号抽样,得到在抽样时刻上的信号抽样值。这个抽样值仍然是模拟量。在它量化之前,通常用保持电路将其作短暂保存,以便电路有时间对其进行量化。在实际电路中,常把抽样和保持电路作在一起,称为抽样保持电路。图中的量化器把模拟抽样信号变成离散的数字量,然后在编码器中进行二进制编码。这样,每个二进制码组就代表一个量化后的信号抽样值。

  常用的编码方法有逐次比较法等等。常用的二进制码有自然二进制码及折叠二进制码等。

图2-2 PCM编码的原理框图

2.2 PCM语音解码原理

  接收端实现PCM解码的原理框图如图2-3所示,其主要原理为逐次比较A/D转换。

图2-3 PCM解码原理框图

  在此图中,本地译码器的记忆电路得到输入c7值后,使恒流源产生为下次比较所需要的权值电流Iw。在编码器输出c8值后,对此抽样值的编码已经完成,所以比较器要等待下一个抽样值到达,暂不需要恒流源产生新的权值电流。在接收端的译码器中,仍保留本地译码器部分。

  由记忆电路接收发送来的码组。当记忆电路接收到码组的最后一位c8后,使恒流源再产生一个权值电流,它等于最后一个间隔的中间值。由于编码器中的比较器只是比较抽样的绝对值,本地译码器也只是产生正值权值电流,所以在接收端的译码器中,最后一步要根据接收码组的第一位c1值控制输出电流的正负极性。由此接收端可得到PCM的语音解码。


三.软件设计

3.1信号产生与采样

  信号产生与采样部分的代码如图3-1所示(正弦波),此处以正弦波为例是为了方便进行PCM编解码正确性的验证。由奈奎斯特采样定理可知该信号的采样频率要大于4000Hz。根据上述原理可知此处选取的信号采样频率为8000Hz,代码和信号采样前后对比如图3-2所示。max函数的作用是用来计算信号采样后各个幅度的极值,为之后PCM编码过程中的量化做准备。

图3-1 正弦波信号产生与采样代码

图3-2 正弦波信号采样前后对比图

3.2 PCM编码

  PCM编码的程序设计采用调用PCM编码函数的方法来实现。该编码函数分为三个部分:采样信号的量化,段落码判断和段内码判断,并且此处采用的压缩律为美国和日本地区所通用的μ-15折线律,先将其分为255个量化区间并采用8位编码,其中从左至右第一位表示采样信号的正负,第二位至第四位表示采样信号处于15折线律的哪一段上,为段落码;第五位至第八位为段内码,用于表示在该段16个量化区间中的位置,每一段的量化间隔分别为分别1/16,1/8,1/4,1/2,1,2,4,8。这三个部分的函数分别如图图3-4,图3-5及图3-6所示。通过如图3-7所示程序调用,结果如图3-8所示。
  

图3-4 PCM编码函数中采样信号的量化部分

图3-5 PCM编码函数中段落码判断部分
图3-6 PCM编码函数中段内码判断部分

图3-7 PCM编码程序调用

图3-8 正弦信号PCM编码结果

3.3 PCM解码

  根据PCM解码的相关原理,可以得到该部分的程序框图如图3-9所示,其中相对幅度即还原后抽样信号的幅值与所有抽样信号的幅值的最大值之比,从而可设计出PCM解码函数如图3-10所示,调用代码如图3-11所示,解码效果图如图3-12所示。

图3-9 PCM解码部分程序框图

图3-10 PCM解码函数

图3-11 PCM解码程序调用

图3-12 PCM解码输出与原输入对比图

  由PCM译码的波形和原始信号波形的对比可以看出,运用μ-15折线律作为压缩律对原始信号进行PCM编解码的还原度还是比较高的。

3.4 PCM编解码的Simulink实现

  由PCM编解码原理,可设计出如图3-13所示的PCM编解码系统。

图3-13 PCM编解码系统示意图

  在图3-13中,我们以一个非周期性正弦波chirp为例,先对该波进行量化,然后将量化后的信号通过对其进行编码,译码和解码,并设置其采样8位2进制编码和解码,随后将解码过后的信号通过一个低通滤波器,滤除其中的高频噪声,从而对原来量化过后的信号进行还原。

图3-14 PCM编解码系统输入设置示意图

  

图3-15 PCM编码模块设置示意图

  

图3-16 PCM解码模块设置示意图

  

图3-17 PCM编解码输出示意图

3.5 PCM编解码的GUI实现

  此处采用GUI界面操作完成语音输入,PCM编码,PCM解码,语音还原输出,界面如图3-18所示,该系统可以使用弹出式菜单分别进行三种不同种类语音:锣声,哈利路亚和笑声的输入,并通过PCM编解码对其进行还原输出,三种不同种类语音输入与语音还原输出后的对比图如图3-19,图3-20和图3-21所示。

图3-18 PCM通信系统的GUI设计界面

  

图3-19 锣声语音输入与PCM语音还原输出后的对比图

  

图3-20 哈利路亚语音输入与PCM语音还原输出后的对比图

  

图3-21 笑声语音输入与PCM语音还原输出后的对比图


四.性能分析

4.1 具体信号分析

   此处主要对正弦还原信号进行失真度分析的测试,如图4-1所示。可得到失真度的大小为0.002030(如图4-2所示),说明对应具体信号而言,PCM编解码后的输出信号还原度较高。

图4-1 信号失真度测试代码

4.2 语音信号分析

  根据图3-19所示程序,同样可以得到三个语音信号(在采样个数相同的条件下)分别为0.0054,0.0048和0.0044,说明语音信号的PCM编解码输出信号还原度比单频信号要略低。


附录代码:

采用美国,日本地区标准的μ-15折线律作为PCM编码的压缩律
.m文件说明:
编解码函数:
PCMcode,PCMdecode
运行顺序:
project3_1
project3_2
project3_3
project3_4
推荐直接GUI操作
PROJECT3GUI.m是设计GUI界面的,直接点PROJECT3GUI.fig就好了
注:simulink.slk是2018版的matlab编写的,要运行的话需要用2018以上的matlab版本


编码函数(PCMcode.m)
function code=PCMcode(S)z=sign(S);                                %判断S的正负MaxS=max(abs(S));                         %求S的最大值 S=abs(S/MaxS);                            %归一化Q=255*S;                                 %量化code=zeros(length(S),1);                  %代码存储矩阵(全零)% 段落码判断程序for i=1:length(S)if (Q(i)>=15)&&(Q(i)<=255)code(i,2)=1;            %在第五段与第八段之间,段位码第一位都为"1"endif (Q(i)>3)&&(Q(i)<15)||(Q(i)>=63)&&(Q(i)<=255)code(i,3)=1;            %在第三四七八段内,段位码第二位为"1"endif (Q(i)>=1)&&(Q(i)<3)||(Q(i)>=7)&&(Q(i)<15)||(Q(i)>=31)&&(Q(i)<63)||(Q(i)>=127)&&(Q(i)<=255)code(i,4)=1;            %在二四六八段内,段位码第三位为"1"endendN=zeros(length(S));                              %段内码判断程序for i=1:length(S)N(i)=bin2dec(num2str(code(i,2:4)))+1;        %找到code位于第几段enda=[0,1,3,7,15,31,63,127];                 %量化间隔b=[1/16,1/8,1/4,1/2,1,2,4,8];                          %除以16,得到每段的最小量化间隔for i=1:length(S)  q=ceil((Q(i)-a(N(i)))/b(N(i)));              %求出在段内的位置if q==0code(i,(5:8))=[0,0,0,0];                 %如果输入为零则输出"0"else k=num2str(dec2bin(q-1,4));              %编码段内码为二进制code(i,5)=str2num(k(1));code(i,6)=str2num(k(2));code(i,7)=str2num(k(3));code(i,8)=str2num(k(4));endif z(i)>0code(i,1)=1;elseif z(i)<0code(i,1)=0;end                                           %符号位的判断endcode = reshape(code', 1, []);
end

解码函数(PCMdecode.m)
function s=PCMdecode(encode, max)encode=(reshape(encode',8,length(encode)/8))';l=size(encode,1);a=[0,1,3,7,15,31,63,127];b=[1/16 1/8 1/4 1/2 1 2 4 8];c=[0 1.5:15.5];for i=1:lx=encode(i,1);T=bin2dec(num2str(encode(i,(2:4))))+1;Y=bin2dec(num2str(encode(i,(5:8))));if Y==0k(i)=a(T)/255;elsek(i)=(a(T)+b(T)*c(Y))/255;endif x==0s(i)=-k(i);elses(i)=k(i);endends = s*max;
end

信号采样(project3_1.m)
clear;clc;
T=0.0005;
t=-0.01:T:0.01;
fs=8000;    %取采样频率为8000Hz
sdt=1/fs;
t1=-0.01:sdt:0.01;
xt=cos(2*pi*30*t)+sin(2*pi*120*t);
st=cos(2*pi*30*t1)+sin(2*pi*120*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编码(project3_2.m)
pcm_encode = PCMcode(xt);
figure;
stairs(pcm_encode);
axis([0 200 -2 2]);
title('PCM 编码');
grid on;

PCM解码(project3_3.m)
pcm_decode = PCMdecode(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;

结果分析(project3_4.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(PROJECT3GUI.m)

GUI设计网上教程很多,这里贴1张效果图。
完整工程文件后续会上传到博客资源当中。


【Matlab】基于μ律15折线的PCM语音编解码系统(GUI设计、simulink、附完整代码)相关推荐

  1. Python基于二维码实现的在线编解码系统

    目 录 摘 要 I Abstract II 第一章 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 工作环境和背景 2 1.3.1 操作系统 3 1.3.2 编程语言 3 1.3.3编码 ...

  2. 深度学习实战案例:基于LSTM的四种方法进行电影评论情感分类预测(附完整代码)

    序列分类是一个预测建模问题,你有一些输入序列,任务是预测序列的类别. 这个问题很困难,因为序列的长度可能不同,包含非常大的输入符号词汇表,并且可能需要模型学习输入序列中符号之间的长期上下文或依赖关系. ...

  3. 基于MATLAB的二维与三维插值拟合运算(附完整代码)

    · 一. 一维插值 interp1函数在上个博客中(如下链接)已经更新了,此处再补充两个相关例题. 基于MATLAB的数据插值运算:Lagrange与Hermite算法(附完整代码)_唠嗑!的博客-C ...

  4. 基于MATLAB的三维数据插值拟合与三次样条拟合算法(附完整代码)

    目录 一. 三维插值 例题1 二. 高维度插值拟合 格式一 格式二 格式三 格式四 格式五 例题2 三. 单变量三次样条插值 例题3 例题4 四. 多变量三次样条插值 例题6 一. 三维插值 首先三维 ...

  5. 【一起读论文系列1】基于压缩感知的语音编解码方向研究

    [一起读论文系列1]基于压缩感知的语音编解码方向研究 2109,李俊鑫,基于压缩感知的快速语音编解码方法研究 1207,李尚靖,基于压缩感知的语音数字编码技术研究 引申资料 搜索关键词:compres ...

  6. 基于matlab的自动人脸识别系统GUI设计

    基于matlab的自动人脸识别系统GUI设计 之前做的一个课设项目半成品,一边网上找资料一边自己瞎捣鼓,完成了GUI界面的设计,实时视频中的人脸检测和追踪,PCA算法训练,单张人脸识别.但是识别率比较 ...

  7. linux局域网语音通讯软件下载,基于Linux平台的局域网可语音的IM软件的设计与实现.doc...

    基于Linux平台的局域网可语音的IM软件的设计与实 作者: 专业:软件工程 指导老师: 摘要 随着计算机网络的日益普及人们通过网络进行交流显得越来越重要.于是出现了一系列的通信软件. 自1990s ...

  8. 视频技术详解:语音编解码技术演进和应用选型

    本文来自现网易云音乐音视频实验室负责人刘华平在LiveVideoStackCon 2017大会上的分享,并由LiveVideoStack整理而成.分享中刘华平以时间为主线,讲述了语音编解码技术的演进路 ...

  9. 语音编解码技术演进和应用选型

    本文来自现网易云音乐音视频实验室负责人刘华平在LiveVideoStackCon 2017大会上的分享,并由LiveVideoStack整理而成.分享中刘华平以时间为主线,讲述了语音编解码技术的演进路 ...

  10. 第十章---《实时语音处理实践指南》语音编/解码笔记

    文章目录 1.语音编/解码简述 2.声音可以进行编码的原理 3.语音编码的过程 4.LPC编码 5.SILK编解码 6.Opus编解码 1.语音编/解码简述  编码的过程就是对语音进行压缩,压缩应该能 ...

最新文章

  1. 图解:轻松看懂机器学习十大常用算法
  2. RDKit | 可视化官能团, 分子聚类, 相似图, 化合物高亮和骨架网络
  3. Windows 技巧篇 - cmd的复制和粘贴功能
  4. 6-uboot relocation介绍
  5. 疯子的算法总结(四)贪心算法
  6. 一体化住户调查_曲麻莱县2020年城乡一体化住户调查表彰会暨年报部署会
  7. 连续整数的和(51Nod-1138)
  8. php 汉字转拼音及获取拼音首字母
  9. Git学习总结(8)——Git和SVN之间的基本区别
  10. Mysql复习(基础概念+基础操作)
  11. 字节序(Endian),大端(Big-Endian),小端(Little-Endian)
  12. 找不到可安装的ISAM
  13. 最新wp建站做淘宝客系统教程(共6课)附源码
  14. python-普通数据分析-科比职业生涯数据分析
  15. XMind思维导图软件导出高清图片的方法
  16. linux 微信客户端 mojo,QQ微信一体客户端教程
  17. python设置桌面歌词_Python生成歌词词云
  18. 基于动态手势识别的酷狗音乐播放器控制
  19. 自媒体视频素材|短视频标题文字动画PR模板素材
  20. ATmega16智能遥控小车

热门文章

  1. 实验五、U_GSQ对共源放大电路电压放大倍数的影响
  2. 一些鲜为人知的的CSS3属性
  3. 警示!一幅漫画揭示了项目研发过程中存在的问题
  4. 在SDK中使用TreeView控件
  5. 整合车辆出险报告Api接口,轻松管理车险理赔!
  6. 固态硬盘如何4K对齐?扇区大小,簇大小的影响
  7. 亚马逊云服务宕机事件警示企业,不要把鸡蛋放在一个篮子里
  8. 2020电科计算机考研结束,一些不成熟的小建议(二)
  9. 「自然语言处理(NLP)论文推送」清华大学XQA数据集(含源码)
  10. SentencePiece android ndk编译