您的任务是创建一个功能,以转换音乐和弦。
我只是想看看你们能用这个做些什么:
因为我并不指望这里的每个人都能成为音乐家,所以我将尝试解释音乐理论中它是如何工作的。希望我别忘了什么。如果是,音乐家们,请纠正我。
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';这里的原始问题:https://stackoverflow.com/questions/7936843/how-do-i-transpose-music-chords-using-javascript (请注意,他要求JS,对于这个挑战,我不在乎它是用什么语言写的)
发布于 2011-10-29 04:39:20
好的,在问题的限制范围内,如果与真正的音乐一起使用(平底鞋是最明显的),而不是满足很多你需要考虑的事情:
function t(c,a) {
var s=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],i;
return c.replace(/[A-G]#?/g,function(m){return s[(i=(s.indexOf(m)+a)%s.length)<0?i+s.length:i];});
}这是我第一次尝试代码-高尔夫,所以我希望我已经采取了正确的方法。以下是我最初在stackoverflow.com上发布的可读版本:
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 ];
});
}发布于 2011-11-17 09:22:34
作为初步的努力,我想充实一些“全面解决方案”应该考虑的内容。
当转换音乐钥匙时,一个人会根据“四分一圈”(或五分之五,视你要走的方向而定)的距离,给钥匙签名增加尖利或平调。
fifths from C up to the enharmonic
key: C G D A E B F# C# G# D# A# E# B#
add: F# C# G# D# A# E# B# F## C## G## D## A##
fourths from C down to the enharmonic
key: C F Bb Eb Ab Db Gb Cb Fb Bbb Ebb Abb Dbb
add: Bb Eb Ab Db Gb Cb Fb Bbb Ebb Abb Dbb Gbb因此,C的键可以用零高音或平行线写,也可以用12高音写,也可以用12平调写。第一种选择显然是优越的。
但是我们只需要上面表格的中间部分,因为所有这些双尖和双平面图意味着一些注释被赋予了一个过于复杂的名字。因此,提取中间部分并按顺序排列给我们这张钥匙列表。
C Db(5 'b's) D(2#) Eb(3b) E(4#) F(1b) F#(6#)[or Gb(6b)]
G(1#) Ab(4b) A(3#) Bb(2b) B(5#) C而且,在F#和Gb之间(所有的公寓看起来都比一个孤独的锋利)更漂亮,这就意味着:
C Db D Eb F Gb G Ab A Bb B C但是对于命名和弦来说,情况就不那么清楚了,因为名字中带有意外。
发布于 2021-01-17 21:16:18
此代码处理bemol输入:
let N=["A","A#","B","C","C#","D","D#","E","F","F#","G","G#"]
let t=(r,n)=>r.split("/").map((i)=>{
let a=i[1]
let m=a=="#"||a=="b"?2:1
let c=i.slice(0,m)
c=a=="b"?t(c[0],-1):c
let x=(N.indexOf(c)+n)%12
x=x<0?12+x:x
return N[x]+i.slice(m)
}).join("/")限制:
G#/C而不是Ab/C。要解决“完全”问题,您需要程序了解和弦修饰符,并计算和弦使用的每个音符,然后将其与转置和弦进行匹配,以获得正确的答案。虽然有可能,但我认为在代码高尔夫环境中编写代码是不切实际的。
let Notes=["A","A#","B","C","C#","D","D#","E","F","F#","G","G#"]
let transpose=(input,n)=>input.split("/").map((splittedInput)=>{
let accident=splittedInput[1]
let modifierIndex=accident=="#"||accident=="b"?2:1
let note=splittedInput.slice(0,modifierIndex)
note=accident=="b"?transpose(note[0],-1):note
let transposedIndex=(Notes.indexOf(note)+n)%12
transposedIndex=transposedIndex<0?12+transposedIndex:transposedIndex
return Notes[transposedIndex]+splittedInput.slice(modifierIndex)
}).join("/")https://codegolf.stackexchange.com/questions/3847
复制相似问题