4

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?

kroppian
  • 127
  • 1
  • 6
  • You should probably add a `break` inside the `if-statement`, seeing as you are just looking for one device – smac89 Jun 25 '18 at 17:25

2 Answers2

1

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.

CL.
  • 173,858
  • 17
  • 217
  • 259
  • Hi CL. Thanks for the quick response. That makes sense. So is it not possible to use the Synthesizer methods described in [the Java MIDI tutorial](https://docs.oracle.com/javase/tutorial/sound/MIDI-synth.html) on software synths like FluidSynth? I am looking to perform actions like muting tracks and changing instruments. – kroppian Jun 29 '18 at 03:09
0

Check your casts:

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;
        }
    }
}   
smac89
  • 39,374
  • 15
  • 132
  • 179