首页 > 解决方案 > 如何在 MATLAB 中使用 FFT 和 findpeaks() 从 .WAV 文件重新创建乐器声音?

问题描述

我想根据我拥有的 .WAV 格式的样本在 MATLAB 中生成我自己的 Kick、Clap、Snare 和 Hi-Hat 声音样本。

现在它听起来根本不正确,我想知道我的代码是否没有意义?或者,如果是我错过了一些合理的理论。

这是我现在的代码。

 [y,fs]=audioread('cp01.wav');
 Length_audio=length(y);
 df=fs/Length_audio;
 frequency_audio=-fs/2:df:fs/2-df;
 frequency_audio = frequency_audio/(fs/2); //Normalize the frequency
 figure
 FFT_audio_in=fftshift(fft(y))/length(fft(y));
 plot(frequency_audio,abs(FFT_audio_in));

y 的原始图。

声音

我的 FFT

在此处输入图像描述

我正在使用 findpeaks() 函数来查找幅度大于 0.001 的 FFT 的峰值。

[pk, loc] = findpeaks(abs(FFT_audio_in), 'MinPeakHeight', 0.001);

然后我从频率音频(正频率)和相应的峰值中找到相应的归一化频率。

 loc = frequency_audio(loc);
 loc = loc(length(loc)/2+1:length(loc))
 pk = pk(length(pk)/2+1:length(pk))

所以一方面,标准化的 FFT 看起来像这样。

在此处输入图像描述

由于它看起来像 FFT,我认为我应该能够通过对具有正确幅度和频率的正弦曲线求和来重新创建声音。由于拍手声有 21166 个数据点,我将其用于 for 循环。

for i=1:21116

    clap(i) = 0;
for j = 1:length(loc);
    clap(i) = bass(i) + pk(j)*sin(loc(j)*i);

end

end

但这会导致以下声音,与原始声音相去甚远。 在此处输入图像描述

我应该怎么做?

标签: matlabaudiofftaudio-processing

解决方案


您正在对样本的整个时间段进行 FFT,然后在整个持续时间内生成平稳的正弦波。这意味着鼓的时间特征消失了。时间特征是打击乐清音乐器的最大特征。

由于这非常重要,我建议您先从那里开始,而不是从频率内容开始。时间特征可以通过信号的包络来近似。MATLAB 为此提供了一个方便的函数,称为信封。使用它来提取样本的信封。

然后生成一些白噪声并将噪声乘以包络,重新创建一个非常简单的打击乐器版本。您应该听到 Kick、Clap、Snare 和 Hi-Hat 之间的明显区别,尽管听起来与原版不同。

一旦这工作,您可以尝试合并频率信息。我建议使用 STFT 来获得声音的频谱图,这样您就可以看到频谱如何随时间变化。


推荐阅读