Android Example Midi USB device manager

stevel05

Expert
Licensed User
The attached project shows the use of the USB library to communicate with Midi Devices over USB. I realize that this may open a can of worms, as it seems nothing about Midi communication is straightforward.

So if there are issues and questions, perhaps we can learn together on this one.

There are two main classes, MidiUSBManager and MidiInClass, the MidiUSBManager deals with the USB connectivity side and holds the USB objects and methods required for the communication. The MidiInClass is basically just a thread that captures incoming mididata and parses it according to the message received (Sysex is ignored).

Midi thru is implemented in the MidiInClass by sending the received messages directly to the USB OutEndpoint, basically a repeater. There are also three buttons which pass Kick Drum, Snare and Hi-Hat, midi data directly to the attached device.

As my main sound device is a Yamaha MU10, I had to implement an XG mode switch to get Drum sounds to play on channel 10.

I have tried it on a couple of interfaces, both of which seem to work OK.

You will need to be aware that midi for USB has it's own standard for communications, which is basically 4 byte packets. Details of which can be found here: http://www.usb.org/developers/devclass_docs/midi10.pdf . If you need information on Midi data structures good places to look are here: http://www.sonicspot.com/guide/midifiles.html

or here: http://www.somascape.org/midi/tech/mfile.html which is a bit more complete.

If you start the application with a usb Midi device already plugged in you will need to press the Connect button. If you plug the device in while the app is running it will automatically connect. It would be straightforward to do a scan when the app starts to see if a device is available if you want to.

If this brings up any questions, which I'm sure it will, please ask them here and I will try to find the answers.

Minimum API is 12 and the device needs to have an OTG USB port. And you obviously need a USB midi cable or device.

The demo requires: Broadcast Receiver Library V2 from Thomas (xverhelstx), which although not strictly necessary, it is nice to know when a device has been disconnected.

Also required: JavaObject, RandomAccessFile, Thread and USB libraries.

It was developed on V3.5 of B4a, but I don't think it uses anything that would preclude it running on older versions.

Please post here and let me know how it works for you.
 

Attachments

Last edited:

stevel05

Expert
Licensed User
Hmmm, I'm not quite sure how I managed that:oops:
 

stevel05

Expert
Licensed User
Updated in first post, the code for sendsysex has been changed to fix a bug.
 

PaulR

Active Member
Licensed User
Interesting, thanks for sharing - I develop/tinker around with the odd VST MIDI plugin myself. I'll give this a once over in the next couple of days, although I'm all virtual so it'll just be the input side I can test....
 

3394509365

Active Member
Licensed User
hello, I'm very interested in your midi example,
I did something similar in VB6 is working perfectly sending messages on three keyboards at the same time including a Yamaha MO6, But with Android I can not even start in the sense that I can not even see the device connected.

Let me explain: I have the OTG cable I have a tablet that supports the 'OTG since I have the 4.2.2 and 3.2 versiobe basic4android your example I can not use but I do not even work the examples simple MIDI.

My SDK is 19. whether I connect the tablet to midi through a program such as ones already packed to see the midi messages or "CAUSTIC" everything works.

What could be the problem? why do not I talk?
 

stevel05

Expert
Licensed User
Are you trying to run the example as it is? If you run the example and plug in your midi device, do you see a message box asking which package to use? and is the example on the list( it should be - USB Midi Test)?
 

3394509365

Active Member
Licensed User
no, my problem is that it is never found a device.
Yesterday I reinstalled the 'sdk that maybe there first' was the platform tool loaded fine.

It could be the cause?
 

stevel05

Expert
Licensed User
So are you saying that it doesn't work with any android app ?
 

stevel05

Expert
Licensed User
OK, try running the example code as it was downloaded with the USB device unplugged, then plug in the USB device. Does 'USB Midi Test' appear in the app chooser that should be displayed?
 

stevel05

Expert
Licensed User
How do you select an existing android app to connect the USB device to?
 

3394509365

Active Member
Licensed User
Now I'm trying to see if it is a problem that maybe ADB drivers missing on my tablet. I do some test and then tell you.

thanks
 

3394509365

Active Member
Licensed User
Good evening, your MIDITESTER3 B4 is developed with version 3.80 but I have version 3.20, you do not have a version compatible with my version?
 

stevel05

Expert
Licensed User
I usually only program on the latest versions, so many improvements. I made the one I just posted for you as I still have 3.2 on my PC (not for long though). Try that and see how it goes.
 

3394509365

Active Member
Licensed User
ok it works, I saw that you preset sounds and that these es 26 28 and 28 are different sounds,
btnKick.Tag = Array As Byte (0x09, 0x99, 0x26, 0x64)
btnSnare.Tag = Array As Byte (0x09, 0x99, 0x28, 0x64)
btnHiHat.Tag = Array As Byte (0x09, 0x99, 0x2B, 0x64)

I have to do in ways that I can send through a button on a channel other than a bank of suonno I choose from time to time.

Help me understand how you composed the 'array (0x09, 0x99, 0x26, 0x64) which is the channel?

and the programmchange owe Mettee instead of 0x99?

I hope I was clear hello

thanks
 

stevel05

Expert
Licensed User
As I said in the first post, USB spec requires a slightly different format from the standard Midi, called USB-Midi Event Packets, it's explained in here : http://www.usb.org/developers/devclass_docs/midi10.pdf page 16.

If you don't know the standard midi spec, I suggest you read one or both of the other two documents I provided links for. But to answer your specific question, the channel is the Least Significant Nibble of the second byte. so in 0x99, the first 9 defines it as a note on message, and the second 9 is the channel (confusingly midi channel 10 as they need to be programmed as 0 - 15).

To send a program change requires a different midi message, you'll need to look at the USB-Midi spec and one of the Midi spec documents to work it out, but it would be

B4X:
Array as Byte(0x0C,0XCc,0xhh,0x0)
Where 0x0C is the USB-Midi header byte, OxCc, is the programchange message (0xC) and channel number (c is the channel number 0 - 15), hh is the program number (0 - 127) and the last 0x0 is a requirement of the USB-Midi Event Packed to pad the data to 32 bits with zero's.
 
Last edited:

3394509365

Active Member
Licensed User
is perfect, it works, but because it does not work for me? I want to send two messages with the same button one for the right hand channel 1 and channel 2 for the left hand

How do you work if you did use 2 different buttons, but I would do it with a single button and send two different messages

sub ButtonSendMessage_Click
'Check USB is initialized
If Not (MidiUSBMan.USBAvailable) Then
ToastMessageShow ("Midi Device not found / enabled", False)
Return
end If


Dim MidiMsg (4) As Byte
Dim MidiMsg2 (4) As Byte
'MidiMsgxx () = 0x0B, 0xC0, 0x25, 0x0 ????
MidiMsg () = 0x0C, 0xC0, 0x25, 0x0

MidiMsg2 () = 0x0C, 0xC1, 0x25, 0x0

MidiUSBMan.Connection.BulkTransfer (MidiUSBMan.OutEndPoint, MidiMsg, MidiMsg.Length, 0)
MidiUSBMan.Connection.BulkTransfer (MidiUSBMan.OutEndPoint, MidiMsg2, MidiMsg2.Length, 0)


end Sub


then before sending the program change 0xC a moment before I send control change 0xB?
 
Last edited:
Top