Complete Java Midi Exit

I wrote this short program to find out the javax.sound.midi system. This uses Java 6. The output looks as expected (a series of System.out.println () lines that are triggered by Sequencer events), but the problem is that after the last sound effect the program remains in the loop and does not work, t ends, as was expected.

Can anyone tell how to fix this? Thank you for your help:

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
source share
1 answer

After you finish playing the track, you need to call seq.close (). The way to do this is to add a metadata listener and call close () when you encounter a message of type 0x2F (which is an optional meta-message "end of track"). Your code will look something like this:

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

Note that you need to add the final modifier to seq to refer to it in the implementation of the anonymous interface.

Hope this helps.

+4
source

All Articles