您好:我正在尝试将MIDI Sequencer的实例同步到外部时钟。我做了:
S_p = MidiSystem.getSequencer(false);
D2 = MidiSystem.getMidiDevice(MidiSystem.getMidiDeviceInfo()[1]);
S_p.open();
D2.open();
R2=S_p.getReceiver();
T2=D2.getTransmitter();
T2.setReceiver(R2);
但
for(int i=0;i<S_p.getMasterSyncModes().length;i++)
{System.out.println("Available modes are "+i+ " "+S_p.getMasterSyncModes()[i].toString());}
退货
Available modes are 0 Internal Clock
这意味着这将是无用的。
S_p.setMasterSyncMode(Sequencer.SyncMode.MIDI_SYNC);
我究竟做错了什么 ?
当然,我已经确认有消息从D2传到另一个接收器自定义消息中,该消息被编写为通知system.out,而音序器正常播放,只是看起来它不支持SyncModes文档所说的。具体来说,这句话使我感到困惑(来自MIDI_SYNC:“此模式仅适用于同时也是MIDI接收器的音序器的主同步模式。”
定序器成为接收器的含义是什么。我认为用我的getReceiver()方法就足够了
致谢,谢谢!
最佳答案
一次有很多问题!
1)最重要的信息是Java Sound中的音序器是插件(服务提供商,SPI)。 Java附带了至少一个Sequencer,但是没有提到它确实支持所有可以想象的功能。特别是,getMasterSyncModes()
查询的存在表明并非每个Sequencer实现都将支持所有同步模式。而且您已经发现,Oracle Java中的默认Sequencer恰好不支持除Internal之外的任何同步模式。需要明确的是:Java规范没有说定序器必须支持任何特定的同步模式。
2)但是,可以以插件的形式添加带有外部同步的Sequencer自己的实现。
定序器成为接收器是什么意思?
3)我认为这是为了与另一个主同步提供者同步,音序器必须能够接收MIDI同步消息,即也可以接收MIDI消息。我同意Java声音中的Receiver和Transmitter术语确实令人困惑。
我究竟做错了什么?
4)您没有做错任何事情。您可以查询同步模式,如果Sequencer支持您要使用的同步模式,它将可以使用。但是有机会,您不会找到这样的Sequencer实现...
S_p = MidiSystem.getSequencer(false);
5)如上所述,在Java Sound中,音序器是类似于MIDI设备和合成器的插件。因此,您的系统可能提供多个Sequencer。您可以查询MidiSystem.getMidiDeviceInfo()
,获取各种设备,然后查看它们是否为instanceof Sequencer
,以查找所有可用的音序器。
但我认为主要的答案是:可能没有公开可用的Sequencer实现支持外部同步。
可以在OpenJDK的RealTimeSequencer中激活并修复它。