0%

ee261中的代码题(1)

本题是ee261中Problem Set 4的一道matlab代码题,主要用到了fft和频域的相关知识。
ee261相关知识点整理博客:https://www.cnblogs.com/TaigaCon/p/5079156.html


坑点

1.matlab的fft函数

首先,根据傅里叶变换的公式可以得知,频域的F(s)关于y轴共轭对称,也就是说两边实部相同而虚部相反。然而,现实中正数频率才有意义,负数频率的数据则使用其它方法处理。
在matlab中,对时域数据进行fft处理后,得到的频域数据前一半为正数频率下的频谱,也就是现实中有意义的数据;而后一半为负数频率下的数据,可以直接删除掉;或者使用fftshift。
但是在频域处理之后,ifft之前要注意恢复到matlab fft之后的模式(即前一半正频率,后一半负频率,两部分关于中间对称),否则点数N都对不上,这肯定是不对的。

参照:https://www.zhihu.com/question/39212146/answer/80239362
第三个回答

2.ifft后取时域信号的实部而非模值

见matlab代码最后,如下写法是错误的:

1
xDecode = abs(ifft(yDecode));

正确如下式:

1
xDecode = real(ifft(yDecode));

matlab代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
%https://see.stanford.edu/materials/lsoftaee261/PS-4-2007.pdf
%第五题,matlab编程题
%题目大意:一段人声音频信号采取了加密,加密方式如下:
%将频域均分成四份,分别称为ABCD;题目中的音频将ABCD打乱为CBDA。
%现在请你还原该音频,并转录。

%%导入信号并进行时域上观察
[x,Fs]=audioread('PS-4-scramble.wav');%可以在官网上下载到:https://see.stanford.edu/materials/lsoftaee261/PS-4-scramble.wav
T=1/Fs; %采样周期
t=(1:length(x))*T;%采样时间
figure(1);
% plot(t,x);
% title('原始信号时域图形');
% xlabel('时间t/s');
% ylabel('音量');

%%对信号fft,变换到频域
y=fft(x); %做FFT变换
yMod = abs(y);
f=(0:length(y)-1).*Fs/length(y);
plot(f,y) %画出原始信号的频谱图
s = 1/(length(y)*T);%delta_s


%%解码
%CBDA->ABCD
yCell = cell(4,1);
sliceNum = length(y)/8;
for i = 0:3
yCell{i+1,1} = y(i*sliceNum+1:(i+1)*sliceNum,1);
end

yDecode = [
yCell{4,1};
yCell{2,1};
yCell{1,1};
yCell{3,1};
conj(yCell{3,1});
conj(yCell{1,1});
conj(yCell{2,1});
conj(yCell{4,1});
];
% plot(f,yDecode);
%%解码之后ifft,获得时域上音频信号xDecode
xDecode = real(ifft(yDecode));
sound(xDecode,Fs);