我正在开发一个java项目,它使用javax.sound.midi库从midi硬件接收midi事件。在文档中,它说MidiSystem.getMidiDeviceInfo()
返回所有连接的midi硬件的列表。它对我有效,但问题是,它只有效一次。第一次实际扫描设备需要一段时间,但每次扫描之后,即使连接了新设备,它也会立即返回相同的列表。有没有办法强制它重新扫描?如果应用程序重新启动,它将重新扫描,但我不希望我的用户在连接新的midi设备时必须重新启动。
顺便说一句,我使用的是Mac OS X...有人指出,对于不同的操作系统,行为可能是不同的。
发布于 2010-09-29 18:04:03
在我的工作PC上没有任何MIDI设备,或者任何一种Mac,我怀疑我是否能够正确地测试它,但是...
MidiSystem类似乎使用com.sun.media.sound.JDK13Services.getProviders(Class providerClass)
来查找系统上的设备列表。在cachingPeriod
外部的连续调用中重新创建列表的API docs for this class状态,可以通过调用setCachingPeriod(int seconds)
方便地进行设置。
如果幸运的话,你只需在应用程序开始时调用它一次,并将其设置为5秒或其他什么,它就会神奇地工作。然而,文档也声明“这种方法只用于测试”,所以我不确定这种方法会有多有效。
希望这足以让你入门,在此期间,我将继续探索,看看是否能找到一种更干净的方法来做这件事。
发布于 2018-07-25 03:51:20
我回答说这也是Update list of Midi Devices in Java,但是对于最终来到这里的人来说,现在有一个库可以正确地支持这一点:https://github.com/DerekCook/CoreMidi4J
该库充当MIDI子系统的设备提供者,因此它基本上是一个插件,您现有的所有代码都将正常工作。
我不是作者,但它很好地满足了我的需求,并且花了相当多的时间才找到它,所以我把它贴在这里给遇到这个问题的其他人。
发布于 2021-03-27 00:32:02
我找到了一个使用JavaFX线程的解决方案。出于某些原因,这至少在MacOSX上有效。在普通的线程上,它不能工作。
import fx.FX_Platform;
import javafx.embed.swing.JFXPanel;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
public class miditest {
static public void main( String[] args ) {
// **** Just to init FX platform
new JFXPanel();
new Thread( () -> {
for( int ix=0; ix<1000; ix++ ) {
try {
Thread.sleep(2000);
} catch( InterruptedException e ) {
}
FX_Platform.runLater( () -> {
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
System.out.println("FOUND: " + infos.length);
for( MidiDevice.Info midiinfo : infos ) {
System.out.println(midiinfo);
}
});
}
}).start();
}
}
https://stackoverflow.com/questions/3752352
复制相似问题