I have a working android app which uses a proprietary java midi implementation to talk to a non-compliant midi device over USB. I now want to move to the standard android midi USB stack but can’t determine how to add/extend the necessary tests to allow the non-compliant device to be detected as a midi device.
The non-compliant device does not present an “Audio Device” type USB interface - which is required in order to be midi class compliant - but rather a number of “Vendor Specific” interfaces, which represent the midi ports. Because of this, the android midi stack (eg using the sample MidiScope) does not see the device.
The current, proprietary stack, on USB device connect, uses a priori knowledge of the specific vendor connection details to determine that the connection is indeed a midi device, and then creates midi device connection events using the correct USB interfaces.
I want to reproduce this connection logic, but using android’s midi stack, but can’t find where incoming USB connection is determined to be a midi device, and thus passed to the android midi service. I have examined the android source for UsbDeviceManager, UsbHostManager, UsbService, MidiService, MidiManager, MidiDeviceInfo, MidiDeviceService etc but can’t not see where this ‘midi device validation/filtering” occurs.
If anyone can point me in the right direction as to how I can achieve my goal I would be very grateful.
Android's UsbAlsaManager.java just uses the Linux MIDI devices.
So to be able to access your device in Android, you have to add support to the Linux USB MIDI driver, and then wait until the new kernel version shows up on your Android device.
Related
Atm I use the kshoji USB-MIDI-Driver to send MIDI data to a USB MIDI device. But I can not send MIDI data to another app on the same device. I'm looking for a Android solution similar to virtual MIDI ports on Linux, iOS/OS x or the Windows loopBe1 driver.
Is it possible to write my data directly to the Input of a connected MIDI interface and other apps read this? (Not the best solution, because the user will need at least one hardware MIDI device).
Or is it possible to create an virtual USB driver and register it as MIDI device?
Or any other solution?
This USB MIDI driver talks directly to the USB controller.
Connecting multiple apps together would be possible only if the OS had some "MIDI port" abstraction (Android has not), or if all the apps are designed to work together with some other mechanism.
I'm trying to get all the audio from my phone to go through my computer speakers via connecting through USB. Does anyone know how to achieve it? I'm trying to write some codes to let my pc being recognized as a dock for my galaxy s2 cell phone.
Thank you
There's no standard way of doing that, unless a given vendor has implemented it as a custom extension.
It's actually going to be easier to do some stream-over-wifi mechanism than to do it over the USB cable, unless you leverage the SDK's adb tool or a USB-tethering capability to get a network connection via the cable.
But a key problem that you will face is that 3rd party android apps on non-rooted devices cannot get permission to intercept audio coming from other unrelated applications.
Silly as it sounds, if you want your pc to be a "dock" for arbitrary application audio, you'll probably need a 3.5mm analog stereo patch cord. Or there might be a few PC bluetooth adapters which can be hacked to look like stereo headsets to the phone.
If you are content to play songs chosen by special software, I'm sure you can find a wifi streamer applications on the market or make your own; or you can access the files on the device from the PC using usb mass storage or MTP (depending on Android version) and play them in a PC-based player.
EDIT Guess what just got announced at Google IO 2012
http://developer.android.com/tools/adk/adk2.html#audio-dock
USB Audio Dock Implementation One of the important new features
introduced with the ADK 2012 is the ability to play audio over a USB
connection. This innovation was introduced as an update to Android
Open Accessory (AOA) protocol 2.0 and is available on devices running
Android 4.1 (API Level 16) and higher.
The ADK 2012 provides a reference implementation of this functionality
for accessory developers. No software application is required to be
installed on the connected Android device, accessory developers only
need to support AOA v2.
The assumption there is that the USB host would be a small embedded board, but I don't see why you couldn't get a PC to do that end of the task, at least if you manage to get any existing drivers installed on the PC out of the way.
Of course the downside is that you need an Android 4.1 or greater device... not many phones like that out. But if you go with the rooting method, you could try to create a compatible or at least similar interface.
I would like to make an app on android which sends MIDI messages over USB to a computer to be able to control music softwares such as Cubase, FL, Reason, ect...
Hardware MIDI controllers (e.g Keyboards) are automatically recognized in music software on Windows. I guess it's because they use the universal MIDI protocol which is directly recognized by the music software. They don't need their own driver.
I'd like to be able to use my phone/tablet as a midi controller without having to install staff on the computer (like with hardware controllers).
There's a Demo Code on Android Developers to control a Missile Launcher toy through USB. If I send, using the same technique, messages that follow the MIDI protocol will it work just like that ?
Thank you in advance for your help
With Android 6.0 (API 23) this is now possible - Android devices can act as class compliant (no drivers required) MIDI devices.
To switch into USB-MIDI mode users can swipe down from the top of the screen to access the USB mode selection screen (below).
An app can send MIDI messages using the new MIDI API. Here's some code to send a MIDI NoteOn message:
byte[] buffer = new buffer[3];
buffer[0] = (byte)0x90 + (byte)0x01; // Note On - Channel 1
buffer[1] = (byte)0x3C; // pitch (Note C3)
buffer[2] = (byte)127; // velocity
int offset = 0;
inputPort.send(buffer, offset, numBytes);
To send other message types consult the MIDI message specification. Note that bytes are signed in Java so this post might be helpful.
I wrote the USB MIDI Driver for Android.
Useful to build your own MIDI controller / receiver.
https://github.com/kshoji/USB-MIDI-Driver
The another midi driver is 'nmj' library.
This library also supports USB MIDI. Moreover, it supports some network-MIDI protocols, MIDI over bluetooth and MIDI over ADB(debug connection).
http://www.humatic.de/htools/nmj/
No, it doesn't work remotely like that.
USB MIDI devices do use a driver... it's just that they are generally "class compliant", and can all use the same stock driver that comes with the OS.
To do what you are proposing, you will need to emulate a device over USB... complete with the appropriate PnP IDs and what not. This is next to impossible. The code you found was for using USB in host mode, not the other way around.
You will find that it is far easier to send MIDI via network, and use one of the many network MIDI drivers available.
What classes are available for Android platform to communicate (in/out) with external MIDI device? I have HTC Desire smartphone, it has USB port, I'd assume it is possible to connect it to a MIDI synthesizer, using standard USB cable + [Type A -> Mini A] converter. I'd like to write a MIDI sequencer app that would be able to record MIDI stream from the synthesizer and then play it back later.
Short answer: None. Slightly longer answer: On the HTC Desire there is no built-in support for USB host mode (which you need, since the usb-midi adapter would be the USB client).
(Android 3.1 does have some support for USB Host mode, but that's not available for the HTC Desire)
If you're not afraid of a soldering iron, you could go the midi-over-bluetooth route: http://nettoyeur.noisepages.com/2011/01/midi-over-bluetooth-part-iii-new-hardware/
Much has changed on this front. The following library allows for MIDI i/o with a USB OTG adapter on API 12+:
https://github.com/kshoji/USB-MIDI-Driver
It's far from perfect, and in my testing, pretty crashy, but it should at least be a good starting point for someone looking for the relevant classes.
As #edovino said, you need USB host mode, and then drivers.
If you don't mind rooting around your phone, and the hardware supports it, you do have some options. Check out this link: http://sven.killig.de/android/N1/2.2/usb_host/
This guy was able to get audio, video, keyboard, and some other stuff working. He includes audio/MIDI drivers.
Yes, as pointed above, it is not feasible using the phone because it does not provide USB-host capability. I have been working religiously over the past few months to make an XY-controller for my synthesizer so that I can transmit controller values to use for performances. I reckon, that is what you want to do with additional functionality.
Bluetooth is definitely an option and if you look up for libpd, Peter Brinkmann himself has addressed this issue and acknowledged that Bluetooth dongles for MIDI are not far away.
WiFi is also something one may be willing to look at. Using rtpMIDI, we can create sessions on the PC side of things and use just about any WiFI enabled MIDI device to transmit/receive data. IF you are looking to control software synthesizers using a phone, this seems ideal. TouchDAW and TouchOSC, applications on android, make use of this feature.
With the USB-Android driver, the only problem I see is no support for isochronous transfers using USB host. So, we cannot guarantee latency deterministic. But, considering no other bus accessories attached, the performance seems pretty decent in my tests.
I am completely new to bluetooth app development. what exactly is a bluetooth profile? is it a hardware specification for the device? can an android mobile phone with bluetooth act as sender and receiver in A2DP profile?
A bluetooth profile is a specification on the protocol and functionality of a bluetooth device. It is not just a hardware specification, because implementing a profile will often depend on both the software stack and the hardware chip. You can find more information from the wikipedia page.
And in the case of A2DP, it is specifically designed for music streaming. It cannot be used for arbitrary data communication (if that's what you mean by "sender and receiver"). If you are looking for a generic data communication mechanism over bluetooth transport, the Serial Port Profile (SPP) is what you need (some people also call it RFCOMM). Android SDK user guide has quite detailed information on how to use RFCOMM API: http://developer.android.com/guide/topics/wireless/bluetooth.html
There are two A2DP profiles: A2DP source (the device that sends audio) and A2DP Sink (the device that receives and plays the audio) like a Bluetooth headset.
Your phone hardware supports both profiles, but A2DP Sink isn't implemented in Android so you cant just write an app to use it. You need to modify Android source code and build your own ROM.
If you want to do so you need a device with an available source code (a Nexus or a device supported by CyanogenMod).
If you use Android 5 or up it wont be very hard to enable the A2DP Sink as it's already included in the source but disabled.
If you use Android 4.2 -4.4 you need to port the A2DP Sink classes from Android 5.
As for Android prior to 4.2 things are different as they used a different Bluetooth stack called BlueZ (now they use Bluedroid) you can activate A2DP Sink by rooting your device and editing "audio.conf" file but unfortunately even though your phone will be advertising itself as a A2DP Sink you will hear no sound as it's not routed to speakers and to route it you will have to build a modified ROM.
Building a ROM might seem complicated but it is not, specially if you're using Android 5 or up as, like i said before, the SINK profile is already there all you need to do is type 6 lines in the terminal (you need a Linux OS) and edit 3 lines of code to enable the A2SP Sink and build your own ROM.
If you are interested in this I can give more details.