Skip to content

和弦类型的基本语法

Rainbow Dreamer edited this page Feb 9, 2025 · 50 revisions

目录

对一个和弦进行音符间隔和音符长度的设置

比如现在有一个和弦A,想要设置其音符间隔都为1个小节,音符长度都为1.5个小节,那么可以使用和弦类的内置方法set,set的第一个参数是音符长度duration,第二个参数是音符间隔interval

A.set(1.5, 1)

得到的是和弦A的音符长度全部设置为1.5,音符间隔全部设置为1的全新的和弦类型,请注意不是修改和弦A的内部属性,而是直接返回一个全新的和弦,这个和弦的内部属性为和弦A修改过后的值。如果对于每个音的音符长度或者每个音符间隔都有不同的设定,那么可以传一个列表进去,比如

A.set([0.5, 0.5, 1, 1], [1, 1, 2, 2])

返回的是一个音符长度分别为0.5, 0.5, 1, 1 (单位为小节),音符间隔分别为1, 1, 2, 2 (单位为小节)的和弦。

进阶写法:

A % (1.5, 1)

根据和弦根音与和弦名获得一个和弦

介绍一个很方便的函数:get_chord,这个函数可以让你得到你想要的类型的和弦,只需给定和弦的根音和和弦类型即可。比如:

Am7 = get_chord('A', 'm7')

这样我们就创建了一个A的小七和弦。其表示为

chord(notes=[A5, C6, E6, G6], interval=[0, 0, 0, 0], start_time=0)

和弦类型的种类很多,具体可以到database.py这个文件里面的chordTypes查看,用户还可以自己添加自己喜欢的和弦种类,只需按照chordTypes里相同的格式,写上和弦名称和对应的和弦音程即可。 get_chord函数的第一个参数和弦的根音,如果不指定具体的音高(比如C5,D6这种是一个有具体音高的音符),则默认按照第4个八度来看待,比如get_chord('A', 'm7'),等价于 get_chord('A4', 'm7'), 如果指定根音具体的音高,比如现在想写根音为D6的大七和弦,则可以写:

Dmaj7 = get_chord('D6', 'maj7')

此外,get_chord函数还有非常多的参数,可以用来设置和弦的省略音,升降音,外加的音,以及和弦的每个音符具体的长度,音符的间隔等等,您甚至可以输入音符的音程来构建和弦(也可以通过设定cumulative的值来决定是要输入每个音符到根音的音程还是每两个音符之间的音程),在musicpy里,每个音程的名字已经定义好了,可以直接用,比如major_third的值为4,也就是大三度的半音数。

比如按照音程的关系构建一个C大七和弦,可以这么写:

get_chord('C5', interval=[database.major_third, database.perfect_fifth, database.major_seventh])

得到的是

chord(notes=[C5, E5, G5, B5], interval=[0, 0, 0, 0], start_time=0)

当一个和弦的interval全部为0的时候,这个和弦就是所有音符一起同时演奏。如果某个interval为0,表示的是两个音同时一起开始弹。

输入音符名称,音符长度和音符间隔构建和弦

比如我们想构建一个大七和弦,根音为C5,音符间隔为每个音都相差一个小节,每个音符的长度都为两个小节,那么可以这么写:

chord(['C5', 'E5', 'G5', 'B5'], interval=1, duration=2)

如果音符间隔和音符长度不是一样的,那么可以传一个列表进去,比如:

chord(['C5', 'E5', 'G5', 'B5'], interval=[0.5, 0.5, 0, 2], duration=[1, 2, 0.5, 1])

除了字符串的列表以外,也可以把所有的音符写在一个字符串里,比如现在我们想要一个C大七和弦,以C5为根音,那么可以写

chord('C5, E5, G5, B5')

或者

chord('C, E, G, B', rootpitch=5)

rootpitch的值默认为4,所以如果想要以C4为根音的C大七和弦,可以直接写

chord('C, E, G, B')

chord函数可以接收完全不带音高数的音名的字符串,并且按照standardize函数的标准来进行标准化和弦输出, 也就是会按照字符串中音名的先后顺序排好音符的音高,然后组成原位和弦,比如

chord('C, E, G, B, D')

会得到

chord(notes=[C4, E4, G4, B4, D5], interval=[0, 0, 0, 0, 0], start_time=0)

当然,最直接的还是接收音符类型的列表,比如

chord([N('C'), N('E'), N('G'), N('B'), N('D')])

不过需要注意的是,如果chord函数接收的是音符类型或者有确定音高数的音名的字符串的列表,那么就不会进行和弦标准化的操作,因为此时所有音符的音高数都是确定的了。如果想要在chord函数接收字符串的时候不进行和弦标准化的操作,那么可以手动指定音符的音高数,比如

chord(['C4', 'E4', 'G4', 'B4', 'D4'])

或者

chord('C4, E4, G4, B4, D4')

在使用chord函数的时候,在写音名的字符串或者音名字符串组成的列表时同时也可以把音符的长度,间隔还有音量用一种新的语法写在字符串中,比如现在我们想要写一段旋律

example = chord('G5, F5, E5, F5, E5, D5, E5, D5, C5, B4, G4')

这段旋律的音符长度的列表为

example_duration = [3/4, 1/8, 1/8, 3/4, 1/8, 1/8, 1/4, 1/4, 1/2, 1/2, 1/2]

这段旋律的音符间隔的列表和音符长度的列表相同,

example_interval = example_duration.copy()

如果是传统的做法是

example % (example_duration, example_interval)

使用新的语法可以写成

example = chord('G5[3/4;3/4], F5[.8;.8], E5[.8;.8], F5[3/4;3/4], E5[.8;.8], D5[.8;.8], E5[.4;.4], D5[.4;.4], C5[.2;.2], B4[.2;.2], G4[.2;.2]')
>>> example
chord(notes=[G5, F5, E5, F5, E5, D5, E5, D5, C5, B4, ...], interval=[3/4, 1/8, 1/8, 3/4, 1/8, 1/8, 1/4, 1/4, 1/2, 1/2, ...], start_time=0)

请注意,括号内的分隔参数的符号必须是;,括号使用中括号,参数之间可以空格,参数的顺序为[音符长度;音符间隔;音符音量],可以只设置音符长度,或者只设置音符长度和音符间隔,或者3个参数都设置。这个新语法的最大的好处是如果在写一段旋律的时候,有时需要改动其中某个音的音符长度或者某个音和下一个音之间的音符间隔,可以直接在音符名称后面修改,而不需要到音符长度的列表和音符间隔的列表里找到想要修改的音符的位置再修改。chord函数也支持这种新语法的音名字符串的列表。

音符长度,音符间隔和音量可以是整数,小数或者分数。在这里我还加了一个语法糖,如果是想输入比如说2分音符,4分音符,8分音符,16分音符这样的音符,那么可以写.n表示n分音符,也就是等价于1/n的音符长度。如果是比如3/4这样的音符长度,那么就可以直接写3/4。

另外,chord函数的新的语法还有一个独特的语法糖,那就是当音符长度和音符间隔相同的时候,音符间隔可以简写为.。比如

chord('G5[3/4;.], F5[.8;.], E5[.8;.]')

插入休止符可以使用r[音符长度]的语法作为音符写在字符串中,也可以使用n分音符的语法糖,音符长度的单位为小节,也支持延续符号-延长前一个音符的长度和间隔。比如

example = chord('G5[3/4;3/4], F5[.8;.8], E5[.8;.8], F5[3/4;1/4], r[.2], E5[.8;.8], D5[.8;.8], E5[.4;.4], D5[.4;.4], C5[.2;.2], B4[.2;.2], G4[.2;.2]')
>>> example
chord(notes=[G5, F5, E5, F5, E5, D5, E5, D5, C5, B4, ...], interval=[3/4, 1/8, 1/8, 4/3, 1/8, 1/8, 1/4, 1/4, 1/2, 1/2, ...], start_time=0)

如果想要多个音符同时演奏,可以使用;将多个音符连接起来,比如C5;E5;G5

有时候相对音程关系在构建和弦时可以更加方便,不用考虑绝对音高,因此也支持相对半音数的语法。语法如下:

  • 使用+n表示前一个音符升高n个半音,但是用来计算相对音高的基准音符并没有变化
  • 使用++n表示前一个音符升高n个半音,同时用来计算相对音高的基准音符变成当前的音符
  • 使用+no表示前一个音符升高n个八度,+nom表示前一个音符升高n个八度之后升高m个半音,也支持++的语法
  • 把以上的语法改为-表示降低音高
  • 使用相对音程的语法必须在之前有至少一个绝对音高
  • 可以使用C4(+n)的语法来表示当前音符为以C4为基准音升高n个半音后的音符,改为-表示降低n个半音,同样也支持+no+nom的语法

这里是一些例子:

example = chord('A#4, +7, +10, +1o2, +1o3, +1o5, +1o3, +1o2', default_interval=1/8, default_duration=1/8)
>>> example
chord(notes=[A#4, F5, G#5, C6, C#6, D#6, C#6, C6], interval=[1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8], start_time=0)

example2 = chord('C5, ++2, ++2, ++1, ++2', default_interval=1/8, default_duration=1/8)
>>> example2
chord(notes=[C5, D5, E5, F5, G5], interval=[1/8, 1/8, 1/8, 1/8, 1/8], start_time=0)

example3 = chord('C5(+1)[.8;.], E5, G5', default_interval=1/8, default_duration=1/8)
>>> example3
chord(notes=[C#5, E5, G5], interval=[1/8, 1/8, 1/8], start_time=0)

根据和弦名称获得和弦

trans函数可以直接输入完整的和弦名进行解析,返回的是对应的和弦。支持原位和弦表示,转位和弦表示,复合和弦表示等等。 trans函数的第一个参数是和弦名,第二个参数是和弦根音的音高(默认值为4),第三个参数是duration(音符的长度,默认值为0.25),第四个参数是interval(音符的间隔,默认值为None,返回的和弦interval都为0),或者也可以写音符:和弦类型来标明具体的音符八度数。 比如:

D大七和弦和以D5为根音的D大七和弦

>>> trans('Dmaj7')
chord(notes=[D4, F#4, A4, C#5], interval=[0, 0, 0, 0], start_time=0)

>>> trans('D5:maj7')
chord(notes=[D5, F#5, A5, C#6], interval=[0, 0, 0, 0], start_time=0)

F大三和弦的第二转位

>>> trans('F/C')
chord(notes=[C5, F5, A5], interval=[0, 0, 0], start_time=0)

转位的解析也可以接收数字,比如:

C大三和弦的第一转位E, G, C

trans('C/1')

C大三和弦的把第1个音放到最高音的和弦E, G, C

trans('C/-1')

C大三和弦的把第二个音放到最低音的转位和弦E, C, G(和传统的转位方式不同)

trans('C/1!')

C大三和弦

>>> trans('C')
chord(notes=[C4, E4, G4], interval=[0, 0, 0], start_time=0)

A小三和弦叠在G小三和弦上面的复合和弦

>>> trans('Am/Gm')
chord(notes=[G4, A#4, D5, A5, C6, E6], interval=[0, 0, 0, 0, 0, 0], start_time=0)

G大三和弦加上一个C在最低音的和弦

>>> trans('G/C', 6, 1, 1)
chord(notes=[C6, G6, B6, D7], interval=[1, 1, 1, 1], start_time=0)

add和sus的语法解析,输入add数字就可以增加距离最低音的某个度数的音,输入sus数字就可以得到之前的和弦类型的sus2或者sus4和弦。

>>> print(C('C,add9'))
chord(notes=[C4, E4, G4, D5], interval=[0, 0, 0, 0], start_time=0)

>>> print(C('Cm7,add11'))
chord(notes=[C4, D#4, G4, A#4, F5], interval=[0, 0, 0, 0, 0], start_time=0)

>>> print(C('Cmaj7,sus4'))
chord(notes=[C4, F4, G4, B4], interval=[0, 0, 0, 0], start_time=0)

>>> print(C('Bb9,sus'))
chord(notes=[Bb4, D#5, F5, G#5, C6], interval=[0, 0, 0, 0, 0], start_time=0)

trans函数的简写方法:

C(和弦名, 其他的参数)

C表示的是和弦chord的首字母大写

对一个和弦进行更高级的操作(变化音,省略音,复合和弦)

比如和弦A是一个C属七和弦,那么如果想要得到C属七升九和弦,可以这么写:

A('#9')

得到的是

chord(notes=[C5, E5, G5, A#5, D#6], interval=[0, 0, 0, 0, 0], start_time=0)

C属七降九和弦则是

A('b9')

比如B是一个C大九和弦,那么如果想要省略三度音,可以这么写:

B('omit3')

或者

B('no3')

多个升降音和省略音可以使用英文的逗号分隔开来,比如

A('#5, b9, omit3')

如果和弦A是C属七和弦,那么得到的是C属七升五降九和弦省略三度音。

如果要构建复合和弦,只需要用'/'连接两个和弦即可,除了两个和弦叠在一起的情况, 还有一个和弦下面外加一个最低音构成的复合和弦,这两种情况都是使用'/'即可。 比如:

C('Amaj7') / 'D'

得到的是

chord(notes=[D4, A4, C#5, E5, G#5], interval=[0, 0, 0, 0, 0], start_time=0)

也就是Amaj7和弦底下加上D作为最低音。 两个和弦的复合和弦的情况,比如:

C('A') / C('G')

得到的是

chord(notes=[G4, B4, D5, A4, C#5, E5], interval=[0, 0, 0, 0, 0, 0], start_time=0)

也就是G大三和弦叠在A大三和弦下面构成的复合和弦。

在和弦名解析结构里,只需要用逗号分隔,就可以直接输入和弦的高级操作并解析,比如C大七和弦省略5度音

C('Cmaj7,no5')

得到的是

chord(notes=[C4, E4, B4], interval=[0, 0, 0], start_time=0)

如何构建一个空和弦

如果想要构建一个什么音符都没有的空和弦,可以写

chord([])

会得到

chord(notes=[], interval=[], start_time=0)

空和弦可以作为循环添加新的和弦的初始化和弦,也可以作为一个和弦类型当做曲子来看待的时候(可以往里面添加新的旋律或者和弦的音符)的初始化和弦,比如

chord([]) | C('Am') | C('F') | C('G')

按照音程关系生成和弦类型

你可以使用get_chord_by_interval函数通过音程关系的列表生成和弦类型,可以选择与根音的音程关系或者相每两个相邻的音之间的音程关系。 音符类型也可以使用这个函数,使用的时候音符类型本身会作为起始音。

get_chord_by_interval(start,
                     interval1,
                     duration=0.25,
                     interval=0,
                     cumulative=True)

# start: 和弦类型的起始音,可以是表示音符的字符串或者音符类型
# interval1: 表示音程关系的列表,元素为整数
# duration: 生成的和弦类型的音符长度
# interval: 生成的和弦类型的音符间隔
# cumulative: 如果为True,音程关系为与起始音的音程关系,如果为False,音程关系为每两个相邻的音之间的音程关系,默认值为True

>>> get_chord_by_interval('C5', [database.major_third, database.perfect_fifth, database.major_seventh])
# 获得起始音为C5,与C5依次形成大三度,完全五度和大七度的音组成的和弦类型
chord(notes=[C5, E5, G5, B5], interval=[0, 0, 0, 0], start_time=0) # 获得C大七和弦

>>> get_chord_by_interval('C5', [database.major_third, database.minor_third, database.major_third], cumulative=False)
# 获得起始音为C5,相邻音程依次为大三度,小三度,大三度的音组成的和弦类型
chord(notes=[C5, E5, G5, B5], interval=[0, 0, 0, 0], start_time=0) # 获得C大七和弦

a = N('C5')
>>> a.get_chord_by_interval([database.major_third, database.perfect_fifth, database.major_seventh]) #音符类型调用这个函数
chord(notes=[C5, E5, G5, B5], interval=[0, 0, 0, 0], start_time=0)

和弦的表示

在musicpy里,一个和弦类型的表示为:

#比如一个C大七和弦,根音为C5
>>> get_chord('C5', 'maj7')
chord(notes=[C4, E4, G4, B4], interval=[0, 0, 0, 0], start_time=0)

获得和弦的转位

inversion可以得到一个和弦的转位,里面有一个参数num代表和弦的第几转位。比如:

get_chord('A', 'm7').inversion(1) 

可以得到A的小七和弦的第一转位,表示出来是这样的:

chord(notes=[C6, E6, G6, A6], interval=[0, 0, 0, 0], start_time=0)

进阶写法:(我为musicpy的很多功能都设计了符号化的写法,写起来更快)

get_chord('A', 'm7') / 1

结果和get_chord('A', 'm7').inversion(1)是一样的。 也可以在'/'后面写想要转位的音符,如果音符在和弦内则会把那个音符转位到最低音,比如

get_chord('A', 'm7') / 'E'

得到的结果是

chord(notes=[E6, G6, A6, C7], interval=[0, 0, 0, 0], start_time=0)

也就是A小七和弦的第二转位。

往一个和弦添加音符

如果想对和弦A添加一个音符x,那么只需要

A + x

即可。得到的是一个添加了音符x的新的和弦。

去掉一个和弦的某一个音

如果想去掉和弦A里面的某一个音x,那么只需要

A - x

即可。得到的是一个去掉了音符x的新的和弦。

重复一个和弦一定的次数

如果想重复一个和弦A重复n次,那么只需要

A * n

即可。得到的是重复n次和弦A的新的和弦。

对一个和弦进行倒序排列

如果想把一个和弦A里面的音符倒序排列,那么只需要

A.reverse()

即可。得到的是倒序过后的新的和弦。

进阶写法:

~A

也可以得到和弦A的倒序排列。

'''
注意这里的和弦A不一定只是乐理上的一个和弦,而是可以是一段旋律,甚至是一段旋律加上一段和弦铺底。因为musicpy里的和弦类定义就是“一串音符的集合”。因此,在musicpy里的一个和弦类的实例是可以存储一整首曲子的信息的,这些信息包括曲子里所有的音符,每个音符的长度,力度,以及每两个音符之间的间隔。
'''

获得一个和弦的音程关系

intervalof函数可以返回一个和弦的构成音之间的音程关系。参数cumulative设为True的时候返回每个音与起始音的音程关系,设为False的时候返回每两个相邻的音之间的音程关系。默认值为True。比如:

get_chord('C','maj').intervalof()

会得到 [4, 7],这个表示C大三和弦(C,E,G)里面第二个音到根音之间有四个半音(大三度),第三个音到根音之间有7个半音(纯五度)。如果你想看音程在乐理上的名称,那么可以设参数translateTrue,那么你就可以看到对应的音程名称了。比如:

get_chord('C','maj').intervalof(translate=True)

会得到 [M3, P5],也就是大三度和纯五度。

cumulative设置为False的时候返回和弦从低到高每两个音符之间的音程,比如:

get_chord('C','maj').intervalof(translate=True, cumulative=False)

会得到[M3, m3],也就是C大三和弦是由一个大三度和一个小三度构成的。

对一个和弦进行索引,切片(通过索引值得到一个和弦的某一个音,或者某一个范围内的片段)

比如现在我们有一个和弦A,

A = get_chord('C', 'maj7')

如果我们想得到和弦A的第1个音,那么就写:

A[0]

如果我们想得到和弦A的第2个音,那么就写:

A[1]

如果我们想得到和弦A的最后一个音,那么就写:

A[-1]
# 请注意和弦的索引值是从0开始作为第1个音的,也就是0对应和弦的第1个音,1对应和弦的第2个音,以此类推。
# 如果要得到和弦的倒数第一个音,索引值为-1,倒数第二个音为-2,以此类推。

如果想对一个和弦/一段旋律/一首曲子A截取其中的一部分,那么只需要A

[开始位置:结束位置]

即可。得到的是一个新的和弦,里面的音符为截取的部分。

比如和弦B有6个音,如果要得到和弦B的前5个音,那么可以写:

B[:5]
# 结束位置5是不包括在内的,所以对应的就是B的第1,2,3,4,5个音

如果要得到和弦B的第2个到第5个音,那么可以写:

B[1:5]
# 请注意这里是左闭右开的,也就是结束位置5是不包括在结果内的,所以B[1:5]是提取B的第2个音到第5个音,总共4个音。

如果要得到和弦B的第2个音及往后的所有的音,那么可以写:

B[1:]

如果要得到和弦B的倒数第3个音到倒数第1个音,那么可以写:

B[-3:]

对一个和弦进行升调和降调(升降音)

如果你想对一个和弦(当然也可能是一段旋律或者音乐片段)升调或者降调,那么可以用up和down函数。给定一个和弦A,

A.up(x)

表示把和弦A整体升高x个半音(x也可以是负数,表示降低x的绝对值个半音),

A.down(x)

表示把和弦A整体降低x个半音。

进阶写法:

+A

表示把和弦A整体升高一个半音,有多少个加号就是升多少个半音,比如

+++A

表示把和弦A整体升高三个半音,但是由于每一个加号和弦A都会重新被覆盖,(等价于A.up().up().up())

所以我还设计了一个一步到位的写法:

A + 3

表示把和弦A整体升高三个半音,等价于A.up(3),

-A

表示把和弦A整体降低一个半音,有多少个减号就是升多少个半音,比如

---A

表示把和弦A整体降低三个半音,等价于A.down().down().down()

A - 3

表示把和弦A整体降低三个半音,等价于A.down(3)

如果你只想把和弦里的某个音升高,那么只需要

A.up(x, k)

或者

A + (x, k)

降低则是

A.down(x, k)

或者

A - (x, k)

其中k表示第几个音。比如

get_chord('C','maj').up(1)

会得到一个新的和弦,里面每个音都比之前的和弦升高一个半音, 构成音为C#, F, G#。

get_chord('C','maj').up(1,0)

会得到一个新的和弦,只有第一个音升高一个半音,构成音为C#, E, G。

如果要对每个音进行不同的升降,那么可以让x等于一个列表,列表里每个元素都是升降的半音数, 比如:

A.up([1,2,0,-1])

或者

A + [1,2,0,-1]

表示把和弦A的前四个音分别升高一个半音,升高两个半音,不变,降低一个半音。 down的情况以此类推。

对一个和弦进行排序

如果你想对一个和弦A的组成音进行排序,那么只需要

A.sort(x)

其中x为一个记载顺序的列表, 比如有一个A的小七和弦,对于它的4个组成音A,C,E,G你想按照CEAG的顺序排列,那么就写

A.sort([2, 3, 1, 4])

即可。

进阶写法:

A / [2, 3, 1, 4]

等价于A.sort([2, 3, 1, 4])

对一个和弦(或者一首曲子)进行转调

如果你想对一段旋律(包括和弦铺底)进行转调,那么可以使用modulation函数。比如现在想给一个音乐片段A转调,那么就可以

A.moulation(之前的调, 要转向的调)

关于如何表示一个调式,这个接下来会谈。 比如现在有一个音乐片段p是A大调,现在想转到A小调,那么就可以写:

p.modulation(scale('A', 'major'), scale('A', 'minor'))

这样就把音乐片段p从A大调转到A小调啦~

得到一个和弦的所有音符的音名

首先,如果只是得到一个和弦A的音符的列表,那么只需要

A.notes

即可,得到的是和弦A的音符列表,比如A是一个A小七和弦,那么得到的是

[A5, C6, E6, G6]

如果想要得到和弦A的所有音符的音名的列表,那么就可以使用和弦的其中一个内置函数names,比如

get_chord('A','m7').names()

就可以得到

['A', 'C', 'E', 'G']

对两个和弦或者两个音乐片段进行合并连接(声部合并,声部拼接)

和弦类型的内置函数add可以合并两个和弦(或者两个音乐片段)。 比如现在有两个音乐片段(和弦类型本身也可以是音乐片段)A 和 B。

参数mode可以用来选择合并的模式,

当mode == 'head',

A.add(B, mode='head')

可以得到合并A和B两个音乐片段后的新的音乐片段,B的开头对齐到A的开头,也就是A和B同时从头开始进行演奏的音乐片段。

合并的机制是重新计算合并过后的音的间隔,然后把A和B的音符按照计算的间隔,调整好顺序进行重新的合并排列。 add函数还有一个参数start,可以用来设定B要从A的什么地方开始进行合并,也就是B的开头对齐到A的什么地方,单位为小节,换句话说,就是B延后A开始多少小节开始进行演奏。比如:

A.add(B, mode='head', start=8)

可以得到B从A的第8小节开始演奏的合并过后的音乐片段。

进阶写法:

A & B
A & (B, start)

当mode == 'tail',

A.add(B, mode='tail')

可以得到音乐片段B追加到音乐片段A之后的新的音乐片段,不过需要注意的是,这个模式是直接把B的音符列表追加到A的音符列表之后,然后把B的音符间隔列表也追加到A的音符间隔列表之后,如果音乐片段A的最后几个音符间隔是0的话,那么可能会出现音乐片段B的开始几个音与A的最后几个音重叠在一起的情况,如果很确定A的最后几个音符间隔不是0,那么这个模式可以放心地使用。

当mode == 'after',

A.add(B, mode='after')

可以得到音乐片段B追加到音乐片段A之后的新的音乐片段,与tail模式的区别在于,这个模式会特别计算A与B之间是否需要多一些音符间隔,以避免tail模式里面某些情况下A的结尾与B的开头会重叠的情况。所以当不确定A的最后几个音符间隔是否为0的时候,使用这个模式最好。

进阶写法:

A | B
A + B

对一个和弦内的音符做出修改

之前我已经讲过如何通过索引值访问一个和弦内的音符,比如A[0]就会得到和弦A的第一个音符。 想要对一个和弦内的音符作出修改,比如和弦A是一个C大七和弦,

(原位的形式,C, E, G, B)我们想把和弦A的第二个音(三度音)换成F,也就是把和弦A变成一个maj7sus4和弦,我们可以这样写:

A[1] = 'F5'

然后我们再打印一下和弦A,

chord(notes=[C5, F5, G5, B5], interval=[0, 0, 0, 0], start_time=0)

会看到和弦A的第二个音已经从E5变成了F5。 请注意,更改的音符可以是音符类型(note('A', 5)这样子通过note的初始化函数得到的),也可以是表示音符的字符串, 但是一定要有八度数,不能只有音名,比如'F'这样子就不能用在这里,必须要有一个八度数,比如'F5'这样子。

对一个和弦的某些音符进行删除,或者在某个位置插入新的音符

可以参考python的列表的逻辑,使用

del A[n]

可以删除和弦A的第n个音,使用

A.pop()

可以去掉和弦A的最后一个音,并且返回的是和弦A的最后一个音,使用

A.insert(i, b)

可以在和弦A的第i个位置插入音符b

A.append(b)

可以往和弦A添加音符b 此外,extend, remove函数和列表的同名内置方法使用逻辑也是一样的。 当你想去掉和弦A里的一个音时,可以使用'-'号来进行去除,比如

A - 'B5'

如果和弦A中有B5这个音符,则会返回一个新的去掉B5这个音的和弦,如果没有,则会返回未经修改的和弦A。

往一个和弦加上一个最低音(加一个贝斯音符)

比如现在和弦A是一个G major和弦(G大三和弦),组成音依次为G5, B5, D6, 我们现在想往和弦A的下面加上一个C音当做最低音, 那么可以写(参数可以是字符串或者音符类型)

A.on('C5')

得到的是和弦A加上C5作为最低音的新的和弦, 表示出来是

chord(notes=[C5, G5, B5, D6], interval=[0, 0, 0, 0], start_time=0)

进阶写法:

A % 'C5'

查找和弦内某个音是第几个音

比如和弦A为一个F大九和弦,根音为F5,原位和弦,想找到'E6'这个音在第几个音,那么可以写

A.index('E6')

得到的结果是3,说明音符E在F大九和弦的第4个音。 如果音符不在和弦内,则返回-1。 也可以省略八度数,只写音名进行查找,返回的是第一个音名相同的音符的位置,比如

A.index('G')

得到的结果是4,说明音符G在F大九和弦的第5个音。

往一个和弦后添加休止符

如果要往和弦A的后面添加n小节的休止符,那么可以使用和弦类的内置函数rest,

A.rest(n)

表示往和弦A后面添加休止符n小节,得到的是一个新的和弦,内容为和弦A加上n小节的休止符。

进阶写法:

A | n

关于休止符在musicpy中目前的定义,休止符本身是一种数据结构,可以用rest(duration)来构建,也可以添加到和弦类型中,但是只会反映在音符间隔上,本身并不会存在于和弦类型的音符列表中,休止符只在构建和弦类型的时候有意义。

和弦转位一个音转位到最高音

比如和弦A是C大三和弦原位C, E, G, 现在想把E转位到最高音,那么可以写

A.inversion_highest(2)

也就是把和弦A的第二个音放到最高音,得到的和弦的音为C, G, E

进阶写法:

A / -2

或者

A ^ 2

(A / -n 表示把和弦A的第n个音转位到最高音)

和弦转位一个音转位到最低音

比如和弦A是C大三和弦原位C, E, G, 现在想把E转位到最低音,那么可以写

A.inv(2)

或者

A.inv('E')

也就是把和弦A的第二个音放到最低音,得到的和弦的音为E, C, G, 注意此处与正常的C大三和弦的第一转位(E, G, C)不同,

通常来说一个和弦的古典音乐意义上的转位是通过把最低音(第一转位时为根音)提高八度得到的,

不过更加广义的转位只需要最低音是转位的那个音即可。

进阶写法:

A @ 2
A @ 'E'

把一个和弦的所有音都转位到一个八度以内

比如和弦A有5个音,最高的几个音分布在比低的几个音更高的八度,那么

A.inoctave()

会返回一个把和弦A的所有的音都放到同一个八度内的和弦类型,八度数为和弦A的第一个音的八度数。

把一个和弦标准化

把和弦A标准化,可以用standardize函数,

A.standardize()

得到的是和弦A标准化之后的新的和弦。

这里标准化的定义是:

1. 如果和弦内有出现重复的音名(即使在不同的八度),那么只保留音高最低(八度数最小)的音。
2. 把所有的音都限制在两个八度以内,也就是到最低音的15度之内,如果有的音比最低音高的半音数超过两个八度,
   那么就往下减一个八度,直到所有的音都在最低音往上的两个八度之内。
3. 把所有的音名全部统一成没有升降号或者只有#号的格式,如果有b号的就转换成十二平均律里等音高的有#号的音名。

标准化之后的和弦的最低音的音高和标准化之前一样。返回的是和弦A标准化过后的新的和弦。

把一个和弦按照音高数进行排序

如果一个和弦里的音并不是按照音高从小到大进行排序的,比如和弦A的音符依次是E5, C5, G5,那么可以写

A.sortchord()

返回的是和弦A的音符的音高按照从低到高排序好的新的和弦。

按照设定的音阶得到一个和弦的负面和声

比如和弦A是C大七和弦,想要得到和弦A关于C大调音阶的负面和声的转换,那么可以写:

A = C('Cmaj7')
>>> alg.negative_harmony(scale('C', 'major'), A)
chord(notes=[G3, D#4, C5, G#4], interval=[0, 0, 0, 0], start_time=0)

得到的是和弦A的音符关于C大调音阶的负面和声的转换过后的组成的新的和弦。

negative_harmony函数的其他参数:

get_map_dict: 为True的时候,返回的是第一个参数音阶的每个音符按照负面和声映射到的音的字典,为False的时候,如果不传入任何和弦类型,那么返回的是传入的音阶类型的负面和声音阶类型,比如

>>> alg.negative_harmony(scale('C', 'major'))
[scale]
scale name: C4 minor scale
scale intervals: [M2, A1, d3, M2, A1, M2, d3]
scale notes: [C4, D4, D#4, F4, G4, G#4, A#4, C5]

还有一个参数sort,为True的时候,会把和弦a转换为负面和声版本之后,将音符按照音高从低到高排序。默认值为True。

对一个和弦内的音符按照索引值提取,包括高八度和低八度的音符变换

比如现在和弦A是C大三和弦,构成音为C5, E5, G5,我们想得到一串阿尔贝蒂低音,也就是把一个三和弦按照根音,五度音,三度音,五度音交替的形式演奏的左手琶音伴奏型,我们现在想要得到的是C5, G5, E5, G5, C6, G5, E5, G5这一串音符(并且放在一个和弦类型里),请注意第5个音是C6,比根音高了一个八度,这串音符是很典型的阿尔贝蒂低音的左手琶音伴奏型。使用和弦类型的get函数可以很方便地从和弦A提取这串音符。

A.get([1, 3, 2, 3, 1.1, 3, 2, 3])

得到的结果是

chord(notes=[C5, G5, E5, G5, C6, G5, E5, G5], interval=[0, 0, 0, 0, 0, 0, 0, 0], start_time=0)

这里的1, 2, 3表示的是和弦A里的第几个音,1.1这种小数表示的是第几个音(小数点前的数字)升高几个八度(小数点后的数字)。

如果想要某个音降低几个八度,那么只需要写负数的小数即可,比如-2.1表示把第二个音降低一个八度后的音。

进阶写法:

A @ [1, 3, 2, 3, 1.1, 3, 2, 3]

构建一套和弦处理规则,适用于任何和弦类型

最简单的方法是使用python自带的lambda函数的语法,比如:

输入和弦名,然后把这个和弦按照第1个音,第2个音,第三个音,第1个音高1个八度,第二个音高1个八度, 第三个音,第1个音高1个八度,第二个音高1个八度的顺序组成一个新的和弦类型(一段和弦伴奏),然后把这段和弦伴奏的每个音符的长度都设置为0.5个小节,每个音符的间隔也都设置为0.5个小节,然后把这段和弦伴奏重复两遍。

rules = lambda x: C(x) @ [1, 2, 3, 1.1, 2.1, 3, 1.1, 2.1] % (1/8, 1/8) * 2

现在我们可以用和弦处理规则rules去对C大三和弦,C属七挂四和弦,G属七和弦/B,C大三和弦来进行处理,然后通过'|'符号连接,形成一段小曲子。

A = rules('Cmajor') | rules('C7sus4') | rules('G7/B') - database.octave | rules('Cmajor')

以115的BPM(曲速)播放曲子片段A

play(A, 115)

得到一个和弦类型的第1转位,然后把和弦的音符长度分别设置为1/4, 1/2, 1/2(单位为小节),音符间隔分别设置为1/4, 1/4, 1/2(单位为小节)。

rules = lambda x: (x / 1) % ([1/4, 1/2, 1/2], [1/4, 1/4, 1/2])

查看一个和弦类型的音符间隔列表和音符长度列表

a = C('Dmaj7')

# 查看一个和弦类型的音符间隔列表
>>> print(a.interval)
[0, 0, 0, 0]

# 查看一个和弦类型的音符长度列表
>>> print(a.get_duration())
[0.25, 0.25, 0.25, 0.25]

查看一个和弦类型的音符音量列表

a = C('Dmaj7')
a.set_volume([80,80,100,100])

# 查看一个和弦类型的音符音量列表
>>> print(a.get_volume())
[80, 80, 100, 100]

设定一个和弦类型的音量的另一种方法

# 可以使用set_volume方法设置一个和弦类型的音量
a = C('Emaj7')
a.set_volume(80)
# 也可以使用set函数或者进阶写法%来设定音量,作为第音符长度和间隔之后的第三个参数
a = a.set(1/8,1/8,80)
a = a % (1/8,1/8,80)

只获取和弦类型中的音符类型

如果想要只保留一个和弦类型中的音符类型,去除所有其他的类型(比如tempo类型,pitch_bend类型等等), 那么可以使用only_notes这个内置函数。

a, bpm, start_time = read('example.mid').merge()
a = a.only_notes()

按照吉他的品格数和吉他定弦标准来得到和弦类型

你可以使用算法库的guitar_chord函数,通过吉他的6根弦的品格数和吉他定弦标准(可以不设置,默认为6弦吉他标准定弦)来得到和弦类型

guitar_chord(frets,
             return_chord=True,
             tuning=['E2', 'A2', 'D3', 'G3', 'B3', 'E4'],
             duration=0.25,
             interval=0,
             **detect_args)
# frets: 你按吉他的6根弦从最低音的弦到最高音的弦的品格数的列表,品格数为一个整数,如果是空弦就写0,如果是不弹的弦就写None
# return_chord: 是否返回和弦类型,为False的时候会判断你按的品格数弹出来是什么和弦,返回的具体的和弦名称,默认值为True。
# tuning: 吉他的定弦,默认值为6弦吉他的标准定弦,你也可以自己定制想要的吉他定弦
# duration: 返回的和弦类型的音符长度的列表
# interval: 返回的和弦类型的音符间隔的列表
# detect_args: 判断和弦的具体类型的参数,也就是detect函数的参数,以关键字参数设置

# 比如吉他的C大三和弦在前三品的一个标准按法是5弦3品,4弦2品,3弦空弦,2弦1品,1弦空弦,那么就可以写
>>> alg.guitar_chord([None, 3, 2, 0, 1, 0])
chord(notes=[C3, E3, G3, C4, E4], interval=[0, 0, 0, 0, 0], start_time=0)
>>> alg.guitar_chord([None, 3, 2, 0, 1, 0], return_chord=False)
'Cmajor'

你可以使用算法库的guitar_pattern函数,通过吉他品格数获得吉他旋律,通过吉他的6根弦的品格数和吉他定弦标准(可以不设置,默认为6弦吉他标准定弦)来得到和弦类型,以下为语法:

函数的第一个参数为字符串,以,分隔,使用sn将当前所在弦切换到第n弦,对应着吉他的1-6弦(更多的弦也支持,只需要吉他定弦标准支持即可),使用整数表示当前需要奏响的品格数,同样也支持相对音高语法与构建鼓点的语法。需要注意,这里第0品会和构建鼓点的语法中的默认休止符0产生冲突,当前的处理逻辑为直接解释为第0品,因此如果需要使用休止符,请使用i:n的语法,或者更换鼓点映射字典。

guitar_pattern(frets,
               tuning=database.guitar_standard_tuning,
               default_duration=1 / 8,
               default_interval=1 / 8,
               default_volume=100,
               mapping=database.drum_mapping)
# frets: 按照吉他的品格数编写的字符串
# tuning: 吉他的定弦,默认值为6弦吉他的标准定弦,你也可以自己定制想要的吉他定弦
# default_duration: 返回的和弦类型的默认音符长度
# default_interval: 返回的和弦类型的默认音符间隔
# default_volume: 返回的和弦类型的默认音符音量
# mapping: 鼓点映射的字典,可以自定义,默认值为drum_mapping

# 比如吉他的C大三和弦在前三品的一个标准按法是5弦3品,4弦2品,3弦空弦,2弦1品,1弦空弦,那么就可以写
>>> alg.guitar_pattern('s3,0,11,s1,12,0,12,s3,11,0,9,s3,0,11,s1,14,0,14,s3,11,0,9', tuning=[N(i)-2 for i in database.guitar_standard_tuning])
chord(notes=[F3, E4, D5, D4, D5, E4, F3, D4, F3, E4, ...], interval=[1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, ...], start_time=0)

#可以更换鼓点映射字典以使用休止符语法
drum_mapping_new = copy(database.drum_mapping)
drum_mapping_new['x'] = drum_mapping_new.pop('0')
>>> alg.guitar_pattern('i:1,s3,0,11,s1,12,0,12,s3,11,0,9,x,x,x,x,s3,0,11,s1,14,0,14,s3,11,0,9,-,-,-,-', tuning=[N(i)-2 for i in database.guitar_standard_tuning], mapping=drum_mapping_new)
chord(notes=[F3, E4, D5, D4, D5, E4, F3, D4, F3, E4, ...], interval=[1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 5/8, 1/8, 1/8, ...], start_time=1)

按照指定的BPM计算一个和弦类型的实际演奏时间

可以使用eval_time这个内置函数,指定一个BPM,计算出一个和弦类型的实际演奏时间

a = C('Cmaj7') | C('Dm7') | C('E9sus') | C('Amaj9', 3)
>>> a.eval_time(80)
'3.0s'

eval_time(bpm,
          ind1=None,
          ind2=None,
          mode='seconds',
          start_time=0,
          normalize_tempo=False,
          audio_mode=0)

# bpm: 指定的速度BPM

# ind1, ind2: 选择小节的区间,以0作为第1个小节,如果不设置则默认以整首曲子为准

# mode: 可以选择'seconds'返回格式为秒数的时间字符串,
# 或者'hms'返回格式为小时,分钟,秒的时间字符串,
# 或者'number'返回格式为秒数的浮点数

# start_time: 和弦的开始时间

# normalize_tempo: 是否量化速度变化

# audio_mode: 参考bars函数的参数

按照小节数的范围进行和弦类型的切片

如果我们想要提取一个和弦类型的第6个小节到第8个小节的片段,可以使用cut这个内置函数

cut(ind1=0,
    ind2=None,
    start_time=0,
    cut_extra_duration=False,
    cut_extra_interval=False,
    round_duration=False,
    round_cut_interval=False)

# ind1, ind2: 提取的小节数的范围,ind2如果不设置,则提取到最后,ind1默认值为0,也就是从开头第0个小节开始提取

# start_time: 在读取一个MIDI文件时,一个MIDI通道的音符会有自己的开始时间,在这里可以作为和弦类型延后演奏的设置,这里的单位为小节

# cut_extra_duration: cut函数默认是包括所有在指定小节范围内开始演奏的音符(不包括右端点), 与音符长度无关,所以可能出现音符长度超过小节范围的情况,如果设为True,则会对于音符长度超过小节范围的音符的音符长度进行调整

# cut_extra_interval: 如果设为True,对于超过小节范围的音符间隔进行调整

# round_duration: 如果设为True,对于调整后的音符长度出现极小值的情况当做去除音符处理

# round_cut_interval: 如果设为True,在计算音符间隔的时候,如果非常接近ind2, 则把当前的值作为ind2

# cut函数返回的是一个新的和弦类型,内容为指定的小节数的范围内的切片

a.cut(6, 8)

# 提取和弦类型a的从第6个小节到第8个小节的部分(从第6个小节的开头到第8个小节的开头)

计算一个和弦类型的总小节数

使用内置函数bars就可以得到一个和弦类型的总小节数

bars(start_time=0,
     mode=1,
     audio_mode=0,
     bpm=None)

# start_time: 额外的开始时间

# mode: 如果为0,计算方式为所有的音符间隔的总和; 如果为1,计算方式为在考虑音符长度的情况下找出和弦中的音符到达的最大距离(不考虑最后一个音符的音符间隔); 如果为2,在1的情况下考虑最后一个音符的音符间隔

# audio_mode: 如果为1,将音符列表中的pydub AudioSegment实例的时间长度转换为音符长度

# bpm: 当计算pydub AudioSegment实例的时间长度对应的音符长度时的bpm

a = C('Cmaj7') | C('Dm7') | C('E9sus') | C('Amaj9', 3)
>>> a.bars()
1.0

按照现实演奏时间的范围进行和弦类型的切片

使用内置函数cut_time,指定一个BPM,就可以选择一个时间范围进行和弦类型的切片,
比如和弦类型a在速度为100BPM的时候,提取第10秒到第20秒的部分,可以写

a.cut_time(100, 10, 20)
# 如果范围的右侧不设置,那么就默认提取到最后,左侧默认为从最开始提取

提取一个和弦类型前n个小节的部分

a.firstnbars(n)

提取一个和弦类型某一个小节的部分

a.get_bar(n)

提取一个和弦类型的每一个小节的内容

a.split_bars()
# 可以得到和弦类型a的每一个小节的部分的和弦类型组成的列表

对一个和弦类型内某个音名的出现次数进行计数

# 如果想得到和弦类型a里音名为F#的音出现了多少次,可以写
a.count('F#')
# 也可以指定八度数,只对音名和八度数都相同的音进行计数
a.count('F#5')

得到一个和弦类型出现次数最多的音

a.most_appear()
# choices参数可以设置要从哪些音里面选,如果不设置则默认为全部的12音

把一个和弦类型的所有音符统一升降音

# 比如一个和弦类型的音符为 C5, Eb5, G5, A#5, D#6, Bb6, F5 (一段随机的旋律),
# 如果我们想统一有升降号的音, 把有降号的音全部转换为有升号的音高等价的音,
# 也就是 C5, D#5, G5, A#5, D#6, A#6, F5, 那么可以写
a = chord('C5, Eb5, G5, A#5, D#6, Bb6, F5')
>>> print(a)
chord(notes=[C5, Eb5, G5, A#5, D#6, Bb6, F5], interval=[0, 0, 0, 0, 0, 0, 0], start_time=0)
a = a.standard_notation()
>>> print(a)
chord(notes=[C5, D#5, G5, A#5, D#6, A#6, F5], interval=[0, 0, 0, 0, 0, 0, 0], start_time=0)

把和弦类型根据里面的速度变化重新量化音符长度和音符间隔

比如现在我们有一个和弦类型,存着一首曲子,里面有一些tempo类型(速度变化类型),也就是一首曲子里的不同部分会有不同的速度,如果我们想统一整首曲子的速度,但是还是想要保留之前不同部分的不同速度,那么我们就需要按照每一部分的不同速度相对于想统一的速度的比例重新计算每一部分的音符长度和音符间隔,然后我们就可以在整首曲子没有速度变化的情况下听起来和之前的一模一样。有很多MIDI文件有非常多的速度变化,在一些古典音乐的MIDI文件里面有很多很复杂,很频繁,很快速细微的速度变化,这个时候统一整首曲子的速度可以方便之后在乐理上的处理,因为统一速度之后相当于把每一部分的不同速度的音符长度和音符间隔重新计算为实际等价于相对统一的速度的音符长度和音符间隔,可以在进行乐理分析的时候方便算法的运算与处理(因为不需要再考虑每一处的速度变化导致的实际演奏时间的变化)

# 使用内置函数normalize_tempo可以根据一个和弦类型里面存着的速度变化类型重新量化音符,
# normalize_tempo函数同时支持和弦类型(chord类型)和乐曲类型(piece类型)
a = read('example.mid') # a是读取example.mid这个MIDI文件之后转换为的乐曲类型
a.normalize_tempo() # 参数bpm, 默认值为None, 如果bpm为None,使用乐曲类型自带的速度参数
a.normalize_tempo(100) # 设定bpm为100,统一整首曲子的bpm为100,重新量化每一部分的音符

b, bpm, start_time = read('example.mid').merge() # b是读取example.mid这个MIDI文件之后合并所有音轨之后的和弦类型
b.normalize_tempo(bpm=100, start_time=0) # bpm参数是想要统一的速度,start_time参数是和弦类型开始演奏的时间,单位为小节,默认值为0
# 在这里我们把b这个和弦类型的速度统一为100BPM

计算一个和弦类型里两个index之间的小节范围

使用和弦类型的内置函数count_bars可以计算两个index之间的小节范围,比如有一个和弦类型有100个音,
我们想计算第2个音到第10个音之间的小节范围,也就是起始为第2个音所在的小节数,终止为第10个音所在的小节数的范围。
又或者我们想要第2个音到第10个音之间经过了多少小节(小节范围)。我们可以这么写:

count_bars(ind1, ind2, bars_range=True)
# ind1, ind2为开始和结束的音符的index(第几个音),为一个整数,
# 以0作为第1个音的index, bars_range为True的时候返回小节范围,值为一个列表[起始小节数,结束小节数],
# 为False的时候返回两个index之间经过的小节长度,值为一个数值
a = chord('A5, B5, C6, G5, G#5, ...') % (duration, interval) # 和弦a有100个音符
bar_length = a.count_bars(2, 10)
>>> print(bar_length)
[1.5, 7.5]
bar_length = a.count_bars(2, 10, False)
>>> print(bar_length)
6
# 这里的数值仅为举例

构建一个和弦进行

之前在讲音阶类型的基本语法的时候,有提到过音阶类型可以按照级数提取出和弦进行,那么如果是直接从和弦名称的角度上生成和弦进行,可以使用chord_progression函数,这是一个全局函数,不需要任何乐理类型作为前提。

chord_progression(chords,
                  durations=1 / 4,
                  intervals=0,
                  volumes=None,
                  chords_interval=None,
                  merge=True,
                  scale=None,
                  separator=',')
'''
chords: 和弦名称的字符串或者和弦类型的列表,其中和弦名称也可以是C函数的参数的元组

durations: 每个和弦的音符长度,可以是一个数值或者列表

intervals:每个和弦的音符间隔,可以是一个数值或者列表

volumes: 默认的每个和弦的音符的音量大小,可以是一个数值或者列表,如果为None则不进行设置

chord_interval: 每个和弦之间的间隔,可以是一个数值或者列表

merge: 如果为True,返回将和弦进行里的所有和弦合并之后的和弦类型,如果为False,返回和弦进行里的和弦类型的列表

scale: 你可以设置一个音阶类型来进行和弦级数的提取,请参考音阶类型的chord_progression函数

separator: 当chords是一个字符串时,按照separator字符串分离每个和弦
'''

chord_progression_example = chord_progression(['F', 'G', 'Am', 'Em'])
chord_progression_example = chord_progression([('F',4), ('G',4), ('C',5), ('Am',4)])
chord_progression_example = chord_progression([C('F')^2, C('G')^2, C('Am')^2, C('Em')^2])
>>> print(chord_progression_example)
chord(notes=[F4, C5, A5, G4, D5, B5, A4, E5, C6, E4, ...], interval=[0, 0, 1/4, 0, 0, 1/4, 0, 0, 1/4, 0, ...], start_time=0)
# 如果对于每个和弦的音符排列(比如转位或者按照一定的音符排列模式演奏等等)有更高的要求,建议使用和弦类型传入,和弦类型也可以直接写旋律,
# 如果是字符串就仅限于C函数可以解析的范围内。

查看一个和弦类型的乐理分析信息

使用和弦类型的内置函数info可以查看一个和弦类型的音符组成的和弦类型,根音,和弦的特殊性(原位,转位还是复合和弦等等),以及省略音,变化音,和弦声部配置,不属于和弦内音的最低音 (如果有的话)。如果和弦类型包含的并不是一个和弦,而是一个音符或者音程,信息会显示音符名称或者音程名称。

>>> print(chord('A,C,F').info())
chord_type(root='F', chord_type='major', chord_speciality='inverted chord', inversion=1, omit=None, altered=None, non_chord_bass_note=None, voicing=None, type='chord', note_name=None, interval_name=None, polychords=None, order=[2])

>>> print(chord('A').info())
chord_type(root=None, chord_type=None, chord_speciality='root position', inversion=None, omit=None, altered=None, non_chord_bass_note=None, voicing=None, type='note', note_name='A4', interval_name=None, polychords=None, order=None)

>>> print(chord('C,E').info())
chord_type(root='C', chord_type=None, chord_speciality='root position', inversion=None, omit=None, altered=None, non_chord_bass_note=None, voicing=None, type='interval', note_name=None, interval_name='major third', polychords=None, order=None)

获得一个和弦类型的sus

如果我们想获得一个和弦类型的sus4或者sus2的变化型,那么可以使用和弦类型内置的sus函数,默认值为4

a1 = chord('C, E, G')
>>> print(a1.sus())
chord(notes=[C4, F4, G4], interval=[0, 0, 0], start_time=0)
>>> print(a1.sus(2))
chord(notes=[C4, D4, G4], interval=[0, 0, 0], start_time=0)
# sus函数可以接收2或者4为参数,对一个和弦类型里的对于最低音的3度音进行sus操作,替换为2度音或者4度音,
# 不只适用于三和弦,同样也适用于七和弦,九和弦,十一和弦等等更复杂的和弦

将同一个和弦类型延后播放n次或者先后有间隔地播放n次

最近新增了将一个和弦类型延后播放n次以及先后有间隔地播放n次的语法,使用到的分别是&|符号, 这2个符号都是用来和另外一个和弦类型同时播放或者先后播放的,但是现在如果传入的是一个元组,那么就可以得到重复延后同一个和弦类型的结果。

a1 = chord('C, E, G')
>>> print(a1 & (3, 1/8)) # 将和弦类型a1播放3遍,每一次比开头多延后1/8个小节
chord(notes=[C4, E4, G4, C4, E4, G4, C4, E4, G4], interval=[0, 0, 1/8, 0, 0, 1/8, 0, 0, 1/4], start_time=0)

>>> print(a1 | (3, 1/8))  将和弦类型a1播放3遍每一次都接在后头但是都会先间隔1/8个小节
chord(notes=[C4, E4, G4, C4, E4, G4, C4, E4, G4], interval=[0, 0, 3/8, 0, 0, 3/8, 0, 0, 0], start_time=0)

统一和弦类型的音符的升降号

你可以使用和弦类型的same_accidentals函数来统一和弦类型的音符的升降号,

a = chord('C5, D#5, F5, Ab5, E5, D5, C#5')
>>> a.same_accidentals('#')
chord(notes=[C5, D#5, F5, G#5, E5, D5, C#5], interval=[0, 0, 0, 0, 0, 0, 0], start_time=0)
>>> a.same_accidentals('b')
chord(notes=[C5, Eb5, F5, Ab5, E5, D5, Db5], interval=[0, 0, 0, 0, 0, 0, 0], start_time=0)

筛选出和弦类型中满足指定条件的音符

你可以使用和弦类型的filter函数,通过指定条件过滤掉和弦类型中不满足条件的音符,筛选出和弦类型中满足指定条件的音符。 比如筛选出音量在20到80之间的音符,音符长度在1/16小节到1小节之间的音符,音高在A0到C8之间的音符等等。你也可以指定一个函数对于筛选出来的音符进行操作。

filter(self, cond, action=None, mode=0, action_mode=0)

# cond: 筛选的条件函数,必须为一个参数为音符,返回值为布尔值的函数,推荐使用lambda函数

# action: 操作函数,如果不为None,则对于筛选出来的音符进行这个函数的操作,但是并不单独提取出筛选出来的音符,
# 返回的是经过修改的和弦类型,如果为None,则返回筛选出来的音符组成的和弦类型和第一个筛选出来的音符的开始时间

# mode: 如果为1,则返回筛选出来的音符的index列表

# action_mode: 如果为0,action函数作用音符的返回值会替换掉它作用的音符,如果为1,action函数会直接作用到音符上

a = chord('C, E, G, B') # 初始化一个和弦
a.set_volume([10, 20, 50, 90]) # 设置音符的音量
>>> a.filter(lambda s: 20 <= s.volume < 80) # 筛选出和弦类型里音量在20到80之间的音符
(chord(notes=[E4, G4], interval=[0, 0], start_time=0), 0) # 返回筛选出来的音符组成的和弦类型以及第一个筛选出来的音符的开始时间

# 对于音量在20到80之间的音符,音量都设置为50
b = a.filter(lambda s: 20 <= s.volume < 80, action=lambda s: s.set_volume(50), action_mode=1)
>>> b
chord(notes=[C4, E4, G4, B4], interval=[0, 0, 0, 0], start_time=0) # 返回经过action函数修改音量的和弦类型
>>> b.get_volume() # 获得新的和弦类型的音量
[10, 50, 50, 90] # 之间音量在20到80之间的音符的音量现在都变成了50

筛选出和弦类型中指定音高范围内的音符

你可以使用和弦类型的pitch_filter函数筛选出和弦类型中指定音高范围内的音符。这个功能在很多场合下非常重要,比如当你读取了一个MIDI文件时, 需要把MIDI文件的音符对应到一个软件里的钢琴上进行显示,一般来说钢琴为88键,音高范围为A0 ~ C8,但是MIDI文件中是可以存储超过这个音高范围的音符的, 可能低于A0,也可能高于C8,因此我们需要把读取的MIDI文件的音符的音高限制在A0到C8之间,不属于这个区间的音符需要去掉。这个功能就可以做到这件事情, 并且会重新计算筛选过后的所有音符的间隔,因此并不会影响到再次输出为MIDI文件时音符的位置。有着更普遍用途的filter函数也会重新计算所有音符的间隔。

pitch_filter(self, x='A0', y='C8')

# x: 音高范围的最低音,默认值为A0

# y: 音高范围的最高音,默认值为C8

a = chord('Ab0, C5, E5, G5, B5, G10') # this is a chord with 2 notes that the pitches do not belongs to A0 ~ C8
>>> a.pitch_filter() # 使用默认音高范围A0到C8对和弦类型进行音符的筛选
(chord(notes=[C5, E5, G5, B5], interval=[0, 0, 0, 0], start_time=0), 0)
# 返回筛选出来的在指定音高范围内的音符组成的和弦类型,和第一个筛选出来的音符的开始时间

b = chord('Ab0, C5, E5, G5, A5, C7, G10')
>>> b.pitch_filter('C5', 'C6') # 筛选出音高在C5到C6之间的音符
(chord(notes=[C5, E5, G5, A5], interval=[0, 0, 0, 0], start_time=0), 0)
# 返回筛选出来的在指定音高范围内的音符组成的和弦类型,和第一个筛选出来的音符的开始时间

查找一个和弦类型的某度音

现在比如你有一个C小十一和弦,你想得到它的3度音和9度音,这时候可以使用和弦类型的interval_note函数,输入一个度数进行查找。 如果当前的和弦类型并不包含指定度数的音符,那么会返回None。支持查找的度数包括从1度(根音)一直到13度,也包括变化音的情况,比如#5, b9

interval_note(self, interval, mode=0)

# interval: 想要查找的度数,可以是整数或者表示度数的字符串

# mode: 为0的时候,如果查找不到指定度数的音,返回None,为1的时候,会返回和弦类型的起始音加上指定度数的音符类型

>>> C('Cm11') # C小十一和弦
chord(notes=[C4, Eb4, G4, Bb4, D5, F5], interval=[0, 0, 0, 0, 0, 0], start_time=0)

>>> C('Cm11').interval_note(3) # 查找C小十一和弦的3度音
Eb4 # 返回C小十一和弦的3度音

>>> C('Cm11').interval_note(9) # 查找C小十一和弦的9度音
D5 # 返回C小十一和弦的9度音

>>> C('Cm11').interval_note('b5', mode=1) # 返回C小十一和弦的起始音的降5度音
Gb4

确认一个音符是一个和弦的第几度音

这里做的是和查找一个和弦类型的某度音反过来的事情,你可以使用和弦类型的note_interval函数,确认一个音符是一个和弦类型的第几度音。 如果指定的音符并不在和弦类型中,也会返回和弦类型的起始音与这个音符的度数关系。

note_interval(self, current_note, mode=0)

# current_note: 想要确认度数的音符,可以是表示音符的字符串或者音符类型

# mode: 为0的时候,会返回以升降号和数字表示的度数,为1的时候,会返回纯英文的音程表示

>>> C('Cm11') # C小十一和弦
chord(notes=[C4, D#4, G4, A#4, D5, F5], interval=[0, 0, 0, 0, 0, 0], start_time=0)

>>> C('Cm11').note_interval('Eb4') # 确认音符Eb4是以C4为起始音的C小十一和弦原位的几度音
'b3' # 返回的结果是3度音(b3表示小3度,或者也可以说降3度,因为没有降的3度是大3度)

>>> C('Cm11').note_interval('D5') # 确认音符D5是以C4为起始音的C小十一和弦原位的几度音
'9' # 返回的结果是9度音 (大9度音)

>>> C('Cm11').note_interval('Db5') # 确认音符Db5是以C4为起始音的C小十一和弦原位的几度音
'b9' # C小十一和弦并没有包含Db这个音,但是这个函数也会返回和弦的起始音C4与Db5形成的音程关系,也就是b9 (降九度或者小九度)

>>> C('Cm11').note_interval('D5', mode=1) # 确认音符D5是以C4为起始音的C小十一和弦原位的几度音,返回纯英文的表示
'major ninth'

按照和弦的度数来获得和弦声位(chord voicing)

一个和弦的音有很多种排列组合的方式,每一种独特的组合都是一种voicing,通过对于和弦的音按照不同的顺序和八度数的摆放,一个和弦可以有各种各样的voicings, 每一种voicing都有着独特的听感,无论是柱式和弦,分解和弦还是琶音都可以听出不同的味道。比如一个Cm11和弦,你可以按照原位1, 3, 5, 7, 9, 11度音的顺序来弹, 也可以按照1, 5, 9, 3, 7, 11度音的顺序来营造一种更加梦幻唯美的听感。因此我们需要一个方便的函数可以通过和弦的音的度数来获得一个和弦的voicing,包括和弦的音的顺序,省略音,重复音在更高的八度的情况都需要考虑到。我最近设计出来的和弦类型的get_voicing函数可以做到这些。

get_voicing(self, voicing)

# voicing: 和弦声位的列表,也就是表示和弦的度数的顺序的列表,元素可以是整数或者表示度数的字符串

# 需要注意的是,和弦声位列表中必须都是当前和弦类型有的度数

>>> C('Cm11').get_voicing([1,5,9,3,11,7]) # C小十一和弦按照根音,5度音,9度音,3度音,11度音,7度音的顺序摆放,
# 并且重新按照后面的音比前面的音更高的规则重新分配所有音符的八度数
chord(notes=[C4, G4, D5, D#5, F5, A#5], interval=[0, 0, 0, 0, 0, 0], start_time=0)
# 返回按照指定的和弦声位列表进行声部排列的C小十一和弦的voicing的和弦类型

play(C('Cm11').get_voicing([1,5,9,3,11,7]) % (1, 1/8), 150) # 以快速琶音进行演奏

把当前的和弦类型的音符调整为距离另一个和弦的音比较近的地方

在考虑和弦声部排列的时候,后一个和弦与前一个和弦之间如果想要更加平滑地连接,那么其中一个办法就是把后一个和弦的音放在距离前一个和弦的音比较近的地方,这样和弦进行中不同声部的连接就会比较顺畅,因为声部的移动比较小。

比如Am和弦的原位接到F和弦的原位,也就是A C E接到F A C,如果想要比较平滑地连接这两个和弦,可以调整F和弦的音的顺序,让F和弦的每个音都距离Am和弦的原位的每个音尽量近,比如调整为A C F,这样F和弦的前两个音都与Am和弦的原位的前两个音是相同的,第三个音F也只比Am和弦的原位的第三个音高一个半音,因此这两个和弦连接起来就会听着比较平滑流畅。

你可以使用和弦类型的near_voicing函数,把当前的和弦类型的音调整为另一个和弦类型的音在音高上比较相近的顺序,如果本身两个和弦的音高差就比较大,那么也会把当前的和弦类型的音移动到另一个和弦类型的音高范围内。

你也可以让当前和弦类型的最低音固定住,不进行最近音高距离的调整,因为有些时候最低音的变化得到的和弦转位并不是我们想要的。

near_voicing(self,
             other,
             keep_root=True,
             standardize=True,
             choose_nearest=False,
             get_distance=False)

# other: 作为调整当前和弦类型的音的标准的和弦类型

# keep_root: 为True的时候,保持当前的和弦类型的最低音在调整过后还是最低音

# standardize: 是否对音符进行标准化

# choose_nearest: 如果设置为True,选择保持最低音和不保持最低音之间距离最小的那一个

# get_distance: 如果设置为True,则返回 (结果, 距离)

>>> C('F').near_voicing(C('Am'), keep_root=False) # 得到F和弦原位关于Am和弦原位的最近距离的voicing,不保持最低音
chord(notes=[A4, C5, F5], interval=[0, 0, 0], start_time=0)

# 写一段C大调的2516和弦进行的平滑声部连接
chord1 = C('Dm7', 3).get_voicing([1, 7, 3]) % (1,[1/4,1/4,1/2])
chord2 = C('G7, omit5', 4).near_voicing(chord1, keep_root=True) % (1,[1/4,1/4,1/2])
chord3 = C('Cmaj7, omit5', 4).near_voicing(chord1, keep_root=True) % (1,[1/4,1/4,1/2])
chord4 = C('Am7, omit5', 4).near_voicing(chord1, keep_root=True) % (1,[1/4,1/4,1/2])
play(chord1 | chord2 | chord3 | chord4, 165)

快速制作和弦琶音

2021年8月新增了快速制作和弦琶音的函数arpeggio, 你可以指定和弦类型,和弦琶音的八度范围,音符长度和音符间隔,也可以选择播放上行琶音或者下行琶音,或者两者都生成。你也可以使用arp作为简写。

arpeggio(chord_type,
          start=3,
          stop=7,
          durations=1 / 4,
          intervals=1 / 32,
          first_half=True,
          second_half=False)

# chord_type: 表示和弦类型的字符串,可以使用C函数支持的语法,也可以是和弦类型

# start: 和弦琶音开始的八度数

# stop: 和弦琶音结束的八度数

# durations: 和弦琶音的音符长度

# intervals: 和弦琶音的音符间隔

# first_half: 生成上行的和弦琶音

# second_half: 生成下行的和弦琶音

Cmaj7_arpeggio = arpeggio('Cmaj7')

>>> Cmaj7_arpeggio
chord(notes=[C3, E3, G3, B3, C4, E4, G4, B4, C5, E5, ...], interval=[1/32, 1/32, 1/32, 1/32, 1/32, 1/32, 1/32, 1/32, 1/32, 1/32, ...], start_time=0)

Cmaj7_arpeggio = arp('Cmaj7', 3, 6)

>>> Cmaj7_arpeggio
chord(notes=[C3, E3, G3, B3, C4, E4, G4, B4, C5, E5, ...], interval=[1/32, 1/32, 1/32, 1/32, 1/32, 1/32, 1/32, 1/32, 1/32, 1/32, ...], start_time=0)

重新设定和弦类型的整体八度数

你可以使用reset_octave函数来把一个和弦类型的整体八度数进行设定,以和弦类型的第1个音的八度数为标准,把和弦类型整体移动到你设定的八度数,返回的是一个新的和弦类型。这个方法在你不知道本来的和弦的整体八度数的情况下很有用。

a = C('Cmaj7', 5)

>>> a
chord(notes=[C5, E5, G5, B5], interval=[0, 0, 0, 0], start_time=0)

b = a.reset_octave(3)

>>> b
chord(notes=[C3, E3, G3, B3], interval=[0, 0, 0, 0], start_time=0)

与其他MIDI信息一起构建和弦类型

一般来说,你可以在构建和弦类型时传入other_messages的属性来添加其他的MIDI信息,但是如果你想在和弦类型构建之后再添加其他的MIDI信息,你可以直接设定和弦类型的other_messages属性,也可以使用和弦类型的with_other_messages函数来获得新的有着其他的MIDI信息的和弦类型。请注意other_messages是一个其他的MIDI信息的列表。

a = C('Cmaj7')

b = a.with_other_messages([event('control_change', control=1, value=50)])

>>> b.other_messages

[event(type=control_change, track=0, start_time=0, control=1, value=50)]

按照多声部来写和弦类型

你可以使用multi_voice函数来将多个和弦类型作为多个声部进行合并,返回的是多个声部合并后的新的和弦类型。这个方法在写同一种乐器的多声部旋律与和声的时候很有用,比如写A cappella和复杂的鼓点的时候。

multi_voice(*current_chord, method=chord, start_times=None)

# *current_chord: 你可以传入任意多个和弦类型作为声部

# method: 如果传入的是表示和弦的字符串,可以在这边选择和弦解析的语法,你可以选择chord, translate和drum

# start_times: 第一个和弦类型之后的和弦类型的开始时间的列表,
# 如果你想设定第一个和弦类型之后的其他的声部相对第一个和弦类型的开始时间,可以设置这个参数,单位为小节

a = multi_voice(chord('C2') % (1, 1) * 2,
                C('G') % (1/8, 1/8) * 4)

>>> a
chord(notes=[C2, G4, B4, D5, G4, B4, D5, G4, B4, C2, ...], interval=[0, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 0, ...], start_time=0)

把一个列表中的和弦类型进行合并

你可以使用concat函数,通过指定一种合并方式把一个列表中的所有的和弦类型进行合并,得到的是一个新的合并过后的和弦类型。

concat(chordlist, mode='+', extra=None, start=None)

# chordlist: 要进行合并的和弦类型的列表

# mode: 合并方式,可以接收的值有'+', '|', '&', 前两个值都对应'after', 第三个值对应'head', 默认值为'+'

# extra: 每两个相邻的和弦类型进行合并时需要额外添加的间隔,单位为小节

# start: 合并的起始值,如果为None,则使用列表的第一个元素为起始值

chord_list = [C('C'), C('D'), C('E')]
>>> chord_list
[chord(notes=[C4, E4, G4], interval=[0, 0, 0], start_time=0), chord(notes=[D4, F#4, A4], interval=[0, 0, 0], start_time=0), chord(notes=[E4, G#4, B4], interval=[0, 0, 0], start_time=0)]

combined_chord = concat(chord_list, '|')

>>> combined_chord
chord(notes=[C4, E4, G4, D4, F#4, A4, E4, G#4, B4], interval=[0, 0, 1/4, 0, 0, 1/4, 0, 0, 0], start_time=0)

把多个音符按照长度比例平均分配到指定的小节长度内

你可以使用distribute函数来把多个音符按照长度比例平均分配到指定的小节长度内。这在写一些特殊的节奏型以及多连音的时候很有用。

distribute(current_chord,
           length=1 / 4,
           start=0,
           stop=None,
           method=translate,
           mode=0)

# current_chord: 表示和弦的字符串或者音符的列表

# length: 用来分配的总长度,单位为小节

# start: 和弦中开始进行分配的音符的index,从0开始,默认从第1个音开始

# stop: 和弦中结束进行分配的音符的index,从0开始,如果为None,则到最后1个音,默认值为None

# method: 传入的是表示和弦的字符串时,用来解析的方法,默认值为translate,可以选择chord, translate

# mode: 为0的时候,音符的长度和间隔都按照各自的值按比例平均分配到指定的小节长度内,
# 为1的时候,音符间隔会取与音符长度一样的值。

# 把Cmaj9和弦的5个音平均分配到1/2个小节的长度,分配之前5个音的音符长度与间隔相同
a = distribute(C('Cmaj9') % (1/8, 1/8), 1/2)

>>> a
chord(notes=[C4, E4, G4, B4, D5], interval=[1/10, 1/10, 1/10, 1/10, 1/10], start_time=0)

>>> a.get_duration()
[0.1, 0.1, 0.1, 0.1, 0.1]

# 把音符长度分别为2分音符,4分音符的2个音符(重复2次)平均分配到1/2个小节的长度
b = distribute('C[.2;.], D[.4;.], {2}', 1/2)

>>> b
chord(notes=[C4, D4, C4, D4], interval=[1/6, 1/12, 1/6, 1/12], start_time=0)

>>> b.get_duration()
[0.16666666666666666, 0.08333333333333333, 0.16666666666666666, 0.08333333333333333]

使用translate函数来按照鼓点语法写和弦类型

在鼓点类型的章节有提到过,你可以使用translate函数,来将鼓点的语法应用到音符中,实现用鼓点的语法写和弦类型。这里有更加详细的说明。translate函数和鼓点类型构建时的一个区别是,translate函数默认的音符间隔是0,而鼓点类型默认的音符间隔是1/8, translate函数和鼓点类型默认的音符长度都是1/8。默认的音符长度,间隔和音量也可以通过和构建鼓点类型时一样的参数来设定。相对音高的语法也是支持的。这里我会给几个使用translate函数来写和弦类型的例子。

>>> translate('A2[l:1; i:1; r:2], i:1, D3[l:1; i:1; r:2]')
chord(notes=[A2, A2, D3, D3], interval=[1, 2, 1, 1], start_time=0)

>>> translate('C5[l:.8; i:.; r:3], D5[l:.16; i:.; r:2], E5[l:.8; i:.], r:2')
chord(notes=[C5, C5, C5, D5, D5, E5, C5, C5, C5, D5, ...], interval=[1/8, 1/8, 1/8, 1/16, 1/16, 1/8, 1/8, 1/8, 1/8, 1/16, ...], start_time=0)

>>> translate('C5, E5, G5')
chord(notes=[C5, E5, G5], interval=[0, 0, 0], start_time=0)

重新设定和弦类型的整体音高

你可以使用和弦类型的reset_pitch函数,以和弦类型的第1个音为标准,将和弦类型整体的音高移动到另一个音高,返回的是一个新的和弦类型。参数可以是一个表示音符的字符串或者音符类型。比如一个Cmaj7和弦,你想移动到Emaj7和弦,但是你又不想使用up或者+来进行移调,因为这需要计算C到E的半音数,那么你可以使用这个方法。

a = C('Cmaj7')

>>> a
chord(notes=[C4, E4, G4, B4], interval=[0, 0, 0, 0], start_time=0)

>>> a.reset_pitch('E')
chord(notes=[E4, G#4, B4, D#5], interval=[0, 0, 0, 0], start_time=0)

>>> a.reset_pitch('E3')
chord(notes=[E3, G#3, B3, D#4], interval=[0, 0, 0, 0], start_time=0)

和弦类型从index列表中提取音符组成新的和弦类型

当你通过index从和弦类型中挑选了一些音符,想把它们取出来,但是还想保留原来的音符之间的距离关系,那么可以使用和弦类型的pick函数,返回的是提取出来的音符组成的新的和弦类型。

pick(indlist)

# indlist: 音符的index的列表

替换和弦类型中的音符和和弦

要用索引替换和弦类型中的一个音符,你可以简单地写a[index] = new_note,其中a是一个和弦类型。

要替换和弦类型中的一个和弦,也就是替换和弦类型中的多个音符,你可以使用和弦类型的replace_chord函数来替换2个索引之间的音符。

replace_chord(ind1, ind2=None, value=None, mode=0)

# ind1: 起始索引

# ind2: 结束索引,如果设置为None,那么它将被计算为`ind1 + len(value)`。

# value: 要替换的和弦,可以是和弦类型或任何`chord`函数可以解析的数据结构

# mode: 如果设置为0,ind1和ind2之间的音符和音符间隔将被新和弦类型的音符和音符间隔取代,
# 如果设置为1,只有音符的音高会被替换,ind1和ind2之间的音符的其他属性和音符间隔保持不变

a = chord('C5, D5, E5, F5, G5, A5, B5', interval=1/8)

>>> a
chord(notes=[C5, D5, E5, F5, G5, A5, B5], interval=[1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8], start_time=0)

a.replace_chord(ind1=1, value=C('A', duration=2))

>>> a
chord(notes=[C5, A4, C#5, E5, G5, A5, B5], interval=[1/8, 0, 0, 0, 1/8, 1/8, 1/8], start_time=0)

>>> a.get_duration()
[0.25, 2, 2, 2, 0.25, 0.25, 0.25]

b = chord('C5, D5, E5, F5, G5, A5, B5', interval=1/8)

>>> b
chord(notes=[C5, D5, E5, F5, G5, A5, B5], interval=[1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8], start_time=0)

b.replace_chord(ind1=1, value=C('A'), mode=1)

>>> b
chord(notes=[C5, A4, C#5, E5, G5, A5, B5], interval=[1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8], start_time=0)

>>> b.get_duration()
[0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25]
Clone this wiki locally