Skip to content

File MIDI_USBH_Input.cpp

File List > examples > MIDI_USBH_Input > MIDI_USBH_Input.cpp

Go to the documentation of this file

Source Code

#include "daisy_seed.h"
#include "usbh_midi.h"

using namespace daisy;

DaisySeed       hw;
MidiUsbHandler midi;
USBHostHandle usbHost;

FIFO<MidiEvent, 128> event_log;

void USBH_Connect(void* data)
{
    hw.PrintLine("device connected");
}

void USBH_Disconnect(void* data)
{
    hw.PrintLine("device disconnected");
}

void USBH_ClassActive(void* data)
{
    if(usbHost.IsActiveClass(USBH_MIDI_CLASS))
    {
        hw.PrintLine("MIDI device class active");
        MidiUsbHandler::Config midi_config;
        midi_config.transport_config.periph = MidiUsbTransport::Config::Periph::HOST;
        midi.Init(midi_config);
        midi.StartReceive();
    }
}

void USBH_Error(void* data)
{
    hw.PrintLine("USB device error");
}

int main(void)
{
    hw.Init();

    hw.StartLog(true);

    hw.PrintLine("MIDI USB Host start");

    USBHostHandle::Config usbhConfig;
    usbhConfig.connect_callback = USBH_Connect,
    usbhConfig.disconnect_callback = USBH_Disconnect,
    usbhConfig.class_active_callback = USBH_ClassActive,
    usbhConfig.error_callback = USBH_Error,
    usbHost.Init(usbhConfig);

    usbHost.RegisterClass(USBH_MIDI_CLASS);

    uint32_t now      = System::GetNow();
    uint32_t log_time = System::GetNow();
    uint32_t blink_time = 0;
    bool ledState = false;

    hw.PrintLine("MIDI USB Host initialized");

    while(1)
    {
        now = System::GetNow();

        if (now > blink_time)
        {
            hw.SetLed(ledState);
            ledState = !ledState;
            if (usbHost.GetPresent())
                blink_time = now + 400;
            else
                blink_time = now + 80;
        }
        usbHost.Process();

        if(usbHost.IsActiveClass(USBH_MIDI_CLASS) && midi.RxActive())
        {
            midi.Listen();

            while(midi.HasEvents())
            {
                MidiEvent msg = midi.PopEvent();

                switch(msg.type)
                {
                    case NoteOn:
                        // Do something on Note On events
                        {
                            uint8_t bytes[3] = {0x90, 0x00, 0x00};
                            bytes[1] = msg.data[0];
                            bytes[2] = msg.data[1];
                            midi.SendMessage(bytes, 3);
                        }
                        break;
                    default: break;
                }

                event_log.PushBack(msg);
            }

            if(now - log_time > 5)
            {
                log_time = now;
                if(!event_log.IsEmpty())
                {
                    auto msg = event_log.PopFront();
                    char outstr[128];
                    const char* type_str = MidiEvent::GetTypeAsString(msg);
                    sprintf(outstr,
                            "time:\t%ld\ttype: %s\tChannel:  %d\tData MSB: "
                            "%d\tData LSB: %d\n",
                            now,
                            type_str,
                            msg.channel,
                            msg.data[0],
                            msg.data[1]);
                    hw.PrintLine(outstr);
                }
            }
        }
    }
}