java midi 〜javax.sound.midiを使う〜

今回はJavaでMIDIを鳴らすためのプログラムを改定みようと思います。まずは、PC上で鳴らすことを考えます。
早い話が、JavaでMidiを扱う時の概要を理解しようというところです。

事の経緯

Microbitからメッセージを送信し、ラズパイで受けて適当なメッセージを作成しMIDI音源に送信、音を鳴らす。というものを作成しようとしています。

でわ。。。学習開始!

java.sound.midi

上のリンク先にはJavaDocがあります。そして、チュートリアルがありました。ここのページを学習します。

ちなみに、大元のページはこちらです。java sound APIのドキュメントになります。

Java Sound プログラマーズガイド

このページを学習します。

Midiを使う

シンプルにMIDIとは音源を鳴らすためのデータです。なのでこれを受け取ったMIDI音源はドラムとかピアノとか音を鳴らすわけです。じゃ、Javaでやろうとしたらどうやるか?
扱うデータは目で見えるようにすると下のようなイメージです。

そして、MIDIの概要を大まかに説明しているのはこちらのページです。ここでMIDIはどんなものか記載されています。
そして、Javaではどのような扱いをするのか記載しています。

プログラミング

JavaでMIDIを扱う時にはMidiSystemクラスを使用するようです。そして以下のものを使用できるようです。

  1. シーケンサ
  2. シンセサイザ
  3. トランスミッタ (MIDI 入力ポートに関連付けられたトランスミッタなど)
  4. レシーバ (MIDI 出力ポートに関連付けられたレシーバなど)
  5. 標準 MIDI ファイルのデータ
  6. サウンドバンクファイルのデータ

プログラムの実行手順

  1. デバイスの取得
  2. デバイスのオープン
  3. トランスミッタとレシーバの接続
  4. (デバイスへの)MIDIメッセージの送信

JavaでMIDIを使う場合は

JavaTM Sound API は、MIDI データ用のメッセージルーティングアーキテクチャーを指定します。

そして、トランスミッタ(MIDI入力)、レシーバ(MIDI出力)を使用します。

トランスミッタが MidiMessages を送信するレシーバの設定および問い合わせを行うためのメソッドが含まれます。

のようなので、この仕組みを使用してMIDI再生を行うプログラムを作ります。

Java Midi の仕組みについて

Java Sound API のメッセージ交換システム内の基本モジュール、以下にまとめます。
MidiDevice 、内容は以下に。。。
< シンセサイザ >
< シーケンサ >
< MIDI入力ポート >
< MIDI出力ポート >

サンプルコード

単一のデバイスの接続

    Sequencer seq;
    Transmitter seqTrans;
    Synthesizer synth;
    Receiver synthRcvr;
    try {
          seq = MidiSystem.getSequencer();
          seqTrans = seq.getTransmitter();
          synth = MidiSystem.getSynthesizer();
          synthRcvr = synth.getReceiver(); 
          seqTrans.setReceiver(synthRcvr);  
    } catch (MidiUnavailableException e) {
          // handle or throw exception
    }

複数のデバイスへの接続

    Synthesizer synth;
    Sequencer seq;
    MidiDevice inputPort;
    // [obtain and open the three devices...]
    Transmitter inPortTrans1, inPortTrans2;
    Receiver synthRcvr;
    Receiver seqRcvr;
    try {
          inPortTrans1 = inputPort.getTransmitter();
          synthRcvr = synth.getReceiver(); 
          inPortTrans1.setReceiver(synthRcvr);
          inPortTrans2 = inputPort.getTransmitter();
          seqRcvr = seq.getReceiver(); 
          inPortTrans2.setReceiver(seqRcvr);
    } catch (MidiUnavailableException e) {
          // handle or throw exception
    }

ぶっちゃけて複数のMIDI音源を使用するつもりはないので、単一のデバイスだけで良い気がしますが、もしかしたら複数ならしたい。。。となるかもしれないので記載しておきます。
が、まずは単一のデバイスを鳴らすことから始めます。

Javaコードを書く

とりあえずは、上のコードを色々と使用できるように「MidiCreator」という名前でクラスを作成しました。

public class MidiCreator {
    private Sequencer seq;
    private Transmitter seqTrans;
    private Synthesizer synth;
    private Receiver synthRcvr;

    /** コンストラクタ */
    public MidiCreator() {
        try {
              seq = MidiSystem.getSequencer();
              seqTrans = seq.getTransmitter();
              synth = MidiSystem.getSynthesizer();
              synthRcvr = synth.getReceiver(); 
              seqTrans.setReceiver(synthRcvr);  
        } catch (MidiUnavailableException e) {
              // handle or throw exception
        }
    }
}

コンストラクタで、使用するクラス群のセットアップを行なっています。ほとんどサンプルコードのコピーです。

今回は、ここまでにします。

でわでわ。。。

投稿者:

takunoji

音響、イベント会場設営業界からIT業界へ転身。現在はJava屋としてサラリーマンをやっている。自称ガテン系プログラマー(笑) Javaプログラミングを布教したい、ラスパイとJavaの相性が良いことに気が付く。 Spring framework, Struts, Seaser, Hibernate, Playframework, JavaEE6, JavaEE7などの現場経験あり。 SQL, VBA, PL/SQL, コマンドプロント, Shellなどもやります。

コメントを残す