我在Javascript中有一个名为NoteArray的数组,大小为16。我还有一个名为NoteToNumberMapping的静态2D数组,大小为11x12,即看起来像这样。现在,作为输入,我让用户选择12个标准注释的任意组合(C#-D#-E#-G#- all #-B),或者根本没有。例如:"C G G#",或"D D# G A B",或空白等。PS:如有必要,注释可能是“失序的”(例如:"D -A-C C#")
以“C G G#”为例,我想提到二维阵列,在倍频程0中,C、G和G#的对应数字是0、7和8。同样,对于倍频程1,数字是12、19和20。按照这种方式,前16个数字是: 0、7、8、12、19、20、24、31、32、36、43、44、48、55、56、60。
我想把这16个号码分配给我的初始NoteArray。
My approach
我将2D数组实现为包含这些字母的128个条目的一维数组。因此,第0项是C0,第1项一直是C#0,直到第127项(G10)。我想使用的事实是,2D表中的值是1-127之间的线性级数。但是我最终得到了3个嵌套的for循环,仍然无法使它工作。在Javascript中实现这一目标的有效方法是什么?
发布于 2014-07-27 00:59:00
您可以首先从便笺名到相对注释号创建一个查找表:
var relativeNoteNumberTable = {
'C': 0, 'C#': 1, 'D': 2, 'D#': 3, 'E': 4, 'F': 5, 'F#': 6,
'G': 7, 'G#': 8, 'A': 9, 'A#': 10, 'B': 11
};
然后,您可以相对容易地获得所选音符的相对注释号:
var selectedNotes = 'C G G#';
var relativeNoteNumbers = selectedNotes.split(' ')
.filter(function(note) { return note }) // remove blanks
.map(function(note) { return relativeNoteNumberTable[note] });
console.log(relativeNoteNumbers); // [0, 7, 8]
然后观察到,对于每个八度音阶,MIDI音符数增加了12。如果您想要为每个八度音阶设置这些音符,直到有16个音符为止,您可以这样做:
var notes = [];
while(notes.length < 16) {
notes.push(Math.floor(notes.length / relativeNoteNumbers.length) * 12 +
relativeNoteNumbers[notes.length % relativeNoteNumbers.length]);
}
发布于 2014-07-27 00:57:26
你应该能够在线性时间复杂度中做到这一点。您应该使用一个对象来存储2D数组,而不是如下所示:
my2dArray = {
"0C": 0,
"0C#": 1,
"0D": 2,
...
}
然后,您将不必遍历2D数组来获得所需的映射值。您只需执行my2dArraymyKey,这就有一个固定的查找时间。
https://stackoverflow.com/questions/24976838
复制相似问题