首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >终止Java Midi输出

终止Java Midi输出
EN

Stack Overflow用户
提问于 2011-05-12 10:08:02
回答 1查看 1K关注 0票数 1

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

有谁能告诉我怎么解决这个问题吗?感谢您的帮助:

代码语言:javascript
复制
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();
        }       
    }   
}   
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-05-12 10:30:00

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

代码语言:javascript
复制
        seq.addMetaEventListener(new MetaEventListener() {

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

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

希望这能有所帮助。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5972603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档