前回プログラムチェンジメッセージによって音色を変える方法を見ました。次にサウンドバンクを変更することによって音色をかえる方法を見ていきます。
サウンドバンク sound bankとは
プログラムチェンジで変える事のできる音色はデータバイトに保持できる値の範囲(0x00-0x7F)を考えると128通りになります。
シンセサイザーによりますが仮に128音色以上の音を保持できたとしてもプログラムチェンジだけでは全てを呼び出すことはできません。サウンドバンクという仕組みを利用するとこれ以上の音色をコントロールすることができます。ただしこれはシンセサイザーのほうでその仕組みを採用しているかどうかによりますので利用するシンセサイザーの説明書などを参考にしてください。
サウンドバンクはプログラムチェンジのバリエーションを指定するものです。例えばプログラムチェンジでAcoustic Grand Pianoという音色を指定するときにサウンドバンクの指定も同時に行うとAcoustic Grand Pianoのバリエーションの音色を使うことができます。
サウンドバンクを利用するにはプログラムチェンジの他に二つのショートメッセージを利用します。両方ともコントロールチェンジと呼ばれるものでステータスバイトは16進数2桁のうち2桁目がB固定、1桁目がチャンネル0-Fになります。チャンネルをnとすると0xBnの形式になります。
一つ目のコントロールチェンジはbank select MSB、二つ目はbank select LSBと呼ばれています。MSBはMost Significant Bit、LSBはLeast Significant Bitの略でMSBが上位の桁、LSBが下位の桁を表します。それぞれが0x00-0x7Fまでの128通りの値をとるのでプログラムチェンジの128通りと掛け合わせて128 * 128 * 128 = 2,097,152通りの音色を理論上は利用できることになります。
コントロールチェンジは二つあるデータバイトのうち最初のデータバイトをコントロール番号に、二つ目のデータバイトを実際の値に使います。MSBのコントロール番号は0x00、LSBは0x20になります。
また送信する順序はMSB、LSB、プログラムチェンジの順になります。
実装する
ではサウンドバンクとプログラムチェンジのためのショートメッセージを配列で返すメソッドを作ります。引数にはチャンネルとMSB、LSB、プログラム番号を受け取るようにします。
public static ShortMessage[] getProgramMessages(int channel, int bank_msb, int bank_lsb, int program) {
長さが3の配列を作りMSB、LSB、プログラムチェンジの順にインスタンスを作ります。
ShortMessage[] messages = new ShortMessage[3]; messages[0] = new ShortMessage(ShortMessage.CONTROL_CHANGE, channel, 0x00, bank_m); messages[1] = new ShortMessage(ShortMessage.CONTROL_CHANGE, channel, 0x20, bank_l); messages[2] = new ShortMessage(ShortMessage.PROGRAM_CHANGE, channel, program, 0);
最後にこの配列を戻します。
return messages;
実際にはショートメッセージ作成時に例外が発生されうるためtry-catchで受け取った例外は実行時例外にして投げるようにしています。
public static ShortMessage[] getProgramMessages(int channel, int bank_m, int bank_l, int program) { ShortMessage[] messages = new ShortMessage[3]; try { messages[0] = new ShortMessage(ShortMessage.CONTROL_CHANGE, channel, 0x00, bank_m); messages[1] = new ShortMessage(ShortMessage.CONTROL_CHANGE, channel, 0x20, bank_l); messages[2] = new ShortMessage(ShortMessage.PROGRAM_CHANGE, channel, program, 0); } catch (InvalidMidiDataException ex) { throw new IllegalStateException(ex); } return messages; }
このメソッドを利用する側のサンプルです。チャンネル0に対してMSBが1、LSBが2、プログラム番号が3の音色の呼び出しをトラックに設定しているところです。
track = sequence.createTrack(); for(ShortMessage message:getProgramMessages(0, 1, 2, 3)){ track.add(new MidiEvent(message, 0)); }
このコードはあくまでサンプルです。それぞれの数値は操作マニュアルにある音色一覧などを参考にして決めてください。