更新 Java 中的 Midi 设备列表
Update list of Midi Devices in Java
我在 Java 从事一个基于 MIDI 的项目,并且努力刷新 Midi 设备列表。
据我所知 MidiSystem.getMidiDeviceInfo();
应该给我一个 Info[]
数组。然而,我什么也没发生。插入或拔出新设备时,阵列内的对象保持不变,长度也保持不变。
搜索 Whosebug 将我带到 this 6 year old question。其中一条评论表明,在 OSX/macOS 上可能是问题所在。我还没有在 Windows 或 Linux 上尝试我的程序,但无论如何它应该可以在 OSX/macOS 上运行。
另一条评论建议通过 com.sun.media.sound.JDK13Services.setCachingPeriod(1);
手动将缓存时间设置为较短的时间可以解决此问题。但是,不在 OSX/macOS 上。
对 Google 的进一步搜索将我带到 openjdk bug report,它声称这是 OSX/macOS.
中 Apple 方面的一些错误
下面是我的 Devices
class 的简化版本以供验证,但我确信它应该是正确的。
private Info[] devices;
public Devices() {
refreshDeviceList();
printDeviceList();
}
// DeviceList Functions
public Info[] getDeviceList() {
return devices;
}
public void printDeviceList() {
for (int i = 0; i < devices.length; i++) {
System.out.println("Description: \t" + devices[i].getDescription());
System.out.println("Name: \t\t" + devices[i].getName());
System.out.println("Vendor: \t" + devices[i].getVendor());
System.out.println("Version: \t" + devices[i].getVersion());
System.out.println();
}
}
public void refreshDeviceList() {
devices = MidiSystem.getMidiDeviceInfo();
}
// DeviceFunctions
public String getDeviceDescription(int i) {
return devices[i].getDescription();
}
public String getDeviceName(int i) {
return devices[i].getName();
}
public String getDeviceVendor(int i) {
return devices[i].getVendor();
}
public String getDeviceVersion(int i) {
return devices[i].getVersion();
}
请注意,在创建新的 Devices
对象时第一次调用 refreshDevices()
可以正常打印并获得可用设备列表。只是不是之后。插入或拔出设备后重新启动程序 returns 但是正确的新设备数量。
任何人都可以提供解决方案吗?
一种方法是按如下方式设置系统:
shell script:
start program with input 1 // that means it's the receiver
while(true) {
start program with input 2 // that means it's the sender
wait for an amount of time
}
end shell script
inside the program is the following:
if code==1:
while(true) {
do whatever you have to do
at specified point in time:
read file "myfile"
assemble the info
}
if code==2:
read the device info
write the info to "myfile"
exit
现在有一个库 CoreMidi4J,可以正确支持 macOS 上的热插拔(以及其他一些功能)。我不是作者,但它似乎很适合我的需要。
我找到了一个使用 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();
}
}
我在 Java 从事一个基于 MIDI 的项目,并且努力刷新 Midi 设备列表。
据我所知 MidiSystem.getMidiDeviceInfo();
应该给我一个 Info[]
数组。然而,我什么也没发生。插入或拔出新设备时,阵列内的对象保持不变,长度也保持不变。
搜索 Whosebug 将我带到 this 6 year old question。其中一条评论表明,在 OSX/macOS 上可能是问题所在。我还没有在 Windows 或 Linux 上尝试我的程序,但无论如何它应该可以在 OSX/macOS 上运行。
另一条评论建议通过 com.sun.media.sound.JDK13Services.setCachingPeriod(1);
手动将缓存时间设置为较短的时间可以解决此问题。但是,不在 OSX/macOS 上。
对 Google 的进一步搜索将我带到 openjdk bug report,它声称这是 OSX/macOS.
中 Apple 方面的一些错误下面是我的 Devices
class 的简化版本以供验证,但我确信它应该是正确的。
private Info[] devices;
public Devices() {
refreshDeviceList();
printDeviceList();
}
// DeviceList Functions
public Info[] getDeviceList() {
return devices;
}
public void printDeviceList() {
for (int i = 0; i < devices.length; i++) {
System.out.println("Description: \t" + devices[i].getDescription());
System.out.println("Name: \t\t" + devices[i].getName());
System.out.println("Vendor: \t" + devices[i].getVendor());
System.out.println("Version: \t" + devices[i].getVersion());
System.out.println();
}
}
public void refreshDeviceList() {
devices = MidiSystem.getMidiDeviceInfo();
}
// DeviceFunctions
public String getDeviceDescription(int i) {
return devices[i].getDescription();
}
public String getDeviceName(int i) {
return devices[i].getName();
}
public String getDeviceVendor(int i) {
return devices[i].getVendor();
}
public String getDeviceVersion(int i) {
return devices[i].getVersion();
}
请注意,在创建新的 Devices
对象时第一次调用 refreshDevices()
可以正常打印并获得可用设备列表。只是不是之后。插入或拔出设备后重新启动程序 returns 但是正确的新设备数量。
任何人都可以提供解决方案吗?
一种方法是按如下方式设置系统:
shell script:
start program with input 1 // that means it's the receiver
while(true) {
start program with input 2 // that means it's the sender
wait for an amount of time
}
end shell script
inside the program is the following:
if code==1:
while(true) {
do whatever you have to do
at specified point in time:
read file "myfile"
assemble the info
}
if code==2:
read the device info
write the info to "myfile"
exit
现在有一个库 CoreMidi4J,可以正确支持 macOS 上的热插拔(以及其他一些功能)。我不是作者,但它似乎很适合我的需要。
我找到了一个使用 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();
}
}