Search code examples
javamidijavax.sound.midifluidsynth

MidiSystem.getMidiDevice(...) returns unexpected class


I'm trying to write a simple program using javax.sound.midi that reads, edits, and then plays midi files through FluidSynth. Here is a snippet of my code:

  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

The code compiles successfully, but when I run it, I get the following exception:

 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)

I was expecting the Synthesizer class to be returned, and I don't understand what the com.sun.media.sound.MidiOutDevice class is. If I switch synth to the MidiDevice class, playback works, but I then don't have access to all of the methods in the Synthesizer class. Any idea of what I'm missing?


Solution

  • The Synthesizer interface is used by synthesizers that are implemented in Java, and that can be controlled through that interface.

    FluidSynth is not written in Java and does not implement that interface. From the point of view of the JVM, FluidSynth looks just like any other MIDI port.

    To control FluidSynth, you have to send normal MIDI messages.