|
|
@@ -30,6 +30,12 @@
|
|
|
#include "bsp/board.h"
|
|
|
#include "tusb.h"
|
|
|
|
|
|
+/* This MIDI example send sequence of note (on/off) repeatedly. To test on PC, you need to install
|
|
|
+ * synth software and midi connection management software. On
|
|
|
+ * - Linux (Ubuntu) : install qsynth, qjackctl. Then connect TinyUSB output port to FLUID Synth input port
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
//--------------------------------------------------------------------+
|
|
|
// MACRO CONSTANT TYPEDEF PROTYPES
|
|
|
//--------------------------------------------------------------------+
|
|
|
@@ -48,6 +54,7 @@ enum {
|
|
|
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
|
|
|
|
|
void led_blinking_task(void);
|
|
|
+void midi_task(void);
|
|
|
|
|
|
/*------------- MAIN -------------*/
|
|
|
int main(void)
|
|
|
@@ -62,6 +69,8 @@ int main(void)
|
|
|
tud_task();
|
|
|
|
|
|
led_blinking_task();
|
|
|
+
|
|
|
+ midi_task();
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
@@ -98,6 +107,49 @@ void tud_resume_cb(void)
|
|
|
blink_interval_ms = BLINK_MOUNTED;
|
|
|
}
|
|
|
|
|
|
+//--------------------------------------------------------------------+
|
|
|
+// MIDI Task
|
|
|
+//--------------------------------------------------------------------+
|
|
|
+
|
|
|
+// Variable that holds the current position in the sequence.
|
|
|
+uint32_t note_pos = 0;
|
|
|
+
|
|
|
+// Store example melody as an array of note values
|
|
|
+uint8_t note_sequence[] =
|
|
|
+{
|
|
|
+ 74,78,81,86,90,93,98,102,57,61,66,69,73,78,81,85,88,92,97,100,97,92,88,85,81,78,
|
|
|
+ 74,69,66,62,57,62,66,69,74,78,81,86,90,93,97,102,97,93,90,85,81,78,73,68,64,61,
|
|
|
+ 56,61,64,68,74,78,81,86,90,93,98,102
|
|
|
+};
|
|
|
+
|
|
|
+void midi_task(void)
|
|
|
+{
|
|
|
+ static uint32_t start_ms = 0;
|
|
|
+
|
|
|
+ // send note every 1000 ms
|
|
|
+ if (board_millis() - start_ms < 286) return; // not enough time
|
|
|
+ start_ms += 286;
|
|
|
+
|
|
|
+ // Previous positions in the note sequence.
|
|
|
+ int previous = note_pos - 1;
|
|
|
+
|
|
|
+ // If we currently are at position 0, set the
|
|
|
+ // previous position to the last note in the sequence.
|
|
|
+ if (previous < 0) previous = sizeof(note_sequence) - 1;
|
|
|
+
|
|
|
+ // Send Note On for current position at full velocity (127) on channel 1.
|
|
|
+ tudi_midi_write24(0, 0x90, note_sequence[note_pos], 127);
|
|
|
+
|
|
|
+ // Send Note Off for previous note.
|
|
|
+ tudi_midi_write24(0, 0x80, note_sequence[previous], 0);
|
|
|
+
|
|
|
+ // Increment position
|
|
|
+ note_pos++;
|
|
|
+
|
|
|
+ // If we are at the end of the sequence, start over.
|
|
|
+ if (note_pos >= sizeof(note_sequence)) note_pos = 0;
|
|
|
+}
|
|
|
+
|
|
|
//--------------------------------------------------------------------+
|
|
|
// BLINKING TASK
|
|
|
//--------------------------------------------------------------------+
|
|
|
@@ -106,7 +158,7 @@ void led_blinking_task(void)
|
|
|
static uint32_t start_ms = 0;
|
|
|
static bool led_state = false;
|
|
|
|
|
|
- // Blink every 1000 ms
|
|
|
+ // Blink every interval ms
|
|
|
if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
|
|
|
start_ms += blink_interval_ms;
|
|
|
|