1 整体流程设计
1.1 样本音频信号的频谱分析
1.2 对音频信号的滤波
1.3 对音频信号进行PCM编码
1.4 对编码后的信号进行汉明编码
1.5 对编码后的信号进行qpsk调制
1.6 发送信号进入AWGN信道
1.7 对接收到的信号进行qpsk解调
1.8 信道译码-汉明纠错和译码
1.9 对音频信号进行pcm译码并播放
2 主要模块说明
2.1 pcm编解码---pcmcoder()&pcmdecoder()
pcm为脉冲调制,选取的压缩特性为A律,采用十三折线编码算法,如下图所示。
从图中可以看到,先把X轴的0~1分为8个不均匀段,其分法是:将0—1之间一分为二,其中点为l,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轴的八段一一对应。从第一段到第八段分别为,0~1/8,1/8—2/8,⋯,7/8~l。这样,便可以作出由八段直线构成的一条折线。再加上第三象限的八段折线,共l6段,由于正向一、二两段和负向一、二两段的斜率相同,这四段实际上为一条直线,因此,正、负双向的折线总共由l3条直线段构成,故称其为13折线。
2.2 汉明编解码---hanmingcoder()&hanmingdecoder()
汉明码是一种线性分组码。线性分组码是指将信息序列划分为长度为k的序列段,在每一段后面附加r位的监督码,且监督码和信息码之间构成线性关系,即它们之间可由线性方程组来联系。这样构成的抗干扰码称为线性分组。
码。
设码长为n,信息位长度为k,监督位长度为r=n-k。如果需要纠正一位出错,因为长度为n的序列上每一位都可能出错,一共有n种情况,另外还有不出错的情况,所以我们必须用长度为r的监督码表示出n+1种情况。而长度为r的监督码一共可以表示2^r种情况。采用(7,4)汉明编码,原信息码4位分组,采用3位监督码。
汉明码是一个校验很严谨的编码方式。通过对4个数据位的3个位的3次组合检测来达到具体码位的校验与修正目的(不过只允许1个位出错,两个出错就无法检查出来了)。在校验时则把每个汉明码与各自对应的数据位值相加,如果结果为偶数(纠错代码为0)就是正确,如果为奇数(纠错代码为1)则说明当前汉明码所对应的三个数据位中有错误,此时再通过其他两个汉明码各自的运算来确定具体是哪个位出了问题。
解码时首先输入7位汉明码a1a2a3a4a5a6a7,然后根据这7位码a1a2a3a4a5a6a7,计算校正子S1,S2,S3,S4的值,可知校正子S与(7,4)汉明码各位之间的关系,要判定校正子与0的关系,若等于0,则表示没有错误;若不为0,则表示其中有一位出错。通过校正子S与错误图样E之间的关系,将得到的错误图样与译码输出进行模二加,纠正错误。将没有错误的汉明码或已经纠正1个错误的汉明码输出,完成译码程序。
2.3 qpsk调制与解调---qpskcoder()&qpskdecoder()
果。
clc;clear all; %/*************************读入音频文件*******************************/ long=input('想处理的音乐的长度(推荐值200 000以下,太长会很慢):'); disp('**********请欣赏发送的的音乐*********') [x,fs]=audioread('高山流水.wav',[1 long]); sound(x,fs); X=fft(x,long); magX=abs(X); angX=angle(X); figure;%画图 subplot(321);plot(x);title('原始信号波形'); subplot(322);plot(abs(X)); title('原始信号频谱'); %/*************************对音频信号滤波*******************************/ N=5;wc=4000/6000; [b,a]=butter(N,wc);%用巴特沃斯滤波器进行滤波 X=fft(x); subplot(323);plot(x);title('滤波前信号的波形'); subplot(324);plot(abs(X));title('滤波前信号的频谱'); y=filter(b,a,x); Y=fft(y); subplot(325);plot(y);title('IIR滤波后信号的波形'); subplot(326);plot(abs(Y));title('IIR滤波后信号的频谱'); %/*************************对音频信号进行pcm编码*************************/ L=length(y); pcmy=pcmcoder(y,L,long); %/*************************对编码后的信号进行信道编码-汉明编码************/ s=pcmy; L=length(s); h=zeros(1,L+L/4*3);%产生编码序列 N=L+L/4*3; h=hanmincoder(s,L); %/*************************对编码后的信号进行qpsk调制********************/ sig=qpskcoder(N,h); %/*************************发送信号进入AWGN信道**************************/ %加入噪声 n=noise(N,L); r=sig+n;%检测器的输入模块 %/*************************对接收到的信号进行qpsk解调********************/ rr=qpskdecoder(N,r); %/*************************信道译码-汉明纠错和译码***********************/ y=hanmingdecoder(rr,L) ; %/*************************对音频信号进行pcm译码************************/ pcmyout=pcmdecoder(y,long); disp('**********请欣赏接收到的音乐*********') sound(pcmyout,fs); disp('**********程序结束,谢谢*********') function y=hanmingdecoder(rr,L) %汉明纠错 for i=1:length(rr)/7 s01=xor(xor(xor(rr(7*i-6),rr(7*i-5)),rr(7*i-4)),rr(7*i-2)); s02=xor(xor(xor(rr(7*i-6),rr(7*i-5)),rr(7*i-3)),rr(7*i-1)); s03=xor(xor(xor(rr(7*i-6),rr(7*i-4)),rr(7*i-3)),rr(7*i-0)); if s01==0&&s02==0&&s03==1; rr(7*i)=not(rr(7*i)); elseif s01==0&&s02==1&&s03==0; rr(7*i-1)=not(rr(7*i-1)); elseif s01==1&&s02==0&&s03==0; rr(7*i-2)=not(rr(7*i-2)); elseif s01==0&&s02==1&&s03==1; rr(7*i-3)=not(rr(7*i-3)); elseif s01==1&&s02==0&&s03==1; rr(7*i-4)=not(rr(7*i-4)); elseif s01==1&&s02==1&&s03==0; rr(7*i-5)=not(rr(7*i-5)); elseif s01==1&&s02==1&&s03==1; rr(7*i-6)=not(rr(7*i-6)); elseif s01==0&&s02==0&&s03==0; continue; end end %汉明译码(把经过纠错的序列去掉汉明码还原为原始的序列) y=zeros(1,L);%最后的序列 j=1; for i=0:length(rr)/7-1 y(j)=rr(7*i+1); y(j+1)=rr(7*i+2); y(j+2)=rr(7*i+3); y(j+3)=rr(7*i+4);%取每一个序列单元的前四个码元 j=j+4; end end
版本:2014a
完整代码或代写加1564658423