29
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Midoを使ってPythonでMIDIを扱ってみよう

Last updated at Posted at 2018-12-19

#まえがき
プログラミング言語Pythonで音楽を扱うためのツールはいくつかありますが、
その中でも、midoはMIDIを扱うにあたって平易でかつSysEX等を含む多くのメッセージを扱うことができます。今回はそんなmidoで音楽を扱うための基本に触れていきたいと思います。

#導入編
Python(2.7以降 or 3.2以降)がインストールされている環境で、
midoを追加しましょう。
また、MIDIポートを使ってメッセージの送受信の為python-rtmidiも追加しましょう。

pip install mido python-rtmidi

#実践編

メッセージの種類やAPI一覧

こちらで参照できます。

##ノートオンを作ってみよう
まずは音を出すためのMIDIメッセージであるノートオンを作ってみましょう。

import mido 
from mido import Message
msg = Message('note_on', note=60)
print(msg)

下記のメッセージが出力されます。

note_on channel=0 note=60 velocity=64 time=0

##ノートオンを出して聴いてみましょう

ノートオンを出すためにはまず、MIDIポートとの接続が必要です。
MIDI出力ポートの一覧は下記で取得できます。

ports = mido.get_output_names()

midoではMessage()でMIDIメッセージを作成します。
open_output()でポートを指定し、send()でメッセージを送信します。
下記ではports[0]をMIDI出力ターゲットとして指定しております。

msg = Message('note_on', note=64, velocity=127, time=480)
with mido.open_output(ports[0]) as outport:
    outport.send(msg)

DAW環境やMIDI対応楽器等が無い方は下記でMIDIの出力が確認できます。

  • Windows
    Microsoft GS Wavetable Synthで確認できます。
    ほかにも、loopMIDI+SendSXでモニタリングすることなども可能です。

  • Mac
    Audio MIDI設定でIAC Driverを有効化して指定すると、GaragebandでMIDI入力を確認できます。

##MIDIファイルを扱ってみよう

MIDIファイルを作ってみましょう

下記でBPM=120でC4の4分音符を鳴らしております。
timeはtickで管理しております。
tickは1拍あたりの分解能でデフォルトが480となっており、前回からの相対値です。
テンポは、MetaMessageで指定します。bpm2tempoでBPMをテンポ時間(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)))
track.append(Message('note_on', note=64, velocity=127, time=0))
track.append(Message('note_off', note=64, time=480))

mid.save('new_song.mid')

作ったMIDIファイルを再生してみましょう

msg.time分のsleepを挟んでMIDI出力をシーケンシャルに行います。

import mido
import time

ports = mido.get_output_names()
with mido.open_output(ports[0]) as outport:
    for msg in mido.MidiFile('new_song.mid'):
        time.sleep(msg.time)
        if not msg.is_meta:
            print(outport, msg)
            outport.send(msg) 
29
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?