Line data Source code
1 : #pragma once
2 :
3 : #include "MIDI_Interface.hpp"
4 : #include <AH/Teensy/TeensyUSBTypes.hpp>
5 : #include <MIDI_Parsers/HexPuller.hpp>
6 : #include <MIDI_Parsers/SerialMIDI_Parser.hpp>
7 : #include <MIDI_Parsers/StreamPuller.hpp>
8 : #include <Settings/SettingsWrapper.hpp>
9 :
10 : BEGIN_CS_NAMESPACE
11 :
12 : /**
13 : * @brief A class that implements MIDI debug send functions.
14 : */
15 : class StreamDebugMIDI_Base {
16 : protected:
17 : void sendChannelMessageImpl(Stream &, ChannelMessage);
18 : void sendSysCommonImpl(Stream &, SysCommonMessage);
19 : void sendSysExImpl(Stream &, SysExMessage);
20 : void sendRealTimeImpl(Stream &, RealTimeMessage);
21 0 : void sendNowImpl(Stream &) {}
22 :
23 : public:
24 16 : StreamDebugMIDI_Base(const char *prefix) : prefix(prefix) {}
25 :
26 : /// Set the prefix to be printed before each message.
27 1 : void setPrefix(const char *prefix) { this->prefix = prefix; }
28 : const char *getPrefix() const { return prefix; }
29 :
30 : private:
31 : const char *prefix = nullptr;
32 : };
33 :
34 : /**
35 : * @brief A class for MIDI outputs sending human-readable MIDI messages
36 : * over a Stream.
37 : *
38 : * @ingroup MIDIInterfaces
39 : */
40 : class StreamDebugMIDI_Output : public StreamDebugMIDI_Base,
41 : public MIDI_Sender<StreamDebugMIDI_Output>,
42 : public TrueMIDI_Sink {
43 : public:
44 : StreamDebugMIDI_Output(Stream &stream, const char *prefix = nullptr)
45 : : StreamDebugMIDI_Base(prefix), stream(stream) {}
46 :
47 : Stream &getStream() const { return stream; }
48 :
49 : protected:
50 : void sendChannelMessageImpl(ChannelMessage);
51 : void sendSysCommonImpl(SysCommonMessage);
52 : void sendSysExImpl(SysExMessage);
53 : void sendRealTimeImpl(RealTimeMessage);
54 : void sendNowImpl();
55 :
56 : void sinkMIDIfromPipe(ChannelMessage m) override { send(m); }
57 : void sinkMIDIfromPipe(SysExMessage m) override { send(m); }
58 : void sinkMIDIfromPipe(SysCommonMessage m) override { send(m); }
59 : void sinkMIDIfromPipe(RealTimeMessage m) override { send(m); }
60 :
61 : Stream &stream;
62 :
63 : friend MIDI_Sender<StreamDebugMIDI_Output>;
64 : };
65 :
66 : class MIDIOutputOnly : public AH::UpdatableCRTP<MIDIOutputOnly> {
67 : public:
68 : virtual ~MIDIOutputOnly() = default;
69 : virtual void begin() = 0;
70 0 : static void beginAll() { applyToAll(&MIDIOutputOnly::begin); }
71 : };
72 :
73 : /**
74 : * @brief A wrapper class for debug MIDI outputs sending
75 : * human-readable MIDI messages over a Serial port of class T.
76 : *
77 : * @note This is a template class because the class of the Serial object
78 : * is completely different on different architectures, and they
79 : * do not share a common super-class that has a `begin` method.
80 : *
81 : * @ingroup MIDIInterfaces
82 : */
83 : template <typename T>
84 : class SerialDebugMIDI_Output : public MIDIOutputOnly,
85 : public StreamDebugMIDI_Output {
86 : public:
87 : /**
88 : * @brief Construct a new Debug MIDI Output on the given Serial
89 : * interface with the given baud rate.
90 : *
91 : * @param serial
92 : * The Serial interface.
93 : * @param baud
94 : * The baud rate for the Serial interface.
95 : * @param prefix
96 : * An optional string to print before each message.
97 : */
98 : SerialDebugMIDI_Output(T &serial, unsigned long baud = AH::defaultBaudRate,
99 : const char *prefix = nullptr)
100 : : StreamDebugMIDI_Output(serial, prefix), baud(baud) {}
101 : /// @see @ref SerialDebugMIDI_Output(T &,unsigned long,const char *)
102 : SerialDebugMIDI_Output(T &serial, const char *prefix)
103 : : SerialDebugMIDI_Output(serial, AH::defaultBaudRate, prefix) {}
104 :
105 : /**
106 : * @brief Start the Serial interface at the predefined baud rate.
107 : */
108 : void begin() override { static_cast<T &>(getStream()).begin(baud); }
109 :
110 : private:
111 : const unsigned long baud;
112 : };
113 :
114 : /**
115 : * @brief A class for debug MIDI outputs sending
116 : * human-readable MIDI messages over a HardwareSerial port.
117 : *
118 : * @ingroup MIDIInterfaces
119 : */
120 : class HardwareSerialDebugMIDI_Output
121 : : public SerialDebugMIDI_Output<HardwareSerial> {
122 : public:
123 : /**
124 : * @brief Construct a new Debug MIDI Output on the given HardwareSerial
125 : * interface with the given baud rate.
126 : *
127 : * @param serial
128 : * The HardwareSerial interface.
129 : * @param baud
130 : * The baud rate for the serial interface.
131 : * @param prefix
132 : * An optional string to print before each message.
133 : */
134 : HardwareSerialDebugMIDI_Output(HardwareSerial &serial,
135 : unsigned long baud = AH::defaultBaudRate,
136 : const char *prefix = nullptr)
137 : : SerialDebugMIDI_Output(serial, baud, prefix) {}
138 : /// @see @ref HardwareSerialDebugMIDI_Output(HardwareSerial &,unsigned long,const char *)
139 : HardwareSerialDebugMIDI_Output(HardwareSerial &serial, const char *prefix)
140 : : SerialDebugMIDI_Output(serial, prefix) {}
141 : };
142 :
143 : /**
144 : * @brief A class for debug MIDI outputs sending
145 : * human-readable MIDI messages over the USB CDC connection.
146 : *
147 : * Boards without a native USB connection (UNO, MEGA, Nano ...)
148 : * use HardwareSerial0 for USB communication.
149 : *
150 : * @ingroup MIDIInterfaces
151 : */
152 : class USBDebugMIDI_Output : public SerialDebugMIDI_Output<decltype(Serial)> {
153 : public:
154 : /**
155 : * @brief Construct a USBDebugMIDI_Output with the given baud rate.
156 : *
157 : * @param baud
158 : * The baud rate to start the USB Serial connection with.
159 : * @param prefix
160 : * An optional string to print before each message.
161 : */
162 : USBDebugMIDI_Output(unsigned long baud = AH::defaultBaudRate,
163 : const char *prefix = nullptr)
164 : : SerialDebugMIDI_Output(Serial, baud, prefix) {}
165 : /// @see @ref USBDebugMIDI_Output(unsigned long,const char *)
166 : USBDebugMIDI_Output(const char *prefix)
167 : : SerialDebugMIDI_Output(Serial, prefix) {}
168 : };
169 :
170 : /**
171 : * @brief A class for MIDI interfaces sending and receiving
172 : * human-readable MIDI messages over a Stream.
173 : *
174 : * @ingroup MIDIInterfaces
175 : */
176 : class StreamDebugMIDI_Interface : public StreamDebugMIDI_Base,
177 : public MIDI_Interface {
178 : public:
179 : /**
180 : * @brief Construct a debug MIDI interface on the given Stream.
181 : *
182 : * @param stream
183 : * The Stream interface.
184 : * @param prefix
185 : * An optional string to print before each message.
186 : */
187 16 : StreamDebugMIDI_Interface(Stream &stream, const char *prefix = nullptr)
188 16 : : StreamDebugMIDI_Base(prefix), hexstream(stream) {}
189 :
190 17 : Stream &getStream() const { return hexstream.puller.stream; }
191 :
192 : /// Try reading and parsing a single incoming MIDI message.
193 : /// @return Returns the type of the read message, or
194 : /// `MIDIReadEvent::NO_MESSAGE` if no MIDI message was available.
195 : MIDIReadEvent read();
196 :
197 : /// Return the received channel voice message.
198 4 : ChannelMessage getChannelMessage() const {
199 4 : return parser.getChannelMessage();
200 : }
201 : /// Return the received system common message.
202 0 : SysCommonMessage getSysCommonMessage() const {
203 0 : return parser.getSysCommonMessage();
204 : }
205 : /// Return the received real-time message.
206 1 : RealTimeMessage getRealTimeMessage() const {
207 1 : return parser.getRealTimeMessage();
208 : }
209 : /// Return the received system exclusive message.
210 1 : SysExMessage getSysExMessage() const { return parser.getSysExMessage(); }
211 :
212 : void update() override;
213 :
214 : protected:
215 : // MIDI send implementations
216 : void sendChannelMessageImpl(ChannelMessage) override;
217 : void sendSysCommonImpl(SysCommonMessage) override;
218 : void sendSysExImpl(SysExMessage) override;
219 : void sendRealTimeImpl(RealTimeMessage) override;
220 : void sendNowImpl() override;
221 :
222 : private:
223 : void handleStall() override;
224 :
225 : private:
226 : HexPuller<StreamPuller> hexstream;
227 : SerialMIDI_Parser parser;
228 : };
229 :
230 : /**
231 : * @brief A wrapper class for debug MIDI interfaces sending and receiving
232 : * human-readable MIDI messages over a Serial port of class T.
233 : *
234 : * @note This is a template class because the class of the Serial object
235 : * is completely different on different architectures, and they
236 : * do not share a common super-class that has a `begin` method.
237 : *
238 : * @ingroup MIDIInterfaces
239 : */
240 : template <typename T>
241 : class SerialDebugMIDI_Interface : public StreamDebugMIDI_Interface {
242 : public:
243 : /**
244 : * @brief Construct a new Debug MIDI Interface on the given Serial
245 : * interface with the given baud rate.
246 : *
247 : * @param serial
248 : * The Serial interface.
249 : * @param baud
250 : * The baud rate for the Serial interface.
251 : * @param prefix
252 : * An optional string to print before each message.
253 : */
254 : SerialDebugMIDI_Interface(T &serial,
255 : unsigned long baud = AH::defaultBaudRate,
256 : const char *prefix = nullptr)
257 : : StreamDebugMIDI_Interface(serial, prefix), baud(baud) {}
258 : /// @see @ref SerialDebugMIDI_Interface(T &,unsigned long,const char *)
259 : SerialDebugMIDI_Interface(T &serial, const char *prefix)
260 : : SerialDebugMIDI_Interface(serial, AH::defaultBaudRate, prefix) {}
261 :
262 : /**
263 : * @brief Start the Serial interface at the predefined baud rate.
264 : */
265 : void begin() override { static_cast<T &>(getStream()).begin(baud); }
266 :
267 : private:
268 : const unsigned long baud;
269 : };
270 :
271 : /**
272 : * @brief A class for debug MIDI interfaces sending and receiving
273 : * human-readable MIDI messages over a HardwareSerial port.
274 : *
275 : * @ingroup MIDIInterfaces
276 : */
277 : class HardwareSerialDebugMIDI_Interface
278 : : public SerialDebugMIDI_Interface<HardwareSerial> {
279 : public:
280 : /**
281 : * @brief Construct a new Debug MIDI Interface on the given HardwareSerial
282 : * interface with the given baud rate.
283 : *
284 : * @param serial
285 : * The HardwareSerial interface.
286 : * @param baud
287 : * The baud rate for the serial interface.
288 : * @param prefix
289 : * An optional string to print before each message.
290 : */
291 : HardwareSerialDebugMIDI_Interface(HardwareSerial &serial,
292 : unsigned long baud = AH::defaultBaudRate,
293 : const char *prefix = nullptr)
294 : : SerialDebugMIDI_Interface(serial, baud, prefix) {}
295 : /// @see @ref HardwareSerialDebugMIDI_Interface(HardwareSerial &,unsigned long,const char *)
296 : HardwareSerialDebugMIDI_Interface(HardwareSerial &serial,
297 : const char *prefix)
298 : : SerialDebugMIDI_Interface(serial, prefix) {}
299 : };
300 :
301 : /**
302 : * @brief A class for debug MIDI interfaces sending and receiving
303 : * human-readable MIDI messages over the USB CDC connection.
304 : *
305 : * Boards without a native USB connection (UNO, MEGA, Nano ...)
306 : * use HardwareSerial0 for USB communication.
307 : *
308 : * @ingroup MIDIInterfaces
309 : */
310 : class USBDebugMIDI_Interface
311 : : public SerialDebugMIDI_Interface<decltype(Serial)> {
312 : public:
313 : /**
314 : * @brief Construct a USBDebugMIDI_Interface with the given baud rate.
315 : *
316 : * @param baud
317 : * The baud rate to start the USB Serial connection with.
318 : * @param prefix
319 : * An optional string to print before each message.
320 : */
321 : USBDebugMIDI_Interface(unsigned long baud = AH::defaultBaudRate,
322 : const char *prefix = nullptr)
323 : : SerialDebugMIDI_Interface(Serial, baud, prefix) {}
324 : /// @see @ref USBDebugMIDI_Interface(unsigned long,const char *)
325 : USBDebugMIDI_Interface(const char *prefix)
326 : : SerialDebugMIDI_Interface(Serial, prefix) {}
327 : };
328 :
329 : END_CS_NAMESPACE
|