首页 > 解决方案 > 无法在 Java MIDI 程序中更改乐器,InvalidMidiDataException:channel out of range

问题描述

我无法使用 javax.sound.midi.ShortMessage.setMessage() 方法更改乐器。通道 0-15 为钢琴,不包括 9 为鼓。但是8-15应该是Chromatic Percussion。当我将频道设置为 16 或更多(范围从 0 到 127)时,我得到 javax.sound.midi.InvalidMidiDataException:频道超出范围:16。请问,我该如何解决这个问题?

    import javax.sound.midi.*;

public class TestMidi{

    public void play(){
        try{
            Sequencer player = MidiSystem.getSequencer();
            System.out.println("Sequencer created succesfully.");

            player.open();

            Sequence s = new Sequence(Sequence.PPQ, 4);

            Track track = s.createTrack();

            addShortMessage(track,1,192,1,102,0);
            addShortMessage(track,1,144,1,44,100);
            addShortMessage(track,16,128,1,44,100);

            player.setSequence(s);

            player.start();

        } catch(Exception e){
            System.out.println("Fail.");
            e.printStackTrace();
        }
    }

    public static void main(String[] args)  {
        TestMidi tm = new TestMidi();
        tm.play();
    }

    void addShortMessage(Track track, long tick, int command, int channel, int data1, int data2) throws Exception {
        ShortMessage msg = new ShortMessage(command, channel, data1, data2);
        MidiEvent event = new MidiEvent(msg, tick);
        track.add(event);
    }
}

标签: javamidijavax.sound.midi

解决方案


通道编号从 0 到 15。每个通道都可以有自己的乐器(通过发送程序更改消息)。

此代码将两条消息添加到轨道。如果要添加第三条消息,则必须track.add()使用第三个对象进行调用。

使用这样的辅助函数添加事件会更容易:

void addShortMessage(Track track, long tick,
                     int command, int channel, int data1, int data2) {
    ShortMessage msg = new ShortMessage(command, channel, data1, data2);
    MidiEvent event = new MidiEvent(msg, tick); //edited here
    track.add(event);
}

推荐阅读