This is an old version of the documentation. View the latest version here.
Control Surface  1.0.0
MIDI Control Surface library for Arduino
BluetoothMIDI_Interface.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "BLEMIDI.hpp"
5 
6 #include <Helpers/Error.hpp>
7 
9 
16  public BLEServerCallbacks,
17  public BLECharacteristicCallbacks {
18 
19  // BLE Callbacks
20 
21  void onConnect(UNUSED_PARAM BLEServer *pServer) override {
22  DEBUGFN("Connected");
23  connected++;
24  };
25  void onDisconnect(UNUSED_PARAM BLEServer *pServer) override {
26  DEBUGFN("Disonnected");
27  if (!connected) {
28  ERROR(F("Error: disconnect event, but was not connected"), 0x7788);
29  return;
30  }
31  connected--;
32  }
33 
34  void onRead(BLECharacteristic *pCharacteristic) override {
35  DEBUGFN("Read");
36  pCharacteristic->setValue(nullptr, 0);
37  }
38  void onWrite(BLECharacteristic *pCharacteristic) override {
39  DEBUGFN("Write: ");
40  std::string value = pCharacteristic->getValue();
41  const uint8_t *const data =
42  reinterpret_cast<const uint8_t *>(value.data());
43  size_t len = value.size();
44  for (size_t i = 0; i < len; i++) {
45  Serial.print(data[i], HEX);
46  Serial.print(' ');
47  }
48  Serial.println();
49  parse(data, len);
50  }
51 
52  constexpr static unsigned long MAX_MESSAGE_TIME = 10000; // microseconds
53 
54  unsigned long startTime = 0;
55 
56  constexpr static size_t BUFFER_LENGTH = 1024;
57 
58  uint8_t buffer[BUFFER_LENGTH] = {};
59  size_t index = 0;
60 
62 
64 
65  uint8_t connected = 0;
66 
67  bool hasSpaceFor(size_t bytes) { return index + bytes < BUFFER_LENGTH; }
68 
69  public:
71 
72  void begin() override { bleMidi.begin(this, this); }
73 
74  void publish() {
75  if (index == 0)
76  return;
77  if (!connected) {
78  DEBUGFN("No connected BLE clients");
79  return;
80  }
82  index = 0;
83  }
84 
85  MIDI_read_t read() override {
86  update(); // TODO
87  return NO_MESSAGE; // TODO
88  }
89 
90  template <size_t N>
91  void addToBuffer(const uint8_t (&data)[N]) {
92  addToBuffer(&data[0], N);
93  }
94 
95  void addToBuffer(const uint8_t *data, size_t len) {
96  bool first = index == 0;
97  if (!hasSpaceFor(len + 1 + first)) { // TODO
98  DEBUGFN("Buffer full");
99  publish();
100  if (!hasSpaceFor(len + 1 + first)) { // TODO
101  DEBUGFN("Message is larger than buffer");
102  return;
103  }
104  }
105 
106  if (first)
107  startTime = micros();
108 
109  if (first)
110  buffer[index++] = 0x80; // header / timestamp msb
111  buffer[index++] = 0x80; // timestamp lsb
112  memcpy(&buffer[index], data, len);
113  index += len;
114 
115  update();
116  }
117 
118  void update() override {
119  if (micros() - startTime >= MAX_MESSAGE_TIME)
120  publish();
121  }
122 
123  void sendImpl(uint8_t m, uint8_t c, uint8_t d1, uint8_t d2,
124  uint8_t cn) override {
125  (void)cn;
126  uint8_t msg[3] = {uint8_t(m | c), d1, d2};
127  addToBuffer(msg);
128  }
129  void sendImpl(uint8_t m, uint8_t c, uint8_t d1, uint8_t cn) override {
130  (void)cn;
131  uint8_t msg[2] = {uint8_t(m | c), d1};
132  addToBuffer(msg);
133  }
134 
135  void sendImpl(const uint8_t *data, size_t length, uint8_t cn) override {
136  (void)data;
137  (void)length;
138  (void)cn; // TODO
139  }
140 
141  void sendImpl(uint8_t rt, uint8_t cn) override {
142  (void)rt;
143  (void)cn; // TODO
144  }
145 
146  void parse(const uint8_t *const data, const size_t len) {
147  if (len <= 1)
148  return;
149  if (MIDI_Parser::isData(data[0]))
150  return;
151  if (MIDI_Parser::isData(data[1]))
152  parse(data[1]);
153  bool prevWasTimestamp = true;
154  for (const uint8_t *d = data + 2; d < data + len; d++) {
155  if (MIDI_Parser::isData(*d)) {
156  parse(*d);
157  prevWasTimestamp = false;
158  } else {
159  if (prevWasTimestamp)
160  parse(*d);
161  prevWasTimestamp = !prevWasTimestamp;
162  }
163  }
164  }
165 
166  void parse(uint8_t data) {
167  MIDI_read_t event = parser.parse(data);
168  dispatchMIDIEvent(event);
169  }
170 
171  BLEMIDI &getBLEMIDI() { return bleMidi; }
172 };
173 
BluetoothMIDI_Interface::parse
void parse(const uint8_t *const data, const size_t len)
Definition: BluetoothMIDI_Interface.hpp:146
BluetoothMIDI_Interface::addToBuffer
void addToBuffer(const uint8_t(&data)[N])
Definition: BluetoothMIDI_Interface.hpp:91
BluetoothMIDI_Interface
Bluetooth Low Energy MIDI Interface for the ESP32.
Definition: BluetoothMIDI_Interface.hpp:15
BluetoothMIDI_Interface::parse
void parse(uint8_t data)
Definition: BluetoothMIDI_Interface.hpp:166
BluetoothMIDI_Interface::read
MIDI_read_t read() override
Definition: BluetoothMIDI_Interface.hpp:85
Parsing_MIDI_Interface::dispatchMIDIEvent
bool dispatchMIDIEvent(MIDI_read_t event)
Definition: MIDI_Interface.cpp:143
ERROR
#define ERROR(x, e)
Definition: Error.hpp:27
Error.hpp
BluetoothMIDI_Interface::publish
void publish()
Definition: BluetoothMIDI_Interface.hpp:74
Parsing_MIDI_Interface
An abstract class for MIDI interfaces.
Definition: MIDI_Interface.hpp:188
BluetoothMIDI_Interface::onConnect
void onConnect(UNUSED_PARAM BLEServer *pServer) override
Definition: BluetoothMIDI_Interface.hpp:21
BluetoothMIDI_Interface::addToBuffer
void addToBuffer(const uint8_t *data, size_t len)
Definition: BluetoothMIDI_Interface.hpp:95
SerialMIDI_Interface.hpp
BluetoothMIDI_Interface::onDisconnect
void onDisconnect(UNUSED_PARAM BLEServer *pServer) override
Definition: BluetoothMIDI_Interface.hpp:25
SerialMIDI_Parser::parse
MIDI_read_t parse(uint8_t midibyte)
Definition: SerialMIDI_Parser.cpp:5
MIDI_read_t
MIDI_read_t
Definition: MIDI_Parser.hpp:29
BluetoothMIDI_Interface::BluetoothMIDI_Interface
BluetoothMIDI_Interface()
Definition: BluetoothMIDI_Interface.hpp:70
BluetoothMIDI_Interface::index
size_t index
Definition: BluetoothMIDI_Interface.hpp:59
BluetoothMIDI_Interface::onWrite
void onWrite(BLECharacteristic *pCharacteristic) override
Definition: BluetoothMIDI_Interface.hpp:38
BluetoothMIDI_Interface::getBLEMIDI
BLEMIDI & getBLEMIDI()
Definition: BluetoothMIDI_Interface.hpp:171
MIDI_Parser::isData
static bool isData(uint8_t data)
Check if the given byte is a MIDI data byte.
Definition: MIDI_Parser.cpp:15
BluetoothMIDI_Interface::connected
uint8_t connected
Definition: BluetoothMIDI_Interface.hpp:65
UNUSED_PARAM
#define UNUSED_PARAM
Definition: Def.hpp:79
BluetoothMIDI_Interface::startTime
unsigned long startTime
Definition: BluetoothMIDI_Interface.hpp:54
BluetoothMIDI_Interface::sendImpl
void sendImpl(uint8_t m, uint8_t c, uint8_t d1, uint8_t cn) override
Low-level function for sending a 2-byte MIDI message.
Definition: BluetoothMIDI_Interface.hpp:129
BLEMIDI::begin
void begin(BLEServerCallbacks *serverCallbacks, BLECharacteristicCallbacks *midiCallbacks)
Definition: BLEMIDI.hpp:52
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: NamespaceSettings.hpp:9
BluetoothMIDI_Interface::sendImpl
void sendImpl(const uint8_t *data, size_t length, uint8_t cn) override
Low-level function for sending a system exclusive MIDI message.
Definition: BluetoothMIDI_Interface.hpp:135
BluetoothMIDI_Interface::onRead
void onRead(BLECharacteristic *pCharacteristic) override
Definition: BluetoothMIDI_Interface.hpp:34
DEBUGFN
#define DEBUGFN(x)
Definition: Debug.hpp:164
BluetoothMIDI_Interface::update
void update() override
Read the MIDI interface and call the callback if a message is received.
Definition: BluetoothMIDI_Interface.hpp:118
NO_MESSAGE
Definition: MIDI_Parser.hpp:30
SerialMIDI_Parser
Definition: SerialMIDI_Parser.hpp:8
BLEMIDI.hpp
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: NamespaceSettings.hpp:10
BluetoothMIDI_Interface::buffer
uint8_t buffer[BUFFER_LENGTH]
Definition: BluetoothMIDI_Interface.hpp:58
BLEMIDI::notifyValue
void notifyValue(uint8_t *data, size_t len)
Definition: BLEMIDI.hpp:92
BluetoothMIDI_Interface::sendImpl
void sendImpl(uint8_t m, uint8_t c, uint8_t d1, uint8_t d2, uint8_t cn) override
Low-level function for sending a 3-byte MIDI message.
Definition: BluetoothMIDI_Interface.hpp:123
BluetoothMIDI_Interface::MAX_MESSAGE_TIME
constexpr static unsigned long MAX_MESSAGE_TIME
Definition: BluetoothMIDI_Interface.hpp:52
BLEMIDI
Definition: BLEMIDI.hpp:24
BluetoothMIDI_Interface::sendImpl
void sendImpl(uint8_t rt, uint8_t cn) override
Low-level function for sending a single-byte MIDI message.
Definition: BluetoothMIDI_Interface.hpp:141
BluetoothMIDI_Interface::parser
SerialMIDI_Parser parser
Definition: BluetoothMIDI_Interface.hpp:61
BluetoothMIDI_Interface::bleMidi
BLEMIDI bleMidi
Definition: BluetoothMIDI_Interface.hpp:63
BluetoothMIDI_Interface::begin
void begin() override
Initialize the MIDI Interface.
Definition: BluetoothMIDI_Interface.hpp:72
BluetoothMIDI_Interface::BUFFER_LENGTH
constexpr static size_t BUFFER_LENGTH
Definition: BluetoothMIDI_Interface.hpp:56
BluetoothMIDI_Interface::hasSpaceFor
bool hasSpaceFor(size_t bytes)
Definition: BluetoothMIDI_Interface.hpp:67
MIDI_Notes::F
constexpr int8_t F
Definition: Notes.hpp:23