java - 无法在 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);
}
}
解决方案
通道编号从 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);
}
推荐阅读
- java - Share Hibernate Second-Level Cache - 多个应用程序可以共享同一个缓存吗
- php - 如何配置 PHPStan 以避免由特定类和/或魔术方法引起的误报?
- json - 如何快速获取特定的json值
- jquery - 数据表 - 当数据表尝试发出 AJAX 请求时获取 net::ERR_CONNECTION_CLOSED
- c# - 服务总线在 ReceiveAndDelete 模式下成功完成后重新启动消息处理
- mysql - Rails 控制台打印消息和查询需要太多时间来加载
- office365 - PHP Mailer 和 Office 365 配置
- r - R:根据文件名合并数据帧
- flutter - 监听传入的通知 Flutter
- java - Java 排序集合与 DB 提取集合