1 changed files with 145 additions and 0 deletions
@ -0,0 +1,145 @@ |
|||||
|
/** Example of setting reading MIDI Input via USB Host
|
||||
|
* |
||||
|
* |
||||
|
* This requires a USB-A connector |
||||
|
* |
||||
|
* This example will also log incoming messages to the serial port for general MIDI troubleshooting |
||||
|
*/ |
||||
|
#include "daisy_seed.h" |
||||
|
#include "usbh_midi.h" |
||||
|
|
||||
|
/** This prevents us from having to type "daisy::" in front of a lot of things. */ |
||||
|
using namespace daisy; |
||||
|
|
||||
|
/** Global Hardware access */ |
||||
|
DaisySeed hw; |
||||
|
MidiUsbHandler midi; |
||||
|
USBHostHandle usbHost; |
||||
|
|
||||
|
/** FIFO to hold messages as we're ready to print them */ |
||||
|
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) |
||||
|
{ |
||||
|
/** Initialize our hardware */ |
||||
|
hw.Init(); |
||||
|
|
||||
|
hw.StartLog(true); |
||||
|
|
||||
|
hw.PrintLine("MIDI USB Host start"); |
||||
|
|
||||
|
/** Configure USB host */ |
||||
|
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"); |
||||
|
|
||||
|
/** Infinite Loop */ |
||||
|
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; |
||||
|
} |
||||
|
/** Run USB host process */ |
||||
|
usbHost.Process(); |
||||
|
|
||||
|
if(usbHost.IsActiveClass(USBH_MIDI_CLASS) && midi.RxActive()) |
||||
|
{ |
||||
|
/** Process MIDI in the background */ |
||||
|
midi.Listen(); |
||||
|
|
||||
|
/** Loop through any MIDI Events */ |
||||
|
while(midi.HasEvents()) |
||||
|
{ |
||||
|
MidiEvent msg = midi.PopEvent(); |
||||
|
|
||||
|
/** Handle messages as they come in
|
||||
|
* See DaisyExamples for some examples of this |
||||
|
*/ |
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
/** Regardless of message, let's add the message data to our queue to output */ |
||||
|
event_log.PushBack(msg); |
||||
|
} |
||||
|
|
||||
|
/** Now separately, every 5ms we'll print the top message in our queue if there is one */ |
||||
|
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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue