-
-
Notifications
You must be signed in to change notification settings - Fork 130
按照乐理逻辑判断任意一组音组成的和弦类型的算法
我在musicpy里面开发的算法中目前最成功的之一就是这个我原创的按照乐理逻辑判断任意一组音组成的和弦类型的算法。
这个算法的代码部分在musicpy.py这个文件里的detect函数里面。
这个算法是一个逻辑比较复杂的算法,我从头到尾讲一遍可能要写一大堆,因此我就挑重点来讲。
这个算法判断和弦类型的效果非常好,首先,这个算法可以判断任何一组音组成的和弦,无论这组音组成的和弦听上去有多复杂,无论这组音有多少个音,都可以判断出来和弦类型,而且在乐理分析上一定是正确的。虽然在不同的场合下,即使是完全相同的一个和弦也可能有不同的叫法,因为可能有完全不同的功能,但是按照这个算法返回的结果来推算和弦,一定会得到你输入的那组音,而且顺序也一样。
这个算法可以判断各种各样复杂的和弦类型,包括原位和弦,转位和弦,和弦的voicings(和弦音的各种不同的排序),复合和弦,有变化音的和弦(比如属七升9和弦,属七降9升13和弦),有省略音的和弦(比如C大9和弦省略3度音), 有很多重复音的和弦(相差一个或者多个八度的音),同样的也可以显示单音的音高,计算两个音之间的音程关系等等。而且这个算法也可以判断上面说的这些情况混合起来的和弦,比如同时有省略音和转位和有变化音的和弦。由于这个算法可以判断的和弦类型以及可以对付的情况非常丰富,所以你可以弹超级复杂的和弦,我这个算法也可以通过乐理逻辑分析出来你弹的和弦是什么。不过,如果是真的特别复杂的和弦(就是几乎是那种随便往钢琴上双手一砸那种),那会需要个几秒钟来分析,因为需要很多不同的乐理分析的步骤才可以分析这么复杂的和弦。如果是正常的和弦以及一般复杂的和弦(其实也包括很复杂的和弦,只要不是钢琴上随便乱砸无调性那种)都是立刻就可以判断出来了。这是一个完全按照乐理逻辑分析任意一组音组成的和弦类型的算法,这个乐理逻辑算法是我完全使用musicpy语言以及其数据结构开发出来的,这个算法有很多乐理逻辑参数可以设置,不同的乐理逻辑参数的设置可能会导致不同的判断结果。默认的参数设置适用程度最广泛。
这个和弦判断的算法在detect函数里,detect函数本身的内容就是这个和弦判断的算法,接下来讲讲detect函数的用法。
detect(current_chord,
mode='chord',
inv_num=False,
change_from_first=True,
original_first=True,
same_note_special=False,
whole_detect=True,
return_fromchord=False,
poly_chord_first=False,
root_position_return_first=True,
alter_notes_show_degree=False)
-
current_chord: 一组音符,可以有多种不同的表示方式,可以是一个和弦类型,也可以是一个音符类型的列表, 也可以是一个表示音符的字符串的列表,也可以是一个单独的字符串(里面是用逗号隔开的音符)。音符可以只有音名,没有八度数,在这种情况下会按照标准化和弦的规则来对音名进行和弦的构建。
-
mode: 选择判断和弦类型还是音阶类型(调式类型)的模式参数,如果为
chord
则对一组音组成的和弦类型进行乐理逻辑判断,如果为scale
则对一组音组成的音阶类型(调式类型)进行乐理逻辑判断。默认值为chord
。 -
inv_num: 为True的时候,判断出来的和弦类型如果是某个和弦的转位和弦,那么会以“第n转位”的形式呈现,n为一个数字,也就是某和弦第1转位,某和弦第2转位这种样子。inv_num为False的时候,则会写出转位的那个音的音名,比如Am/C这样。默认值为False。
-
change_from_first: 为True的时候,优先对于一组音是否为某种和弦通过变化音(升降音,比如#5, b5, #9, b9, #11, b13这种)而得到的进行乐理逻辑分析。返回的和弦判断结果也会比较大概率是某种和弦加上变化音(会给出具体的变化音的音名以及升降的具体情况)。默认值为True。
-
original_first: 在这个算法中,会先对a的音符的本来顺序进行乐理逻辑分析,(先检查是否符合原位和弦的音程关系)然后将a进行转位(包括最低音转位和最高音转位),然后对于每个转位进行乐理逻辑分析,在途中只要成功判断出来和弦类型就立即返回结果。original_first为True的时候,如果a的音符的本来顺序的和弦类型的判断有结果,那么会在这个结果的和弦相似程度大于或等于0.86(默认的和弦相似阈值,这个阈值没有提供在函数的参数里修改,但是可以直接到代码里修改)并且结果的类型不是变化音类型的时候直接返回结果,而不进行之后把a进行转位的乐理逻辑分析。original_first为False的时候,则不会进行这一步,在判断了a的音符的本来顺序的和弦类型之后,接着乐理逻辑分析a的各个转位的和弦类型。如果和弦a的本来顺序的和弦相似程度为1,也就是完全匹配,那么无论original_first的值为True还是False,都会直接返回和弦a的本来顺序的和弦判断的结果。至于为什么在original_first为True的时候和弦a的本来顺序的判断结果不是变化音类型的时候才可以返回,是因为如果是变化音类型,那么在将和弦a的顺序进行变换或者分成两部分之后可能会有更好的更合理的乐理逻辑分析结果(比如省略音,voicings,复合和弦等等)。默认值为True。
-
same_note_special: 为True的时候,如果和弦a的音符的音名集合等价于某种和弦的音符的音名集合(音符的音名构成一样,不考虑顺序),那么对于那种和弦的和弦相似程度就会设置为1,也就是会优先选择音名集合相同的和弦类型作为判断的结果。默认值为False。
-
whole_detect: 为True的时候,在和弦a的组成音极其复杂,使用本来顺序,各种转位也无法分析出来和弦类型的时候,会对于和弦a的每个转位使用detect函数再来判断一次,也就是几乎可以判断和弦a的音符的所有排序的情况下可能出现的和弦类型,只要有一种情况判断出来和弦类型就立即返回结果。默认值为True。
-
return_fromchord: 为True的时候,返回的结果除了和弦类型名,还有来自于的和弦种类。默认值为False。
-
poly_chord_first: 为True的时候,在需要进行whole_detect之前,会直接将和弦a的音拆成上下两部分,分开进行乐理逻辑分析,返回的结果以复合和弦的形式表示。如果和弦a的音符数量小于4,那么还是继续进行whole_detect的判断,如果大于或等于4,小于6的时候,会把和弦a分解成最底下是第一个音,上面是剩下的音组成的新的和弦,返回的结果为上面的和弦的判断结果/最底下的音。如果大于6的时候,会把和弦a按照长度分成上下两个和弦,其中下面的和弦的音符数量为a的音符数量除以2的向下取整,上面的和弦则为除了下面的和弦以外剩下的音。比如和弦a有7个音,那么下面的和弦就是和弦a的前3个音,上面的和弦就是和弦a的后4个音,上下两个和弦分开进行detect函数的判断,返回的结果为上面的和弦的判断结果/下面的和弦的判断结果。poly_chord_first为True可以让这个算法在很复杂的和弦判断中的速度快很多,非常适用于爵士乐的和弦分析(尤其是实时和弦分析)。默认值为False。
-
root_position_return_first: 为False的时候,如果当前输入的音符组成的是原位和弦,那么会返回一个列表,列表里是这种和弦的各种不同版本的称呼。为True的时候,只返回一个字符串,内容为这种和弦最常用的称呼。默认值为True。
-
alter_notes_show_degree: 为False的时候,返回的和弦类型如果有涉及到省略音,变化音等需要提到和弦内的某一些音的变动的时候,会直接把变动的那些音的音名写出来,比如
Cmaj7 (omit E)
。为True的时候,会计算变动的那些音在这个和弦里的位置(和根音的音程关系,或者说度数),并且以度数的形式显示出来,比如Cmaj7 (omit 3)
。默认值为False。
detect函数返回的是输入的音符构成的和弦类型具体名称的字符串(包括根音的名称与和弦类型),比如Cmaj7
,Cmaj9(omit 3)
,Em/G
# 这几个例子都是正确的,都会对A5, C5, E5, G5这组音符进行乐理逻辑分析,返回的是这组音符组成的和弦类型(包括根音的音名)。
detect(chord(['A5', 'C5', 'E5', 'G5']))
detect(chord('A, C, E, G'))
detect([N('A5'), N('C5'), N('E5'), N('G5')])
detect([N('A'), N('C'), N('E'), N('G')])
detect(['A5', 'C5', 'E5', 'G5'])
detect(['A', 'C', 'E', 'G'])
detect('A5, C5, E5, G5')
detect('A, C, E, G')
>>> Am7
在这个算法最开始接收到一组音符的时候,会首先将这组音符组成的和弦进行标准化,这个是musicpy的乐理系统里的一个独特的概念,具体的定义请到基础语法的章节里面看,简单来说就是去除所有重复音名的音(八度等价的音),然后在不影响音的顺序的前提下调整所有音的八度数,使得最低音与最高音相差15度之内。标准化的关键点是标准化前后的两组音实际上组成的和弦是等价的,因为我们只是去除了八度等价的音和在不影响音符顺序的情况下让这组音变得集中一些,好处是让这个算法能够更加流畅地对这组音符进行乐理逻辑分析组成的和弦类型。
在database.py这个文件里面的chordTypes是目前支持判断的原位和弦的类型,原位和弦都是通过输入的音符的从第二个音起每一个音和第一个音的音程关系来判断的,比如你输入的音是C5, E5, G5, B5
,那么这个算法会计算E5, G5, B5到C5的音程关系,分别是大三度,纯五度和大七度,我们以半音数来表示这些度数,也就是4, 7, 11
,如果一组音符从第二个音到最后一个音和第一个音的音程关系是4, 7, 11
,那么就是大七和弦的原位,因此原位和弦的判断是最简单的,这些半音数的信息是直接写在chordTypes里面的,而且这个算法在对输入的一组音符进行乐理逻辑分析的第一步就是计算第二个音到最后一个音和第一个音的音程关系,然后看看是否符合某个原位和弦的音程关系。如果没有任何一个原位和弦的音程关系可以匹配,那么就开始考虑可能是转位和弦。转位和弦的乐理逻辑分析的步骤比较复杂,我在这里不多做讲解,感兴趣的可以直接看detect函数的代码。如果也不是某种和弦的转位和弦,那么就会进行乐理逻辑分析是否有省略音或者变化音(或者两者都有),这部分的算法同样也是非常复杂的,感兴趣的可以去看代码。与此同时,也会乐理逻辑分析输入的音符是否为某种和弦的voicings(某种和弦的音符的其中一种排序),具体的算法是判断是否和某种和弦的组成音相同(顺序可以不同)。如果还是没有匹配到,那么就会考虑是否为复合和弦,然后以复合和弦的角度对输入的音符进行乐理逻辑分析,把输入的音符按照音符数量分为上下两部分,(如果输入的音符的数量小于6个,那么会分成第一个音,其他的音两部分,如果大于或等于6个,那么会平均分成两部分,如果是奇数,那么第一个部分就是前一半取整的个数的音,第二个部分是其他的音)分别判断两个部分的和弦类型,然后以复合和弦的形式返回(也是字符串)。这个算法几乎考虑到了任意一组音能组成的和弦类型的所有复杂的情况,因此你随便输入一组音都可以判断出来一个结果,而且都一定是乐理逻辑上正确的。大家也可以在database.py里面的chordTypes自己定制加入想要的原位和弦类型,语法是和弦类型名称的列表 : 和弦里每一个音到根音的音程关系
。
这个算法的效果非常好,而且不是依靠和弦查表(网上有很多查询和弦类型的网站都是靠直接查和弦表来返回结果,并不是按照乐理逻辑分析的算法来进行和弦的判断,而只是查字典而已,因此有很多非常复杂的情况无法判断),而且有很多的乐理逻辑参数可以进行设置,也可以设置返回的和弦类型的显示内容。这个算法目前已经被一位写编曲宿主的大佬拿去实际使用了,也算是对我这个算法的肯定吧。在我写的钢琴软件Ideal Piano的实时进行乐理逻辑分析并且显示你当前演奏的音符组成的和弦类型的功能,用的就是这个算法,效果非常好,而且Ideal Piano的其中一个模式,播放midi文件演示也是实时进行乐理逻辑分析并且显示当前演奏的音符组成的和弦类型的,这个算法让想扒一首曲子的和弦进行的小伙伴可以实时看到当前的和弦类型,非常方便。
- Basic syntax of note type
- Basic syntax of chord type
- Basic syntax of scale type
- Basic syntax of piece type
- Basic syntax of track type
- Basic syntax of tempo type
- Basic syntax of pitch_bend type
- Basic syntax of pan type
- Basic syntax of volume type
- Basic syntax of drum type
- Basic syntax of rhythm type
- Musicpy composition code examples Part 1
- Musicpy composition code examples Part 2
- Musicpy composition code examples Part 3
- Introduction of musicpy algorithms module
- The algorithm to split the main melody and chords from a piece of music
- The algorithm to determine the chord type of any group of notes according to the logic of music theory
- The algorithm to analyze the chord progressions of a piece of music
- The algorithm to analyze tonality and modulations in a piece of music