我想知道如何创建一个javascript函数来转换音乐和弦。
因为我并不指望这里的每个人都能成为音乐家,所以我将尝试解释音乐理论中它是如何工作的。希望我别忘了什么。如果是,音乐家们,请纠正我。
1)简单和弦
简单的和弦几乎和字母表一样简单,它是这样的:
C,C#,D,D#,E,F,F#,G,G#,A,A# B
因此,如果最初的chord是E,并且我们想要转置+1,则得到的和弦是F。如果我们转置+4,得到的和弦是G#。
2)扩展和弦
它们的工作方式几乎像简单的和弦,但包含更多的字符,这些字符在转换时可以安全地忽略。例如:
C#7,Dsus7,Emi,Fsus4,F#mi,G.
同样,和简单的和弦一样,如果我们转换Dsus7 +3= Fsus7
3)非根部低音
当低音演奏的音调与和弦的根音不同时,就会出现问题。这是由一个斜杠后的和弦,也需要转置。示例:
C/G、Dmi/A、F#sus7 7/A#
与示例1和例2一样,所有内容都是相同的,但斜杠后面的部分也需要转换,因此:
C/G +5= F/C
F#sus7/A# +1= Gsus7/B
我认为这应该是全部,除非我忘了什么。
因此,基本上,假设您有一个名为chord的javascript变量和transpose值transpose。什么代码会把和弦转过来?
示例:
var chord = 'F#sus7/C#';
var transpose = 3; // remember this value also may be negative, like "-4"
... code here ...
var result; // expected result = 'Asus7/E';发布于 2011-10-29 04:22:41
像这样的事怎么样:
function transposeChord(chord, amount) {
var scale = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
return chord.replace(/[CDEFGAB]#?/g,
function(match) {
var i = (scale.indexOf(match) + amount) % scale.length;
return scale[ i < 0 ? i + scale.length : i ];
});
}
alert(transposeChord("Dm7/G", 2)); // gives "Em7/A"
alert(transposeChord("Fmaj9#11", -23)); // gives "F#maj9#11"请注意,我加入了"F#maj9#11“示例,只是为了让您更多地思考如何构成有效的和弦名称:您可能会找到一个"#”尖锐符号,它不跟在字母后面(在本例中,它属于"11")。
而且,很明显,我的函数只理解锐利,不懂平面语,不懂键,因此,当它真正应该是"C#/E#“时,transposeChord("C/E", 1)会给出"C#/F”。
发布于 2017-08-31 11:01:25
只是为了进一步了解nnnnnn的答案。我们可以使用他的代码,并添加更多的代码,以使它实际上工作的单位。
transposeChord("F#sus7/A#", 1)
> "Gsus7/B"
transposeChord("Bb", 1)
> "B"
... works like a charm
function transposeChord(chord, amount) {
var scale = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
var normalizeMap = {"Cb":"B", "Db":"C#", "Eb":"D#", "Fb":"E", "Gb":"F#", "Ab":"G#", "Bb":"A#", "E#":"F", "B#":"C"}
return chord.replace(/[CDEFGAB](b|#)?/g, function(match) {
var i = (scale.indexOf((normalizeMap[match] ? normalizeMap[match] : match)) + amount) % scale.length;
return scale[ i < 0 ? i + scale.length : i ];
})
}<!-- Example Page -->
Chord: <input id="chord" type="text" value="C#" style="width:70px">
transposed by <input id="amount" type="number" value="0" style="width:30px">
= <input id="new-chord" type="text" style="width:70px">
<button onclick="document.getElementById('new-chord').value = transposeChord(document.getElementById('chord').value,parseInt(document.getElementById('amount').value))">Calculate</button>
发布于 2011-10-29 03:40:17
function transpose(chord, increment)
{
var cycle = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
var el = chord.charAt(0);
if(chord.length > 1 && chord.charAt(1) == '#')
{
el += "#";
}
var ind = cycle.indexOf(el);
var newInd = (ind + increment + cycle.length) % cycle.length;
var newChord = cycle[newInd];
return newChord + chord.substring(el.length);
}我会让你找出低音部分,因为它实际上只是调用功能两次。
此外,对于不支持这里的旧浏览器,可以在函数之前添加代码indexOf。
我在演示上放了一个jsFiddle。
编辑:问题是负模数。只要负数不超过长度(例如,你不能向下转100步),上面的内容就会起作用。
https://stackoverflow.com/questions/7936843
复制相似问题