Mido
midoはMIDIを扱うことができるpythonライブラリです。このライブラリを使うことでMIDIファイルの読み書きが可能です。今回はpython3で音を指定してMIDIファイルを作成するmidoの使い方についてメモしていきます。
基本形
まずはこのドキュメント通りに出力して、noteの値を変えて音が変わることを確認してみましょう。MIDI Files — Mido 1.2.10 documentation
import mido
from mido import Message, MidiFile, MidiTrack
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
# MIDIの音色を指定
track.append(Message('program_change', program=12, time=0))
# C3(note=60, ド)の音を、指定の音量と時間で再生
track.append(Message('note_on', note=60, velocity=64, time=32))
track.append(Message('note_off', note=60, velocity=127, time=32))
mid.save('new_song.mid')
※Messageに指定する値と範囲はこちらのドキュメントを参照してください。
Message Types — Mido 1.2.10 documentation
テンポを指定するにはset_tempoを使います。4分音符の長さを480tickとして、tick数により長さを指定します。
テンポを指定しつつ、いくつかの音を出してみましょう。
import mido
from mido import Message, MidiFile, MidiTrack, MetaMessage
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
track.append(MetaMessage('set_tempo', tempo=mido.bpm2tempo(120)))
track.append(Message('note_on', note=60, velocity=64, time=0))
track.append(Message('note_off', note=60, time=480))
track.append(Message('note_on', note=60+4, velocity=64, time=0))
track.append(Message('note_off', note=60+4, time=480))
track.append(Message('note_on', note=60+7, velocity=64, time=0))
track.append(Message('note_off', note=60+7, time=480))
mid.save('new_song.mid')
このような内容のmidiが出力されます。
和音の出し方
音を重ねるにはこのように指定します。
import mido
from mido import Message, MidiFile, MidiTrack, MetaMessage
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
track.append(MetaMessage('set_tempo', tempo=mido.bpm2tempo(120)))
track.append(Message('note_on', note=64, velocity=60, time=0))
track.append(Message('note_on', note=64+4, velocity=60, time=0))
track.append(Message('note_on', note=64+7, velocity=60, time=0))
track.append(Message('note_off', note=64, time=480))
track.append(Message('note_off', note=64+4, time=0))
track.append(Message('note_off', note=64+7, time=0))
mid.save('new_song.mid')
複数のトラックの作成
トラックを複数用意し、それぞれに音を入れていきましょう。
import mido
from mido import Message, MidiFile, MidiTrack, MetaMessage
mid = MidiFile()
track1 = MidiTrack()
track2 = MidiTrack()
mid.tracks.append(track1)
mid.tracks.append(track2)
track1.append(MetaMessage('set_tempo', tempo=mido.bpm2tempo(120)))
track2.append(MetaMessage('set_tempo', tempo=mido.bpm2tempo(120)))
track1.append(Message('note_on', note=64, velocity=60, time=0))
track1.append(Message('note_on', note=64+7, velocity=60, time=0))
track1.append(Message('note_off', note=64, time=480))
track1.append(Message('note_off', note=64+7, time=0))
track2.append(Message('note_on', note=64+4, velocity=60, time=40))
track2.append(Message('note_off', note=64+4, time=480))
mid.save('new_song.mid')
複雑な音階
midoはプログラムの中で扱えるので、このように適当に変数を使いつつ組み立てていくことになるでしょう。今回はバッハ 平均律クラヴィーア曲集 第1巻 みたいな音を作ります。ただしコードを見て分かるように、読みやすいものを作るのは難易度が高そうです。
import mido
from mido import Message, MidiFile, MidiTrack, MetaMessage
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
track.append(MetaMessage('set_tempo', tempo=mido.bpm2tempo(120)))
node_time = 480 * 2
node_pos = 60
node_16 = int(node_time/8)
track.append(Message('note_on', note=node_pos, velocity=60, time=0))
track.append(Message('note_on', note=node_pos+4, velocity=60, time=node_16 ))
track.append(Message('note_on', note=node_pos+7, velocity=60, time=node_16 ))
track.append(Message('note_off', note=node_pos+7, velocity=60, time=node_16 ))
track.append(Message('note_on', note=node_pos+12, velocity=60, time=0 ))
track.append(Message('note_off', note=node_pos+12, velocity=60, time=node_16 ))
track.append(Message('note_on', note=node_pos+16, velocity=60, time=0 ))
track.append(Message('note_off', note=node_pos+16, velocity=60, time=node_16 ))
track.append(Message('note_on', note=node_pos+7, velocity=60, time=0 ))
track.append(Message('note_off', note=node_pos+7, velocity=60, time=node_16 ))
track.append(Message('note_on', note=node_pos+12, velocity=60, time=0 ))
track.append(Message('note_off', note=node_pos+12, velocity=60, time=node_16 ))
track.append(Message('note_on', note=node_pos+16, velocity=60, time=0 ))
track.append(Message('note_off', note=node_pos+16, velocity=60, time=node_16 ))
track.append(Message('note_off', note=node_pos+4, velocity=60, time=0 ))
track.append(Message('note_off', note=node_pos, velocity=60, time=0))
mid.save('new_song.mid')
このような内容が出力されます。
これを使った作例がこちらです。
バッハの平均律クラヴィーアみたいのをランダム生成する - えんたつの記録
このようにMidoはプログラムでMidi生成することにも活用できます。
@tattyamm





このブログにコメントするにはログインが必要です。
さんログアウト
この記事には許可ユーザしかコメントができません。