JUCE MidiDemo Android Inter-App MIDI Issue <Bug?>

Hi,

I’m confused with the MidiDemo of JUCE running on Android. When I run the demo on my device, the virtual midi input ports of other apps (which should receive midi data) are listed under the input list of the MidiDemo. Instead they should appear under the output, so that you could send data to the input of other apps.

Tests with the midi suite
apps from android midi suite: GitHub - philburk/android-midisuite: Android MIDI test programs and examples.
Midi Keyboard: https://play.google.com/store/apps/details?id=com.mobileer.midikeyboard
Midi Scope: https://play.google.com/store/apps/details?id=com.mobileer.example.midiscope
or Midi Synth Example: https://play.google.com/store/apps/details?id=com.mobileer.midisynthexample

Both Midi Scope and the Synth Example have virtual midi inputs (but no outputs), which works correctly with the Midi Keyboard app.

After fiddling around with JUCE I renamed the path from modules\juce_audio_devices\native\java\app\com\roli\juce\JuceMidiSupport.java to modules\juce_audio_devices\native\javacore\app\com\roli\juce\JuceMidiSupport.java - just for my changes to take effect.
In the JuceMidiSupport.java I changed all the occurrences of MidiDeviceInfo.PortInfo.TYPE_OUTPUT to MidiDeviceInfo.PortInfo.TYPE_INPUT and vice versa. Basically swapping all midi input and output ports…

Now in the MidiDemo inter-app (virtual) Midi works as expected. Can somebody confirm if it works also with Bluetooth Midi?

Midi over USB works also with or without the changes. Hmm I guess, if a midi device has both input and output ports, then JUCE still can open the ports correctly…

Is this just me? Or there is a bug in JUCE?

Samsung S9 (Android 28)
JUCE 5.4.4

Hmm, as of JUCE 5.4.7 this is still definitely a bug. On android the midi input ports are still mixed up with the output ports.

After reading this guide https://developer.android.com/ndk/guides/audio/midi#sending_midi_data
the code examples show the proper way on the Java side…

Sending MIDI data
A typical example of a MIDI writing app is a MIDI controller or sequencer.

Setting up a MidiDevice and its input ports
An app writes outgoing MIDI data to a MIDI device’s input ports. The Java side of your app must determine which MIDI device and ports to use.

//AppMidiManager.java
public class AppMidiManager {
  private native void startWritingMidi(MidiDevice device, int portNumber);
  private MidiManager mMidiManager;

  AppMidiManager(Context context){
    mMidiManager = (MidiManager)
      context.getSystemService(Context.MIDI_SERVICE);
    List midiDevices = getMidiDevices(false); // method defined in snippet above
    if (midiDevices.size() > 0){
      mMidiManager.openDevice(midiDevices.get(0),
        new MidiManager.OnDeviceOpenedListener() {
        @Override
        public void onDeviceOpened(MidiDevice device) {
          startWritingMidi(device, 0);
        }
      },null);
    }
  }
}

and the getMidiDevices method

private List getMidiDevices(boolean isOutput){
  ArrayList filteredMidiDevices = new ArrayList<>();

  for (MidiDeviceInfo midiDevice : mMidiManager.getDevices()){
    if (isOutput){
      if (midiDevice.getOutputPortCount() > 0) filteredMidiDevices.add(midiDevice);
    } else {
      if (midiDevice.getInputPortCount() > 0) filteredMidiDevices.add(midiDevice);
    }
  }
  return filteredMidiDevices;
}

Looks like this is still a problem in the current master, and a trivial fix at that as well. Can we please get this done? Thanks.