【数字信号处理】
第一次
介绍Matlab的使用 略
第二次
Task1 求解差分方程
解差分方程
求解方法——递推
差分方程:
递归形式:
对于本题:
其中,
验证方法——filter
编程实现
点击查看代码
clc;clear all b=1;a=[1 -1 0.9]; N=100; x=(-2:100); h=zeros(1,N+2); s=zeros(1,N+2); %构造单位脉冲序列和单位阶跃序列 n=(-2:N); delta=(n==0); u=(n>=0); %求单位脉冲响应 for k=3:N+3 h(k)=b*delta(k)-a(2)*h(k-1)-a(3)*h(k-2); end subplot(2,1,1) plot1 = plot(x,delta,'.'); hold on plot2 = plot(x,h,'linewidth',1); %y=impz(b,a,N); %plot3 = stem((0:99),y','.'); y = filter(b,a,delta); plot3 = stem(x,y,'.'); legend("单位冲激序列","单位冲激响应","通过impz验证") title("求冲激响应") hold off %求单位阶跃响应 for k=3:N+3 s(k)=b*u(k)-a(2)*s(k-1)-a(3)*s(k-2); end subplot(2,1,2); plot4 = stem(x,u,'.'); hold on plot5 = plot(x,s,'linewidth',1); %y= stepz(b,a,N); %plot6 = stem((0:99),y','.'); y = filter(b,a,u); plot6 = stem(x,y,'.'); legend("单位阶跃序列","单位阶跃响应","通过stepz验证") title("求阶跃响应")
Task2 自相关检测
雷达测距原理

编程实现
点击查看代码
clear all;clc; %相位相关算法在延时检测中的应用 a=0.4;B=60;%衰减系数a,延时B dt=0.2; t=0:dt:100; f=ft(6,t);%发射波 r=a*ft(6,t-B);%回波 L=length(t); n=randn(1,L)/5;%噪声 rn=r+n;%带有噪声的回波 subplot(5,1,1);plot(t,f);ylabel('f(t)') title('发出波') subplot(5,1,2);plot(t,r);ylabel('r(t)') title('回波') subplot(5,1,3);plot(t,rn);ylabel('rn(t)') title('叠加随机噪声的回波') F=fftshift(fft(f));%求信号f的傅里叶变换F(jw) R=fftshift(fft(r));%求信号x的傅里叶变换F(jw),并将零频率点移至频谱的中心位置 G=conj(F).*R;%求F*(jw)R(jw) Cp=ifft(G);%求傅里叶反变换 subplot(5,1,4);plot(t,abs(Cp));ylabel('Cp(t)') title('相关算法在延时检测中的应用'); G=G./abs(G);%归一 Rn=fftshift(fft(rn)); G=conj(F).*Rn;G=G./abs(G); Cp=ifft(G); subplot(5,1,5);plot(t,abs(Cp));ylabel('Cpn(t)') title('相位相关算法在延时检测中的应用'); function ft=ft(w,t) ft=heaviside(t)-heaviside(t-20); for k=1:w ft = ft+sin(pi*k/2*t).*(heaviside(t)-heaviside(t-20)) ; end end
Task3 傅里叶变换
参考手动实现离散傅里叶正变换与逆变换(程序+例子) - 简书 (jianshu.com)
点击查看代码
data = [2 3 8 9 12 4 8 10]; % 原始离散时域信号 N = length(data); % DFT需要的相关矩阵: WN = exp(-i*2*pi/N); % 常数 WN_nk = zeros(N)+WN; % WN_kn矩阵(初始) xk = data'; % 时域信号振幅(列矩阵) E = zeros(N); % 辅助的E(WN_kn的幂,单独拿出来算) %%% 傅里叶正变换即结果 %%% for row = 0:N-1 for cow = 0:N-1 E(row+1,cow+1) = row*cow; WN_nk(row+1,cow+1) = WN_nk(row+1,cow+1)^E(row+1,cow+1); end end Xk = WN_nk * xk; % 频域结果 figure; subplot(1,2,1);stem(Xk,'b','fill');hold on stem(fft(data),'r'); % Matlab自带语句,验证 legend('自己算的','Matalab自带语句验证')hold off % 继DFT代码后跟着写 % IDFT需要的相关矩阵: WN_nk_n = zeros(N)+WN; % WN_kn矩阵(初始) E_n = zeros(N); % 辅助的E(WN_kn的幂,单独拿出来算) for row = 0:N-1 for cow = 0:N-1 E_n(row+1,cow+1) = -row*cow; % 注意负号 WN_nk_n(row+1,cow+1) = WN_nk_n(row+1,cow+1)^E_n(row+1,cow+1); end end xk_n = real((WN_nk_n * Xk)/N)'; % IDFT手写结果 subplot(1,2,2);stem(xk_n,'b','fill');hold on stem(ifft(Xk),'r'); % Matlab自带语句,验证
第三次
Task1.计算DTFT
求的离散时间傅里叶变换
序列是绝对可加的,因此它的FT存在
说明:
1.这是一个无限长的信号,但在Matlab中只能取N个有限制来近似
2.是一个之间变化的实变量,在Matlab中尽量取间隔小一些模拟连续
3.周期性和对称性(对于实信号)共轭对称
其实只需要取就可以知道的全部信息,但为了观察我们选取区间
点击查看代码
%要求:求x(n)=0.5^nu(n)的FT %产生x(n) clear;clc N=500; n=0:N; xn=ones(1,N+1); x=xn.*(power(0.5,n)); %画原始信号 figure; subplot(3,2,[1,2]);plot(x);grid title('Primary Singal'); K=1000; k=-K:K; %----------------FT变换----------------- w=(2*pi/K)*k; %1.方法一循环 X=ones(1,2*K+1); for i=1:401 X(i)=sum(x.*exp(-1i*w(i)*n)); end %2.方法二矩阵 X_2=x*(exp(-1i*pi/N)).^(n'*k); %3.公式手算验证 X_confirm=exp(1i*w)./(exp(1i*w)-0.5*ones(1,2*K+1)); T = (X==X_confirm); T_2=(X_2==X_confirm); %对结果分析展示 magX=abs(X);angX=angle(X); realX=real(X);imagX=imag(X); subplot(3,2,3);plot(k*2/K,magX);grid title('|X(e^{-jw})|=|X(e^{jw})|(偶对称)');ylabel('Magnitude'); subplot(3,2,5);plot(k*2/K,angX);grid title('∠X(e^{-jw}=-∠X(e^{-jw}(奇对称)');ylabel('Radians'); subplot(3,2,4);plot(k*2/K,realX);grid title('Re[X(e^{-jw}]=Re[X(e^{jw}](偶对称)');ylabel('Real'); subplot(3,2,6);plot(k*2/K,imagX);grid title('Im[X(e^{-jw}]=-Im[X(e^{-jw}](奇对称)');ylabel('Imaginary'); figure; subplot(2,2,1);polarplot(w,magX);title('|X(e^{-jw})|=|X(e^{jw})|(偶对称)'); subplot(2,2,3);polarplot(w,angX);title('∠X(e^{-jw}=-∠X(e^{-jw}(奇对称)'); subplot(2,2,2);polarplot(w,realX);title('Re[X(e^{-jw}]=Re[X(e^{jw}](偶对称)'); subplot(2,2,4);polarplot(w,imagX);title('Im[X(e^{-jw}]=-Im[X(e^{-jw}](奇对称)');
Task2.计算DFT
计算的4/8/16点离散傅里叶变换
以为例
说明:在Matlab里面因为精度的问题,0通常会是极小极小的数而不是真正的0,这就会导致用复数求相位不准确,所以在求相位之前需要先将复数按照某一误差归零,但是这一误差我还不知道怎么调好,所以16点4N点误归0了。
Task3.频谱-1
1.取求频谱
2.将补90个0求频谱
3.取求
说明:
1.虽然Task2编的DFT虽然相频特性效果不佳,但这里只观察幅频特性,所以继续用,后来换回fft效果是一样的。
2.周期性和对称性(对于实信号)共轭对称。只需要取就可以知道的全部信息。
3.第一排图:样本太少,采样频率不足
3.第二排图:补零所得更长一些的DFT对原序列的离散时间傅里叶变换提供了更为密集的样本,从而给出了一种高密度的谱,但是它没有任何新的信息附加到这个信号,只是让第一排图更平滑。很明显的主要频率并不在而是在和。
4.第三排图:为了得到更高分辨率的谱,我们需要观察更多的数据,这样就可以较为准确地描述的幅频特性。
点击查看代码
%要求: x(n),0<=n<=9, 0<=n<=9+90,0<=n<=99 fft clear;clc n=0:1:99;x=cos(0.48*pi*n)+cos(0.52*pi*n); %1.signal x(n),0<=n<=9 X_{1}(k) n1=0:1:9;y1=x(1:1:10); subplot(3,2,1);stem(n1,y1);title('x(n) 0<=n<=9'); k1=0:1:5;w1=2*pi/10*k1; Y1=y1*exp(-1i*n1'*w1);magY1=abs(Y1(1:1:6)); subplot(3,2,2);stem(w1/pi,magY1);title('DTFT 幅频特性图[0,π]'); %2.Add zeros(1,90) X_{2}(k) n2=0:1:99;y2=[x(1:1:10) zeros(1,90)]; subplot(3,2,3);stem(n2,y2);title('x(n) 0<=n<=9+90 zeros'); k2=0:1:50;w2=2*pi/100*k2; Y2=y2*exp(-1i*n2'*w2);magY2=abs(Y2(1:1:51)); subplot(3,2,4);plot(w2/pi,magY2);title('DTFT 幅频特性图[0,π]'); %3.signal x(n),0<=n<=99 X_{3}(k) subplot(3,2,5);stem(n,x); title('x(n),0<=n<=99');xlabel('n') k=0:1:50;w=2*pi/100*k; X=x*exp(-1i*n'*w);magX=abs(X(1:1:51)); subplot(3,2,6);plot(w/pi,magX);title('DTFT 幅频特性图[0,π]');
Task4.频谱-2
模拟信号采样率采0.04s/0.16s/0.32s求频谱
采样周期
以相距秒的采样间隔对采样,得到离散时间信号
随着采样点数的增多,得到更高分辨率的谱,这样就可以更为准确地描述信号的幅频特性。
点击查看代码
%要求:fs=400,t=0.04,0.16,0.32 dft clear;clc fs=400; Ts=1/fs; t1=0.04;N1=t1*fs;n1=0:1:N1;x1=cos(200*pi*n1*Ts)+sin(100*pi*n1*Ts); t2=0.16;N2=t2*fs;n2=0:1:N2;x2=cos(200*pi*n2*Ts)+sin(100*pi*n2*Ts); t3=0.32;N3=t3*fs;n3=0:1:N3;x3=cos(200*pi*n3*Ts)+sin(100*pi*n3*Ts); %DTFT K=500;k=0:1:K;w=pi*k/K; X1=x1*exp(-1i*n1'*w);X1=real(X1); X2=x2*exp(-1i*n2'*w);X2=real(X2); X3=x3*exp(-1i*n3'*w);X3=real(X3); %展示 subplot(3,2,1);stem(n1,x1);title('f=400Hz,t_{1}=0.04') subplot(3,2,2);plot(w/pi,X1);title('X_{1}(k)') subplot(3,2,3);stem(n2,x2);title('t_{2}=0.16') subplot(3,2,4);plot(w/pi,X2);title('X_{2}(k)') subplot(3,2,5);stem(n3,x3);title('t_{3}=0.32') subplot(3,2,6);plot(w/pi,X3);title('X_{3}(k)')
第四次
模仿钢琴音色
点击查看代码
clear;clc %made by tty 2021.11.15 %泛频参考:wuli玩 | MATLAB的音乐物理学(上)https://mp.weixin.qq.com/s/9XQ1mzeGzE0-jL9ijoIcww %《钢琴及其调律》廖志坚 附录 %% Musical Offering Canon A2 BWV1079 music.pitch=[ "C" "#D"... "G" "#G"... "B1" "G"... "#F" "F"... "E" "#D"... "D" "#C" "C" "B1"... "G1" "C" "F" "E"... "#D" "D"... "C" "#D"... "G" "F" "G" "c" "G" "#D" "D" "#D"... "F" "G" "A" "B" "c" "#D" "F" "G"... "#G" "D" "#D" "F" "G" "F" "#D" "D"... "#D" "F" "G" "#G" "#A" "#G" "G" "F"... "G" "#G" "#A" "c" "#c" "#A" "#G" "G"... "A" "B" "c" "d" "#d" "c" "B" "A"... "B" "c" "d" "#d" "f" "d" "G" "d"... "c" "d" "#d" "f" "#d" "d" "c" "B"... "c" "G" "#D" "C" "Sh" ... ]; music.Rhythm=[ 2 2 ... 2 2 ... 4/3 4 ... 4/3 4 ... 4/3 4 ... 4 4 4 4 ... 4 4 4 4 ... 2 2 ... 2 2 ... 8 8 8 8 8 8 8 8 ... 8 8 8 8 8 8 8 8 ... 8 8 8 8 8 8 8 8 ... 8 8 8 8 8 8 8 8 ... 8 8 8 8 8 8 8 8 ... 8 8 8 8 8 8 8 8 ... 8 8 8 8 8 8 8 8 ... 8 8 8 8 8 8 8 8 ... 8 8 8 8 2 ... ]; %% 播放 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%设置参数%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Fs=44100;%mp3标准采样品频率表44100 %四分音符为一拍,一拍0.5s,这个曲子4/4拍,拍的时长为2s Duration=2; T=0:Fs^-1:Duration; L=length(T); %%%%%%%%%%%%%%%%%%%%%%%%%%%分两个声部(左右手)%%%%%%%%%%%%%%%%%%%%%%%%%%%%% right=zeros(1, L);left=zeros(1, L); right=piece(Duration,music,Fs,2); %右手高音,频率高一些2*f left=piece(Duration,music,Fs,1); %右手低音,频率低一些f right = smoothdata(right); %做简单的平滑处理,希望没有剧烈变化又不希望旋律失真 left = smoothdata(left); pplay = fliplr(left); %根据螃蟹卡农的特点,正放和倒放都成旋律 stereo(:,2)=right; %将左右手旋律存入双声道 stereo(1:length(right),1)=pplay; %ppplay=play+pplay;%error %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%写入文件%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sound(stereo,Fs); % audiowrite("D:\大三上\3.5数字信号处理\钢琴\正向.wav",right,Fs); % audiowrite("D:\大三上\3.5数字信号处理\钢琴\反向.wav",left,Fs); % audiowrite("D:\大三上\3.5数字信号处理\钢琴\螃蟹卡农.wav",stereo,Fs); %根据键盘名获取对应的频率 function frequency=hz(name) %音列 KeyBoard.name=[ "A2" "#A2" "B2"... %大字二组 "C1" "#C1" "D1" "#D1" "E1" "F1" "#F1" "G1" "#G1" "A1" "#A1" "B1"... %大字一组 "C" "#C" "D" "#D" "E" "F" "#F" "G" "#G" "A" "#A" "B"... %大字组(1-27为低音区) "c" "#c" "d" "#d" "e" "f" "#f" "g" "#g" "a" "#a" "b"... %小字组 "c1" "#c1" "d1" "#d1" "e1" "f1" "#f1" "g1" "#g1" "a1" "#a1" "b1"... %小字一组 "c2" "#c2" "d2" "#d2" "e2" "f2" "#f2" "g2" "#g2" "a2" "#a2" "b2"... %小字二组(28-63为中音区) "c3" "#c3" "d3" "#d3" "e3" "f3" "#f3" "g3" "#g3" "a3" "#a3" "b3"... %小字三组 "c4" "#c4" "d4" "#d4" "e4" "f4" "#f4" "g4" "#g4" "a4" "#a4" "b4"... %小字四组 "c5"... %小字五组(64-88为高音区) ]; KeyBoard.rest=("Sh"); %调音 if (ismember(KeyBoard.rest,name)) frequency=0; else n=find(KeyBoard.name==name); %根据谱号找其在整个键盘中的位置 c=find(KeyBoard.name=="c");%28 %a=find(KeyBoard.name=="a");sigma=2^(1/12); pure=[261.63 275.59 290.63 310.05 326.97 348.83 367.86 391.99 413.39 435.95 465.09 490.47]; %纯律系数 tw=[261.63 277.18 293.66 311.13 329.63 349.23 369.99 391.99 415.30 440.00 456.16 493.88]; %用十二平均律系数 fifths=[261.63 279.11 294.34 314.02 331.15 349.23 372.37 392.45 418.68 441.55 471.04 496.74]; %五度相生律系数, if n < 28 p=mod((n-c),12)+1; group=(n-p-2)/12-1; frequency=pure(p)*2^(group); elseif n < 64 %frequency=440*sigma^(n-a); p=mod((n-c),12)+1; group=(n-p-2)/12-1; frequency=tw(p)*2^(group); else p=mod((n-c),12)+1; group=(n-p+2)/12-1; frequency=fifths(p)*2^(group); end end end %合成音符 function part=note(Fs,f,T) t=0:Fs^-1:T; L=length(t); %不同频率范围的泛音列 if Fs<=33 lvl_wave = [10000 2190 6095 2297 2131 1139 1745 576.8 724.8 883.4,... 207.9 355.4 403.9 146.2 901 392.6 212.5 192.4 368.8 234.9 99.55 198.8 393.8 72.65 89.79] / 10000; elseif Fs>33&&Fs<=524 lvl_wave = [10000 3007 6964 587.5 1185 660.4 1206 370.9 580.3 501.2 ... 260 224.3 57.98 319.9 685.9 550.4 200.3 200.3 244 221.4 115.9 71.42 299.3] / 10000; elseif Fs>524&&Fs<=1047 lvl_wave = [10000 6447 2793 3265 938.3 1371 1284 1.909 2549 1075 ... 44.95 1211 690.5 1085 566.8 428.9] / 10000; elseif Fs>1047&&Fs<=2094 lvl_wave = [10000, 2371, 885.3, 258.6] / 100000; else lvl_wave = [10000, 541] / 100000; end %依据泛音列合成泛音 overtone = zeros(1, L); %泛音初始化 for i = 1 : length(lvl_wave) overtone = overtone + lvl_wave(i) * sin(pi*f*i*t); %模仿泛音 end overtone=6*overtone; %包络 envelope1 =(1 - exp(-80*(t))) ./ (1 + exp(-80*(t))); % 包络函数1,指数渐入的效果 envelope1= [(zeros(fix(L/100)-1,1))' envelope1((fix(L/100)):end)]; % 模仿wav前面有一些空白 envelope2 = (t.^0.01.*exp(-2*t)); % 包络函数2,指数渐出的效果 part=overtone.*envelope1.*envelope2; end %合成一个声部 function single=piece(Duration,music,Fs,m) single=[]; for i=1:length(music.pitch) f=hz(music.pitch(i));%基音频率,单位赫兹 t=Duration*(1/music.Rhythm(i));%每个音对应的音长 part=note(Fs,m*f,t); single=[single,part]; end end %% 其它编程 % %根据键盘名获取对应的频率 % function frequency=hz(name) % %音列 % KeyBoard.name=[ % "A2" "#A2" "B2"... %大字二组 % "C1" "#C1" "D1" "#D1" "E1" "F1" "#F1" "G1" "#G1" "A1" "#A1" "B1"... %大字一组 % "C" "#C" "D" "#D" "E" "F" "#F" "G" "#G" "A" "#A" "B"... %大字组(1-27为低音区) % "c" "#c" "d" "#d" "e" "f" "#f" "g" "#g" "a" "#a" "b"... %小字组 % "c1" "#c1" "d1" "#d1" "e1" "f1" "#f1" "g1" "#g1" "a1" "#a1" "b1"... %小字一组 % "c2" "#c2" "d2" "#d2" "e2" "f2" "#f2" "g2" "#g2" "a2" "#a2" "b2"... %小字二组(28-63为中音区) % "c3" "#c3" "d3" "#d3" "e3" "f3" "#f3" "g3" "#g3" "a3" "#a3" "b3"... %小字三组 % "c4" "#c4" "d4" "#d4" "e4" "f4" "#f4" "g4" "#g4" "a4" "#a4" "b4"... %小字四组 % "c5"... %小字五组(64-88为高音区) % ]; % KeyBoard.rest=("Sh"); % %调音 % if (ismember(KeyBoard.rest,name)) % frequency=0; % else % n=find(KeyBoard.name==name); %根据谱号找其在整个键盘中的位置 % a=find(KeyBoard.name=="a");sigma=2^(1/12); % frequency=440*sigma^(n-a); % end % end % music.pitch=["C" "C" "G" "G" "A" "A" "G" "Sh" "F" "F" "E" "E" "D" "D" "C"]; % music.Rhythm=[4 4 4 4 4 4 4 8 4 4 4 4 4 4 4]; % music.pitch=[ % "E" "G" "G" "A" "G" "E" "C" "D" "E" "E" "D" "C" "D" ... % "E" "G" "G" "A" "G" "E" "C" "D" "E" "E" "D" "D" "C" ... % ]; % music.Rhythm=[ % 4 4 2 8 ... % 4 4 2 8 ... % 4 4 4 4 ... % 1 ... % 4 4 2 8 ... % 4 4 2 8 ... % 4 4 4 4 ... % 1 ... % ];
第五次
实序列的FFT算法
合二为一:用一个N点FFT计算两个实序列的FFT
一个小例子:
设两个长度的实序列:
解:令计算格式如下图
点击查看代码
clear;clc;close all; %初始化 %实序列的FFT算法对比 %参数初始化设置 N = 4; %FFT点数 %fft_time1=zeros(1,N); %存储运行所需时间的向量,1指“合二为一”方法 %fft_time2=zeros(1,N); %存储运行所需时间的向量,2指“直接FFT”方法 x1 = [1,1,3,1]; %第1个实序列 x2 = [2,1,2,2]; %第2个实序列 %合二为一:用一个N点FFT计算两个实序列的FFT tic x = complex(x1, x2); %根据x1、x2构造复数序列 X=fft(x); %对复序列做FFT Xf=flip(X); %为了求X*(N-k),先做翻转 Xf=[Xf(end) Xf(1:end-1)]; %X(0)即X(N),坑 Xc=conj(Xf); %取复共轭 X1=0.5*(X+Xc); %按照公式,时域的实部对应频域的对称部分 X2=-1j*0.5.*(X-Xc); %时域的虚部对应频域的反对称部分 toc %与分别直接做FFT对比验证 tic X11=fft(x1); X22=fft(x2); toc confire_1=(X1==X11); confire_2=(X2==X22);
点击查看代码
clear;clc;close all; %初始化 %实序列的FFT算法对比 %参数初始化设置 Nmax = 2048*2; %FFT点数从1变到2048*2看两种方法用时变化 fft_time1=zeros(1,Nmax); %存储运行所需时间的向量,1指“直接FFT”方法 fft_time2=zeros(1,Nmax); %存储运行所需时间的向量,2指“合二为一”方法 for n=1:1:Nmax x1 = rand(1,n); x2 = rand(1,n); t1=tic;Realfft(x1,x2);fft_time1(n)=toc(t1); t2=tic;Myfft(x1,x2);fft_time2(n)=toc(t2); end n=1:1:Nmax; plot(n,fft_time1,':b'); hold on; plot(n,fft_time2,':r'); legend('Realfft','Myfft') xlabel('N');ylabel('Time in Sec.') title('FFT execution times') %“直接FFT”方法 function [X1,X2]=Realfft(x1,x2) X1=fft(x1); X2=fft(x2); end %“合二为一”方法 function [X1,X2]=Myfft(x1,x2) x = complex(x1, x2); %根据x1、x2构造复数序列 X=fft(x); %对复序列做FFT Xf=flip(X); %为了求X*(N-k),先做翻转 Xf=[Xf(end) Xf(1:end-1)]; %X(0)即X(N),坑 Xc=conj(Xf); %取复共轭 X1=0.5*(X+Xc); %按照公式,时域的实部对应频域的对称部分 X2=-1j*0.5.*(X-Xc); %时域的虚部对应频域的反对称部分 end
第六次
Butterworth Filter
一个N阶低通滤波器的幅度平方响应:
表示截止频率(3dB截止频率)
阶数N的大小主要影响通带幅频特性的平坦程度和过渡带、阻带的下降速度,它由技术指标和
技术指标 | ||
---|---|---|
通带截止频率 | ||
阻带截止频率 | ||
通带最大衰减(即通带中允许的最大值) | dB | |
阻带最小衰减(即阻带上允许的最小值) | dB |
点击查看代码
clear;clc; %对输入的两个正弦信号x1(t)、x2(t)进行采样 f1=200; %正弦信号x1(t)的频率 f2=1700; %正弦信号x2(t)的频率 Fs=10000; %采样频率Fs Ts=1/Fs; %采样间隔Ts t=0:Ts:2; %“录音”2s x1=cos(2*pi*f1*t); %数字信号x1 x2=cos(2*pi*f2*t); %数字信号x2 x=x1+x2; L=length(t); Y1 = fft(x); P2 = abs(Y1/L); P1 = P2(1:L/2+1); P1(2:end-1) = 2*P1(2:end-1); f = Fs*(0:(L/2))/L; subplot(4,1,1),plot(f/1000,P1) title('Single-Sided Amplitude Spectrum of x(t)');xlabel('f/kHz');ylabel('|P1(f)|');xlim([0,2]) %设置低通滤波器指标 %通带截止频率 %阻带截止频率 %通带最大衰减 %阻带最大衰减 wp=2*pi*600;ws=2*pi*800;Rp=3;As=30; [N,wc]=buttord(wp,ws,Rp,As,'s'); [z,p,k]=buttap(N); [bp,ap]=zp2tf(z,p,k); [B,A]=lp2lp(bp,ap,wp); % [B,A]=butter(N,wc,'s'); k=0:L/2;wk=2*pi*f; Hk=freqs(B,A,wk); subplot(4,1,2),plot(f/1000,20*log10(abs(Hk)));grid on;hold on pha=angle(Hk)*180/pi;plot(f/1000,20*log10(abs(pha))); title(sprintf('N = %d Butterworth Lowpass Filter',N));xlabel('f/kHz');ylabel('-A(f)/dB');xlim([0,2]) %除去高频信号 A=2*abs(Y1(1:L/2+1)).*(abs(Hk)); subplot(4,1,3),plot(f/1000,A);xlim([0,2]);grid on %还原信号 A=[A(1:end-1),flip(A)]; z2=real(ifft(A)); subplot(4,2,7),plot(f(1:200)/1000,z2(1:200)*L/2) subplot(4,2,8),plot(f(1:200)/1000,x1(1:200)*L/2)
第七次
FIR实现线性相位
FIR实现非线性相位
点击查看代码
clear all;clc; %设计滤波器 %Design a 31-tap linear-phase lowpass filter. Display its magnitude and phase responses. b = cfirpm(30,[-1 -0.5 -0.4 0.7 0.8 1],@lowpass); fvtool(b,1,'OverlayedAnalysis','phase') %Design a nonlinear-phase allpass FIR filter of order 22 with frequency response given approximately by an efunction % n = 22; % Filter order % f = [-1 1]; % Frequency band edges % w = [1 1]; % Weights for optimization % b = cfirpm(n,f,'allpass',w,'real'); % Approximation [audio,fs]=audioread('D:\大三上\3.5数字信号处理\上机matlab\第七次\boliping.0033.wav');%声音读取 audio = audio(:,1); %双通道变单通道 T = 1/fs;%采样间隔 n = length(audio); t = (0:n-1)*T;%时间轴 f = (0:n-1)/n*fs;%频率轴 k=-fs+1:fs; w=(2*pi/fs)*k; %快速傅里叶变换 audio_fft = fftshift(fft(audio,n)); audioab = abs(audio_fft); subplot(2,2,1) plot(k/fs,20*log10(audioab)) %幅值变换为分贝单位 title('fft后信号幅值');ylabel 'A / dB';ylim([-100,50]) subplot(2,2,2) plot(k/fs,angle(audio_fft)/pi) title('fft后信号相位');ylabel 'Phase / \pi' %滤波 z=filter(b,1,audio); z_fft= fftshift(fft(z)); %滤波后的信号频谱 audiowrite('6.wav',abs(z),fs) hold on; subplot(2,2,3) plot(k/fs,20*log10(z_fft)) %幅值变换为分贝单位 title('滤波后fft信号幅值');ylabel 'A / dB';ylim([-100,50]) subplot(2,2,4) plot(k/fs,angle(z_fft)/pi) title('滤波后fft信号相位');ylabel 'Phase / \pi'
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)