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