终止Java Midi输出 [英] Terminate Java Midi output

查看:148
本文介绍了终止Java Midi输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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


推荐答案

一旦曲目播放完毕,你需要调用seq.close()。这样做的方法是添加元消息监听器,并在遇到类型为0x2F的消息时调用close()(这是非可选的元消息end of track)。你的代码看起来像这样:

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

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

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

希望有所帮助。

这篇关于终止Java Midi输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆