我正在编写一段代码,找出歌曲在任何给定时间播放的频率(音符)(注:目前我正在测试它,只捕捉歌曲的第一秒)。为此,我将音频文件的第一秒钟分成8个不同的块。然后,我对每个块执行FFT,并用以下代码绘制它:
% Taking a second of an audio file and breaking it into n many chunks and
% figuring out what frequencies make up each of those chunks
clear all;
% Read Audio
fs = 44100; % sample frequency (Hz)
full = audioread('song.wav');
% Perform fft and get frequencies
chunks = 8; % How many chunks to break wave into
for i = 1:chunks
beginningChunk = (i-1)*fs/chunks+1
endChunk = i*fs/chunks
x = full(beginningChunk:endChunk);
y = fft(x);
n = length(x); % number of samples in chunk
amp = abs(y)/n; % amplitude of the DFT
%%%amp = amp(1:fs/2/chunks); % note this is my attempt that I think is wrong
f = (0:n-1)*(fs/n); % frequency range
%%%f = f(1:fs/2/chunks); % note this is my attempt that I think is wrong
figure(i);
plot(f,amp)
xlabel('Frequency')
ylabel('amplitude')
end
当我这样做时,我得到的图形如下所示:
看起来我画的点太多了,因为在图的最右边,频率的幅度上升了,所以我想我用的是双面谱。我想我只需要使用1:fs/2的样本,问题是我没有足够大的矩阵来获取那么多的点。我试着从1:fs/2/chunk开始,但我不相信这些值是正确的,所以我把它们注释掉了。当样本数少于fs/2时,如何找到单侧光谱?
当我绘制所有图表时,我注意到给出的频率几乎完全相同。这让我很惊讶,因为我认为我把这些音块做得足够小,只有在准确的时间发生的频率才能被捕捉到,因此我会得到当前播放的音符。如果有人知道我如何更好地挑出每次演奏的音符,我将不胜感激。