在Matlab中使用Audioread读取WAV文件和FFT

3

我正在使用Matlab,希望对之前在Matlab上录制的wav文件执行FFT。

fs = 44100; % Hz
t = 0:1/fs:1; % seconds
f = 600; % Hz

y = sin(2.*pi.*f.*t);

audiowrite('600freq.wav',y,fs)

这是我在wav文件中记录的方式。 现在开始进行读取和FFT处理:

[y,Fs] = audioread('600freq.wav');
sound(y)
plot(fft(y))

这是我得到的FFT图:

enter image description here

也许我对FFT理解有所遗漏,但我期望看到两个垂直的棒棒糖。

另外一个我注意到的问题是,当我读取文件并播放声音时,声音变长了且音调显著降低。 我猜测这可能是采样率的问题,但我真的不知道该怎么办。

非常感谢您提前的任何帮助。

1个回答

7
那是因为您没有绘制幅度。您正在绘制系数,但这些系数是复数值。因此,水平轴是实数分量,而垂直轴是虚数分量。此外,当您仅使用sound时,默认采样频率为8 kHz(确切地说是8192 Hz),这就解释了为什么您的声音音调较低。您需要将采样频率作为第二个参数传递给sound,这是通过audioread的第二个输出给出的。
因此,请尝试在fft调用后添加abs,并且在sound中使用Fs
[y,Fs] = audioread('600freq.wav');
sound(y, Fs);
plot(abs(fft(y)))

此外,上面的代码未能正确绘制水平轴。如果您想要正确显示,请确保在进行傅里叶变换后使用fftshift函数处理您的频谱,然后正确标记轴线。如果您想要确定每个水平值的频率是多少,可以参考这篇由Paul R撰写的文章:如何获取FFT中每个值的频率? 基本上,您的FFT中每个水平值都是:
F = i * Fs / N

i是bin号,Fs是采样频率,N是用于FFT的点数。 F是所查看分量的解释频率。

默认情况下,fft假定N是数组中总点数。 对于单边FFT,由于奈奎斯特采样定理,i0,1,2,增加到floor((N-1)/2)

因为在你尝试编写的代码中实际上显示了频谱的两侧,所以将频谱居中对齐是很好的选择,这样DC频率就位于中间,左侧是负频谱,右侧是正频谱。

我们可以将其合并到你的代码中:

[y,Fs] = audioread('600freq.wav');
sound(y, Fs);
F = fftshift(abs(fft(y)));
f = linspace(-Fs/2, Fs/2, numel(y)+1);
f(end) = [];    
plot(f, F);

现在水平轴反映了每个分量的正确频率,垂直轴反映了每个分量的幅度。

通过运行生成600 Hz正弦波音频的代码,然后运行上面的代码来绘制光谱图,我得到了这个:

enter image description here

请注意,我在光谱图的正侧插入了一个工具提示...它大约是600 Hz!


3
投反对票者:能否解释一下你的反对意见?这个答案非常清晰且直截了当。 - rayryeng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接