matlab - 如何在 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
我应该怎么做?
解决方案
您正在对样本的整个时间段进行 FFT,然后在整个持续时间内生成平稳的正弦波。这意味着鼓的时间特征消失了。时间特征是打击乐清音乐器的最大特征。
由于这非常重要,我建议您先从那里开始,而不是从频率内容开始。时间特征可以通过信号的包络来近似。MATLAB 为此提供了一个方便的函数,称为信封。使用它来提取样本的信封。
然后生成一些白噪声并将噪声乘以包络,重新创建一个非常简单的打击乐器版本。您应该听到 Kick、Clap、Snare 和 Hi-Hat 之间的明显区别,尽管听起来与原版不同。
一旦这工作,您可以尝试合并频率信息。我建议使用 STFT 来获得声音的频谱图,这样您就可以看到频谱如何随时间变化。
推荐阅读
- java - 如果使用@Autowired + @Qualifier 注入,如何避免在重构期间更改 bean 名称
- sh - 如何从目录中的一堆文件中删除长文件名中的一些文本
- r - knitr 将 (1) 更改为
- 渲染html时?
- javascript - Javascript在单元格点击时修改网页内容
- logging - 通过 ConfigurationAdmin 更新 PAX 日志记录配置
- c - 尝试计算 C 中的单词时 EOF 未终止
- php - 如何提高 Symfony 中的查询性能?
- drupal - Drupal webform多步保存一步一步
- excel - 为列中的最后一行定义一个整数
- makefile - Make:目标选择