5188円で始めるフィジカルコンピューティング 第5回 〜テルミンつくってみるミン MIDIを使ってみるミディの巻〜

今までの連載:
5188円で始めるフィジカルコンピューティング 第1回 〜テルミンつくってみるミン イントロの巻〜
5188円で始めるフィジカルコンピューティング 第2回 〜テルミンつくってみるミン 動けArduinoさん!の巻〜
5188円で始めるフィジカルコンピューティング 第3回 〜テルミンつくってみるミン センサを使ってみるの巻〜
5188円で始めるフィジカルコンピューティング 第4回 〜テルミンつくってみるミン テルミンできたミンの巻〜
 前回、以下の3つの課題があったので、今回はこれを解決します。

1.音量の調整ができない
2.音色が変えられない
3.色々むき出しでかっこ悪い

 3に関しては特に解説はないです、各自のセンスにおまかせします(実は、ここが一番重要で難しいかも)。ちなみに、僕はこんな感じで作ってます。今回のメインは、1、2です。Arduinoは普通はPWM波というパルス波しか出力できず、音量や音色を変えることができません。じゃあどうするかというと、困ったら先人の知恵を頼ります。今ある電子楽器(シンセサイザ)等って、音の高さとか音量を調整する仕組みはどうなっているかというと、たいていコントロール部と音源部に分かれていて、鍵盤などのコントロール部から、音源部に「ドの音をピアノの音でこれくらいの強さで弾いたよ!」とかいう情報を逐一伝えてやって、音源部は来た情報をもとに、「ウヲォー!」と音を出すと言うしくみなわけです。この情報のやり取りの仕方は規格化されていてMIDIといいます。図にすると以下のような感じ。

090626_AbbacchioMIDI解説
090626_AbbacchioMIDI解説 posted by (C)karaage
 わかりやすいかもしれない図

 今回は、このMIDIコントローラの部分を作ってやって、音源部はすでにあるものを活用します。これで、音色、音量の調整をできるようにしつつ、いい音出してやろうというもくろみ。ただ、ハードのMIDI音源やシンセサイザを買うのは高いので、今回はソフトウェアシンセとUSB-MIDI変換器を使ってパソコンをMIDI音源化してやります。基本的に、MIDI端子を装備したあらゆる機器に繋がるので、既にそういう機器を持っている方はぜひぜひ繋いで見てください。

 
 今回は、完成した動画から紹介。第九っぽいものを演奏しています。アバッキオをコントローラ、隣のPCをMIDI音源として音を出しています。興味を持って仕組みをもっと知りたいぜという電波な人は、下の続きを読むをクリックすれば続きが読めるという親切設計です。

 まず回路は下みたいな感じです。自分は小型化のため今回Arduino Pro miniというのを使ったのですが、Arduinoでも基本は同じです。凄い回路図が見にくいのは、なるべく省略せずに書いたためです。一応線をしっかり繋げて電気が通れば動くはずです。
 回路図で、MIDIコネクタのピン接続間違っていました。下の方にあるMIDIコネクタの写真を参考に電源、GND、信号を繋いで下さい(真ん中がGNDです)。申し訳ありません。

090623_Abbacchio01
090623_Abbacchio01 posted by (C)karaage

 まずは下の方から。赤外線センサは、第2回でやったのでばっちりですね。音程(ピッチ)の調整と音量(ボリューム)の調整用に2個つけています。可変抵抗はチューニングをするためにつけています。可変抵抗については…グーグルさんに聞いてね☆どうしてもわからない人は、別につけなくても大丈夫です。
 次は、右上のMIDIコネクタ。今回の肝ですね。コネクタと220Ωの抵抗は、マルツパーツとかで買えばOKです。下みたいに接続してやって下さい。

090623_Abbacchio02
090623_Abbacchio02 posted by (C)karaage
 こんな感じ。赤が5V、黄色がMIDI信号、緑がGND(0V)です。5VとMIDIコネクタは回路図のように220Ωを介して繋ぐようにして下さい。理由はよくわかりませんが、そんな決まりみたいです。プルアップしてるだけだと思って、手持ちに220Ωが無いとき100kΩでやってみたら駄目でした(恥ずかしい)。

 左のLEDは完全なおまけです。つけるとピカピカ光るよと言うだけ。光りものが好きな人はつけて下さい。つけなくても動きます。
ソフトは下のような感じ。コメントの英語は適当だから間違ってても黙っててください。

/* Abbacchio -Arduino Theremin-
 * http://d.hatena.ne.jp/karaage
 */
// Pin Assign
#define PITCHPIN 0    // select the input pin for the potentiometer
#define VOLPIN 1    // select the input pin for the potentiometer
#define BASEPIN 2    // select the input pin for the determing base note
#define LEDPIN 11 // led output

// Parameter
#define ANALOG_MAX 1024
#define MIDI_SPEED 31250
#define PITCH_RANGE 24
#define MIDI_MAX 128 // midi char 128
#define VAL_OFFSET ANALOG_MAX/5*0.5
#define SENSIVITY_PITCH_MIDI 0.4 
#define SENSIVITY_VOLUME_MIDI 0.5

char base_pitch_midi; // base pitch for midi
char base_pitch_midi_old = base_pitch_midi; // base pitch for midi
char pitch_midi; // pitch for midi
char volume_midi; // volume for midi

void setup() {
  // LED ON
  pinMode(LEDPIN, OUTPUT);
  digitalWrite(LEDPIN, HIGH);

  MidiSetup();
}

// Midi Setup
void MidiSetup() {
  // start serial
  Serial.begin(MIDI_SPEED);

  //ピッチベンドのレンジを2オクターブ(MAX)に設定
  noteOn(0xB0, 0x65, 0);
  noteOn(0xB0, 0x64, 0);
  noteOn(0xB0, 0x06, PITCH_RANGE);
}

void noteOn(char cmd, char data1, char data2) {
  Serial.print(cmd, BYTE);
  Serial.print(data1, BYTE);
  Serial.print(data2, BYTE);
}

// Midi Output
void MidiOut(){
  if(base_pitch_midi != base_pitch_midi_old){
    noteOn(0x90, base_pitch_midi_old, 0);
    base_pitch_midi_old = base_pitch_midi;
  }

  // 基準音出力
  noteOn(0x90, base_pitch_midi, 100);

  // 音量調整
  noteOn(0xB0, 7, volume_midi);

  // ピッチベンド
  noteOn(0xE0, 0, pitch_midi);
}

// Input Sensor data
void InputSensordata(){
  int val; 
  float tmpval;
  val = analogRead(BASEPIN);  // base pitch is inputed by the potentio meter

  // 基準音階を入力。可変抵抗をつけない人は、base_pitch_midi=60;とか適当な値を入れておいてください
  base_pitch_midi = (char)(MIDI_MAX*val/ANALOG_MAX);

  val = analogRead(PITCHPIN);    // read the value from the sensor

  // cancel offset of sensor
  tmpval = val - VAL_OFFSET;
  if(tmpval < 1){
    tmpval = 1;
  }

  float tmp_pitch;
  tmp_pitch = tmpval * SENSIVITY_PITCH_MIDI;

  if(tmp_pitch < 1){
    tmp_pitch = 1;
  }
  if(tmp_pitch > MIDI_MAX-1){
    tmp_pitch = MIDI_MAX-1;
  }
  pitch_midi = (char)tmp_pitch;

  // volume is inputed by IR sensor 
  val = analogRead(VOLPIN);    // read the value from the sensor

  // cancel offset of sensor
  tmpval = val - VAL_OFFSET;
  if(tmpval < 1){
    tmpval = 1;
  }

  // calculate volume
  float tmp_volume;
  tmp_volume = tmpval * SENSIVITY_VOLUME_MIDI;

  if(tmp_volume > MIDI_MAX-1){
    tmp_volume = MIDI_MAX-1;
  }
  volume_midi = (char)tmp_volume;
}

void loop() {
  InputSensordata();
  MidiOut();
  delayMicroseconds(1);
}

 肝になる、MIDIの部分だけちょっと解説します。MIDIという規格は、一定の周期で3バイトの信号を1単位としてやりとりすると決まっている(らしい)です。通信速度は、31.25kbpsと決まっています。かなり古い規格だけあってかなり遅いスピードです。ちなみにUSB2.0の一番早い通信速度は480Mbpsです。およそ1万分の1の転送速度ってことになるのかな?何が凄いってこの規格がまだ最新機種にも現役バリバリで使われていること。この規格を作り出すために、日本の企業ではローランドさんが一役買ったらしいです、ローランドさんに感謝。そのMIDI通信の実体はというと、3バイト分の情報を1つのコマンドとして送ってやるだけという簡単なものです。下が、その情報を送る関数です。

void noteOn(char cmd, char data1, char data2) {
  Serial.print(cmd, BYTE);
  Serial.print(data1, BYTE);
  Serial.print(data2, BYTE);
}

 たとえば、ドという情報を送りたいときは、noteOn(0x90, 60, 100);と書いてやります。ここで0x90は、ピアノで言う俺は鍵盤押すモードだぜ!というコマンドのことです。頭の0xは16進数を表しますが、よくわからない人はあんまり気にしないでいいです。次の60が音の高さ。その次の100はベロシティといって、鍵盤を押す強さを表します。音をとめたいときは、noteOn(0x90, 60, 0);レを出したいときは、noteOn(0x90, 62, 100);といった感じです。MIDIの詳細については、「詳説MIDI規格(リンク修正)」というサイトが詳しいです。
 他にも、ボリュームを変えたり、ピッチを変えたりできます。ちなみに、上のプログラムでは、つまみで設定した高さの基準音を出力し続け、2つの赤外線センサの入力で、ボリュームと、ピッチ(音の高さ)を連続的に変化させて音をコントロールしています。最初に、ピッチベンドのレンジを2オクターブに設定しているのは、デフォルトだと上下1音程度しかかわらないため、赤外線センサでのピッチの調整がほとんどできなくて、演奏にあまり面白みがないためです。MIDI機器によっては、このピッチレンジ変更のコマンドを受け付けてくれないものもあります。そのときはMIDI機器側で設定できる場合が多いので、設定してみてください。できなかったら、潔く諦めましょう。

//ピッチベンドのレンジを2オクターブ(MAX)に設定
noteOn(0xB0, 0x65, 0);
noteOn(0xB0, 0x64, 0);
noteOn(0xB0, 0x06, PITCH_RANGE);

// 基準音出力
noteOn(0x90, base_pitch_midi, 100);

// 音量調整
noteOn(0xB0, 7, volume_midi);

// ピッチベンド
noteOn(0xE0, 0, pitch_midi);

 次は、パソコンのMIDI音源化です。まずパソコンには通常MIDI端子がないのでつけてやります。今はなんでもUSBに変換できちゃいます。僕が買ったのは、下のやつですが、基本的にはどれでもOK。

EDIROL USB MIDIインターフェース UM-1EX

EDIROL USB MIDIインターフェース UM-1EX

 では、パソコンに音源を入れてやりましょう。昔はMIDI音源といえば、ハードウェアの音源でSC-88とかが結構売れていたのですが、今はソフトウェアで実現するのがほとんどみたいです。いろんなソフトがあるのですが、どれもVSTiというプラグイン形式になっていて、ホストとなるアプリケーションから呼び出して使う形式が多いです。基本これらのVSTiプラグインとホストアプリは、有料でピンからキリまであるのですが、ともに「Synth1」と「Savihost」というフリーで使える素晴らしいソフトがあるので今回はそれを使います。セットアップに関しては、「パソコンをシンセサイザーにしてみよう!」という素晴らしい動画の解説があるので、それを参照して下さい。以上で、パソコンのMIDI音源化完了です。UM-1Gをぶっさして、Savihost+Synth1を起動してDevice→MIDIからUM-1Gを選べるようになっているので、それを選択すれば接続したMIDIコントローラでパソコン上のシンセをコントロールできるようになります。音は、「84:SYNTH LEAD」あたりを選んでおくとよいです。ここで、おもむろにアバッキオ君をつっこんでやると最初の動画のようなしょぼいプレイができるというわけです。他にもアバッキオ君はMIDI-IN端子のあるあらゆる機器に繋がる(はず)です。夢が広がりますね☆

 ここまでついてこれたかな?ついてこれた人は偉い☆ではいよいよ次回最終回という名のまとめの予定です。