【问题标题】:Terminate Java Midi output终止 Java Midi 输出
【发布时间】:2011-05-13 04:11:09
【问题描述】:

我编写了这个小程序来学习 javax.sound.midi 系统。这是使用 Java 6。输出符合预期(由 Sequencer 事件触发的一系列 System.out.println() 字符串),但问题是,在最后一个声音效果之后,程序停留在循环中并且没有t 按预期终止。

谁能告诉我如何解决这个问题?感谢您的帮助:

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();
        }       
    }   
}   

【问题讨论】:

    标签: java midi terminate


    【解决方案1】:

    曲目播放完毕后,您需要调用 seq.close()。这样做的方法是添加一个元消息侦听器,并在遇到类型为 0x2F 的消息时调用 close() (这是非可选的元消息“轨道结束”)。您的代码将如下所示:

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

    请注意,您需要将 final 修饰符添加到 seq 以便在匿名接口实现中引用它。

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-07
      • 2014-04-10
      • 2014-12-21
      • 1970-01-01
      • 2011-10-16
      • 2017-07-03
      相关资源
      最近更新 更多