nmj Network MIDI for Android™
 
humatic - htools
 


nmj is a low-level Android™ MIDI solution with support for various network protocols.

It is compatible with

  • RTP MIDI (as specified in RFC 4695 and implemented in Apple's Network MIDI in OS X)
  • ipMIDI
  • Class-compliant Usb MIDI interfaces
  • The HTML5 WebSocket specification
  • and more...
The library provides a user defineable number of MIDI connections and is fully configureable through a simple java api.

With the release of the mnet driver (currently in public beta) we are about to close the circle and do no longer rely on computer side java proxies and third party (loopback) drivers. Along with the driver release nmj's desktop java version has been deprecated. It is still included in the download, but will not see any more feature additions.

mnet supports all of nmj's connection options (Multicast, RTP, Bluetooth, Usb and WebSocket MIDI) and is available for Windows and OS X (Linux version pending).

nmj remains to be compatible with these fine network MIDI drivers for PC-side applications:
rtpMIDI (Tobias Erichsen's Windows implementation of RFC 4695 and Apple's session initialization protocol)
OS X's MIDI Network driver (and its iOS implementation in MIDINetworkSession)
ipMIDI (Multicast MIDI for Windows and OS X by nerds.de)
qmidinet & multimidicast (Multicast MIDI for Linux)




The library is under ongoing development. The version available here may at times not be fully up to date and may differ from what is currently used in TouchDAW - nmj's demo and road hardening app - in details. It should be fine to get started though. Please check back for updates or us directly. Thank you.



download nmj 0.895

Creative Commons License

Released under
Creative Commons Attribution-NonCommercial-NoDerivs 3.0
license


Interested in using nmj in commercial apps? .



An Android M MidiDeviceService



(July 15th: Updated with new permissions for M preview version 2)

To follow up on part 1 of this little investigation into Android M's MIDI api, here is the mentioned MidiDeviceService implementation. Download it here. Should it crash or otherwise misbehave, please let me know and forgive me, it's just an experiment.

This comes in form of a standard .apk and can be sideloaded as usual long as you are running the Android M preview.

The "app" itself does not really do anything on its own. It basically serves as an installer for the service and can then be used to set the network side connections that the service will use: Touch the upper text and a popup will come up. Like TouchDAW it defaults to a local RTP session that needs to be connected in rtpMIDI or Audio MIDI Setup. Multicast (ipMIDI) mode is available as well. Other than in the first release, in version 2 of the M preview the CHANGE_WIFI_MULTICAST permission is generally granted, so no more prompts here.

The MidiDeviceService itself will only come to life when another app opens its android.media.midi ports, so if you do not already have an M test project you will need to copy some boilerplate code from Google's docs or write some yourself to try this.




System MIDI support in Android M

If you are interested in the subject you probably heard that Android M will bring native MIDI support of some sort. Chances are that you have seen a screenshot showing the below menu in one way or the other:



This has made it into numerous popular tech - though not really "dev" - publications since Google IO (see for example Android Police, Ars Technica, a.o.) and sparked lengthy discussion threads on why on earth one would want badly sounding 90's style music being auto-played when visiting website X or how this would change everything and finally would make all the high gloss iOS music apps magically appear on Android (like they did when the audio latency issue was finally and forever solved the last ten times, I suppose)

So far, so good. I don't think anybody had actually tried the new apis yet and the web was more about buzz than substance once again. Of course I am personally very much interested in what this all means and wanted to know more, so I started to play around a bit.

Overall, information is sparse at the time being. You can find java API docs in the preview release's documentation and there is some additional info for device manufacturers on the AOSP site. Looks like we will get support for Usb MIDI devices both in host and peripheral mode. The former is not really new, but having an official API for it can't be bad of course. Peripheral mode on the other hand is new and it seems to be way more interesting to me. Basically this means that an Android device now can BE a MIDI device to other hosts (like PCs). If you enable MIDI in the infamous menu above you will get a MIDI device named after your phone on the host. Here's a screenshot from MidiOx (click to enlarge):




This is quite nice. Not really the "software defineable Usb client mode" that I had always hoped for, but it does what it says (MIDI) and seems to work well. Hopefully this can make the adb hack in nmj / TouchDAW obsolete. I know there is demand for this kind of direct Usb link, so this will be very welcome. For developers it is a bit ugly to work with it in the moment, because adb via usb is obviously disabled when the bus is in use for MIDI and at least on my Nexus 5 I can't get adb to work over TCP on M when this is active either, but I haven't spent too much time with it so far.

Here's the Android side info for the port you get (printed to some TextView in absence of logcat):



It's ALSA, unfortunately there seems to be just one such port and you should not change the Usb mode while the MIDI port is open or your phone will crash hard and reboot...

What else is in the package? MIDI over Bluetooth LE, whatever that means. There are some references to an upcoming MMA standard, maybe that means Apple's standard, I don't know. Bluetooth ports are supposed to be enabled by default, but there is nothing in the MidiDeviceInfo lists when you just fire up the MidiManager. I would think this is primarily intended for hardware input devices again (Miselu et all). It does not seem to do anything with a Yosemite Mac set to act as a Bluetooth MIDI host, but that may be because the Nexus 5's Bluetooth hardware is in some "in between 4.0 and 4.1" state and might be generally incompatible. I do not have a Nexus 6 or 9 to try with.

Finally there is a concept of virtual MIDI devices. This of course is cool. It will allow apps to act as MIDI sources and destinations for other apps. It will also allow to extend the system. One could for example provide the wireless standards and de-facto standards that are missing from the API (but are the centerpiece of nmj) in form of a virtual MIDIDeviceService. Of course I had to try this and it looks promising. Here is another MidiDeviceInfo printout:

MidiDeviceInfo[mType=2,mInputPortCount=1,mOutputPortCount=1,mProperties=Bundle[{manufacturer=humatic,product=Midifi,service_info=ServiceInfo{b8a19d4 de.humatic.midifi.VirtualIO}}],mIsPrivate=false

This is from a simple test service that I created. Some manifest, xml and intent magic makes Android M's MidiManager aware of the service and the MIDI ports it has to offer. Other apps (or more correctly: one other app at a time) will then be able to open the ports and exchange MIDI via RTP or multicast over them. The good thing about this is that it can make nmj really easy to use for developers. The slightly worse thing is that it all runs in seperate processes and configuration etc. needs to be done via IPC. However, I think it's doable. I will put this up for download here once it is reasonably stable.

Anyway, to come to a conclusion: My first impression of the API is rather positive overall. It will need more ports and concurrent access to them to make everybody happy in the real world, but other than that I think it's heading into a good direction. There are some minor things that I did not like that much: The MidiDeviceStatus object is not that nicely designed in my eyes. Also the raw data makes me wonder why it always starts with a 1. It's not raw MIDI as claimed in the docs at least. And why it uses a 1024 byte array for all data exchange is a mystery to me. Odd choice.




  humatic

DirectShow and Windows are trademarks of Microsoft Inc.
Apple, Mac, Mac OS X and CoreMIDI are trademarks of Apple Computer Inc.
Java is a registered trademark of Oracle and/or its affiliates.
Android is a trademark of Google Inc.