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