Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

まえがき

プログラミング言語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) 
tjsurume
ポケモン緑を買ったときの初手はゼニガメ、ポケモン金を買ったときの初手はヒノアラシでした
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした