1
1

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 3 years have passed since last update.

MIDIスイッチャを作る:mididingsを使ってシンセを仮想化する

Last updated at Posted at 2019-09-25

はじめに

キーボーディストのみなさん、ライブのセッティングどうしてますか?

最近はソフトシンセ一本でライブに臨んだりすることも多いと思うのですが、
ハードシンセも残したいとか、この曲はこの音源使いたいとか、こだわり始めると沼ですね。

たとえば:

  • 昔はワークステーション型シンセでキースプリットしてたけど、そこにソフトシンセ混ぜたいんだよなー
  • ハードシンセとソフトシンセ組み合わせてスプリットしたりレイヤーしたりしたい
  • メインの鍵盤とサブの鍵盤の音色の設定をスイッチ一つでセッティングをまとめてささっと切り替えたい

なーんてことは多々あるんじゃないでしょうか。

今回はmididingsというソフトを使って、複数のシンセを束ねて仮想化してみます。

synth-virtualization.png

たとえば、ハードシンセA+ソフトシンセをレイヤーして、
そのレイヤーしたものをハードシンセBとスプリットして使う、
なんてことが、mididingsのスクリプトを使うと簡単にできます。

mididingsとは

mididingsはpythonで書かれた高機能なmidiパッチベイみたいなものです。
パッチベイ機能だけじゃなくて、フィルタリングやMIDIイベントのコンバートの機能などもあります。

http://das.nasophon.de/mididings/
http://das.nasophon.de/mididings/doc/index.html

たとえば、こんな風にレイヤーしたい時は

layer-example.png

こんな風に書けます

example-mididings-01.py

# !/usr/local/bin/mididings -f 
# -*- coding: utf-8 -*-
from mididings import *

#################################################################
# ALSAデバイスの列挙
# aplaymidi -l で表示されるALSAデバイスに対してエイリアス名をつけられる 
# この例では:
#   マスターキーボードを UM-4のポート1に
#   音源をUM-4のポート2に
#################################################################

config(
    backend = 'alsa',
    in_ports = [('MST',   '.*UM-4 MIDI 1')],
    out_ports = [('SC88', '.*UM-4 MIDI 2')],

    data_offset = 0
)

#################################################################
# OSCインターフェースの設定、
# これをやっとくと、外部プログラムからシーン切り替えができるようになる
#################################################################

hook(
    OSCInterface(56418,56419)
)

#################################################################
# フィルタの定義&実行
#   MIDI入力を拾ってくるPortFilter('MST')を書く必要があるが、
#   MIDI入力デバイスが1つの場合は明記する必要なし
#################################################################

run(
    scenes = {
      0: Scene('layer-example',[
               KeyFilter('c0:e4') >> Output('SC88',0,program=(48)),
               KeyFilter('c0:e4') >> Transpose(12) >> Output('SC88',1,program=(48)),
               KeyFilter('f4:b7') >> Transpose(24) >> Output('SC88',2,program=(89)),
               
         ]),
    }
)



フィルタの実行は、以下のコマンドで行います


$ mididings -f example-mididings-01.py

MIDIイベントのルーティング/フィルタリングはlinux内でやってるのでソフト処理ですが、
ソフトシンセ上で試した限りだと16チャネルレイヤーしても遅れや途切れはなかったです。
(古いハードシンセだと、ハードシンセ側の処理が追いつかないかもしれないです)

mididingsではこのMIDIイベントのルーティング/フィルタリング処理の塊を
「シーン」という単位で管理していて、
プログラムチェンジを受け取るとシーンを切り替えてセッティングを変更する、
などといったことができます。
(この例ではシーン0にlayer-exampleという名前のシーンをひとつだけ定義してますが、
 これらを複数定義できます)

シーンの切り替え

シーンの切り替えはMIDIキーボードから送られるプログラムチェンジの受信で行えますが、
今回はタブレットPCの画面から行いたかったので、Pythonで簡単なアプリを作りました。

ボタンを押すとOSCインターフェース(pyliblo)経由で
シーンの切り替えを指示する仕組みです。

vmidictl.py

# !/usr/bin/env python

import liblo,sys
import gi
gi.require_version('Gtk','3.0')
from gi.repository import Gtk, Gdk

#####################################
class PrgChgBtnSet(Gtk.Fixed):
    """Program change button set """

    n_cols = 8

    def __init__(self, num_buttons=16,width=800,height=480):
        Gtk.Fixed.__init__(self)
        self.n_btns = num_buttons
        self.btns = {}
        self.oscif = liblo.Address("127.0.0.1",56418)

        # mk grid/frame
        self.grd = Gtk.Grid()
        self.add(self.grd)

        # mk prog.chg buttons
        for i in range(0,self.n_btns):
            self.btns[i] = Gtk.Button("Scene:"+str(i))
            self.btns[i].connect("clicked",self._clicked,i)
            self.grd.attach(self.btns[i],i % self.n_cols,int(i/self.n_cols),1,1)
            self.btns[i].set_size_request(int(width/self.n_cols),
                                             int(height/(self.n_btns/self.n_cols))) 
        # mk quit button
        self.q_btn=Gtk.Button("quit")
        self.q_btn.connect("clicked",Gtk.main_quit)
        self.grd.attach(self.q_btn,0,int(self.n_btns/self.n_cols)+1,self.n_cols,1)

    def _clicked(self, btn, ag):
        liblo.send(self.oscif, '/mididings/switch_scene', int(ag))

#####################################
top = Gtk.Window()
pcb = PrgChgBtnSet()

top.add(pcb)
top.connect("destroy",Gtk.main_quit)
top.show_all()

Gtk.main()


で、出来上がった画面はこんな感じ。ボタンを押すとmididingsのシーンが切り替わります
vmidictl-capture.png

おわりに

mididings使い始めるまではmidishという別のパッチベイと
rubyを組み合わせてシンセ仮想化してたのですが、
今回作りなおしてみたら「mididings, なんでもできるやんけ!!」と関心しました。
フォーラム見てると rasberry pi に組み込んでる方なんかもいらっしゃるご様子
僕も秋葉原で仕入れた激安のWindowsタブレットに
UbuntuStudioをインストールしてmididings専用機にしてます。

できればGUIで仮想化したシンセをエディットできると完璧なのですが、
残念ながらmididingsはシーンの変更はできますが、
各シーンのMIDIフィルタの組み合わせをリアルタイムに変更することができない
(毎回再起動が必要)っぽいです。

中身はpythonなので工夫(エディットモードはMIDIイベントフックして個別にフィルタリング処理書いて、実行モード時はmididingsの組み込み関数を使うとか)すればなんとかなりそうですけど、そこはまぁまた別の機会に

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?