ポケミクさんで「運命」 じゃんじゃんじゃんじゃーん

大人の科学 歌うキーボード ポケットミクさんで普通に演奏すると、ノートオン(カーボンキーボードに端子で触れた瞬間)のみ声が出ます。
で、 『ドラグネット』だとか、ベートーベン『運命』の冒頭『じゃんじゃんじゃん じゃーん』ってところなどは、ノートオフ時(音が止まった瞬間)に『』って言って欲しい。

というわけで、ポケットミクのノートオフを検知して語尾に『ん』を付けて『じゃじゃー』 ではなく、『じゃんじゃーん』と言わせるサンプルプログラムを組んでみました (PyGame

ついでにビブラートスイッチを押してると、ノートオン時にオーケストラヒットが鳴ります

  • 終了はCtrl-Cにて強制終了でお願いしますゴメンナサイ
  • 「じゃ」〜「ん」 しか言いません
  • プログラムが重いので、速奏きすると音が変になります
  • うちでは動作してますが、生産ロットによっては、ポケミクさんの挙動が変になるかもです。自己責任でお願いします
  • 余分なコードを削って高速化すれば『鋼鉄ジーグ』だとか、AKB48「鈴懸なんちゃら」の「ちゃんちゃかちゃ〜(ry」も可能かも
  • 語尾に『ん』が付いてるかどうかは、気分の問題、かも。正直、そんなに違わんかも
  • 今思ったけど、オーケストラヒットを無しにして、代わりにシフトキーなどを押して、必要なときだけ「ん」を付けるようにしても良いかもです。

以下プログラム


Windows Vista のPython2.6 で動作確認。 要PyGameです


#!/usr/bin/env python
# -*- coding: utf8 -*-
import sys,time,os
import pygame
import pygame.midi
from pygame.locals import *
#import pokemiku

DEBUG=False
def debugprint(*args):
if DEBUG :
for a in args:
print a,
print

ja=36 #ja=pokemiku.kanadict[u"じゃ"]
nn=123 #nn=pokemiku.kanadict[u"ん"]



class MyMIDI(object):
def __init__(self):
pygame.init()
pygame.midi.init()


def get_device_info(self):
self.devlist=[]
for i in range( pygame.midi.get_count() ):
r = pygame.midi.get_device_info(i)
(interf, name, input, output, opened) = r

in_out = ""
if input:
in_out = "(input)"
if output:
in_out = "(output)"

print ("%2i: interface :%s:, name :%s:, opened :%s: %s" %
(i, interf, name, opened, in_out))
self.devlist.append((interf, name, opened, in_out))
if output and "NSX-39" in name:
self.default_output_id=i
print "self.default_output_id",i,name
elif input and "NSX-39" in name:
self.default_input_id=i

def quit(self):
pygame.midi.quit()

def input_main(self):
input_id =self.default_input_id
output_id=self.default_output_id
midiout = pygame.midi.Output( output_id)
midiin = pygame.midi.Input( input_id )
going = True
midiout.write_sys_ex(0,
[0xF0,0x43,0x79,0x09,0x11,0x0a,0x00,ja,nn,0xF7])
midiout.set_instrument(0x37,1) # ch 1 オーケストラヒット
#ピッチベンド幅
midiout.write_short(0xb1,0x64,0)
midiout.write_short(0xb1,0x65,0)
midiout.write_short(0xb1,0x06,16)
midiout.write_short(0xb1,0x26,0)
hitsnd=False
try:
while going:
if 1 and midiin.poll():
midi_events = midiin.read(10)
for m_e in midi_events:
[[status,data1,data2,data3],timestamp]=m_e
if status ==0x90: # note on ch 0
note=data1
velocity=data2
if hitsnd:
#ビブラートスイッチが入ってたら
#オーケストラヒット
midiout.write_short(0xe1,lsb,msb) #ピッチベンド
midiout.note_on(note,72,1)
debugprint( "n",note,"v",velocity)
elif status == 0xe0 : # pitch bend
lsb=data1
msb=data2
midiout.write_short(0xe1,lsb,msb)
pitch=(lsb|(msb<<7))
pitch if pitch<0x2000 else -(~(pitch&0x003fff)+1)
debugprint( "p",pitch)
elif status ==17: #ビブラートスイッチ判定
if data3==32 : #シフトスイッチなら64
hitsnd=True
else:
hitsnd=False
elif status==0x80: # note off ch 0
ts=pygame.midi.time()
midiout.note_on(note,velocity,0)
pygame.time.delay(64)
if not midiin.poll():
midiout.note_off(note)

else:
debugprint(m_e)

except Exception ,e:
pygame.midi.quit()
del midiin
del midiout

if __name__ == '__main__':
mymidi=MyMIDI()
mymidi.get_device_info()
mymidi.input_main()