こち亀
今週のジャンプのこち亀でポケット・ミクさんが取り上げられていましたね。結構ガッツリ取り上げられていて驚きました。このサイトも少しはアクセス数増えるかなと思ったのですが、特にそんなことはありませんでした。もうちょっと盛り上がってもよいのに。
公式ムック本
歌うキーボード ポケット・ミク 公式ブック (Gakken Mook)
- 作者: 大人の科学マガジン編集部
- 出版社/メーカー: 学研プラス 児童・幼児事業部 音楽事業室
- 発売日: 2014/06/12
- メディア: 単行本
- この商品を含むブログ (1件) を見る
公式本も出ました。それほど新しい情報無く、本に公式Webサイト参照と書いてあるのにまだサイトが更新されてなかったりとアレっと思う箇所はあるのですが、大物へのインタビュ等あるので、ファンならとりあえず買っておけばよいでしょう。
コマンドスロット
ポケミクの公式本で一つよかったのは、「コマンドスロット」の使い方が分かったこと。コマンドスロットは、ポケミクの起動時、ボタンを押した時等に実行される一連の動作のことです。まあマクロのようなものと思って下さい。この「コマンドスロット」をポケミクに特定のMIDIデータを送ることでこのマクロを書き換えることができるというものです。
これを弄ると、起動時にポケミクが喋る声を変えたり、あるボタンを押したら特定の音を出す等、ポケミクを自由にカスタマイズできるようになります。
コマンドスロットの具体的な使い方
コマンドは以下のようなフォーマットになります。
0xF0, 0x43, 0x79, 0x09, 0x11, 0x0C, 0x(Command Slot Number), 0x(Data), 0xF7
Command Slot Numberはコマンドスロットのナンバーで0〜127まであります。例えば0(0x00)だと起動時のコマンドスロット、17(0x11)だとSHIFTボタンを押した時のコマンドスロットです。
コマンドスロットの対応表は公式サイトでは実はまだ公開されていないのですが、偉大な先駆者が解析済ですので、偉大な先駆者に最大の敬意を払いつつ参考にさせていただきましょう。
その後のDataにはコマンドスロットの中身の一連のコマンドを記載します。ここには8bitx3のMIDIコマンドを7bitx4の形式に変換しないという鉄の掟があります。まあこの世界ではよくあることです。変換考えるの面倒くさいとか、変換の仕方がわからない人もいるかもしれませんが、心配することはありません。偉大な先駆者が変換のスクリプトを作ってくれています。
例えば、トライアングルをの音を鳴らすMIDIコマンド ノートオン10ch/ ノートno.81/ベロシティ101((0x99, 0x51, 0x65)を入力してcommand->data変換ボタンを押すと一瞬で (0x04, 0x65, 0x22, 0x65)に変換してくれます。この人ほんとうに凄い…感謝です。
ポケミクドラム作成
ここまでの知識を応用して、ポケミクをドラムマシンにしてみようと思います。ボタンを押すとドラムの音を出すだけの簡単なものです。
ソースコード
Processingで作ったソースコード。ただコマンドを流し込んでいるだけです。同じコマンドをMIDIシーケンサーとかで送っても同じことができるはずです。
import themidibus.*; import de.humatic.mmj.*; // OSX specific //// Please refer http://www.humatic.de/htools/mmj/doc/ //CoreMidiDevice[] cmd; // OSX specific MidiOutput mo_vocaloid; // OSX specific MidiSystem ms; // OSX specific MidiBus vocaloid; //int channel = 0; //0:eVocaloid //int pitch = 0; //int velocity = 0; // VIBRATO byte[] data_1 = {(byte)0xF0, (byte)0x43, (byte)0x79, (byte)0x09, (byte)0x11, (byte)0x0C, // header(SysEx) (byte)0x10, (byte)0x04, (byte)0x64, (byte)0x48, (byte)0x65, (byte)0xF7 // Bass Drum 1 }; // SHIFT byte[] data_2 = {(byte)0xF0, (byte)0x43, (byte)0x79, (byte)0x09, (byte)0x11, (byte)0x0C, // header(SysEx) (byte)0x11, (byte)0x04, (byte)0x64, (byte)0x54, (byte)0x65, (byte)0xF7 // Closed Hi-Hat }; // A byte[] data_3 = {(byte)0xF0, (byte)0x43, (byte)0x79, (byte)0x09, (byte)0x11, (byte)0x0C, // header(SysEx) (byte)0x0B, (byte)0x04, (byte)0x64, (byte)0x5C, (byte)0x65, (byte)0xF7 // Open Hi-Hat }; // I byte[] data_4 = {(byte)0xF0, (byte)0x43, (byte)0x79, (byte)0x09, (byte)0x11, (byte)0x0C, // header(SysEx) (byte)0x0C, (byte)0x04, (byte)0x64, (byte)0x66, (byte)0x65, (byte)0xF7 // Ride Cymbal }; // U byte[] data_5 = {(byte)0xF0, (byte)0x43, (byte)0x79, (byte)0x09, (byte)0x11, (byte)0x0C, // header(SysEx) (byte)0x0D, (byte)0x04, (byte)0x64, (byte)0x52, (byte)0x65, (byte)0xF7 // Low Floor Tom }; // E byte[] data_6 = {(byte)0xF0, (byte)0x43, (byte)0x79, (byte)0x09, (byte)0x11, (byte)0x0C, // header(SysEx) (byte)0x0E, (byte)0x04, (byte)0x64, (byte)0x5E, (byte)0x65, (byte)0xF7 // Low-Mid Tom }; // O byte[] data_7 = {(byte)0xF0, (byte)0x43, (byte)0x79, (byte)0x09, (byte)0x11, (byte)0x0C, // header(SysEx) (byte)0x0F, (byte)0x04, (byte)0x64, (byte)0x64, (byte)0x65, (byte)0xF7 // High Tom }; void setup() { size(400, 200); background(255); MidiBus.list(); // vocaloid = new MidiBus(this, "NSX-39 " , "NSX-39 "); detectMidiDevices(); } void detectMidiDevices(){ String midiDevices[] = MidiSystem.getOutputs(); String pokemikuName = "NSX-39 - NSX-39 "; int devNumb = 0; int detect = 0; for(int i = 0; i < MidiSystem.getNumberOfOutputs(); i++){ println(i); println(midiDevices[i]); println("--------------------"); if(midiDevices[i].equals(pokemikuName)){ println("NSX-39 OK"); devNumb = i; detect = 1; }else{ println("NSX-39 NG"); } } mo_vocaloid = ms.openMidiOutput(devNumb); // OSX specific } void draw() { // draw info fill(0,0,0); text("Press d -> dram setting", 15, 50); } void keyPressed(){ if(key == 'd'){ mo_vocaloid.sendMidi(data_1); mo_vocaloid.sendMidi(data_2); mo_vocaloid.sendMidi(data_3); mo_vocaloid.sendMidi(data_4); mo_vocaloid.sendMidi(data_5); mo_vocaloid.sendMidi(data_6); mo_vocaloid.sendMidi(data_7); } } void exit() { // vocaloid.sendNoteOff(channel, pitch, velocity); vocaloid.close(); // bye bye! super.exit(); }