Control Surface
main
MIDI Control Surface library for Arduino
Toggle main menu visibility
Loading...
Searching...
No Matches
src
MIDI_Parsers
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
7
BEGIN_CS_NAMESPACE
8
16
class
BLEMIDIParser
{
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
53
void
extend
(
const
uint8_t *
data
,
size_t
length) {
54
this->data =
data
;
55
this->
end
=
data
+ length;
56
}
57
60
bool
pull
(uint8_t &output) {
61
while
(
data
!=
end
) {
62
// Simply pass on all normal data bytes to the MIDI parser.
63
if
(
isData
(*
data
)) {
64
output = *
data
++;
65
prevWasTimestamp
=
false
;
66
return
true
;
67
}
68
// If it's not a data byte, it's either a timestamp byte or a
69
// MIDI status byte.
70
else
{
71
// Timestamp bytes and MIDI status bytes should alternate.
72
prevWasTimestamp
= !
prevWasTimestamp
;
73
// If the previous non-data byte was a timestamp, this one is
74
// a MIDI status byte, so send it to the MIDI parser.
75
if
(!
prevWasTimestamp
) {
76
output = *
data
++;
77
return
true
;
78
}
79
// Otherwise it's a time stamp
80
else
{
81
uint16_t timestampLow = *
data
++ & 0x7F;
82
// The BLE MIDI spec has the following to say about overflow:
83
// > Should the timestamp value of a subsequent MIDI message
84
// > in the same packet overflow/wrap (i.e., the
85
// > timestampLow is smaller than a preceding timestampLow),
86
// > the receiver is responsible for tracking this by
87
// > incrementing the timestampHigh by one (the incremented
88
// > value is not transmitted, only understood as a result
89
// > of the overflow condition).
90
if
(timestampLow < (
timestamp
& 0x7F))
// overflow
91
timestamp
+= 0x80;
92
timestamp
= (
timestamp
& 0x3F80) | timestampLow;
93
}
94
}
95
}
96
return
false
;
97
}
98
99
uint16_t
getTimestamp
()
const
{
return
timestamp
; }
100
101
private
:
102
const
uint8_t *
data
;
103
const
uint8_t *
end
;
104
bool
prevWasTimestamp
=
true
;
105
uint16_t
timestamp
= 0;
106
107
private
:
110
static
bool
isData
(uint8_t
data
) {
return
(
data
& (1 << 7)) == 0; }
111
};
112
113
END_CS_NAMESPACE
NamespaceSettings.hpp
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition
Settings/NamespaceSettings.hpp:14
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition
Settings/NamespaceSettings.hpp:11
BLEMIDIParser::end
const uint8_t * end
Definition
BLEMIDIParser.hpp:103
BLEMIDIParser::extend
void extend(const uint8_t *data, size_t length)
Extend the BLE packet with the given buffer.
Definition
BLEMIDIParser.hpp:53
BLEMIDIParser::isData
static bool isData(uint8_t data)
Check if the given byte is a data byte (and not a header, timestamp or status byte).
Definition
BLEMIDIParser.hpp:110
BLEMIDIParser::pull
bool pull(uint8_t &output)
Get the next MIDI byte from the BLE packet (if available).
Definition
BLEMIDIParser.hpp:60
BLEMIDIParser::data
const uint8_t * data
Definition
BLEMIDIParser.hpp:102
BLEMIDIParser::prevWasTimestamp
bool prevWasTimestamp
Definition
BLEMIDIParser.hpp:104
BLEMIDIParser::timestamp
uint16_t timestamp
Definition
BLEMIDIParser.hpp:105
BLEMIDIParser::BLEMIDIParser
BLEMIDIParser(const uint8_t *data, size_t length)
Definition
BLEMIDIParser.hpp:18
BLEMIDIParser::getTimestamp
uint16_t getTimestamp() const
Definition
BLEMIDIParser.hpp:99
Generated by
1.17.0