楽譜をランダムで生成するコードを作りました。機械学習の楽譜のデータセット作成用として使ってください。
#こんな感じの画像ができます
#環境
- chromebookのdebian9 (stretch)
- numpy (1.16.6)
- music21 (5.7.2)
- lilypond (2.18.2)
- python3 (3.5.3)
#必要なライブラリーやソフト
pythonのライブラリー:
- numpy
- music21
ソフト:
- lilypond
#コード
randomScore.py
import music21 as m21
from numpy.random import choice
def makeScore(symbleNum=200, scoreNum=20, noteRange=[3, 4, 5, 6, 7],
noteRangeProbs=[0.05, 0.4, 0.4, 0.1, 0.05], sharpProb=0.1,
restProb=0.2, exportDir='/home'):
'''
symbleNum:楽譜一枚あたり何個の音符と休符があるか
scoreNum:楽譜を何枚生成するか
noteRange:何オクターブ目から何オクターブ目の音符があるか(デフォルトはC3からB#7まで)
noteRangeProbs:それぞれの音符がオクターブ別にどのくらい出てくるかの確率のリスト
sharpProb:音符にシャープがつく確率
restProb:休符が出る確率
exportDir:出力ファイルの保存先
===========================
デフォルトではファイル名は1, 2, 3, ... となっております。
.pngファイルの他に色々なファイルが出ますが、消していいです。
'''
quarterLengths = [4, 2.5, 2, 1.5, 1, 0.75, 0.5, 0.25]
notes = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
noteRange = list(map(lambda x: str(x), noteRange))
typeProbs = [1 - restProb, restProb]
sharpProbs = [sharpProb, 1 - sharpProb]
chooseThese = [True, False]
for i in range(scoreNum):
noteList = []
measure = m21.stream.Measure()
for j in range(symbleNum):
if choice(a=chooseThese, p=typeProbs):
if choice(a=chooseThese, p=sharpProbs):
pitchName = choice(notes) + '#' + choice(a=noteRange, p=noteRangeProbs)
else:
pitchName = choice(notes) + choice(a=noteRange, p=noteRangeProbs)
n = m21.note.Note(pitchName, quarterLength=choice(quarterLengths))
noteList.append(n)
else:
n = m21.note.Rest(quarterLength = choice(quarterLengths))
noteList.append(n)
measure.append(noteList)
fileName = exportDir + str(i)
measure.write('lily.png', fileName)
if __name__ == "__main__":
makeScore()
#悪いところ
- 四拍子だけ
- 一小節内の音符の数がおかしい
- 音楽的に(旋律)おかしい
- フラットがない
- 題名がない
- ダイナミクス、アーティキュレーションがない
などなど