如何在MATLAB中使用FFT和findpeaks()从.WAV文件重新创建乐器声音?

时间:2019-05-03 11:32:26

标签: matlab audio fft audio-processing

我想基于.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的原始图。

The sound

我的y的FFT

enter image description here

我正在使用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看起来像这样。

enter image description here

由于它看起来像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

但这会导致以下声音,与原始声音相去甚远。 enter image description here

我该怎么做?

1 个答案:

答案 0 :(得分:1)

您正在对样本整个时间段进行FFT,然后在整个持续时间内生成固定的正弦波。这意味着感光鼓的暂时性特征消失了。而时间特征是打击乐器的最大特征。

由于这非常关键,因此建议您先从此处开始,而不要从频率内容入手。 时间签名可以通过信号的包络来近似。 MATLAB为此提供了一个方便的功能,称为envelope。用它来提取样品的包膜。

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

一旦成功,您就可以尝试合并频率信息。我建议您使用STFT来获取声音的声谱图,以便您查看频谱随时间的变化。