59 lines
1.7 KiB
C++
59 lines
1.7 KiB
C++
/*
|
|
This is an example of a MIDI Music Box using an ESP32 with a native USB support stack (S2, S3, etc.).
|
|
|
|
Every time the button on the ESP32 board (attached to pin 0) is pressed the next note of a melody is
|
|
played. It is up to the user to get the timing of the button presses right.
|
|
|
|
One simple way of running this sketch is to download the Pianoteq evaluation version, because upon
|
|
application start it automatically listens to the first MIDI Input on Channel 1, which is the case,
|
|
if the ESP32 is the only MIDI device attached.
|
|
|
|
View this sketch in action on YouTube: https://youtu.be/JFrc-wSmcus
|
|
*/
|
|
#if ARDUINO_USB_MODE
|
|
#warning This sketch should be used when USB is in OTG mode
|
|
void setup() {}
|
|
void loop() {}
|
|
#else
|
|
|
|
#include "USB.h"
|
|
#include "USBMIDI.h"
|
|
USBMIDI MIDI;
|
|
|
|
#define END_OF_SONG 255
|
|
uint8_t notes[] = {END_OF_SONG, 71, 76, 79, 78, 76, 83, 81, 78, 76, 79, 78, 75, 77, 71};
|
|
uint8_t noteIndex = 0; // From 0 to sizeof(notes)
|
|
#define SONG_LENGTH (sizeof(notes) - 1) // END_OF_SONG does not attribute to the length.
|
|
|
|
#define BUTTON_PIN 0
|
|
|
|
// Simple button press check with debounce
|
|
// (See also: https://tinyurl.com/simple-debounce)
|
|
bool isButtonPressed() {
|
|
static uint16_t state = 0;
|
|
state = (state << 1) | digitalRead(BUTTON_PIN) | 0xfe00;
|
|
return (state == 0xff00);
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
// Make the BUTTON_PIN an input:
|
|
pinMode(BUTTON_PIN, INPUT_PULLUP);
|
|
|
|
MIDI.begin();
|
|
USB.begin();
|
|
}
|
|
|
|
void loop() {
|
|
if (isButtonPressed()) {
|
|
// Stop current note
|
|
MIDI.noteOff(notes[noteIndex]);
|
|
|
|
// Play next note
|
|
noteIndex = noteIndex < SONG_LENGTH ? noteIndex + 1 : 0;
|
|
if (notes[noteIndex] != END_OF_SONG) {
|
|
MIDI.noteOn(notes[noteIndex], 64);
|
|
}
|
|
}
|
|
}
|
|
#endif /* ARDUINO_USB_MODE */
|