所以我创建了一个MATLAB程序来检测钢琴录音中的频率。现在我需要将这些检测到的频率转换为相应的钢琴音符。
我知道有一个关于使用A4(440Hz)作为参考音符的理论,并基于此推导出其余部分。但我正在寻找像查找表这样的东西,在那里我可以通过查看查找表直接调用相应的钢琴音符。我不太确定如何继续谈论它,所以想要一些关于我能做什么的建议...... Thanx
答案 0 :(得分:5)
从here(只是第一次Google点击,没什么特别的),您可以看到同等级别中所有音符的所有频率都是通过
相关联的。f = f0 · 2^(i/12)
f0 = A4 = 440
Hz,i
距离基本音符半步的数量。这允许您为所有笔记创建查找表(LUT
)。
你需要做的一件事就是:
今天是你的幸运日(我很无聊和拖延:),所以这是一个相当完整的实现,从C0到E8的笔记♭:
% Your frequencies (can be of any size, must be in Hz)
V = [17 450 4000];
% Generate the lookup table
LUT = 440 * (2^(1/12)).^(-57:42);
% The names of all those notes
noteNames = {...
'AN' 'AN♯/BN♭' 'BN' 'CN' 'CN♯/DN♭' 'DN' 'DN♯/EN♭' 'EN' 'FN' 'FN♯/GN♭' 'GN' 'GN♯/AN♭'};
allNotes = [];
for ii = 0:8
allNotes = [allNotes regexprep(noteNames, 'N', num2str(ii))]; end %#ok<AGROW>
allNotes = allNotes(4:end-4);
% Indices into the lookup table
[~,I] = min(abs(bsxfun(@minus, V(:), LUT)), [], 2);
% The named noted corresponding to your frequencies
allNotes(I)
答案 1 :(得分:0)
您不需要查找表,也不必将自己限制在特定范围内:(Javascript)
function getNoteFromFrequency(frequency) {
var noteOrder = 'G# A A# B C C# D D# E F F# G'.split(" ");
var n = Math.round(49 + 12 * Math.log(frequency / 440) / Math.log(2));
var note = noteOrder[n % noteOrder.length];
var index = Math.ceil((n - 3) / noteOrder.length);
return note + index;
}