Завершить вывод Java Midi

#java #midi #terminate

#java #midi #завершить

Вопрос:

Я написал эту короткую программу, чтобы изучить систему javax.sound.midi. Для этого используется Java 6. Вывод соответствует ожиданиям (серия строк System.out.println (), которые запускаются событиями секвенсора), но проблема в том, что после последнего звукового эффекта программа остается в цикле и завершается не так, как ожидалось.

Кто-нибудь может сказать, как это исправить? Спасибо за вашу помощь:

 import javax.sound.midi.MidiEvent;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.ControllerEventListener;
import javax.sound.midi.Sequencer;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Track;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiUnavailableException;

class MySound {

    public static MidiEvent makeEvent(int comd, int chan, int one, 
                                      int two, int tick) {
        MidiEvent event = null;

        try {

            ShortMessage a = new ShortMessage();
            a.setMessage(comd, chan, one, two);
            event = new MidiEvent(a, tick);

        } catch (InvalidMidiDataException imde) {

            imde.printStackTrace();
        }       

        return event;
    }
}

class MyControllerListener implements ControllerEventListener {

    public void controlChange(ShortMessage event) {

        System.out.println("la");
    }
}

class SoundEffects {

    public static void main(String[] args) {

        try {

            Sequencer seq = MidiSystem.getSequencer();
            seq.open();

            int[] events = { 127 };

            MyControllerListener mcl = new MyControllerListener();

            seq.addControllerEventListener(mcl, events);

            Sequence s = new Sequence(Sequence.PPQ, 4);

            Track t = s.createTrack();

            for (int i = 5; i < 60; i  = 4) {

                t.add(MySound.makeEvent(144, 1, i, 100, i));
                t.add(MySound.makeEvent(176, 1, 127, 0, i));
                t.add(MySound.makeEvent(128, 1, i, 100, i   2));
            }

            seq.setSequence(s);

            seq.setTempoInBPM(220);

            seq.start();

        } catch (InvalidMidiDataException imde) {

            imde.printStackTrace();

        } catch (MidiUnavailableException mue) {

              mue.printStackTrace();
        }       
    }   
}   
  

Ответ №1:

Вам нужно вызвать seq.close() после завершения воспроизведения трека. Способ сделать это — добавить прослушиватель мета-сообщений и вызвать close () при обнаружении сообщения типа 0x2F (которое является необязательным мета-сообщением «конец дорожки»). Ваш код будет выглядеть примерно так:

         seq.addMetaEventListener(new MetaEventListener() {

            @Override
            public void meta(MetaMessage metaMsg) {
                if (metaMsg.getType() == 0x2F) {
                    seq.close();
                }
            }
        });
  

Обратите внимание, что вам нужно было бы добавить final модификатор в seq , чтобы ссылаться на него в реализации анонимного интерфейса.

Надеюсь, это поможет.