Mistake on this page?
Report an issue in GitHub or email us

USBMIDI

USBMIDI class hierarchy

You can use the USBMIDI interface to send and receive MIDI messages over USB using the standard USB-MIDI protocol.

Examples of tasks you can perform using this library include sending MIDI messages to a computer (such as to record in a sequencer, or trigger a software synthesiser) and receiving messages from a computer (such as actuating things based on MIDI events).

USBMIDI class reference

Public Member Functions
 USBMIDI (bool connect_blocking=true, uint16_t vendor_id=0x0700, uint16_t product_id=0x0101, uint16_t product_release=0x0001)
 Basic constructor. More...
 USBMIDI (USBPhy *phy, uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
 Fully featured constructor. More...
virtual ~USBMIDI ()
 Destroy this object. More...
bool ready ()
 Check if this class is ready. More...
void wait_ready ()
 Block until this device is configured. More...
bool write (MIDIMessage m)
 Send a MIDIMessage. More...
bool readable ()
 Check if a message can be read. More...
bool read (MIDIMessage *m)
 Read a message. More...
void attach (mbed::Callback< void()> callback)
 Attach a callback for when a MIDIEvent is received. More...
void init ()
 Initialize this instance. More...
void deinit ()
 Power down this instance. More...
bool configured ()
 Check if the device is configured. More...
void connect ()
 Connect a device This method can also be used to resume USB operation when USB power is detected after it was suspended via USBDevice::deinit. More...
void disconnect ()
 Disconnect a device. More...
void sof_enable ()
 Enable the start of frame interrupt. More...
void sof_disable ()
 Disable the start of frame interrupt. More...
bool endpoint_add (usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type, mbed::Callback< void()> callback=nullptr)
 Add an endpoint. More...
template<typename T >
bool endpoint_add (usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type, void(T::*callback)())
 Add an endpoint. More...
void endpoint_remove (usb_ep_t endpoint)
 Remove an endpoint. More...
void endpoint_remove_all ()
 Remove all non-zero endpoints. More...
void endpoint_stall (usb_ep_t endpoint)
 Stall an endpoint. More...
void endpoint_unstall (usb_ep_t endpoint)
 Un-stall an endpoint. More...
uint32_t endpoint_max_packet_size (usb_ep_t endpoint)
 Get the current maximum size for this endpoint. More...
void endpoint_abort (usb_ep_t endpoint)
 Abort the current transfer on this endpoint. More...
bool read_start (usb_ep_t endpoint, uint8_t *buffer, uint32_t size)
 start a read on the given endpoint More...
uint32_t read_finish (usb_ep_t endpoint)
 Get the status of a read. More...
bool write_start (usb_ep_t endpoint, uint8_t *buffer, uint32_t size)
 Write a data to the given endpoint. More...
uint32_t write_finish (usb_ep_t endpoint)
 Get the status of a write. More...
Protected Member Functions
virtual void callback_state_change (DeviceState new_state)
 Called when USB changes state. More...
virtual void callback_request (const setup_packet_t *setup)
 Called by USBDevice on Endpoint0 request. More...
virtual void callback_request_xfer_done (const setup_packet_t *setup, bool aborted)
 Called by USBDevice on data stage completion. More...
virtual void callback_power (bool powered)
 Called by USBDevice layer on power state change. More...
virtual void callback_sof (int frame_number)
 Called by USBDevice layer on each new USB frame. More...
virtual void callback_reset ()
 Called by USBDevice layer on bus reset. More...
void complete_request (RequestResult result, uint8_t *data=NULL, uint32_t size=0)
 Called to complete the setup stage of a callback request. More...
void complete_request_xfer_done (bool success)
 Called to complete the data stage of a callback request. More...
void complete_set_configuration (bool success)
 Called to complete a set configuration command. More...
void complete_set_interface (bool success)
 Called to complete a set interface command. More...
uint8_t * find_descriptor (uint8_t descriptor_type, uint8_t index=0)
 Find a descriptor type inside the configuration descriptor. More...
const usb_ep_table_tendpoint_table ()
 Get the endpoint table of this device. More...
virtual void start_process ()
 Callback called to indicate the USB processing needs to be done. More...
virtual void lock ()
 Acquire exclusive access to this instance USBDevice. More...
virtual void unlock ()
 Release exclusive access to this instance USBDevice. More...
virtual void assert_locked ()
 Assert that the current thread of execution holds the lock. More...

The two examples below use a program called "Anvil Studio 32-bit" to play MIDI notes from an Mbed board through the host PC. You can play back the MIDI notes through headphones or speakers by following the steps below:

  1. Flash the board, and ensure the target's USB is plugged into the PC.
  2. Open Anvil Studio.
  3. Click View > Synthesizers, MIDI + Audio Devices.
  4. Uncheck Synth is too slow to echo incoming events.
  5. Click View > Composer (Staff Editor) to see notes from the board being mapped to the sheet music.

USBMIDI example

Below is an example to send a series of MIDI notes to the host PC:

/*
 * Copyright (c) 2006-2020 Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 */
#include "mbed.h"
#include "USBMIDI.h"

USBMIDI midi;

int main()
{
    while (1) {
        for (int i = 48; i < 83; i++) { // send some messages!
            midi.write(MIDIMessage::NoteOn(i));
            ThisThread::sleep_for(250);
            midi.write(MIDIMessage::NoteOff(i));
            ThisThread::sleep_for(500);
        }
    }
}

Play "Take Me Out to the Ball Game" example

You can use USBMIDI to play an entire song, not just a series of notes. "Take Me Out to the Ball Game" is a popular song in the public domain. To play "Take Me Out to the Ball Game" (public domain) using MIDI over USB on the host PC:

/*
 * Copyright (c) 2006-2020 Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 */
#include "mbed.h"
#include "USBMIDI.h"

#define REST -1
#define C  0
#define Cs 1
#define D  2
#define Ds 3
#define E  4
#define F  5
#define Fs 6
#define G  7
#define Gs 8
#define A  9
#define As 10
#define B  11

#define OCTAVE0  0
#define OCTAVE1  12
#define OCTAVE2  24
#define OCTAVE3  36
#define OCTAVE4  48
#define OCTAVE5  60
#define OCTAVE6  72
#define OCTAVE7  84

#define WHOLE_NOTE     1150
#define HALF_NOTE      (WHOLE_NOTE / 2)
#define QUARTER_NOTE   (WHOLE_NOTE / 4)
#define EIGHTH_NOTE    (WHOLE_NOTE / 8)
#define SIXTEENTH_NOTE (WHOLE_NOTE / 16)

#define THREE_EIGHTHS_NOTE   (EIGHTH_NOTE * 3)
#define THREE_FORTHS_NOTE   (QUARTER_NOTE * 3)

USBMIDI midi;

void PlayNote(int note, int octave, uint32_t duration)
{
    if (note == REST) {
        ThisThread::sleep_for(duration);
    } else {
        midi.write(MIDIMessage::NoteOn(note + octave));
        ThisThread::sleep_for(duration);
        midi.write(MIDIMessage::NoteOff(note + octave));
    }
}

void TakeMeOutToTheBallGame()
{
    //https://www.bethsnotesplus.com/2012/09/take-me-out-to-ball-game.html
    PlayNote(C, OCTAVE5, HALF_NOTE);
    PlayNote(C, OCTAVE6, QUARTER_NOTE);

    PlayNote(A, OCTAVE5, QUARTER_NOTE);
    PlayNote(G, OCTAVE5, QUARTER_NOTE);
    PlayNote(E, OCTAVE5, QUARTER_NOTE);

    PlayNote(G, OCTAVE5, THREE_FORTHS_NOTE);

    PlayNote(D, OCTAVE5, THREE_FORTHS_NOTE);

    PlayNote(C, OCTAVE5, HALF_NOTE);
    PlayNote(C, OCTAVE6, QUARTER_NOTE);

    PlayNote(A, OCTAVE5, QUARTER_NOTE);
    PlayNote(G, OCTAVE5, QUARTER_NOTE);
    PlayNote(E, OCTAVE5, QUARTER_NOTE);

    PlayNote(G, OCTAVE5, THREE_FORTHS_NOTE);

    PlayNote(G, OCTAVE5, HALF_NOTE);
    PlayNote(REST, 0, QUARTER_NOTE);

    PlayNote(A, OCTAVE5, QUARTER_NOTE);
    PlayNote(Gs, OCTAVE5, QUARTER_NOTE);
    PlayNote(A, OCTAVE5, QUARTER_NOTE);

    PlayNote(E, OCTAVE5, QUARTER_NOTE);
    PlayNote(F, OCTAVE5, QUARTER_NOTE);
    PlayNote(G, OCTAVE5, QUARTER_NOTE);

    PlayNote(A, OCTAVE5, HALF_NOTE);
    PlayNote(F, OCTAVE5, QUARTER_NOTE);

    PlayNote(D, OCTAVE5, THREE_FORTHS_NOTE);

    PlayNote(A, OCTAVE5, HALF_NOTE);
    PlayNote(A, OCTAVE5, QUARTER_NOTE);

    PlayNote(A, OCTAVE5, QUARTER_NOTE);
    PlayNote(B, OCTAVE5, QUARTER_NOTE);
    PlayNote(C, OCTAVE6, QUARTER_NOTE);

    PlayNote(D, OCTAVE6, QUARTER_NOTE);
    PlayNote(B, OCTAVE5, QUARTER_NOTE);
    PlayNote(A, OCTAVE5, QUARTER_NOTE);

    PlayNote(G, OCTAVE5, QUARTER_NOTE);
    PlayNote(E, OCTAVE5, QUARTER_NOTE);
    PlayNote(D, OCTAVE5, QUARTER_NOTE);

    PlayNote(C, OCTAVE5, HALF_NOTE);
    PlayNote(C, OCTAVE6, QUARTER_NOTE);

    PlayNote(A, OCTAVE5, QUARTER_NOTE);
    PlayNote(G, OCTAVE5, QUARTER_NOTE);
    PlayNote(E, OCTAVE5, QUARTER_NOTE);

    PlayNote(G, OCTAVE5, THREE_FORTHS_NOTE);

    PlayNote(D, OCTAVE5, HALF_NOTE);
    PlayNote(D, OCTAVE5, QUARTER_NOTE);

    PlayNote(C, OCTAVE5, HALF_NOTE);
    PlayNote(D, OCTAVE5, QUARTER_NOTE);

    PlayNote(E, OCTAVE5, QUARTER_NOTE);
    PlayNote(F, OCTAVE5, QUARTER_NOTE);
    PlayNote(G, OCTAVE5, QUARTER_NOTE);

    PlayNote(A, OCTAVE5, THREE_FORTHS_NOTE);

    PlayNote(A, OCTAVE5, QUARTER_NOTE);
    PlayNote(A, OCTAVE5, QUARTER_NOTE);
    PlayNote(B, OCTAVE5, QUARTER_NOTE);

    PlayNote(C, OCTAVE6, THREE_FORTHS_NOTE);

    PlayNote(C, OCTAVE6, THREE_FORTHS_NOTE);

    PlayNote(C, OCTAVE6, QUARTER_NOTE);
    PlayNote(B, OCTAVE5, QUARTER_NOTE);
    PlayNote(A, OCTAVE5, QUARTER_NOTE);

    PlayNote(G, OCTAVE5, QUARTER_NOTE);
    PlayNote(Fs, OCTAVE5, QUARTER_NOTE);
    PlayNote(G, OCTAVE5, QUARTER_NOTE);

    PlayNote(A, OCTAVE5, THREE_FORTHS_NOTE);

    PlayNote(B, OCTAVE5, THREE_FORTHS_NOTE);

    PlayNote(C, OCTAVE6, THREE_FORTHS_NOTE);

    PlayNote(C, OCTAVE6, HALF_NOTE);
    PlayNote(REST, 0, QUARTER_NOTE);
}

int main()
{
    while (1) {
        TakeMeOutToTheBallGame();
    }
}

Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.