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

如何在MATLAB中使用FFT和findpeaks()从.WAV文件中重建乐器声音?,matlab,audio,fft,audio-processing,Matlab,Audio,Fft,Audio Processing,我想根据.WAV格式的示例,在MATLAB中生成我自己的踢腿、拍手、圈套和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);

我想根据.WAV格式的示例,在MATLAB中生成我自己的踢腿、拍手、圈套和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的原图

我的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
但这会产生以下声音,与原始声音相差甚远。


我该怎么做呢?

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

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

然后产生一些白噪声,将噪声乘以包络线,重新创建一个非常简单的打击乐器版本。你应该能听到踢腿、拍手、圈套和高帽之间的明显区别,尽管听起来和原来的不一样

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