[Diary/2012/May]

Java内蔵シンセサイザMIDI音色変更 / 2012-05-15 (火)

今日

修士で作ったJavaで書いた作曲支援システムのMIDIの音色変更の部分.

基本は,SequenceクラスのインスタンスをSequencerクラスのインスタンスに食わせてJava内蔵シンセサイザの音をならす.

import javax.sound.midi.spi.*;
import javax.sound.midi.*;
public class HelloFile {
  public static void main(String[] args){
    try {

      //Sequenceの作成とトラックの生成
      Sequence sequence = new Sequence(Sequence.PPQ, 24);
      Track track = sequence.createTrack();

      //試しにならす音のChannel, NoteNumber, Velocity
      int channel = 0;
      int pitch = 48;
      int velocity = 127;

      //Instrument: GMの番号でよし
      int instrument = 6;

      //Set Tempo
      MetaMessage mmessage = new MetaMessage();
      int tempo = 20;
      int l = 60*1000000/tempo;
      mmessage.setMessage(0x51, 
                          new byte[]{(byte)(l/65536), (byte)(l%65536/256), (byte)(l%256)}, 
                          3);
      track.add(new MidiEvent(mmessage, 0));

      //set instrument
      ShortMessage message = new ShortMessage();
      message.setMessage(ShortMessage.PROGRAM_CHANGE, channel, instrument, 0);
      track.add(new MidiEvent(message, 0));

      // Note on
      message = new ShortMessage();
      message.setMessage(ShortMessage.NOTE_ON, channel, pitch, velocity);
      track.add(new MidiEvent(message, 0));
      // Note off after quater (24tick)
      message = new ShortMessage();
      message.setMessage(ShortMessage.NOTE_OFF, channel, pitch, velocity);
      track.add(new MidiEvent(message, 24));

      // 再生してみる.
      //Sequencerのインスタンスを作成して,Sequenceを食わせる
      Sequencer sequencer = MidiSystem.getSequencer();
      sequencer.open();
      sequencer.setSequence(sequence);

      //Synthesizerを作成して,TransmitterとReceiverを接続する.
      Synthesizer synthesizer = MidiSystem.getSynthesizer();
      synthesizer.open();
      Receiver synthReceiver = synthesizer.getReceiver();
      Transmitter seqTransmitter = sequencer.getTransmitter();
      seqTransmitter.setReceiver(synthReceiver);

      sequencer.start();

      //write to file
      MidiSystem.write(sequence, 0,new java.io.File("hello.mid"));
     } catch(Exception e){
      e.printStackTrace();
    }
  }
}

この小さいプログラムではきちんと音色変更できるのだが,なぜか直しているプログラムでは音色変更されない.
コードをもうちょっときちんとトレースして,使いやすくするために書いたラッパクラスやメソッドなどを消していく必要有りか.