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 : #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 : Stream &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 StreamDebugMIDI_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 : : StreamDebugMIDI_Base(prefix), hexstream(stream) {}
191 :
192 17 : 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 : #endif
228 :
229 : private:
230 : HexPuller<StreamPuller> hexstream;
231 : SerialMIDI_Parser parser;
232 : };
233 :
234 : /**
235 : * @brief A wrapper class for debug MIDI interfaces sending and receiving
236 : * human-readable MIDI messages over a Serial port of class T.
237 : *
238 : * @note This is a template class because the class of the Serial object
239 : * is completely different on different architectures, and they
240 : * do not share a common super-class that has a `begin` method.
241 : *
242 : * @ingroup MIDIInterfaces
243 : */
244 : template <typename T>
245 : class SerialDebugMIDI_Interface : public StreamDebugMIDI_Interface {
246 : public:
247 : /**
248 : * @brief Construct a new Debug MIDI Interface on the given Serial
249 : * interface with the given baud rate.
250 : *
251 : * @param serial
252 : * The Serial interface.
253 : * @param baud
254 : * The baud rate for the Serial interface.
255 : * @param prefix
256 : * An optional string to print before each message.
257 : */
258 : SerialDebugMIDI_Interface(T &serial,
259 : unsigned long baud = AH::defaultBaudRate,
260 : const char *prefix = nullptr)
261 : : StreamDebugMIDI_Interface(serial, prefix), baud(baud) {}
262 : /// @see @ref SerialDebugMIDI_Interface(T &,unsigned long,const char *)
263 : SerialDebugMIDI_Interface(T &serial, const char *prefix)
264 : : SerialDebugMIDI_Interface(serial, AH::defaultBaudRate, prefix) {}
265 :
266 : /**
267 : * @brief Start the Serial interface at the predefined baud rate.
268 : */
269 : void begin() override { static_cast<T &>(getStream()).begin(baud); }
270 :
271 : private:
272 : const unsigned long baud;
273 : };
274 :
275 : /**
276 : * @brief A class for debug MIDI interfaces sending and receiving
277 : * human-readable MIDI messages over a HardwareSerial port.
278 : *
279 : * @ingroup MIDIInterfaces
280 : */
281 : class HardwareSerialDebugMIDI_Interface
282 : : public SerialDebugMIDI_Interface<HardwareSerial> {
283 : public:
284 : /**
285 : * @brief Construct a new Debug MIDI Interface on the given HardwareSerial
286 : * interface with the given baud rate.
287 : *
288 : * @param serial
289 : * The HardwareSerial interface.
290 : * @param baud
291 : * The baud rate for the serial interface.
292 : * @param prefix
293 : * An optional string to print before each message.
294 : */
295 : HardwareSerialDebugMIDI_Interface(HardwareSerial &serial,
296 : unsigned long baud = AH::defaultBaudRate,
297 : const char *prefix = nullptr)
298 : : SerialDebugMIDI_Interface(serial, baud, prefix) {}
299 : /// @see @ref HardwareSerialDebugMIDI_Interface(HardwareSerial &,unsigned long,const char *)
300 : HardwareSerialDebugMIDI_Interface(HardwareSerial &serial,
301 : const char *prefix)
302 : : SerialDebugMIDI_Interface(serial, prefix) {}
303 : };
304 :
305 : /**
306 : * @brief A class for debug MIDI interfaces sending and receiving
307 : * human-readable MIDI messages over the USB CDC connection.
308 : *
309 : * Boards without a native USB connection (UNO, MEGA, Nano ...)
310 : * use HardwareSerial0 for USB communication.
311 : *
312 : * @ingroup MIDIInterfaces
313 : */
314 : class USBDebugMIDI_Interface
315 : : public SerialDebugMIDI_Interface<decltype(Serial)> {
316 : public:
317 : /**
318 : * @brief Construct a USBDebugMIDI_Interface with the given baud rate.
319 : *
320 : * @param baud
321 : * The baud rate to start the USB Serial connection with.
322 : * @param prefix
323 : * An optional string to print before each message.
324 : */
325 : USBDebugMIDI_Interface(unsigned long baud = AH::defaultBaudRate,
326 : const char *prefix = nullptr)
327 : : SerialDebugMIDI_Interface(Serial, baud, prefix) {}
328 : /// @see @ref USBDebugMIDI_Interface(unsigned long,const char *)
329 : USBDebugMIDI_Interface(const char *prefix)
330 : : SerialDebugMIDI_Interface(Serial, prefix) {}
331 : };
332 :
333 : END_CS_NAMESPACE
|