实验内容与步骤
采用matlab对数字通信系统基本模型图5-1进行搭建并仿真。
信源为时间长度为7秒钟的音频test_speech.wav,其采样频率为8000Hz。基本要求:
- 信源编码采用A律13折线非均匀PCM编码;
- 信道编码采用(7,4)汉明码;
- 发送端采用平方根升余弦滤波器进行脉冲成型,发送端符号速率为RB=1000Baud,采样频率为fs=16000Hz,滚降系数α=0.25,延迟delay=5;
- 调制方式为2PSK,载波频率fc=4000Hz;
- 信道为AWGN信道,信噪比分别取成-10dB、-5dB、0dB、5dB;
- 解调,采用2PSK相干解调;
- 接收端采用匹配滤波。抽样判决方式:硬判决,即接收到的信号y与0相比,如果y>0则将y解调为1,否则解调为0;
- 信道译码,采用校正子译码方式对解调后的信号进行译码;
- 信源译码,采用A律13折线非均匀PCM译码;
- 性能分析:计算信道编码误码率;对比发送端发送的原始语音信号与接
代码:
fs1=8000;
fs=16000;
N=56000;
fc=4000;
N_point=16000;
fb=1000; %发送端符号速率
alpha=0.25;
delay=5;
oversamp=fs/fb; %过采样率
h_sqrt=rcosine(1, oversamp, 'fir/sqrt', alpha, delay);
%读取语音信号,并进行归一化处理
[test_speech,fs1] = audioread('test_speech.wav');
len_speech=length(test_speech);%语音的采样点个数len_speech
normal_speech= -1+2*(test_speech-min(test_speech))/(max(test_speech)-min(test_speech));%对语音进行归一化处理(压缩)
a=audioplayer(normal_speech,fs1);play(a);%播放归一化后的语音
figure('name','1');
subplot(2,1,1);
plot(normal_speech);
axis([0 len_speech-1 -1 1]);
title('发送方语音时域波形');
subplot(2,1,2);plot((0:len_speech-1)/len_speech*fs,abs(fft(normal_speech)));
ylim([0 1000]);%取归一化频率
title('发送方语音信号频域波形');
%信源编码,A率13折线非均匀PCM编码
scrsignal=round(2048*normal_speech);%将归一化后的语音信号放大到[-2048,2048]
code_out=zeros(len_speech,8);%code矩阵用于存储PCM编码结果
code_out( : ,1)=(scrsignal>0);%极性码
srcsignal_abs=abs(scrsignal);
for i=1:len_speech
if srcsignal_abs(i) >=0 && srcsignal_abs(i) <16
code_out(i,2:4) =zeros(1,3);%段落码
step=1;%段内量化间隔
start_point=0;%段内起始点
tmp=floor((srcsignal_abs(i)-start_point)/step);%由于是从0000开始,所以要减去一个量化间隔
code_out(i,5:8)=dec2bin(tmp,4)-48;%转化成二进制代码,并且赋值到code_out中
else if srcsignal_abs(i) >=16 && srcsignal_abs(i) <32
code_out(i,2:4) =[0,0,1];%段落码
step=1;%段内量化间隔
start_point=16;%段内起始点
tmp=floor((srcsignal_abs(i)-start_point)/step);
code_out(i,5:8)=dec2bin(tmp,4)-48;
else if srcsignal_abs(i) >=32 && srcsignal_abs(i) <64
code_out(i,2:4) =[0,1,0];%段落码
step=2;%段内量化间隔
start_point=32;%段内起始点
tmp=floor((srcsignal_abs(i)-start_point)/step);
code_out(i,5:8)=dec2bin(tmp,4)-48;
else if srcsignal_abs(i) >=64 && srcsignal_abs(i) <128
code_out(i,2:4) =[0,1,1];%段落码
step=4;%段内量化间隔
start_point=64;%段内起始点
tmp=floor((srcsignal_abs(i)-start_point)/step);
code_out(i,5:8)=dec2bin(tmp,4)-48;
else if srcsignal_abs(i) >=128 && srcsignal_abs(i) <256
code_out(i,2:4) =[1,0,0];%段落码
step=8;%段内量化间隔
start_point=128;%段内起始点
tmp=floor((srcsignal_abs(i)-start_point)/step);
code_out(i,5:8)=dec2bin(tmp,4)-48;
else if srcsignal_abs(i) >=256 && srcsignal_abs(i) <512
code_out(i,2:4) =[1,0,1];%段落码
step=16;%段内量化间隔
start_point=256;%段内起始点
tmp=floor((srcsignal_abs(i)-start_point)/step);
code_out(i,5:8)=dec2bin(tmp,4)-48;
else if srcsignal_abs(i) >=512 && srcsignal_abs(i) <1024
code_out(i,2:4) =[1,1,0];%段落码
step=32;%段内量化间隔
start_point=512;%段内起始点
tmp=floor((srcsignal_abs(i)-start_point)/step);
code_out(i,5:8)=dec2bin(tmp,4)-48;
else if srcsignal_abs(i) >=1024 && srcsignal_abs(i) <2048
code_out(i,2:4) =[1,1,1];%段落码
step=64;%段内量化间隔
start_point=1024;%段内起始点
tmp=floor((srcsignal_abs(i)-start_point)/step);
code_out(i,5:8)=dec2bin(tmp,4)-48;
end;
end;
end;
end;
end;
end;
end;
end;
end;
source_codeout0=code_out()';
source_codeout=source_codeout0(:)';
%n,k
%第三步 信道编码,(7,4)汉明码
n=7;
k=4;
len_speech=length(source_codeout);
Q=[1,1,1; 1,1,0; 1,0,1; 0,1,1];%校验矩阵Q
GMat=[eye(k), Q]; %生成矩阵G
HMat=[Q',eye(n-k)]; %监督矩阵H
Channel_Data=zeros(n,len_speech/k); %每k个信息码元为一组,进行信道编码,矩阵Channel_Data用于存储(7,4)汉明码后的码元
for i=1:len_speech/k %一共有多少组信息码
Channel_Data(:,i) = (mod(source_codeout((i-1)*k+1:i*k)* GMat,2));
end
Channel_Data1=Channel_Data(:)'; %将Channel_Data矩阵按每一列排列,拉长为一个行向量Channel_Data1
origin_shaped=2*Channel_Data1-1;
%平方根升余弦滤波器 h_sqrt,进行脉冲成型
sendsignal_oversample=kron(origin_shaped, [1, zeros(1, (oversamp-1))]);
sendshaped=conv(sendsignal_oversample, h_sqrt); %频域乘积,时域卷积
Nt=0:length(sendshaped)-1;
CarrierWave=cos(2*pi*fc*Nt/fs);%生成载波信号
ModemWave=sendshaped.*CarrierWave; %调制
snr=-10;
TransSignal = awgn(ModemWave, snr,'measured','db');%加入白噪声
CarrierWave_rec=cos(2*pi*fc*Nt/fs);
%相干解调
ModemWave_rec=TransSignal.*CarrierWave_rec;
conj(h_sqrt);%接受滤波器接收
RecMatched=conv(ModemWave_rec, h_sqrt);
N2=784000;
SynPosi =delay*oversamp*2+1;
SymPosi=SynPosi+(0:oversamp:(N2-1)*oversamp);
RecSignal=RecMatched(SymPosi);
%抽样判决
Rect_M = RecSignal; % 初始化
for i = 1:N2
if RecSignal(i) >0
Rect_M(i)=1;
else
Rect_M(i)=0;
end
end
Rect_M0=reshape(Rect_M,7,length(Rect_M)/n);
Rect_M1=Rect_M0';
%信道译码
%纠错
for i=1:length(Rect_M1)
if(mod(Rect_M1(i,:),2)==1)
~Rect_M1(bin2dec(num2str(Rect_M1(i,5:7))));
end;
end;
%Rec_trans1=Rect_M1;
%去掉监督码
%Rec_trans2=mod(Rec_trans1*GMat',2);%还原成信息码
Rec_tran2=zeros(length(Rect_M1),4);
for i=1:length(Rect_M1)
Rec_trans2(i,:)= Rect_M1(i,1:4);
end;
Rec_get0 = Rec_trans2()';
Rec_get = Rec_get0(:);
% 计算误码率
N3=N2/7*4;
erro = 0;
for i =1:N3
if Rec_get(i) ~= source_codeout(i)
erro = erro + 1;
end
end
error_lv = erro/N3;
erro
disp("误码率:");
disp(error_lv);
%信源译码,利用PCM译码
Rec_pcm = reshape(Rec_get,8,length(Rec_get)/8)';
Rec_polar = Rec_pcm(:,1);
%创建一个临时变量
%用于存储极性码
code_rec = zeros(N3/8,8);
code_rec1 = 2*Rec_polar-1;
code_rec(:,1)= code_rec1;
len_coderec=length(code_rec);
% 段号
duan_pcm=Rec_pcm(:,2:4);
duan_pcm1=Rec_pcm(:,5:8);
len_pcm = length(duan_pcm);
duanluo = zeros(1,len_pcm);
duan=0;
for i=1:len_pcm
duan = duan_pcm(i,1:3);
duanluo(1,i) = bin2dec(num2str(duan));
end;
duannei = zeros(1,len_pcm);
for i=1:len_pcm
duan1=duan_pcm1(i,1:4);
duannei(1,i) = bin2dec(num2str(duan1));
end;
duanhao=zeros(1,len_pcm); %求段号的绝对值
for i=1:len_pcm
if duanluo(1,i)==0
step=1;%段内量化间隔
start_point=0;%段内起始点
duanhao(1,i)=duannei(1,i)*step+start_point;
else if duanluo(1,i)==1
step=1;%段内量化间隔
start_point=16;%段内起始点
duanhao(1,i)=duannei(1,i)*step+start_point;
else if duanluo(1,i)==2
step=2;%段内量化间隔
start_point=32;%段内起始点
duanhao(1,i)=duannei(1,i)*step+start_point;
else if duanluo(1,i)==3
step=4;%段内量化间隔
start_point=64;%段内起始点
duanhao(1,i)=duannei(1,i)*step+start_point;
else if duanluo(1,i)==4
step=8;%段内量化间隔
start_point=128;%段内起始点
duanhao(1,i)=duannei(1,i)*step+start_point;
else if duanluo(1,i)==5
step=16;%段内量化间隔
start_point=256;%段内起始点
duanhao(1,i)=duannei(1,i)*step+start_point;
else if duanluo(1,i)==6
step=32;%段内量化间隔
start_point=512;%段内起始点
duanhao(1,i)=duannei(1,i)*step+start_point;
else if duanluo(1,i)==7
step=64;%段内量化间隔
start_point=1024;%段内起始点
duanhao(1,i)=duannei(1,i)*step+start_point;
end;
end;
end;
end;
end;
end;
end;
end;
end;
%将极性赋予上
for i=1:len_pcm
if Rec_polar(i,1)==0
duanhao(1,i)=duanhao(1,i)*-1;
end;
end;
rec_audio = duanhao';
len_audio=length(rec_audio);
a1=audioplayer(rec_audio/2048,fs1);play(a1);%播放归一化后的语音
figure('name','1');
subplot(2,1,1);
plot(rec_audio/2048);
axis([0 len_audio-1 -1 1]);
title('接收端语音时域波形');
subplot(2,1,2);plot((0:len_audio-1)/len_audio*fs,abs(fft(rec_audio/2048)));
ylim([0 1000]);%取归一化频率
title('接收端语音信号频域波形');