Line data Source code
1 : #pragma once
2 :
3 : #include <Def/Def.hpp>
4 : #include <Def/MIDICNChannelAddress.hpp>
5 : #include <MIDI_Parsers/MIDI_Parser.hpp>
6 :
7 : BEGIN_CS_NAMESPACE
8 :
9 : constexpr auto MIDI_BAUD = 31250;
10 :
11 : class MIDI_Callbacks;
12 :
13 : /**
14 : * @brief An abstract class for MIDI interfaces.
15 : */
16 : class MIDI_Interface {
17 : protected:
18 : /**
19 : * @brief Constructor.
20 : */
21 : MIDI_Interface();
22 :
23 : public:
24 : /**
25 : * @brief Destructor.
26 : */
27 : virtual ~MIDI_Interface();
28 :
29 : /**
30 : * @brief Initialize the MIDI Interface.
31 : */
32 1 : virtual void begin() {}
33 :
34 : /**
35 : * @brief Send a 3-byte MIDI packet.
36 : *
37 : * @param m
38 : * MIDI message type. [0x80, 0xE0]
39 : * @param c
40 : * The MIDI channel. [1, 16]
41 : * @param d1
42 : * The first data byte. [0, 127]
43 : * @param d2
44 : * The second data byte. [0, 127]
45 : */
46 : void send(uint8_t m, uint8_t c, uint8_t d1, uint8_t d2);
47 :
48 : /**
49 : * @brief Send a 2-byte MIDI packet.
50 : *
51 : * @param m
52 : * MIDI message type. [0x80, 0xE0]
53 : * @param c
54 : * The MIDI channel. [1, 16]
55 : * @param d1
56 : * The first data byte. [0, 127]
57 : */
58 : void send(uint8_t m, uint8_t c, uint8_t d1);
59 :
60 : /**
61 : * @brief Send a 3-byte MIDI packet with cable number.
62 : *
63 : * @param m
64 : * MIDI message type. [0x80, 0xE0]
65 : * @param c
66 : * The MIDI channel. [1, 16]
67 : * @param d1
68 : * The first data byte. [0, 127]
69 : * @param d2
70 : * The second data byte. [0, 127]
71 : * @param cn
72 : * The MIDI Cable Number. [0, 15]
73 : */
74 : void sendOnCable(uint8_t m, uint8_t c, uint8_t d1, uint8_t d2, uint8_t cn);
75 :
76 : /**
77 : * @brief Send a 2-byte MIDI packet with cable number.
78 : *
79 : * @param m
80 : * MIDI message type. [0x80, 0xE0]
81 : * @param c
82 : * The MIDI channel. [1, 16]
83 : * @param d1
84 : * The first data byte. [0, 127]
85 : * @param cn
86 : * The MIDI Cable Number. [0, 15]
87 : */
88 : void sendOnCable(uint8_t m, uint8_t c, uint8_t d1, uint8_t cn);
89 :
90 : /**
91 : * @brief Send a single-byte MIDI packet with cable number.
92 : *
93 : * @param r
94 : * The MIDI byte to send.
95 : * @param cn
96 : * The MIDI Cable Number. [0, 15]
97 : */
98 : void sendOnCable(uint8_t r, uint8_t cn);
99 :
100 : /// Send a MIDI Note On event.
101 : void sendNoteOn(MIDICNChannelAddress address, uint8_t velocity);
102 : /// Send a MIDI Note Off event.
103 : void sendNoteOff(MIDICNChannelAddress address, uint8_t velocity);
104 : /// Send a MIDI Key Pressure event.
105 : void sendKP(MIDICNChannelAddress address, uint8_t pressure);
106 : /// Send a MIDI Control Change event.
107 : void sendCC(MIDICNChannelAddress address, uint8_t value);
108 : /// Send a MIDI Program Change event.
109 : void sendPC(MIDICNChannelAddress address);
110 : /// Send a MIDI Program Change event.
111 : void sendPC(MIDICNChannel address, uint8_t value);
112 : /// Send a MIDI Channel Pressure event.
113 : void sendCP(MIDICNChannel address, uint8_t pressure);
114 : /// Send a MIDI Pitch Bend event.
115 : void sendPB(MIDICNChannel address, uint16_t value);
116 : /// Send a MIDI System Exclusive message.
117 : void send(SysExMessage message);
118 : /// Send a MIDI System Exclusive message.
119 : template <size_t N>
120 11 : void send(const uint8_t (&sysexdata)[N], uint8_t cn = 0) {
121 11 : send(SysExMessage{sysexdata, N, cn});
122 11 : }
123 : /// Send a single-byte MIDI message.
124 : void send(uint8_t rt, uint8_t cn = 0);
125 :
126 : /**
127 : * @brief Read the MIDI interface and call the callback if a message is
128 : * received.
129 : */
130 : virtual void update() = 0;
131 :
132 : /**
133 : * @brief Return the default MIDI interface.
134 : */
135 : static MIDI_Interface *getDefault();
136 :
137 : /**
138 : * @brief Set this MIDI interface as the default interface.
139 : */
140 : void setAsDefault();
141 :
142 : /**
143 : * @brief Set the callbacks that will be called when a MIDI message is
144 : * received.
145 : *
146 : * @param cb
147 : * A pointer to an object that implements the MIDI_Callbacks class.
148 : */
149 : virtual void setCallbacks(MIDI_Callbacks *cb) = 0;
150 :
151 : /**
152 : * @brief Set the callbacks that will be called when a MIDI message is
153 : * received.
154 : *
155 : * @param cb
156 : * A reference to an object that implements the MIDI_Callbacks
157 : * class.
158 : */
159 1 : void setCallbacks(MIDI_Callbacks &cb) { setCallbacks(&cb); }
160 :
161 : /**
162 : * @brief Low-level function for sending a 3-byte MIDI message.
163 : */
164 : virtual void sendImpl(uint8_t m, uint8_t c, uint8_t d1, uint8_t d2,
165 : uint8_t cn) = 0;
166 : /**
167 : * @brief Low-level function for sending a 2-byte MIDI message.
168 : */
169 : virtual void sendImpl(uint8_t m, uint8_t c, uint8_t d1, uint8_t cn) = 0;
170 :
171 : /**
172 : * @brief Low-level function for sending a system exclusive MIDI message.
173 : */
174 : virtual void sendImpl(const uint8_t *data, size_t length, uint8_t cn) = 0;
175 :
176 : /**
177 : * @brief Low-level function for sending a single-byte MIDI message.
178 : */
179 : virtual void sendImpl(uint8_t rt, uint8_t cn) = 0;
180 :
181 : private:
182 : static MIDI_Interface *DefaultMIDI_Interface;
183 : };
184 :
185 : /**
186 : * @brief An abstract class for MIDI interfaces.
187 : */
188 76 : class Parsing_MIDI_Interface : public MIDI_Interface {
189 : protected:
190 : /**
191 : * @brief Construct a MIDI interface with the given parser.
192 : *
193 : * Also set this interface as the default MIDI interface.
194 : *
195 : * @param parser
196 : * The MIDI parser to use for the interface.
197 : */
198 : Parsing_MIDI_Interface(MIDI_Parser &parser);
199 :
200 : public:
201 : MIDI_Parser &getParser() { return parser; }
202 :
203 : /**
204 : * @brief Return the received channel message.
205 : */
206 : ChannelMessage getChannelMessage();
207 :
208 : /**
209 : * @brief Return the received system exclusive message.
210 : */
211 : SysExMessage getSysExMessage() const;
212 :
213 : /**
214 : * @brief Return the cable number of the received message.
215 : */
216 : uint8_t getCN() const;
217 :
218 : void update() override;
219 :
220 10 : void setCallbacks(MIDI_Callbacks *cb) override { this->callbacks = cb; }
221 : using MIDI_Interface::setCallbacks;
222 :
223 : protected:
224 : bool dispatchMIDIEvent(MIDI_read_t event);
225 :
226 : private:
227 : /**
228 : * @todo Documentation
229 : */
230 : virtual MIDI_read_t read() = 0;
231 :
232 : void onRealtimeMessage(uint8_t message);
233 :
234 : void onChannelMessage();
235 :
236 : void onSysExMessage();
237 :
238 : private:
239 : MIDI_Parser &parser;
240 : MIDI_Callbacks *callbacks = nullptr;
241 : };
242 :
243 : // LCOV_EXCL_START
244 : /**
245 : * @brief A class for callbacks from MIDI input.
246 : */
247 : class MIDI_Callbacks {
248 : public:
249 : virtual void onChannelMessage(Parsing_MIDI_Interface &midi) { (void)midi; }
250 : virtual void onSysExMessage(Parsing_MIDI_Interface &midi) { (void)midi; }
251 : virtual void onRealtimeMessage(Parsing_MIDI_Interface &midi,
252 : uint8_t message) {
253 : (void)midi;
254 : (void)message;
255 : }
256 :
257 : virtual ~MIDI_Callbacks() = default;
258 : };
259 : // LCOV_EXCL_STOP
260 :
261 : END_CS_NAMESPACE
|