電子楽器を作ってみたいんだが
もう4年くらい前か、GAINERというのが一部で流行ってたので買ってみたけど、けっきょく使いこなせなかった。やりたかったことは、練習用のサイレントアコーディオン作成*1。バイオリンなどのメジャーな楽器はサイレント楽器が出ていて音をあまり出さずに練習できる。アコーディオンもローランドからVアコーディオンというシリーズが出てるけど、アコーディオンは形が千差万別で、自分のとは合わない*2。
電子楽器の原理としてはそんなに複雑でもないはず。ボタンのON/OFFと、蛇腹内部の気圧の変位がわかれば音は出せるはずなので、デジタルなボタンと圧力センサーでできるんじゃなかろうか。胴体は自分で作れるわけもなく、壊れたものを再利用するか、キットを買ってきて電子用にするか。とりあえずウッドストック キッズアコーディオンとかの安価な子供用のおもちゃでもいい。
まあそんな風にずっと思っていたところにRaspberry Piを買ったから、試してみない理由はない。
圧力センサーは後回しにして、とりあえずキーボードのa、s、dに音を割り当てて、ブレッドボード上のスイッチのON/OFFで音が変わるようにしてみた(自分のアコーディオンは蛇腹の押し引きで音が変わる、ダイアトニックというタイプなので。この点はハーモニカと同じ。)。音はMIDIで出して、音源はTiMidity。いろんなところから借りて来たコードなので作りはひどい。試してみると、遅延もひどくて話にならない。考えてみれば、これまでボタンを押す長さを表すプログラムとかには縁がなかったので、そこから考え直しつつ*3、ボトルネックを解消するしかないかなぁ。それが一段落したところで、あらためて圧力センサーを組み込めるように、アナログ回路のお勉強か。
#!/usr/bin/python import os, sys import tty from select import select import pygame import pygame.midi from time import sleep import RPi.GPIO as GPIO class NotTTYException(Exception): pass class TerminalFile: def __init__(self,infile): if not infile.isatty(): raise NotTTYException() self.file=infile #prepare for getch self.save_attr=tty.tcgetattr(self.file) newattr=self.save_attr[:] newattr[3] &= ~tty.ECHO & ~tty.ICANON tty.tcsetattr(self.file, tty.TCSANOW, newattr) def __del__(self): #restoring stdin import tty #required this import here tty.tcsetattr(self.file, tty.TCSADRAIN, self.save_attr) def getch(self): if select([self.file],[],[],0)[0]: c=self.file.read(1) else: c='' return c if __name__=="__main__": s=TerminalFile(sys.stdin) print "Press q to quit..." pygame.init() pygame.midi.init() GPIO.setmode(GPIO.BCM) GPIO.setup(24,GPIO.IN) instrument = 0 note = 74 volume = 127 port = 2 midiOutput = pygame.midi.Output(port, 1) midiOutput.set_instrument(instrument) key = s.getch() inputValue = GPIO.input(24) while key!="q": if key == "a": if inputValue == True: note = 60 else: note = 61 elif key == "s": if inputValue == True: note = 62 else: note = 63 elif key == "d": if inputValue == True: note = 64 else: note = 65 midiOutput.note_on(note,volume) key = s.getch() inputValue = GPIO.input(24) sleep(1) midiOutput.note_off(note,volume) del midiOutput pygame.midi.quit() print "-- END --"