Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
USBMIDI_Parser.hpp
Go to the documentation of this file.
1#include "MIDI_Parser.hpp"
2#include "SysExBuffer.hpp"
4
5#ifdef MIDI_NUM_CABLES
6#define USB_MIDI_NUMBER_OF_CABLES MIDI_NUM_CABLES
7#elif defined(USB_MIDI4_SERIAL) || defined(USB_MIDI4)
8#define USB_MIDI_NUMBER_OF_CABLES 4
9#elif defined(USB_MIDI16_AUDIO_SERIAL) || defined(USB_MIDI16_SERIAL) || \
10 defined(USB_MIDI16)
11// TODO: || defined(USB_EVERYTHING)
12#define USB_MIDI_NUMBER_OF_CABLES 16
13#elif defined(ARDUINO_ARCH_RP2040)
14#define USB_MIDI_NUMBER_OF_CABLES 16
15#elif !defined(ARDUINO) || defined(DOXYGEN)
16#define USB_MIDI_NUMBER_OF_CABLES 16
17#else
18#define USB_MIDI_NUMBER_OF_CABLES 1
19#endif
20
22
29 public:
31
40 template <class BytePuller>
41 MIDIReadEvent pull(BytePuller &&puller);
42
43 protected:
48
49 public:
50#if !IGNORE_SYSEX
59#endif
60
61 protected:
65 template <uint8_t NumBytes>
68
69 protected:
70#if !IGNORE_SYSEX
71 void startSysEx(Cable cable) { sysexbuffers[cable.getRaw()].start(); }
72 void endSysEx(Cable cable) {
73 sysexbuffers[cable.getRaw()].end();
74 activeCable = cable;
75 }
76 void endSysExChunk(Cable cable) { activeCable = cable; }
77 bool hasSysExSpace(Cable cable, uint8_t amount) const {
78 return sysexbuffers[cable.getRaw()].hasSpaceLeft(amount);
79 }
80 void addSysExByte(Cable cable, uint8_t data) {
81 sysexbuffers[cable.getRaw()].add(data);
82 }
83 void addSysExBytes(Cable cable, const uint8_t *data, uint8_t len) {
84 sysexbuffers[cable.getRaw()].add(data, len);
85 }
86 bool receivingSysEx(Cable cable) const {
87 return sysexbuffers[cable.getRaw()].isReceiving();
88 }
89
90 void storePacket(MIDIUSBPacket_t packet) { storedPacket = packet; }
91 bool hasStoredPacket() const { return storedPacket[0] != 0x00; }
94 storedPacket[0] = 0x00;
95 return t;
96 }
97
99
100 private:
103#endif
104};
105
106template <class BytePuller>
107inline MIDIReadEvent USBMIDI_Parser::pull(BytePuller &&puller) {
108 // First try resuming the parser, we might have a stored packet that has to
109 // be parsed first.
110 MIDIReadEvent evt = resume();
111 if (evt != MIDIReadEvent::NO_MESSAGE)
112 return evt;
113
114 // If resumption didn't produce a message, read new packets from the input
115 // and parse them until either we get a message, or until the input runs out
116 // of new packets.
117 MIDIUSBPacket_t midiPacket;
118 while (puller.pull(midiPacket)) {
119 evt = feed(midiPacket);
120 if (evt != MIDIReadEvent::NO_MESSAGE)
121 return evt;
122 }
124}
125
constexpr Cable Cable_1
Definition Cable.hpp:118
MIDIReadEvent
Values returned by the MIDI reading functions.
@ NO_MESSAGE
No new messages were received.
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
#define USB_MIDI_NUMBER_OF_CABLES
A class for serial-in/parallel-out shift registers, like the 74HC595 that are connected to the SPI bu...
A type-safe class for MIDI USB Cable numbers.
Definition Cable.hpp:13
constexpr uint8_t getRaw() const
Get the cable as an integer.
Definition Cable.hpp:29
Base class for MIDI parsers.
Helper for storing the System Exclusive messages being received by a MIDI parser.
const uint8_t * getBuffer() const
Get a pointer to the buffer.
bool hasSpaceLeft(uint8_t amount=1) const
Check if the buffer has at least amount bytes of free space available.
void start()
Start a new SysEx message.
void add(uint8_t data)
Add a byte to the current SysEx message.
void end()
Finish the current SysEx message.
uint16_t getLength() const
Get the length of the SysEx message in the buffer.
bool isReceiving() const
Check if the buffer is receiving a SysEx message.
Parser for MIDI over USB packets.
bool hasSysExSpace(Cable cable, uint8_t amount) const
MIDIReadEvent handleSingleByte(MIDIUSBPacket_t packet, Cable cable)
MIDIReadEvent resume()
Resume the parser with the previously stored and unhandled packet.
SysExBuffer sysexbuffers[16]
MIDIReadEvent handleSysExStartCont(MIDIUSBPacket_t packet, Cable cable)
void endSysExChunk(Cable cable)
void storePacket(MIDIUSBPacket_t packet)
MIDIReadEvent handleSysExEnd(MIDIUSBPacket_t packet, Cable cable)
MIDIReadEvent handleChannelMessage(MIDIUSBPacket_t packet, Cable cable)
void startSysEx(Cable cable)
bool receivingSysEx(Cable cable) const
bool hasStoredPacket() const
MIDIUSBPacket_t storedPacket
MIDIUSBPacket_t popStoredPacket()
MIDIReadEvent feed(MIDIUSBPacket_t packet)
Feed a new packet to the parser.
MIDIReadEvent pull(BytePuller &&puller)
Parse one incoming MIDI message.
void addSysExByte(Cable cable, uint8_t data)
void endSysEx(Cable cable)
void addSysExBytes(Cable cable, const uint8_t *data, uint8_t len)
MIDIReadEvent handleSysCommon(MIDIUSBPacket_t packet, Cable cable)
SysExMessage getSysExMessage() const
Get the latest SysEx message.
AH::Array< uint8_t, 4 > MIDIUSBPacket_t