Java MIDI合成器 - 无法更改乐器

11

我好像无法改变乐器。我将乐器的值更改了,但输出上没有任何不同。无论我尝试什么值,都只能播放钢琴乐器。下面是简单的代码。有人有建议吗?或者我是否忽略了乐器对象的基本知识?

import javax.sound.midi.*;
//import javax.sound.*;

public class Drum {
    static int instrument = 45;
    static int note = 100;
    static int timbre = 0;
    static int force = 100;
    public static void main(String[] args) {        
        Synthesizer synth = null;
        try {
            synth = MidiSystem.getSynthesizer();
            synth.open();
        }
        catch (Exception e) {
            System.out.println(e);
        }
        Soundbank soundbank = synth.getDefaultSoundbank();
        Instrument[] instr = soundbank.getInstruments();
        synth.loadInstrument(instr[instrument]);    //Changing this int (instrument) does nothing
        MidiChannel[] mc = synth.getChannels();
        mc[4].noteOn(note, force);
        try { Thread.sleep(1000); } 
        catch(InterruptedException e) {}
        System.out.println(instr[instrument].getName());

        synth.close();

    }
} 

你不能仅仅加载一个乐器,还必须发送一个程序变换消息。我不是Java程序员,所以我不知道如何做到这一点,但这是你必须做的。请参阅http://download.oracle.com/javase/1.4.2/docs/api/javax/sound/midi/Synthesizer.html#loadInstrument(javax.sound.midi.Instrument)。 - Brad
https://stackoverflow.com/questions/30718831/midi-midimessage-program-change-with-instrument-from-different-bank - Martin Zeitler
3个回答

14

你需要告诉通道使用这个乐器。我承认我从未在Java中使用过MIDI,但像mc.programChange(instr.getPatch().getProgram())这样的代码听起来很有前途。


那是正确的。我需要使用programChange命令。例如,我使用了mc[4].programChange(0, instrument);现在我可以更改乐器类型,但打击乐器好像没有播放出来。我得查一下这个问题的原因,我想可能是某个设置有问题。感谢你们! - Matt

5

要演奏打击乐器,您需要使用通道10,该通道仅用于打击乐器。(http://en.wikipedia.org/wiki/General_MIDI)

例如:

int instrument = 36;

Sequence sequence = new Sequence(Sequence.PPQ, 1);

Track track = sequence.createTrack();


ShortMessage sm = new ShortMessage( );
sm.setMessage(ShortMessage.PROGRAM_CHANGE, 9, instrument, 0); //9 ==> is the channel 10.
track.add(new MidiEvent(sm, 0));

那么,您添加的每个音符都将带有打击乐。

0
你需要向音序器发送一个程序更改事件。如何操作?发送一个短消息即可。
sound.setMessage(ShortMessage.PROGRAM_CHANGE, channel, instrument, channel);
            long timeStam1p = -1;
            Receiver rcv1r = MidiSystem.getReceiver();
            rcv1r.send(sound, timeStam1p);
            sound.setMessage(ShortMessage.NOTE_ON, channel, note, velocity);
            long timeStamp = -1;
            Receiver rcvr = MidiSystem.getReceiver();
            rcvr.send(sound, timeStamp);

变量有频道(int),音符(int),乐器(int),速度(int)。 此外,我建议学习MIDI事件。事件是指MIDI播放音符、停止音符、改变乐器、改变速度、控制变化等方式。我花了2年时间使用一个MIDI程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接