ArthurVasseur / USB-Midi-Android-Plugin

A USB MIDI plugin for Android 6.0 and above
MIT License
9 stars 2 forks source link

Device string and question about USB data order #6

Closed trzy closed 1 year ago

trzy commented 1 year ago

Another small issue is that the device name returned seems to be the USB port name. Tomorrow or next week I was going to address this and extend the API to transmit the device name for each event, if that is ok?

But more importantly, it would be good to transmit the channel as well. However, I looked more closely at the code and am very confused now:

int CIN = receiveBuffer[i] & 0xf;
int byte2 = receiveBuffer[i + 2] & 0xff;
int byte3 = receiveBuffer[i + 3] & 0xff;

I didn't pay much attention during my last PR but what exactly is going on here? What happened to the second byte (i+1)? And why is CIN the low 4 bits instead of the high 4 bits? I see that it works but I don't understand why. Is there some transformation that the Android USB driver is making?

The command/status byte format should be: high 4 bits=command, low 4 bits=channel. I would expect CIN to be receiveBuffer[i]>>4. Then the channel would be receiveBuffer[i]&0xf.

Did some quick Googling but I don't see anything mentioned about this situation being different on Android.

ArthurVasseur commented 1 year ago

When using USB MIDI, each device that sends and receives MIDI messages should have a unique USB device ID. This ID can be obtained by using the Android USB Host API to enumerate the connected USB devices and find the device that matches the USB vendor ID and product ID of the USB MIDI device.

Once you have obtained the USB device ID of the device, you can use it to retrieve the device name by calling the UsbManager.getDeviceList() method to get a list of connected USB devices and then calling the UsbDevice.getDeviceName() (or maybe getProductName ?) method on the specific UsbDevice object that represents the USB MIDI device.

It would be better to pass the device ID instead of the device name for each events, and create a new utility function like that :

String getDeviceName(int deviceID) 
{
//code
}

For your question about CIN it's because the USB MIDI specification defines that the CIN must be transmitted over USB as part of a 4-byte packet, where the CIN is in the lowest 4 bits of the first byte. Therefore, the code needs to extract the CIN from the lower 4 bits of the first byte in order to correctly interpret the MIDI message received over USB. You can look at the documentation here on the section 4 USB-MIDI Event Packets page 16

trzy commented 1 year ago

Thank you! This is helpful. I'm going to look at this more closely during the week and I may make another PR. Having the channel number and the correct MIDI device name would be very useful.

ArthurVasseur commented 1 year ago

Okay !