Music21
建议配合官方图片食用
音符(Notes)
标准音符的概念被包含在 note 的 Note 对象之中
直接输入 note 便可得到该模块的位 置
如果你想知道 note 除了 Note 还包含什么,可以输入 dir(note)
创建音符
让我们使用 note.Note 创建一个音符
f = note.Note('F5')
音符的属性
F5 是这个音符的音名
通过 .name .step 和 .octave 可以得到其音名、音级、八度(在第几个八度)信息
f.name f.step f.octave
'F' 'F' 5
.step 得到不包含变化音及八度信息的音名,这里成为音级严格来说并不准确
当然也可以使用 .pitch 直接得到其音名
f.pitch
<music21.pitch.Pitch F5>
使用 .pitch.frequency 得到其频率
f.pitch.frequency
音高698.456462866008
使用 .pitch.pitchClass 同样可以得到其音级(距离同一个八度中 c 的半音数字),使用 .pitch.pitchClassString 则可以得到一个 String
f.pitch.pitchClassf.pitch.pitchClassString type(f.pitch.pitchClassString)
音高5 '5' <class'str'>
在 music21 中,升降分别使用 # 和 -,我们创建一个新的音符
b_flat = note.Note("B2-")
使用 .pitch.accidental 可获得其属性 (accidental 在音乐中表示变音记号),使用 .pitch.accident.alter 获得其半音变化数量,使用 .pitch.accidental.name 获得其
b_flat.pitch.accidental b_flat.pitch.accidental.alter b_flat.pitch.accidental.name
<accidental flat> -1.0 'flat'
注意,这里是一个浮点数,这意味着 music21 支持四分音符之类现实中通常不使用的东西
此外,并不是每一个音符都有 accidental 的,某些音符会返回 None
我们可以使用一个判断语句来解决:
if d.pitch.accidental is not None:
print(d.pitch.accidental.name)
如果你安装了 MusicXML 阅读器,使用 f.show() 可查看其五线谱
修改音符
使用 .transpose 修改你的音符
d = b_flat.transpose("M3") #将Bb上调大三度,变为D
这种用法并没有改变音符本身,而是返回一个变量
可以使用 inplace=True 进行原地操作
休止符
使用 note.rest
a = note.rest() # 记得加括号
最后提醒一个点,不要使用 note 作为音符的变量
note = note.Note("C4")
音高(Pitch),时值(Duration)
音高
使用 pitch.pitch() 创建一个音高对象
p1 = pitch.Pitch('b-4')
有许多属性和 note 是一样的
pl.octave pl.name pl.pitchClass pl.accidental.alter
4 'B-' 10 -1.0
.transpose() 同样可以使用
.nameWithOctave 和 .midi
pl.nameWithOctave pl.midi
'B-4' 70
这些属性大多数都可以修改
pl.name = "d#"
pl.octave = 3
pl.nameWithOctave
'D#3'
这时 pl 代表的音符已经变为了 D#3
实际上,每一个 Note 对象内部,都有一个 Pitch 对象,我们对 note.Note 做的一切,都可以用 note.Note.pitch 对象代替
一些 note 不支持的属性
csharp.pitch.spanish # 获得其西班牙名称
可以使用一些其他的方法,来更清晰地打印
print(csharp.pitch.unicodeName)
C♯
获得一些同音的方法
print( csharp.pitch.getEnharmonic() )
print( csharp.pitch.getLowerEnharmonic() )
D-4
B##3
时值
任何音符的存在都离不开时值 Duration
创建一个二分音符
halfDuration = duration.Duration('half')
# ‘whole','half','quarter','eighth','16th','32th','64th' 一直到'2048th',虽太小无法在乐谱上无法显示
# 'breve','longa','maxima' 2,4,8个全音
另一种创建方法是说明他有多少个四分音符
dottedQuarter = duration.Duration(1.5)
可以使用 .quarterLength 得到时值是多少个四分音符
还可以使用 Note 创建
c = note.Note("C4", type='whole')
.type 可以得到一般类型,如 'half','quarter'
.dots 可以得到音符有多少个附点
使用 .lyric 添加歌词(具体看文档吧,不具体介绍了)
otherNote = note.Note("F6")
otherNote.lyric = "I'm the Queen of the Night!"
流 (Stream)
我们可以通过列表对 note 等对象进行处理,但是它们对音乐一无所知,因此需要一个类似于列表的对象具有一定“智能”的对象,成为 Stream
流有许多子类 Score 乐谱、Part 声部、Measure 小节
创建流
Stream 中储存的元素必须是 music21 对象,如果想加入不属于 music21 的对象,请将其放入 ElementWrapper
使用 Stream() 创建流,.append() 方法添加元素,.repeatAppend() 方法添加多个相同的音符
stream1 = stream.Stream()
stream1.append(note1)
stream1.append(note2)
stream1.append(note3)
stream2 = stream.Stream()
n3 = note.Note('D#5') # octave values can be included in creation arguments
stream2.repeatAppend(n3, 4)
使用 .show('text') 查看其中的内容及其偏移量(从 0.0 开始,一般 1 个偏移量指一个四分音符的长度)
stream1.show('text')
{0.0} <music21.note.Note C>
{2.0} <music21.note.Note F#>
{3.0} <music21.note.Note B->
流的大部分方法和列表相同,如切片、索引(还可使用 .index() 访问)、pop()、.append()、len() 等,并且流中也可以存放列表
按类分离元素
提供一种过滤流以获取所需元素 .getElementByClass()
for thisNote in stream1.getElementsByClass(["Note", "Rest"]):
print(thisNote, thisNote.offset)
<music21.note.Note C> 0.0
<music21.note.Note F#> 2.0
<music21.note.Note B-> 3.0
此外也可使用 .notes、.notesAndRests、.pitches 等来进行过滤,直接使用会返回所有,如
stream1.pitches
[<music21.pitch.Pitch D#5>,
<music21.pitch.Pitch D#5>,
<music21.pitch.Pitch D#5>,
<music21.pitch.Pitch D#5>]
for thisNote in stream1.notesAndRests:
print(thisNote)
<music21.note.Note C>
<music21.note.Note F#>
<music21.note.Note B->
通过偏移量分离元素
getElementsByOffset()
sOut = stream1.getElementsByOffset(2, 3).stream()
sOut.show('text')
{2.0} <music21.note.Note F#>
{3.0} <music21.note.Note B->
还有 getElementAtOrBefore()(某个偏移量及其之前 score = stream.Score()
1),getElementAfterElement()(某个偏移量之后)
更多功能
.analyze('ambitus') 获得流中的音域范围
.lowestOffset 返回偏移量的最小值
__repr__
.id,可以自己设定,相当于名字,如
s = stream.Score(id='mainScore')
p0 = stream.Part(id='part0')
p1 = stream.Part(id='part1')
.duration 储存 Duration 对象的属性