Line data Source code
1 : #pragma once 2 : 3 : #include "MIDI_Interface.hpp" 4 : #include <AH/Arduino-Wrapper.h> // Stream 5 : #include <AH/STL/utility> 6 : #include <AH/Teensy/TeensyUSBTypes.hpp> 7 : #include <MIDI_Parsers/SerialMIDI_Parser.hpp> 8 : #include <Settings/SettingsWrapper.hpp> 9 : 10 : #if defined(ESP32) || !defined(ARDUINO) 11 : #include <mutex> 12 : #endif 13 : 14 : BEGIN_CS_NAMESPACE 15 : 16 : /** 17 : * @brief A class for MIDI interfaces sending and receiving MIDI messages 18 : * over a Stream. 19 : * 20 : * @ingroup MIDIInterfaces 21 : */ 22 18 : class StreamMIDI_Interface : public Parsing_MIDI_Interface { 23 : public: 24 : /** 25 : * @brief Construct a StreamMIDI_Interface on the given Stream. 26 : * 27 : * @param stream 28 : * The Stream interface. 29 : */ 30 18 : StreamMIDI_Interface(Stream &stream) 31 18 : : Parsing_MIDI_Interface(parser), stream(stream) {} 32 : 33 : StreamMIDI_Interface(StreamMIDI_Interface &&other) 34 : : Parsing_MIDI_Interface(std::move(other)), stream(other.stream) {} 35 : // TODO: should I move the mutex too? 36 : 37 5 : MIDIReadEvent read() override { 38 22 : while (stream.available() > 0) { 39 21 : uint8_t midiByte = stream.read(); 40 21 : MIDIReadEvent parseResult = parser.parse(midiByte); 41 21 : if (parseResult != MIDIReadEvent::NO_MESSAGE) 42 4 : return parseResult; 43 21 : } 44 1 : return MIDIReadEvent::NO_MESSAGE; 45 5 : } 46 : 47 : protected: 48 : SerialMIDI_Parser parser; 49 : 50 7 : void sendImpl(uint8_t header, uint8_t d1, uint8_t d2, 51 : uint8_t cn) override { 52 : #if defined(ESP32) || !defined(ARDUINO) 53 7 : std::lock_guard<std::mutex> lock(mutex); 54 : #endif 55 : (void)cn; 56 7 : stream.write(header); // Send the MIDI message over the stream 57 7 : stream.write(d1); 58 7 : stream.write(d2); 59 : // stream.flush(); // TODO 60 7 : } 61 : 62 5 : void sendImpl(uint8_t header, uint8_t d1, uint8_t cn) override { 63 : #if defined(ESP32) || !defined(ARDUINO) 64 5 : std::lock_guard<std::mutex> lock(mutex); 65 : #endif 66 : (void)cn; 67 5 : stream.write(header); // Send the MIDI message over the stream 68 5 : stream.write(d1); 69 : // stream.flush(); // TODO 70 5 : } 71 : 72 1 : void sendImpl(const uint8_t *data, size_t length, uint8_t cn) override { 73 : #if defined(ESP32) || !defined(ARDUINO) 74 1 : std::lock_guard<std::mutex> lock(mutex); 75 : #endif 76 : (void)cn; 77 1 : stream.write(data, length); 78 : // stream.flush(); // TODO 79 1 : } 80 : 81 0 : void sendImpl(uint8_t rt, uint8_t cn) override { 82 : #if defined(ESP32) || !defined(ARDUINO) 83 0 : std::lock_guard<std::mutex> lock(mutex); 84 : #endif 85 : (void)cn; 86 0 : stream.write(rt); // Send the MIDI message over the stream 87 : // stream.flush(); // TODO 88 0 : } 89 : 90 : protected: 91 : Stream &stream; 92 : #if defined(ESP32) || !defined(ARDUINO) 93 : std::mutex mutex; 94 : #endif 95 : }; 96 : 97 : /** 98 : * @brief A wrapper class for MIDI interfaces sending and receiving 99 : * MIDI messages over a Serial port of generic class T. 100 : * 101 : * @note This is a template class because the type of the Serial object 102 : * is completely different on different architectures, and they 103 : * do not share a common super-class that has a `begin` method. 104 : * 105 : * @ingroup MIDIInterfaces 106 : */ 107 : template <class T> 108 : class SerialMIDI_Interface : public StreamMIDI_Interface { 109 : public: 110 : /** 111 : * @brief Create a new MIDI Interface on the given Serial interface 112 : * with the given baud rate. 113 : * 114 : * @param serial 115 : * The Serial interface. 116 : * @param baud 117 : * The baud rate for the Serial interface. 118 : */ 119 : SerialMIDI_Interface(T &serial, unsigned long baud = MIDI_BAUD) 120 : : StreamMIDI_Interface(serial), baud(baud) {} 121 : 122 : /** 123 : * @brief Start the Serial interface at the predefined baud rate. 124 : */ 125 : void begin() override { static_cast<T &>(stream).begin(baud); } 126 : 127 : private: 128 : const unsigned long baud; 129 : }; 130 : 131 : /** 132 : * @brief A class for MIDI interfaces sending and receiving 133 : * MIDI messages over a Hardware Serial port. 134 : * 135 : * @ingroup MIDIInterfaces 136 : */ 137 : class HardwareSerialMIDI_Interface 138 : : public SerialMIDI_Interface<HardwareSerial> { 139 : public: 140 : /** 141 : * @brief Construct a new MIDI Interface on the given HardwareSerial 142 : * interface with the given baud rate. 143 : * 144 : * @param serial 145 : * The HardwareSerial interface. 146 : * @param baud 147 : * The baud rate for the serial interface. 148 : */ 149 : HardwareSerialMIDI_Interface(HardwareSerial &serial, 150 : unsigned long baud = MIDI_BAUD) 151 : : SerialMIDI_Interface(serial, baud) {} 152 : }; 153 : 154 : /** 155 : * @brief A class for MIDI interfaces sending and receiving 156 : * MIDI messages over the Serial port of the USB connection. 157 : * 158 : * @ingroup MIDIInterfaces 159 : */ 160 : class USBSerialMIDI_Interface : public SerialMIDI_Interface<decltype(Serial)> { 161 : public: 162 : /** 163 : * @brief Construct a USBSerialMIDI_Interface with the given baud rate. 164 : * 165 : * @param baud 166 : * The baud rate to start the USB Serial connection with. 167 : */ 168 : USBSerialMIDI_Interface(unsigned long baud) 169 : : SerialMIDI_Interface(Serial, baud) {} 170 : }; 171 : 172 : #if !defined(TEENSYDUINO) || \ 173 : (defined(TEENSYDUINO) && defined(TEENSY_SERIALUSB_ENABLED)) 174 : /** 175 : * @brief A class for MIDI Interfaces sending and receiving 176 : * data over the USB Serial CDC connection for the use 177 : * with the [Hairless MIDI<->Serial Bridge] 178 : * (http://projectgus.github.io/hairless-midiserial/). 179 : * 180 : * @ingroup MIDIInterfaces 181 : */ 182 : class HairlessMIDI_Interface : public USBSerialMIDI_Interface { 183 : public: 184 : /** 185 : * @brief Construct a HairlessMIDI_Interface. 186 : * 187 : * The default Hairless baud rate of 115200 baud is used. 188 : * This can be changed in the Settings.hpp file. 189 : */ 190 : HairlessMIDI_Interface() : USBSerialMIDI_Interface(HAIRLESS_BAUD){}; 191 : }; 192 : #endif 193 : 194 : END_CS_NAMESPACE 195 : 196 : // TODO: Teensy 4.0 SoftwareSerial bug 197 : #if defined(__AVR__) || (defined(TEENSYDUINO) && TEENSYDUINO != 147) || \ 198 : (defined(TEENSYDUINO) && !defined(__IMXRT1052__) && \ 199 : !defined(__IMXRT1062__)) 200 : 201 : #include <SoftwareSerial.h> 202 : 203 : BEGIN_CS_NAMESPACE 204 : 205 : /** 206 : * @brief A class for MIDI interfaces sending and receiving 207 : * MIDI messages over a SoftwareSerial interface. 208 : * 209 : * @ingroup MIDIInterfaces 210 : */ 211 : class SoftwareSerialMIDI_Interface 212 : : public SerialMIDI_Interface<SoftwareSerial> { 213 : public: 214 : /** 215 : * @brief Create a SoftwareSerialMIDI_Interface on the given 216 : * SoftwareSerial interface with the given baud rate. 217 : * 218 : * @param serial 219 : * The SoftwareSerial interface. 220 : * @param baud 221 : * The baud rate for the serial interface. 222 : */ 223 : SoftwareSerialMIDI_Interface(SoftwareSerial &serial, unsigned long baud) 224 : : SerialMIDI_Interface(serial, baud) {} 225 : }; 226 : 227 : END_CS_NAMESPACE 228 : 229 : #endif