Control Surface new-input
MIDI Control Surface library for Arduino
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:
40  }
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 handleStatus(uint8_t midiByte);
54  MIDIReadEvent handleData(uint8_t midiByte);
55 
56  protected:
60  void storeByte(uint8_t midiByte) { storedByte = midiByte; }
63  bool hasStoredByte() const { return storedByte != 0xFF; }
65  uint8_t popStoredByte() {
66  uint8_t t = storedByte;
67  storedByte = 0xFF;
68  return t;
69  }
70 
71  public:
75 
76  private:
81  bool thirdByte = false;
85  uint8_t currentHeader = 0;
87  uint8_t runningHeader = 0;
89  uint8_t storedByte = 0xFF;
90 };
91 
92 template <class BytePuller>
93 inline MIDIReadEvent SerialMIDI_Parser::pull(BytePuller &&puller) {
94  // First try resuming the parser, we might have a stored byte that has to
95  // be parsed first.
96  MIDIReadEvent evt = resume();
97  if (evt != MIDIReadEvent::NO_MESSAGE)
98  return evt;
99 
100  // If resumption didn't produce a message, read new bytes from the input and
101  // parse them until either we get a message, or until the input runs out of
102  // new bytes.
103  uint8_t midiByte;
104  while (puller.pull(midiByte)) {
105  evt = feed(midiByte);
106  if (evt != MIDIReadEvent::NO_MESSAGE)
107  return evt;
108  }
110 }
111 
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.
Definition: MIDI_Parser.hpp:16
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 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.
bool hasSysExSpace() const
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.
Definition: SysExBuffer.hpp:13
const uint8_t * getBuffer() const
Get a pointer to the buffer.
Definition: SysExBuffer.cpp:34
bool hasSpaceLeft(uint8_t amount=1) const
Check if the buffer has at least amount bytes of free space available.
Definition: SysExBuffer.cpp:25
void start()
Start a new SysEx message.
Definition: SysExBuffer.cpp:6
void add(uint8_t data)
Add a byte to the current SysEx message.
Definition: SysExBuffer.cpp:15
void end()
Finish the current SysEx message.
Definition: SysExBuffer.cpp:11
uint16_t getLength() const
Get the length of the SysEx message in the buffer.
Definition: SysExBuffer.cpp:36