提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
一、设计任务
二、课程设计解决的主要问题
三、设计内容
四、结果分析
五、参考资料
总结
前言
本人是通信工程的本科生,这是本人在学习《通信原理》时,老师布置的课程设计,现已大致完成,本片文章是一个总结。由于本科阶段培养方案里没有一门系统学习MATLAB的课程,我是自己学习,掌握了一些MATLAB的知识,所以本文中讲的东西不一定都是对的,如果我有讲错的地方,欢迎指出,如果我的思路过于复杂,也希望评论区的大佬们不吝赐教。
一、设计任务
公共电话网(PSTN)的语音终端(电话)基本都是模拟的,然而 PSTN 传输的是数字信号,请参照公共电话网的方式设计一个语音信号通信系统,用数字传输方式,发送端和接收端需要分别将模拟语音信号 A/D、D/A 变换,可采用PCM 编码方式。
要求: (1)Matlab 编程实现; (2)自己录制音频数据; (3)发送、接收端须为独立的系统。
二、课程设计解决的主要问题
1、录制音频信号
2、PCM编码
3、码型变换
4、两独立系统间传输(采用创建共享文件夹的方式)
5、抽样判决
6、PCM译码
三、设计内容
1.整体设计方案
(1)语音信号通信系统原理框图
图1 总系统框图
声音由系统A(电脑A)麦克风录入,转换成原始电信号,原始电信号经过采样后进行PCM编码,将编码生成的0/1二进制序列通过码型变换转换成双极性不归零码,将其以.mat文件形式保存至电脑A创建的共享文件夹内进行传输;在系统B(电脑B)上打开电脑A共享的文件,把其中接收到的双极性不归零码.mat文件导入,然后对数据进行抽样判决生成0/1二进制序列,最后PCM译码输出;由扬声器进行播放。
(2)各个部分功能及作用
1)麦克风:充当信源,作用是把声音消息转换成原始电信号。
2)扬声器:充当信宿,作用是将复原的电信号转换成声音。
3)码型变换:将0/1二进制码转换成双极性不归零码。
4)信道:是允许基带信号通过的媒介,此处采用创建共享文件夹方式在两独立系统间进行传输。
5)抽样判决:在噪声背景下,在规定时刻(由位定时脉冲控制)对信道输出的基带信号进行抽样判决,以恢复或再生基带信号。
6)PCM编码:将模拟信号变换成二进制信号。对输入的模拟信号进行抽样、量化和编码;编码后的PCM信号是一个二进制数字序列,传输方式采用数字基带传输。接收端PCM信号经过译码后还原为量化值序列,得到重建的模拟信号。
①PCM系统原理方框图
图2 PCM系统原理框图
②抽样
是对模拟信号进行周期性扫描,把时间上连续的信号变成时间上离散的信号。该模拟信号经过抽样后还应当包含原信号中所有信息,也就是说能无失真的恢复原模拟信号。抽样速率的下限是由抽样定理确定的。
③量化
模拟信号的量化分为均匀量化和非均匀量化。由于均匀量化存在的主要缺点是:无论抽样值大小如何,量化噪声的均方根值都固定不变。因此实际中,往往采用非均匀量化。
非均匀量化的实际方法通常是将抽样值通过压缩再进行均匀量化。通常使用的压缩器中,大多采用对数式压缩。广泛采用的两种对数压缩律是μ压缩律和A压缩律。美国采用μ压缩律,我国和欧洲各国均采用A压缩律,因此,PCM编码方式采用的也是A压缩律。所谓A压缩律也就是压缩器具有如下特性的压缩律:
式中,x是归一化压缩器输入电压;y是归一化压缩器输出电压;A是压扩参数,表示压缩程度。实际应用中,采用近似于A律函数规律的13折线( A=87.6)的压缩特性。
把x轴的0~ 1分为8个不均匀段,其分法是将0~1之间一分为二,其中点为1/2, 取1/2~1之间作为第八段;剩余的0~1/2在一分为二,中点为1/4, 取1/4~1/2之间为第七段;再把剩余的0~1/4 一分为二,中点为1/8,取 1/8~1/4之间作为第六;依次下去,直到剩余最小的一段为0~1/128作为第一段。而y轴的0~1均匀的分为八段,与x轴的八段一一对应。这样,便可做出由八段直线构成的折线,折线除了一、二段外,其他各段折线的斜率都不相同,如表1所示。
表1 13折线分段时的各段折线的斜率
折线段号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
斜 率 | 16 | 16 | 8 | 4 | 2 | 1 | 0.5 | 0.25 |
④PCM编码译码原理
抽样信号I按照13折线A律特性编成8位码组C1C2C3C4C5C6C7C8,其中C1为极性码,I为正时取1,I为负时取0。
C2C3C4为段落码,决定I被编码所在的码段。13折线A律PCM编码将0 ~ 2048不均等的分为8个编码段落[0,16]、 [16,32]、 [32, 64]、 [64,128]、 [128, 256]、[256, 1024]、 [1024, 2048]。各个段落的编号和起点电平如表2所示。
表2 编码段落
段落 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
起点电平 | 0 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 |
均匀量化数 | 16 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 |
量化间隔 | 1 | 1 | 2 | 4 | 8 | 16 | 32 | 64 |
C2C3C4 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
将每一个码段做16等分,每一份作为量化间隔,并用段内码C5C6C7C8来表示之。13折线中的第一、二段最短,只有动态范围的1/128,将其等分为16小段后,每一小段的长度为(1/128)x(1/16)= 1/2048,第八段归一化值为1/2,等分16小段后每一段的最小长度为1/32。显然,随着段落编号的增大,量化间隔越大,量化误差也越大。
编码时,先确定极性码;再采用逐次比较的办法,确定段落码;最后,由段落起点电平的差值来确定段内码。译码时,先由段落码确定编码所在段落,确定段落起点电平和量化间隔,由段落起点电平加上段内码与相应量化间隔的乘积之和,即得到了抽样信号的绝对值,再由极性码C1来确定抽样值的正负号。
2.设计内容
(1)录制音频
利用“audiorecorder”函数录制音频数据。
(2)抽样
Xn = resample(x1,Fs,fs);利用“resample”函数重新采样。
(3)PCM编码
1)判断极性
通过if语句进行判断即可确定C1 ;代码如下:
if z(i)>0
code(i,1)=1;
elseif z(i)<0
code(i,1)=0;
2)判断段落码
运用逐次比较法,确定段落码C2C3C4 ;代码如下:
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
3)判断段内码
由段落码确定相应的段落计算出电平所在的位置,进行编码。代码如下:
N(i)=bin2dec(num2str(code(i,2:4)))+1;
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)));
if q==0
code(i,(5:8))=[0,0,0,0];
else k=num2str(dec2bin(q-1,4));
(4)码型变换
通过if判断语句将01二进制码转换成双极性不归零码,降低误码率。代码如下:
if pcm_encode(oo)>0.5
pcm_encode2(oo)=1;
else
pcm_encode2(oo)=-1;
end
(5)文件传输
在系统A中创建共享文件夹
将系统A和系统B连接在同一个WIFI下
在系统A中运行程序
系统A运行获得的双极性不归零码以.mat文件形式保存在共享文件夹内
在系统B中打开共享文件夹获得.mat文件
(6)抽样判决
同样是利用if判断语句将数据文件直接转换成01二进制码。代码如下:
if transf_sig(nn) >= 0
transf_sig2(nn) = 1;
else
transf_sig2(nn) = 0;
end
(7)PCM译码
1)判断极性
代码如下:
if x==0
s(i)=-k(i);
else
s(i)=k(i);
2)计算电平
通过8位二进制码判断出电平所在位置;利用公式计算即可得到量化电平值。代码如下:
x=encode(i,1);
T=bin2dec(num2str(encode(i,(2:4))))+1;
Y=bin2dec(num2str(encode(i,(5:8))));
if Y==0
k(i)=a(T)/2048;
else
k(i)=(a(T)+b(T)*c(Y))/2048;
end;
(8)播放语音信号
“sound”函数对语音信号进行播放。
代码如下:
sound(x,FS);
pause(T_end+1);
(9)画图
“plot”函数进行画图,“fft”进行离散傅里叶变换的到频域图,“fftshift”移动频域范围。
四、结果分析
1、模拟信号的生成
语音实时录音,原始数据采用了44kHz采样率,为了减少数据量便于处理,本次实验仅提取了原始音频信号的单个声道作为原始数据进行处理。同时为了进一步减少处理数据量,还对单声道音频数据进行了降采样处理(8khz)。
2、模拟信号数字化
图3 原始语音信号
图4 采样后的语音信号
3、模拟信号还原
图5 译码恢复的语音信号
将传输后的数据抽样判决得到二进制序列,再将其进行PCM译码并归一化从而得到恢复后的音频模拟信号。如图5可以发现与采样后的语音信号时域图、频谱图几乎一致。
4、播放语音信号
播放原始语音信号、采样后的语音信号、译码恢复的语音信号。
五、参考资料
[1]《通信原理(第7版)》樊昌信,曹丽娜著.国防工业出版社,2012。
[2] 邢巨伟.模拟信号的数字化传输-PCM编码[J].黑龙江科技信息,2014
[3] 张毅勇.模拟信号PCM编码的实现[J].甘肃冶金,2007(06)
[4] 别志松,别红霞. 系统与通信系统仿真.北京:北京邮电大学出版社,2010.
[5] 樊昌信,宫锦文,刘忠成编著《通信原理及系统实验》[M]北京:电子工业出版社,2007
[6] 通信原理实验编写组编著.《通信原理实验》[M].上海:上海交通大学出版社,1987
[7] 曹志刚等编著《现代移动通信原理》[M].北京:清华大学出版社,1999
[8] 赵谦等.《通信系统中MATLAB基础与仿真应用》[M]西安:西安电子科技大学出版社,2010
[9] 张威.MATLAB基础与编程入门.西安电子科技大学出版社,2004.2
六、附录程序
系统A主程序
%%系统A%%
%%主程序:
clear;
clc;
close all;
%%声音录制%%
FS=44100; % 设置的采样频率是audiorecorder函数的参数之一
voice = audiorecorder(FS,8,2);
% audiorecorder函数:(采样频率,比特数,通道数)——创建录制音频对象,放入声明的voice数组变量中
disp('Start speaking.');
%disp函数——命令窗口中提示录音的开始
recordblocking(voice,5);
% recordblocking函数:(音频存放对象,录音时间/S)为实际控制录音的函数
disp('End speaking.');
%disp函数——命令窗口中提示录音的结束
MyRecording=getaudiodata(voice);
% getaudiodata函数——从音频存放对象中获取记录到的音频数据,存储到数值数组MyRecording
filename='D:\学习\通信原理课设尝试代码\尝试共享文件夹\通信课设录音.wav';
%以采样率 Fs 将数值数组MyRecording写入filename ,保存到指定路径下,命名为‘通信课设录音’
audiowrite(filename,MyRecording,44100);
% audiowrite函数——用于将音频数据作为文件存放到到你建立的文件夹中
clear voice;
[x,fs]=audioread(filename);
% audioread函数——用于从音频文件中将数据读出来:x是音频数据,fs是采样频率,它们对应录音过程中你在audiowrite函数写入的MyRecording和44100
x1 = x(:,2);%取单声道
T=1/FS; %采样时间
TIME=T*length(x1); %计算音频长度,其中length(x1)计算变换的点数
tx1=T:T:TIME; %计算采样点,作为时域横坐标
X = fftshift(fft(x1./(length(x1))));
%用fft得出离散傅里叶变换,fftshift将零频分量移到频谱中心
% % 从-Fs/2到Fs/2,取length(Xn)个向量
f = linspace(-FS/2,FS/2-1,length(x1));
%频域横坐标:将[-FS/2,FS/2-1]进行length(Xn)-1等分
%奈奎斯特采样定理,原始信号最大频率<=采样频率的一半
% % 原始信号画图
Figure(’Name’,’原始声音信号’); %figure函数——创建图形窗口
subplot(2,1,1);plot(tx1,x1);title('原始声音信号(时域)');
xlabel(‘时间’);ylabel(‘振幅’);grid on;
subplot(2,1,2);plot(f,X);title('原始声音信号(频域)');
xlabel(‘F(Hz)’);ylabel(‘H(jw)’);grid on;
% % 以8000hz采样:人声频率在0~4000hz,根据奈奎斯特采样定理——采样频率应高于原始模拟信号最高频率两倍
Fs = 8e3; %设置目标采样频率
Xn = resample(x1,Fs,fs); %降采样率,从fs降到Fs。重新取样。
Ts = 1/Fs; %采样间隔
T_end = length(Xn)/Fs; %采样时间终点。length为矩阵最大长度
tx1 = Ts:Ts:T_end; %计算采样点,作为抽样信号横坐标
X1 = fftshift(fft(Xn./(length(Xn))));
%用fft得出离散傅里叶变换,fftshift将零频分量移到频谱中心
f1 = linspace(-Fs/2,Fs/2-1,length(Xn));
%频域横坐标:将[-FS/2,FS/2-1]进行length(Xn)-1等分
% % 抽样信号画图
figure(’Name’,’抽样后原始声音信号’);
subplot(2,1,1);plot(tx1,Xn);title('原始信号抽样后(时域)');
xlabel(‘时间’);ylabel(‘振幅’);grid on;
subplot(2,1,2);plot(f1,X1);title('原始信号抽样后(频域)');
xlabel(‘F(Hz)’);ylabel(‘H(jw)’);grid on;
% % PCM编码
pcm_encode = PCMcoding(Xn);
% % 双极性不归零编码
pcm_encode2=zeros(length(pcm_encode),1);
%预设一个全零代码存储矩阵大小为length(pcm_encode)×1
for oo=1:length(pcm_encode)
if pcm_encode(oo)>0.5
pcm_encode2(oo)=1;
else
pcm_encode2(oo)=-1;
end
end
save('D:\学习\通信原理课设尝试代码\尝试共享文件夹\保存的mat在这里');
系统A子程序——PCM编码
%%PCM编码
function [code ] = PCMcoding( S )
%UNTITLED3 此处显示有关此函数的摘要
% 此处显示详细说明
z=sign(S); %判断S的正负
MaxS=max(abs(S)); %求S的最大值
S=abs(S/MaxS); %归一化
Q=2048*S;%量化
code=zeros(length(S),8); %预设代码存储矩阵(全零)
% 判断段落码程序
for i=1:length(S)
if (Q(i)>=128)&&(Q(i)<=2048)
code(i,2)=1; %在第五段与第八段之间,段位码第一位都为"1"
end
if (Q(i)>=32)&&(Q(i)<128)||(Q(i)>=512)&&(Q(i)<2048)
code(i,3)=1; %在第三四七八段内,段位码第二位为"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; %在二四六八段内,段位码第三位为"1"
end
end
%段内码判断程序
N=zeros(length(S));
for i=1:length(S)
N(i)=bin2dec(num2str(code(i,2:4)))+1;%找到code位于第几段
end
a=[0,16,32,64,128,256,512,1024]; %量化间隔
b=[1,1,2,4,8,16,32,64]; %除以16,得到每段的最小量化间隔
for i=1:length(S)
q=ceil((Q(i)-a(N(i)))/b(N(i))); %求出在段内的位置;ceil向上取整
if q==0
code(i,(5:8))=[0,0,0,0]; %如果输入为零则输出"0"
else k=num2str(dec2bin(q-1,4));%编码段内码为二进制。把q-1转换成二进制数
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
code(i,1)=1;
elseif z(i)<0
code(i,1)=0;
end
end
code = reshape(code', 1, []);%重塑数组为1xX
end
系统B主程序
%%系统B主程序
transf_sig = awgn(pcm_encode2,10,'measured');
% awgn函数——将高斯白噪声添加到pcm_encode2双极性不归零码中,10dB为snr,指定了每个采样点的信号与噪声的比率。measure则是测量了信号的能量。
% % 抽样判决,判决电平为0
transf_sig2=zeros(length(transf_sig),1);
%预设代码存储矩阵(全零)大小为length(transf_sig)×1
for nn=1:length(transf_sig)
if transf_sig(nn) >= 0
transf_sig2(nn) = 1; % 大于判决电平为1
else
transf_sig2(nn) = 0; % 小于判决电平为0
end
end
% % PCM解码
xmax = max(abs(Xn)); %求Xn的最大值
pcm_decode = PCMdecoding(transf_sig2,xmax);% PCM 译码
X2 = fftshift(fft(pcm_decode./(length(pcm_decode))));
%用fft得出离散傅里叶变换, fftshift将零频分量移到频谱中心
f2 = linspace(-Fs/2,Fs/2-1,length(pcm_decode));
%频域横坐标: 将[-FS/2,FS/2-1]进行length(pcm_decode)-1等分,注意奈奎斯特采样
% % 译码后信号画图
figure(‘Name’,’PCM译码后’);
subplot(2,1,1);plot(tx1, pcm_decode);title('PCM译码后(时域)');
xlabel(‘时间’);ylabel(‘振幅’);grid on;
subplot(2,1,2);plot(f2,X2 );title('PCM译码后(频域)');
xlabel(‘F(Hz)’);ylabel(‘H(jw)’);grid on;
% % 播放
sound(x,FS); %播放原始语音信号
%sound函数——用于将音频数据播放出来:用采样频率fs来播放音频数据x
pause(T_end+1);
sound(Xn,Fs); %播放降采样率之后的语音信号
pause(T_end+1);
sound(pcm_decode,Fs); %播放解码译码后的语音信号
pause(T_end+1);
系统B子程序——PCM译码
%%PCM译码
function [ s ] = PCMdecoding( encode, max )
%UNTITLED6 此处显示有关此函数的摘要
% 此处显示详细说明
encode=(reshape(encode',8,length(encode)/8))';%重排矩阵为8xX
L=size(encode,1);%计算encode的行数
a=[0,16,32,64,128,256,512,1024];
b=[1 1 2 4 8 16 32 64];
c=[0 1.5:15.5];%0 1.5 2.5 .....15.5
for i=1:L
x=encode(i,1);
T=bin2dec(num2str(encode(i,(2:4))))+1;%十进制
Y=bin2dec(num2str(encode(i,(5:8))));
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
总结
共享文件夹那一块还需要各位再去根据自己的电脑配置一下,博主的两台电脑是有时能连上,有时连接不上。