和音の構成音数によってモジュレーションのかかり具合を自動制御する – PythonによるMIDI信号処理Programming
電子ピアノとPCをUSB接続し、MIDI信号処理を行いました。単音ではモジュレーションのかからない普通の音色ですが、同時に発音する音が2音3音と増えていくに従ってモジュレーションが深くかかるようになります。同時発音数が6音くらいになると非常に深くかかります。わずか30行程度のPythonプログラムですが、このような楽器があっても面白いのではないでしょうか。※起動のタイミングの問題で表示がバグってしまいましたが、機能的には正常です。本実験のソースコードは固定コメントをご参照ください。MIDI制御には弊社開発のMIDI信号処理ライブラリpymidiateを使用しています。
https://github.com/PGkids/pymidiate
## 本実験のソースコードです ##
import midiate
import devel
mid = midiate.Midiator();
mid.start_process()
indev,outdev = devel.open_both_io(mid);
mid.send(outdev, 'C010')
mid.send(outdev, 'B07A00')
mid.send(outdev, 'B07800')
note_count = 0
def thru(dev, msg, raw):
global note_count
st = raw[0]
if st&0xF0 in {0x90,0x80}:
if st&0xF0==0x90 and raw[2]>0:
note_count += 1
else: note_count -= 1
if note_count <= 1: mod_level = 0
elif note_count <= 4: mod_level = (note_count-1) * 32
else: mod_level = 127
ch = raw[0]&0xF
mid.send(outdev, msg)
mid.send(outdev, b'B%X%02X%02X'%(ch,1,mod_level))
devel.status(f'同時発音数 {note_count}音、\n変調レベル = {mod_level}')
else: mid.send(outdev, msg)
print('受信: ', dev, msg)
mid.callback(None,'******', thru)
mid.listen(indev)
devel.wait(title='automatic modulator',
text='自動でモジュレーションを掛けるよ!\n'
'単音では掛からないよ。\n和音の構成音数が増えるに連れて深く掛かるよ!')
mid.stop_process()
################
### devel.py ###
################
import tkinter
from tkinter import font
def choose_input(midiate):
inputs = midiate.enum_input()
def f(x):
if x in inputs: return x
return (f('UM-1') or f('MPKmini2') or f('CASIO USB-MIDI') or f('USB Oxygen 8 v2') or f('A-500S') or f('loopMIDI port') or
inputs[0])
def choose_output(midiate):
outputs = midiate.enum_output()
def f(x):
if x in outputs: return x
return (f('CASIO USB-MIDI') or f('Microsoft GS Wavetable Synth') or
outputs[0])
def open_input(midiate):
return midiate.open_input(name=choose_input(midiate));
def open_output(midiate):
return midiate.open_output(name=choose_output(midiate));
def open_both_io(midiate):
return open_input(midiate),open_output(midiate)
class Application(tkinter.Frame):
def __init__(self, master=None):
super().__init__(master)
self.pack()
self.create_widgets()
def create_widgets(self):
font0 = font.Font(family='Consolas', size=14, weight='bold')
self.label = tkinter.Label(self, text='' , fg='darkSlateGray', font=font0)
self.label.pack()
self.quit = tkinter.Button(self, text="終了しま~す!",
bg='white',
command=self.master.destroy)
self.quit.pack()
font1 = font.Font(family='Helvetica', size=18, weight='bold')
self.statusLabel = tkinter.Label(self, text="", font=font1)
self.statusLabel.pack()
def say_hi(self):
print("hi there, everyone!")
statusLabel = None
def status(text):
statusLabel.config(text=text)
def wait(title="MIDI信号処理デモ",text=""):
root = tkinter.Tk()
root.geometry("600x200")
root.title(title)
app = Application(master=root)
app.label.config(text=text)
global statusLabel
statusLabel = app.statusLabel
app.mainloop()