Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
SerialMIDI_Parser.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "MIDI_Parser.hpp"
4#include "SysExBuffer.hpp"
5
7
14 public:
17
26 template <class BytePuller>
27 MIDIReadEvent pull(BytePuller &&puller);
28
29 protected:
31 MIDIReadEvent feed(uint8_t midibyte);
34
35#if !IGNORE_SYSEX
36 public:
41
42 protected:
43 void addSysExByte(uint8_t data) { sysexbuffer.add(data); }
44 bool hasSysExSpace() const { return sysexbuffer.hasSpaceLeft(); }
46 void endSysEx() { sysexbuffer.end(); }
47
49#endif
50
51 protected:
52 MIDIReadEvent handleRealTime(uint8_t midiByte);
53 MIDIReadEvent handleNonRealTimeStatus(uint8_t midiByte);
54 MIDIReadEvent handleStatus(uint8_t midiByte);
55 MIDIReadEvent handleData(uint8_t midiByte);
56
57 protected:
61 void storeByte(uint8_t midiByte) { storedByte = midiByte; }
64 bool hasStoredByte() const { return storedByte != 0xFF; }
66 uint8_t popStoredByte() {
67 uint8_t t = storedByte;
68 storedByte = 0xFF;
69 return t;
70 }
71
72 public:
76
77 private:
82 bool thirdByte = false;
86 uint8_t currentHeader = 0;
88 uint8_t runningHeader = 0;
90 uint8_t storedByte = 0xFF;
91};
92
93template <class BytePuller>
94inline MIDIReadEvent SerialMIDI_Parser::pull(BytePuller &&puller) {
95 // First try resuming the parser, we might have a stored byte that has to
96 // be parsed first.
97 MIDIReadEvent evt = resume();
99 return evt;
100
101 // If resumption didn't produce a message, read new bytes from the input and
102 // parse them until either we get a message, or until the input runs out of
103 // new bytes.
104 uint8_t midiByte;
105 while (puller.pull(midiByte)) {
106 evt = feed(midiByte);
107 if (evt != MIDIReadEvent::NO_MESSAGE)
108 return evt;
109 }
111}
112
MIDIReadEvent
Values returned by the MIDI reading functions.
@ NO_MESSAGE
No new messages were received.
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Base class for MIDI parsers.
Parser for Serial MIDI streams (and BLE-MIDI).
MIDIReadEvent resume()
Resume the parser with the previously stored and unhandled byte.
SerialMIDI_Parser(bool sysCommonCancelsRunningStatus=true)
bool sysCommonCancelsRunningStatus
Accounts for running status differences between MIDI 1.0 and BLE-MIDI.
uint8_t currentHeader
Current header (not necessarily running), contains the header of the message that's currently being r...
MIDIReadEvent handleNonRealTimeStatus(uint8_t midiByte)
MIDIReadEvent handleRealTime(uint8_t midiByte)
uint8_t runningHeader
Running status header.
bool hasStoredByte() const
Check whether there's a stored byte.
uint8_t popStoredByte()
Get the stored byte. Afterwards, hasStoredByte will return false.
MIDIReadEvent pull(BytePuller &&puller)
Parse one incoming MIDI message.
MIDIReadEvent feed(uint8_t midibyte)
Feed a new byte to the parser.
void storeByte(uint8_t midiByte)
Store a byte to parse later.
MIDIReadEvent handleData(uint8_t midiByte)
SysExMessage getSysExMessage() const
Get the latest SysEx message.
bool thirdByte
Flag that remembers that the next data byte will be the third byte of a message.
void addSysExByte(uint8_t data)
void cancelRunningStatus()
Clear the running status header for MIDI Channel messages.
MIDIReadEvent handleStatus(uint8_t midiByte)
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.