MIDI - MidiMessage 程序随来自不同库的乐器而变化
MIDI - MidiMessage Program Change with Instrument From Different Bank
我使用的默认合成器的音库包含各种不同的乐器。例如,这个代码片段...
Synthesizer synthesizer = MidiSystem.getSynthesizer();
synthesizer.open();
Instrument instruments = synthesizer.getDefaultSoundbank().getInstruments();
for (Instrument i : instruments)
System.out.println(i);
... 打印以下内容:
Instrument: Piano 1 bank #0 preset #0
Instrument: Piano 2 bank #0 preset #1
[...]
Instrument: Applause bank #0 preset #126
Instrument: Gun Shot bank #0 preset #127
Instrument: SynthBass101 bank #128 preset #38
Instrument: Trombone 2 bank #128 preset #57
[...]
Instrument: Machine Gun bank #128 preset #127
Instrument: Echo Pan bank #256 preset #102
Instrument: String Slap bank #256 preset #120
[...]
Instrument: Lasergun bank #256 preset #127
[...]
Instrument: Starship bank #1024 preset #125
Instrument: Carillon bank #1152 preset #14
[...]
Instrument: Choir Aahs 2 bank #4096 preset #52
我可以通过 MidiChannel
、programChange
方法和 noteOn
演奏这些库中任何一个的乐器,就像这样(这会演奏来自库 1152 的乐器 14,"Carillon"):
MidiChannel channel = synthesizer.getChannels()[0];
if (channel != null) {
channel.programChange(1152, 14);
channel.noteOn(70, 100);
}
我想将程序更改事件添加到序列的轨道中,以便我可以在序列中演奏 "Carillon" 乐器。我尝试使用 ShortMessage
:
Sequence sequence = new Sequence(Sequence.PPQ, 2);
Track track = sequence.createTrack();
ShortMessage pcMessage = new ShortMessage(ShortMessage.PROGRAM_CHANGE, 0, 14, 0);
track.add(new MidiEvent(pcMessage, 0));
但是当我在银行 1152 中寻找仪器 14 时,这会将仪器更改为银行 0 中的仪器 14 ("Tubular-bell")。尝试将 ShortMessage 构造函数中的最后两个参数之一更改为1152 导致数据字节值超出范围的 javax.sound.midi.InvalidMidiDataException
。其他 MidiMessage 子类似乎也不包含从其他银行加载工具的选项。
如何在 MidiEvent 的 MidiMessage 中使用来自不同银行的工具?
在 MIDI 协议本身中,bank 编号被分成两个 7 位部分,并作为两个 controllers、"Bank Select" 和 "Bank Select LSB" 的值传输:
... = new ShortMessage(ShortMessage.CONTROL_CHANGE, 0, 0, 1152 >> 7); // = 9
... = new ShortMessage(ShortMessage.CONTROL_CHANGE, 0, 32, 1152 & 0x7f); // = 0
... = new ShortMessage(ShortMessage.PROGRAM_CHANGE, 0, 14, 0);
请注意,不同的标准(GS、XG、GM2)以不同方式命名银行 select 号码的两个部分。
在这种情况下,Carillon 来自 GS 标准,将其定义为 "variation number 9",即 MSB 控制器。但控制器名称无关紧要;只要将控制器 0 设置为 9,就可以得到正确的乐器。
我使用的默认合成器的音库包含各种不同的乐器。例如,这个代码片段...
Synthesizer synthesizer = MidiSystem.getSynthesizer();
synthesizer.open();
Instrument instruments = synthesizer.getDefaultSoundbank().getInstruments();
for (Instrument i : instruments)
System.out.println(i);
... 打印以下内容:
Instrument: Piano 1 bank #0 preset #0
Instrument: Piano 2 bank #0 preset #1
[...]
Instrument: Applause bank #0 preset #126
Instrument: Gun Shot bank #0 preset #127
Instrument: SynthBass101 bank #128 preset #38
Instrument: Trombone 2 bank #128 preset #57
[...]
Instrument: Machine Gun bank #128 preset #127
Instrument: Echo Pan bank #256 preset #102
Instrument: String Slap bank #256 preset #120
[...]
Instrument: Lasergun bank #256 preset #127
[...]
Instrument: Starship bank #1024 preset #125
Instrument: Carillon bank #1152 preset #14
[...]
Instrument: Choir Aahs 2 bank #4096 preset #52
我可以通过 MidiChannel
、programChange
方法和 noteOn
演奏这些库中任何一个的乐器,就像这样(这会演奏来自库 1152 的乐器 14,"Carillon"):
MidiChannel channel = synthesizer.getChannels()[0];
if (channel != null) {
channel.programChange(1152, 14);
channel.noteOn(70, 100);
}
我想将程序更改事件添加到序列的轨道中,以便我可以在序列中演奏 "Carillon" 乐器。我尝试使用 ShortMessage
:
Sequence sequence = new Sequence(Sequence.PPQ, 2);
Track track = sequence.createTrack();
ShortMessage pcMessage = new ShortMessage(ShortMessage.PROGRAM_CHANGE, 0, 14, 0);
track.add(new MidiEvent(pcMessage, 0));
但是当我在银行 1152 中寻找仪器 14 时,这会将仪器更改为银行 0 中的仪器 14 ("Tubular-bell")。尝试将 ShortMessage 构造函数中的最后两个参数之一更改为1152 导致数据字节值超出范围的 javax.sound.midi.InvalidMidiDataException
。其他 MidiMessage 子类似乎也不包含从其他银行加载工具的选项。
如何在 MidiEvent 的 MidiMessage 中使用来自不同银行的工具?
在 MIDI 协议本身中,bank 编号被分成两个 7 位部分,并作为两个 controllers、"Bank Select" 和 "Bank Select LSB" 的值传输:
... = new ShortMessage(ShortMessage.CONTROL_CHANGE, 0, 0, 1152 >> 7); // = 9
... = new ShortMessage(ShortMessage.CONTROL_CHANGE, 0, 32, 1152 & 0x7f); // = 0
... = new ShortMessage(ShortMessage.PROGRAM_CHANGE, 0, 14, 0);
请注意,不同的标准(GS、XG、GM2)以不同方式命名银行 select 号码的两个部分。 在这种情况下,Carillon 来自 GS 标准,将其定义为 "variation number 9",即 MSB 控制器。但控制器名称无关紧要;只要将控制器 0 设置为 9,就可以得到正确的乐器。