#はじめに
以前コード進行を自動で生成してくれるサービスを作成した。
https://chordprogressor.herokuapp.com/
https://qiita.com/Giita2000/items/b0a500762a127b7ad69b
このときは生成したコード進行を表示するだけだったが,楽器を弾かなくてもコード進行を耳で確認できれば便利。
#pretty_midiを用いたMIDIファイル生成
そこでWeb上で鳴らすことを考え,生成したコードを鳴らすMIDIファイルの作成をpython上でできる方法を探したところ,pretty_midiというライブラリが良いみたい。
https://qiita.com/tackey/items/d0525798bddc4516f4f9
鳴らす音を一個づつ加えていけば良いので,コード進行を文字列で入力すればmidiファイルが出来上がるように関数化した。
import numpy as np
import pretty_midi
import re
def midi_create(imput_chords):
root = {'C':0,
'C#':1,
'D♭':1,
'D':2,
'D#':3,
'E♭':3,
'E':4,
'F':5,
'F#':6,
'G♭':6,
'G':7,
'G#':8,
'A♭':8,
'A':9,
'A#':10,
'B♭':10,
'B':11,}
chord_type = {'':np.array([0, 4, 7]),
'm':np.array([0, 3, 7]),
'7':np.array([0, 4, 7, 10]),
'm7':np.array([0, 3, 7, 10]),
'mM7':np.array([0, 3, 7, 11]),
'M7':np.array([0, 4, 7, 11]),
'dim':np.array([0, 3, 6, 9]),
'aug':np.array([0, 4, 8]),
'add9':np.array([0, 4, 7, 14]),
'sus4':np.array([0, 5, 7]),
'7sus4':np.array([0, 5, 7, 10]),
'm6':np.array([0, 3, 7, 9]),
'6':np.array([0, 4, 7, 9]),
'm7-5':np.array([0, 3, 6, 10]),
'm6':np.array([0, 3, 7, 9]),
'9':np.array([0, 4, 7, 10, 13]),
}
def split_chord(chord):
j=chord
c=j
if len(c)>1:
c=c[0:2]
if c[1]=='#' or c[1]=='♭':
c=c[0:2]
j=j[2:]
else:
c=c[0:1]
j=j[1:]
else:
j=''
return c, j
pm = pretty_midi.PrettyMIDI(resolution=960, initial_tempo=120)
instrument = pretty_midi.Instrument(0)
chords = np.array(re.split(" +", imput_chords.rstrip()))
d_time = 1#コードを鳴らす間隔
time = 0
for chord in chords:
croot, ctype = split_chord(chord)
notes = 60 + root[croot]
if ctype in chord_type:
notes += chord_type[ctype]
else:
notes += np.array([0, 12])
for note_number in notes:
note = pretty_midi.Note(velocity=100, pitch=note_number, start=time, end=time+d_time)
instrument.notes.append(note)
time = time + d_time
pm.instruments.append(instrument)
filepass='chords.mid'
pm.write(filepass)
if __name__ == '__main__':
chords = "C G Am7 Em F CM7 F G7 C"
midi_create(chords)
コードタイプは思いついた代表的な物を並べてあるが,一覧にないもの場合はルート音をオクターブで重ねたものが鳴る。