電子楽器をつくろう

このページでは電子楽器を制作する際に必要な知識をまとめます.馬場の忘備録も兼ねています.電子楽器はその名前にある通り,電子回路を利用した楽器一般を指します. さらに,電子楽器についても様々な種類がありますが,このページではコンピュータソフトウェア及びハードウェアを利用し,MIDIインタフェースを備えたソフトウェア音源を 発音装置として操作可能な電子楽器を対象とします.実際に具体的にやってみましょう.このページは書きかけです.手が空いているときに順に更新するつもりです.

    目次
  1. とりあえずPCだけで色々やってみる
    • ProcessingとSoundCipher/MidiBus
    • 音源の変更
    • Openframeworksでやってみる
      • ofxMIDI
      • 自前で&手軽にMIDI音源っぽいのをつくる
      • iOSで動かす
      • サンプルアプリケーション
      • DTMソフトウェアとの連携
  2. MIDIメッセージについて
  3. ArduinoでMIDI
  4. 演奏のためのハードウェア
  5. 演奏インタフェース発想法
  6. 作品紹介
    • 作品例:Freqtric Drums
    • 作品例:PocoPoco
    • 作品例:Gocen

1.ProcessingとSoundCipher/MidiBus

Processing からMidiデバイスにアクセスする簡単な方法として,SoundCipherやMidiBusといったライブラリを利用するのが よいでしょう.特にMidiBusはProcessing2.0から標準ライブラリとして登録されているので,ライブラリのインストールが 簡単です.また,最小の機能だけを提供しているので潔癖症の人にもよいかもしれません. SoundCipher(processing用ライブラリ)を以下からダウンロードします.MidiBusのインストールは下記手順どおりです.

  • Processing
  • SoundCipher:インストール方法はウェブサイトに従ってください
  • MidiBus:Processingメニュー → Sketch → Import Library.. → Add Library を選択し,検索欄に midi と入れればMidiBusが候補にあがるので,インストールしてください.

メニューのExampleからsoundchpher/The MidiBus があるのを確認してください.試しにMidiBusを動かして,MIDI音源から様々な楽器を鳴らしてみましょう.

MidiBusサンプル
import themidibus.*; //Import the library

MidiBus myBus; // The MidiBus
int instrument = 0;
void setup() {
  size(400,400);
  background(0);
  MidiBus.list();
  //myBus = new MidiBus(this, -1, "Microsoft GS Wavetable SW Synth");
  myBus = new MidiBus(this, -1, "Java Sound Synthesizer");
}

void draw() {
  background(0);
  int channel = 0;
  int pitch = 64;
  int velocity = 127;

  myBus.sendNoteOn(channel, pitch, velocity); // Send a Midi noteOn
  delay(100);
  myBus.sendNoteOff(channel, pitch, velocity); // Send a Midi nodeOff
  delay(100);
  instrument++;
  changeInstrument(instrument);
  text("Instrument: "+instrument, 200,200);
}

void changeInstrument(int value)
{
  byte data[] = new byte[2];
  data[0] = (byte)0xC0;
  data[1] = (byte)value;
  myBus.sendMessage(data);
}

実際に鳴らせる音の種類はGMというMIDI規格に沿った楽器が準備されています.具体的には こちらを参照のこと.

2.音源を変える

ここまでで簡単に様々な楽器音をMIDIを利用して再生することができました.上記で利用した音源はOSにデフォルトでインストールされているソフトウェア音源(MIDI音源)になります. 非常に手軽に様々な楽器音を利用できるのは便利ですが,音質がいまいちではあります.そこで音源を変更して,高品質な楽器音を利用してみます.

音源部分にNative Instruments社製のKontakt Playerを利用します.Kontakt Player及びシンプルな音源パックはNative Instruments社のホームページから,ユーザー登録をすることで無料でダウンロード,インストールが可能です. ここからKontakt PlayerとKontact Factory Selectionをダウンロード,インストールして下さい.インストール後,登録したemail宛に送られてくるシリアル番号を入力することで時間制限無しで利用可能になります. Windowsユーザはこの他にVirtual MIDI PortをWindows上に設定する必要があります.様々な種類がありますが,フリーソフトウェアのMIDI Yokeを利用して解決できます.MIDI-OXのページの左メニューから MIDI Yokeをクリックし,Windows XP用のソフトウェアをダンロードし,インストールして下さい.

ここまでできたらProcessingからKontaktプレーヤー上の音源を鳴らしてみましょう.Kontakt Playerを立ち上げ,OptionメニューからMIDIのインプットを Kontakt Virtual Input: PortAに変更します.次に適当な楽器を選択し,チャンネル設定を済ませたら 下記コードをProcessingにコピーし,実行してみましょう.

import arb.soundcipher.*;
SoundCipher sc = new SoundCipher(this);

void setup(){
  SoundCipher.getMidiDeviceInfo(); // 使用可能なMIDIデバイスを表示
  sc.setMidiDeviceOutput(0);       // 一番始めにあるデバイスを使う
}
void draw() {
  background(180); // 背景色設定  0: 黒 - 255: 白
  ellipse(mouseX, mouseY, 10, 10); // マウスカーソル的な表示
}
void mousePressed() {
  sc.sendMidi(sc.PROGRAM_CHANGE, 0, random(100), 0); // 音を鳴らす度に楽器を0-100でランダム変更
  sc.sendMidi(sc.NOTE_ON, 0, 60, 100);  // channel:0, note:60, velocity:100
}
void mouseDragged() {
  sc.sendMidi(sc.PITCH_BEND, 0, 0, mouseY); // マウスのY位置でベンド
}
void mouseReleased() {
  sc.sendMidi(sc.NOTE_OFF, 0, 60, 0); // マウスを話すと音を消す
}
import arb.soundcipher.*;
SoundCipher sc = new SoundCipher(this);
import processing.serial.*;
Serial myPort;  // Create object from Serial class

int val;

void setup(){
  SoundCipher.getMidiDeviceInfo();
  sc.setMidiDeviceOutput(0);
   String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
}
void draw() {
  if ( myPort.available() > 0) {  // If data is available,
    val = myPort.read();         // read it and store it in val
    println(val);
  }
  background(180);
  ellipse(mouseX, mouseY, 10, 10); 
  sc.sendMidi(sc.PITCH_BEND, 0, 0, val);
}
void mousePressed() {
  sc.sendMidi(sc.NOTE_ON, 0, 60, 100);
}
void mouseDragged() {
  
}
void mouseReleased() {
  sc.sendMidi(sc.NOTE_OFF, 0, 60, 0);
}