终止 Java Midi 输出

发布于 2024-11-06 14:45:07 字数 2218 浏览 4 评论 0原文

我编写这个简短的程序是为了学习 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();
        }       
    }   
}   

I wrote this short program to learn the javax.sound.midi system. This is using Java 6. The output is as expected (a series of System.out.println() strings that are triggered by Sequencer events) but the problem is, after the last sound effect, the program stays in a loop and doesn't terminate as expected.

Can anyone tell how to fix this? Thanks 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();
        }       
    }   
}   

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮云落日 2024-11-13 14:45:07

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

        seq.addMetaEventListener(new MetaEventListener() {

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

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

希望有帮助。

You need to call seq.close() once the track has finished playing. The way to do that is to add a meta message listener, and invoke close() when you encounter a message of type 0x2F (which is the non-optional meta message "end of track"). Your code would look something like this:

        seq.addMetaEventListener(new MetaEventListener() {

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

Note that you would need to add the final modifier to seq in order to refer to it in the anonymous Interface implementation.

Hope that helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文