wav文件和FFT的matlab中的Audioread

Posted

技术标签:

【中文标题】wav文件和FFT的matlab中的Audioread【英文标题】:Audioread in matlab of wav file and FFT 【发布时间】:2015-05-04 18:00:08 【问题描述】:

我正在使用 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 图:

也许我错过了有关 FFT 的一些信息,但我预计会有两个垂直棒棒糖。 我注意到的另一件事是错误的,当我从文件中读取声音后播放声音时,它的长度更长,音高明显更低。 我的猜测是采样率问题,但我真的不知道该怎么办。

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

那是因为您没有绘制幅度。您正在绘制的是系数,但这些是复数值。因此,横轴是实数分量,纵轴是虚数分量。此外,当您单独使用 sound 时,默认采样频率为 8 kHz(准确地说是 8192 Hz),这解释了为什么您的声音音调较低。您需要使用采样频率作为sound 的第二个参数,这是由audioread 的第二个输出提供给您的。

所以,尝试将abs 放在fft 调用之后,并将Fs 放入sound

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

另外,上面的代码没有正确地绘制水平轴。如果您想这样做,请确保在进行傅里叶变换后fftshift您的光谱,然后正确标记您的轴。如果您想确定每个水平值的频率,Paul R 的这篇很棒的帖子可以解决问题:How do I obtain the frequencies of each value in an FFT?

基本上,FFT 中的每个水平值都是这样的:

F = i * Fs / N

i 是 bin 编号,Fs 是采样频率,N 是您用于 FFT 的点数。 F 是您正在查看的组件的解释频率。

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

因为您在尝试编写的代码中实际所做的是显示频谱的两侧,这就是为什么最好将频谱居中以使直流频率位于中间而左侧是负值谱图,右侧为正谱图。

我们可以在此处将其合并到您的代码中:

[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 正弦音的音频生成代码,然后运行上面的代码来绘制频谱,我得到了:

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

【讨论】:

投反对票:想解释一下你投的反对票吗?这个答案很清楚,而且切中要害。

以上是关于wav文件和FFT的matlab中的Audioread的主要内容,如果未能解决你的问题,请参考以下文章

wav音频文件解析读取 定点转浮点分析 幅值提取(C语言实现)

matlab中的FFT,出乎意料的结果

通过 C 中的 FFT 将 1000Hz 噪声添加到 wav 文件

WAV 文件的 FFT 和输出以绘制频谱

我如何获得定义频带中的所有 fft bin 数量?

提取 Wav 文件的时域 double[] 以输入到 FFT - Java