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;
        }
    }
}   
Другие вопросы по тегам