MIDI over USB

Hi, are there any permissions that needed to be granted in order to use MIDI over USB? There doesn’t appear to be anything in the Projucer options.

thx

I assume you’re on desktop? Because I’ve never had any permission issues manipulating MIDI hardware under macOS and Windows. Could be different under mobile platforms though.

I think he refers to Android given the topic’s category

Yes, this is for Android. The functions for returning MIDI inputs and outputs are not returning any results. Other Android apps I run are seeing the attached devices.

You need to build for at least SDK 23.

ah, really? wow… there’s no MIDI support in Juce at all before that? thx

I think that’s because there’s no MIDI support in Android before that!

2 Likes

I was wondering that, but then I have other apps running on 19 that access MIDI. From what I’ve read it was overhauled in 23 though and given much better APIs so I just assumed you chose to support from then onwards. It seems that MIDI have been available from 3.1

Doh, missed that this was in the Android section (usually just read from the aggregate main page)… sorry @leehu!

1 Like

ha, no probs - i normally put things in the title aswell, but didn’t on this occasion

Hi Fabian. Rebuilt for 23 and upgraded tablet and still no MIDI in/out showing. Are there any demo/tests apps to run for MIDI connectivity? thx

Hmm that’s strange. Should definitely work. When re-saving for any API version >= 23 the Projucer will add extra code to your app’s main java file, so make sure you are really using the Projucer to re-save after changing the API version.

Can you point me to any website that Android has support for midi prior to SDK version 23. This page states that SDK version 23 is required.

You can use this sample code from google to test midi connectivity. Or re-target the JuceDemo to API version 23, enable bluetooth permissions and then go to the audio settings page in the JuceDemo to select your midi input. You can then use the synthesiser example to play some notes.

thx. i’ll try that. i don’t have bluetooth permission enabled for my app, so I’ll try that too.

This is page I was looking at:
https://source.android.com/devices/audio/midi

Maybe I’ve misunderstood something, but this page seems to suggest MIDI is available from 3.1 but new APIs were added from 23 to presumably make things easier for developers. Whilst still on 19 I was running this app:

https://play.google.com/store/apps/details?id=com.extreamsd.usbmidimonitor&hl=en_GB

and it was showing the incoming MIDI from a synth that I had connected via an OTG cable

Hi, so found a bug in my MIDI in/out filtering code for Android so now the inputs/outputs are appearing. Opening output is fine, but the call to MidiInput::openDevice() is failing. After looking at the demo code it appears as though this is not called directly but via the DeviceManager so perhaps I should be doing this instead. Seems to work fine for other OSes. Anyway, will try this on Android. thx

You may need bluetooth runtime permissions if this is a bluetooth midi device.

Not using any bluetooth - this is all direct USB over an OTG cable.

Hmmm if it works with the JUCE demo then have a look at how the AudioDeviceManager opens the midi device. There isn’t a whole lot of fancy code there.

yeah, just looking at that now - doesn’t seem to be anything special as you say…

Ok, so I think I have a handle on this and why my stuff is not working and the demo does.
When building a standalone, this code gets executed at startup for OSX and Android:

#if JUCE_IOS || JUCE_ANDROID
void timerCallback() override
{
auto newMidiDevices = MidiInput::getDevices();


for (auto& newDevice : newMidiDevices)
if (! lastMidiDevices.contains (newDevice))
deviceManager.setMidiInputEnabled (newDevice, true);
}
#endif

It opens all the MIDI devices it can find. Any calls to MidiInput::OpenDevice() on Android will then fail - seems to be ok on iOS - maybe this is because iOS MIDI is mulit-ported like OSX and Android isn’t like Windows? Anyway, I commented out this code and my code now works as expected. So it seems on Android that we have to go through the DeviceManager created at startup. As the JuceDemo is not running the standalone code, it does not see this issue.

I’m not sure how to get hold of the DeviceManager class that lives inside the standalone filter window from my plugin inside my code to use it - can you tell me how?

I guess ideally, if we want to manage MIDI devices ourselves, without using the DeviceManager class, it would be nice to be able to tell the Android build not to go and open all the MIDI input devices at startup so that the rest the same behaviour is seen across all platforms. Or maybe there’s a call on DeviceManager to tell it to close everything - haven’t checked yet

Yes that’s spot on. I forgot about that. We had a similar issue with ROLI’s NOISE app on Android: you can only open midi devices once.

So the standalone target is a simple standalone app to get you going quickly. It will simply connect all midi devices to your AudioProcessor - so without even opening any MidiDevices in your own code, you should be getting the midi into your AudioProcessor via the processBlock callback. You don’t need to use any AudioDeviceManager or anything. Check-out the JuceDemoPlugin or the AUv3Synth samples.

If you need something more custom [1] then you may need to roll your own custom app for your plugin. See option number 2 in this post for more information:

[1] Let us know why the midi handling of the default standalone target app does not work for you. Maybe we can add it to JUCE.