Control Surface pin-t-adl
MIDI Control Surface library for Arduino
BLEMIDIParser.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <Settings/NamespaceSettings.hpp>
4#include <stddef.h>
5#include <stdint.h>
6
8
17 public:
18 BLEMIDIParser(const uint8_t *data, size_t length)
19 : data(data), end(data + length) {
20 // Need at least two bytes to be useful.
21 // Usually, we have header, timestamp and at least one MIDI byte,
22 // but a SysEx continuation could perhaps have only a header and a
23 // single data byte (this is not explicitly allowed by the spec, but
24 // handling this case requires no extra effort)
25 if (length < 2) {
26 this->data = end;
27 }
28 // First byte should be a header. If it's a data byte, discard packet.
29 else if (isData(data[0])) {
30 this->data = end;
31 }
32 // If the second byte is a data byte, this is a SysEx continuation
33 // packet
34 else if (isData(data[1])) {
35 this->timestamp = data[0] & 0x7F;
36 this->timestamp <<= 7;
37 this->data += 1;
38 }
39 // Otherwise, the second byte is a timestamp, so skip it
40 else {
41 this->timestamp = data[0] & 0x7F;
42 this->timestamp <<= 7;
43 this->timestamp |= data[1] & 0x7F;
44 this->data += 2;
45 }
46 }
47
50 bool pull(uint8_t &output) {
51 while (data != end) {
52 // Simply pass on all normal data bytes to the MIDI parser.
53 if (isData(*data)) {
54 output = *data++;
55 prevWasTimestamp = false;
56 return true;
57 }
58 // If it's not a data byte, it's either a timestamp byte or a
59 // MIDI status byte.
60 else {
61 // Timestamp bytes and MIDI status bytes should alternate.
63 // If the previous non-data byte was a timestamp, this one is
64 // a MIDI status byte, so send it to the MIDI parser.
65 if (!prevWasTimestamp) {
66 output = *data++;
67 return true;
68 }
69 // Otherwise it's a time stamp
70 else {
71 timestamp = (timestamp & 0x3F80) | (*data++ & 0x7F);
72 }
73 }
74 }
75 return false;
76 }
77
78 uint16_t getTimestamp() const { return timestamp; }
79
80 private:
81 const uint8_t *data;
82 const uint8_t *const end;
83 bool prevWasTimestamp = true;
84 uint16_t timestamp = 0;
85
86 private:
89 static bool isData(uint8_t data) { return (data & (1 << 7)) == 0; }
90};
91
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Class for parsing BLE-MIDI packets.
static bool isData(uint8_t data)
Check if the given byte is a data byte (and not a header, timestamp or status byte).
bool pull(uint8_t &output)
Get the next MIDI byte from the BLE packet (if available).
const uint8_t *const end
const uint8_t * data
uint16_t timestamp
BLEMIDIParser(const uint8_t *data, size_t length)
uint16_t getTimestamp() const