Android USB MIDI Driver

repository·develop·Indexed 43 days ago

https://github.com/kshoji/usb-midi-driver

An Android library that enables USB MIDI connectivity using the Android USB Host API, allowing developers to interface with MIDI instruments and sequencers without root access. It provides a javax.sound.midi compatible API, supports multiple simultaneous device connections, and works with Android OS version 3.1 (API Level 12) or higher.

Tokens
2.4K
Snippets
3
Records
10
Agent score
54%

What's inside usb-midi-driver

  1. Overview of Android USB MIDI Driver

    develop

    The Android USB MIDI Driver is a library that uses the Android USB Host API to connect USB MIDI devices (such as sequencers or instruments) to an Android device without requiring root privileges. It supports multiple device connections and provides classes compatible with javax.sound.midi.

    Key Features:

    • No root privilege required.
    • Supports standard USB MIDI devices.
    • Supports non-standard USB MIDI devices (check device_filter.xml for supported makers like YAMAHA, Roland, or MOTU).
    • Supports multiple simultaneous device connections.
    • javax.sound.midi compatible API.
  2. Understand the 'cable' parameter in MIDI methods

    develop
    In the onMidi... and sendMidi... methods, the cable parameter refers to the virtual MIDI cables supported by a single USB MIDI device. This is used to extend the number of available MIDI channels. The cable index can range from 0 to 15.
  3. Understand the 'cable' argument in MIDI methods

    develop

    When calling methods such as onMidi... or sendMidi..., you will encounter a cable argument.

    A single USB MIDI endpoint can have multiple "virtual MIDI cables" used to increase the number of available MIDI channels. The valid range for the cable number is 0 to 15.

  4. Set up the MIDIDriver library in your Android project

    develop

    To use the MIDIDriver library in your Android application, follow these steps:

    1. Clone the repository.
    2. Import the MIDIDriver library project into your IDE (e.g., Eclipse or Android Studio) and build it.
    3. Create a new Android project and add the MIDIDriver project as a library dependency.
    4. Configure your AndroidManifest.xml to include the USB host feature and set the launchMode of your MIDI activity to singleTask.

    Important: The launchMode must be singleTask to ensure the activity handles USB connection intents correctly.

    <uses-feature android:name="android.hardware.usb.host" /> 
    
    <application>
        <activity
            android:name=".MyMidiMainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTask" >
            <intent-filter>
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>
    </application>
  5. Implement MIDI event handling with AbstractSingleMidiActivity

    develop

    Use AbstractSingleMidiActivity when your application only needs to connect to one MIDI device at a time.

    Receiving MIDI Events

    Implement the corresponding onMidi... methods (e.g., onMidiNoteOn).

    Warning: These methods are called from a background thread, not the UI thread. To update your UI, you must use a Handler and Callback to communicate with the UI thread.

    Sending MIDI Events

    1. Call getMidiOutputDevices() to get an instance of MIDIOutputDevice.
    2. If no device is connected, getMidiOutputDevices() returns null.
    3. Call the sendMidi... method on the returned instance to transmit MIDI data.
    public class SampleActivity extends AbstractSingleMidiActivity {
    
        // This field belongs to the UI thread
        final Handler uiThreadEventHandler = new Handler(new Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                if ("note on".equals(msg.obj)) {
                    textView.setText("note on event received.");
                }
                return true;
            }
        });
    
        // This method is called from a background thread
        @Override
        public void onMidiNoteOn(final MidiInputDevice sender, int cable, int channel, int note, int velocity) {
            // Send a message to the UI thread to update views
            String message = "note on";
            uiThreadEventHandler.sendMessage(Message.obtain(uiThreadEventHandler, 0, message));
        }
    }
  6. Implement MIDI event handling with AbstractMultipleMidiActivity

    develop

    Use AbstractMultipleMidiActivity when your application needs to connect to multiple MIDI devices simultaneously.

    Note: Connecting many devices may impact performance, potentially increasing latency or CPU usage.

    Receiving MIDI Events

    Implement the onMidi... methods. Unlike the single-device version, the first argument provided to these methods is the MIDIInputDevice instance that sent the event, allowing you to identify the source.

    Sending MIDI Events

    1. Call getMidiOutputDevices() (inherited from AbstractMidiActivity) to obtain a Set<MIDIOutputDevice>.
    2. Select the desired MIDIOutputDevice from the set.
    3. Call the sendMidi... method on that instance to transmit MIDI data.
  7. Requirements for using the USB MIDI Driver

    develop

    To use this driver, your environment must meet the following criteria:

    Software Requirements:

    • Android OS: Version 3.1 (API Level 12) or higher.
    • Hardware: An Android device with a USB host port.
    • Kernel Support: The Android Linux kernel must support USB MIDI devices. Note that some devices may only recognize USB-HID and USB-MSD due to kernel configurations.

    Hardware Requirements:

    • A USB MIDI (or compatible) device.

    Optional Hardware for specific use cases:

    • Self-powered USB hub: Required if you want to connect multiple USB MIDI devices.
    • USB OTG cable: Required if your Android device lacks a standard USB-A port.
    • USB MIDI <--> Legacy MIDI (MIDI 1.0) converter cable: Required to connect legacy MIDI instruments.
  8. Configure device_filter.xml for custom USB MIDI devices

    develop

    If your device is detected by the Android host but not by the driver, you may need to manually add its VendorId to the project's device_filter.xml file.

    Steps to modify the filter:

    1. Clone the repository and open the library project in your IDE.
    2. Open res/xml/device_filter.xml.
    3. Add a new <usb-device /> entry using the VendorId you identified during troubleshooting.

    CRITICAL: Conversion Requirement The VendorId displayed in USB diagnostic tools is typically in Hexadecimal, but the device_filter.xml file requires the value in Decimal.

    Testing the modification:

    1. Uninstall the existing sample application from your Android device.
    2. Build and run your modified version of the sample app.
    3. Launch the app, then connect the USB MIDI device.
    4. Verify detection in the app and test MIDI message bidirectional transfer (sending and receiving).
    <!-- Example of adding a device to res/xml/device_filter.xml -->
    <!-- If your Hex VendorId is 0x0483, use decimal 1155 -->
    <usb-device vendor-id="1155" />
  9. Troubleshoot USB MIDI device detection

    develop

    If the sample application cannot detect your USB MIDI device, follow these diagnostic steps to identify if the issue is with Android connectivity, device standards, or driver configuration.

    1. Verify Android Host Connectivity

    Use the USB Device Info app to ensure the Android host sees the hardware:

    • Open the app and select the Android tab (do not use the Linux tab).
    • Tap Refresh, connect your USB MIDI device, and tap Refresh again.
    • If the device information does not appear, the Android host is not detecting the hardware at all.

    2. Verify USB Interface Class

    In the USB Device Info app, check the Interface section. A standard USB MIDI device must have one or more interfaces with the following class:

    • Audio Device (0x1)

    If the device only shows other classes (like CDC or HID), it is not a standard USB MIDI device. The driver may still work if the device uses a USB MIDI compatible protocol.

    3. Verify USB Endpoints

    Check the Endpoint information in the USB Device Info app. A compatible device must have one or more endpoints that meet these criteria:

    • Type: Must be Bulk or Interrupt.
    • Direction: Must be Inbound, Outbound, or both.

    If these conditions are met, note the device's VendorId for the next step.

  10. Reference of supported MIDI events

    develop

    The library supports various MIDI message types via specific method suffixes. Note that some low-frequency messages are not extensively tested.

    Method SuffixMeaningExtensively Tested?
    MidiSystemExclusiveSysExYES
    MidiNoteOffNote OffYES
    MidiNoteOnNote OnYES
    MidiControlChangeControl ChangeYES
    MidiProgramChangeProgram ChangeYES
    MidiPitchWheelPitch BendYES
    MidiMiscellaneousFunctionCodesMiscellaneousNO
    MidiCableEventsCable EventsNO
    MidiSystemCommonMessageSystem Common / 1-byte SysExNO
    MidiPolyphonicAftertouchPolyphonic AftertouchNO
    MidiChannelAftertouchChannel AftertouchNO
    MidiSingleByte1-byte MessageNO