我正在尝试使用MATLAB读取WAV文件中有音乐音符序列的项目。例如,我的WAV文件可能包含一系列C-D-C-E。把这个文件加入我的程序将打印出“C D C E”。用matlab识别声音的音高
我尝试使用WAVREAD将文件转换为矢量,然后 使用采样将其下采样并制作为单通道文件。 然后,我能够想出在某些频率具有“峰值”的谱图。
从这里,我想获得关于如何让MATLAB识别峰值频率的帮助,从而使我能够打印出笔记。
还是我在错误的轨道上?
在此先感谢!
我正在尝试使用MATLAB读取WAV文件中有音乐音符序列的项目。例如,我的WAV文件可能包含一系列C-D-C-E。把这个文件加入我的程序将打印出“C D C E”。用matlab识别声音的音高
我尝试使用WAVREAD将文件转换为矢量,然后 使用采样将其下采样并制作为单通道文件。 然后,我能够想出在某些频率具有“峰值”的谱图。
从这里,我想获得关于如何让MATLAB识别峰值频率的帮助,从而使我能够打印出笔记。
还是我在错误的轨道上?
在此先感谢!
你是在正确的轨道上,但这不是一个简单的问题。我会建议看看是什么叫chromagram。这将使用从光谱图中收集的信息,并将其“存入”到钢琴音符频率中。这将给出歌曲谐波含量的近似值。虽然这可能不完全准确,但因为音符谐波中存在剩余能量,但这是一个开始。
是否意识到转录这是你正在做的事情,是一项非常困难的任务,并且尚未完全解决。人们至今仍在研究这一点。我有代码来产生色度,但我将不得不去挖掘它。
编辑
下面是一些代码色度
clc; close all; clear all;
% didn't have wav file, but simply replace this with the following
% [audio,fs] = wavread('audioFile.wav')
audio = rand(1,10000);
fs = 44100; % temp sampling frequency, will depend on audio input
NFFT = 1024; % feel free to change FFT size
hamWin = hamming(NFFT); % window your audio signal to avoid fft edge effects
% get spectral content
S = spectrogram(audio,hamWin,NFFT/2,NFFT,fs);
% Start at center lowest piano note
A0 = 27.5;
% all 88 keys
keys = 0:87;
center = A0*2.^((keys)/12); % set filter center frequencies
left = A0*2.^((keys-1)/12); % define left frequency
left = (left+center)/2.0;
right = A0*2.^((keys+1)/12); % define right frequency
right = (right+center)/2;
% Construct a filter bank
filter = zeros(numel(center),NFFT/2+1); % place holder
freqs = linspace(0,fs/2,NFFT/2+1); % array of frequencies in spectrogram
for i = 1:numel(center)
xTemp = [0,left(i),center(i),right(i),fs/2]; % create points for filter bounds
yTemp = [0,0,1,0,0]; % set magnitudes at each filter point
filter(i,:) = interp1(xTemp,yTemp,freqs); % use interpolation to get values for frequencies
end
% multiply filter by spectrogram to get chroma values.
chroma = filter*abs(S);
%Put into 12 bin chroma
chroma12 = zeros(12,size(chroma,2));
for i = 1:size(chroma,1)
bin = mod(i,12)+1; % get modded index
chroma12(bin,:) = chroma12(bin,:) + chroma(i,:); % add octaves together
end
这应该做的伎俩。这可能不是最快的解决方案,但它应该完成工作。
当然可以优化。
由于MZimmerman6这是一个非常复杂的问题。峰值到峰值测量可能会成功,但如果音乐变得复杂,肯定不会。之前我已经解决了这个问题,并且看到其他人也尝试了这个,我见过的最成功的项目涉及以下内容:
1)限制时间。一个程序实际上可能很难确定一个音符何时改变!如果你试图从乐器中分离人声,或者例如当两个和弦按顺序播放时,尤其如此,但是它们之间有一个音符保持不变。因此,通过限制时间来查明每一段音乐何时发生,因此在您的情况下,将音轨分成四个音轨,每个音符一个。您可以使用每个音符的攻击来获得优势,自动将攻击检测为要测试的新分段的开始。
2)限制频率。你必须使用你所知道的,否则你将需要进行本征模式比较。奇异值分解在这个领域已经很有效。但是,如果您以某种方式让钢琴演奏单独的音符(单独),并且您有钢琴演奏曲目的录音,您可以做的是对每个段进行快速傅里叶变换(参见上面的时间限制),切出噪音,并且比较它们。然后,您使用减法或其他度量来确定每个音符的最佳“适合度”。
这是对问题的粗略解释,但请相信我,对这种分析的限制越多越好。
是的,我绝对需要这些限制因为这是我的第一个项目。谢谢! – Diletante
谢谢! 我会查找chromagram是什么。 但无论如何要正确访问生成的频谱图数据? – Diletante
是'S =谱图(x,窗口,noverlap,nfft,fs)' – MZimmerman6
太棒了!我一定会尝试你的代码。谢谢 – Diletante