MidiSystem.getMidiDevice(...) возвращает неожиданный класс
Я пытаюсь написать простую программу с использованием javax.sound.midi, которая читает, редактирует, а затем воспроизводит MIDI-файлы через FluidSynth. Вот фрагмент моего кода:
Synthesizer synth;
// Look through the available midi devices for a software synthesizer
MidiDevice.Info[] deviceInfo = MidiSystem.getMidiDeviceInfo();
for(MidiDevice.Info currentDevice : deviceInfo){
if(currentDevice.getName().matches("FluidSynth virtual port.*"))
synth = (Synthesizer) MidiSystem.getMidiDevice(currentDevice);
}
// If FluidSynth is not found, use default synth
if(synth == null){
synth = MidiSystem.getSynthesizer();
System.out.println("Using default synth");
}
// Do stuff with synth
Код успешно компилируется, но когда я его запускаю, я получаю следующее исключение:
Exception in thread "main" java.lang.ClassCastException: java.desktop/com.sun.media.sound.MidiOutDevice cannot be cast to java.desktop/javax.sound.midi.Synthesizer
at SynthesizerDemo.main(SynthesizerDemo.java:49)
Я ожидал, что класс Synthesizer будет возвращен, и я не понимаю, что com.sun.media.sound.MidiOutDevice
класс есть. Если я переключу синтезатор на MidiDevice
класс, воспроизведение работает, но у меня нет доступа ко всем методам в Synthesizer
учебный класс. Есть идеи о том, что мне не хватает?
2 ответа
Synthesizer
Интерфейс используется синтезаторами, которые реализованы на Java и которыми можно управлять через этот интерфейс.
FluidSynth не написан на Java и не реализует этот интерфейс. С точки зрения JVM, FluidSynth выглядит так же, как и любой другой порт MIDI.
Чтобы управлять FluidSynth, вы должны отправлять обычные MIDI-сообщения.
Проверьте ваши приведения:
for(MidiDevice.Info currentDevice : deviceInfo){
if(currentDevice.getName().matches("FluidSynth virtual port.*")) {
MidiDevice device = MidiSystem.getMidiDevice(currentDevice);
if (device instanceof Synthesizer) {
synth = (Synthesizer) MidiSystem.getMidiDevice(currentDevice);
break;
}
}
}