1#if !defined(ARDUINO) || defined(ESP32) || defined(DOXYGEN)
15 auto send_loop = [
this] {
51 assert(lock.owns_lock());
64 assert(lock.owns_lock());
86 const std::vector<uint8_t> &packet) {
104 uint16_t timestamp = millis();
122 uint16_t timestamp = millis();
135 uint16_t timestamp = millis();
148 uint16_t timestamp = millis();
163 size_t length = msg.
length;
164 const uint8_t *data = msg.
data;
165 uint16_t timestamp = millis();
168 if ((timestamp & 0x77) == 0x77)
201 mididata.getTimestamp()))
202 std::this_thread::yield();
207 mididata.getTimestamp()))
208 std::this_thread::yield();
212 mididata.getTimestamp()))
213 std::this_thread::yield();
217 mididata.getTimestamp()))
218 std::this_thread::yield();
269 if (force_min_mtu_c == 0)
309 DEBUGFN(F(
"Initializing BLE MIDI Interface"));
311 ERROR(F(
"Error initializing BLE MIDI interface"), 0x2022);
320 DEBUGFN(F(
"Deinitializing BLE MIDI Interface"));
322 ERROR(F(
"Error deinitializing BLE MIDI interface"), 0x2023);
void BluetoothMIDI_Interface_midi_mtu_callback(uint16_t mtu)
void BluetoothMIDI_Interface_midi_write_callback(const uint8_t *data, size_t length)
MIDIReadEvent
Values returned by the MIDI reading functions.
@ CHANNEL_MESSAGE
A MIDI Channel message was received.
@ SYSEX_CHUNK
An incomplete System Exclusive message.
@ SYSCOMMON_MESSAGE
A MIDI System Common message was received.
@ NO_MESSAGE
No new messages were received.
@ SYSEX_MESSAGE
A MIDI System Exclusive message was received.
@ REALTIME_MESSAGE
A MIDI Real-Time message was received.
#define BEGIN_CS_NAMESPACE
uint16_t getSize() const
Get the size of the current packet.
void setCapacity(uint16_t capacity)
Set the maximum capacity of the buffer.
void continueSysEx(const uint8_t *&data, size_t &length, uint16_t timestamp)
Add a SysEx continuation to the packet.
bool addSysEx(const uint8_t *&data, size_t &length, uint16_t timestamp)
Try adding (part of) a SysEx message to the packet.
bool empty() const
Check if the packet buffer is empty.
bool add2B(uint8_t header, uint8_t data1, uint16_t timestamp)
Try adding a 2-byte MIDI channel voice message to the packet.
bool addSysCommon(uint8_t num_data, uint8_t header, uint8_t data1, uint8_t data2, uint16_t timestamp)
Try adding a MIDI system common message to the packet.
bool addRealTime(uint8_t rt, uint16_t timestamp)
Try adding a MIDI real-time message to the packet.
const std::vector< uint8_t > & getPacket() const
Return the packet as a vector of bytes.
void reset()
Reset the builder to start a new packet.
bool add3B(uint8_t header, uint8_t data1, uint8_t data2, uint16_t timestamp)
Try adding a 3-byte MIDI channel voice message to the packet.
Class for parsing BLE-MIDI packets.
Bluetooth Low Energy MIDI Interface for the ESP32.
ChannelMessage getChannelMessage() const
Return the received channel voice message.
RealTimeMessage getRealTimeMessage() const
Return the received real-time message.
std::condition_variable cv
Condition variable used by the background sender thread to wait for data to send, and for the main th...
std::unique_lock< std::mutex > lock_t
Lock type used to lock the mutex.
std::chrono::milliseconds timeout
Timeout before the sender thread sends a packet.
MIDIMessageQueue::MIDIMessageQueueElement incomingMessage
Incoming message that can be from retrieved using the getChannelMessage(), getSysCommonMessage(),...
bool handleSendEvents()
Function that waits for BLE packets and sends them in the background.
void sendChannelMessageImpl(ChannelMessage) override
Low-level function for sending a MIDI channel voice message.
void parse(const uint8_t *const data, const size_t len)
void forceMinMTU(uint16_t mtu)
Force the MTU to an artificially small value (used for testing).
static BluetoothMIDI_Interface * instance
Only one active instance.
SysCommonMessage getSysCommonMessage() const
Return the received system common message.
void sendRealTimeImpl(RealTimeMessage) override
Low-level function for sending a MIDI real-time message.
std::atomic_uint_fast16_t force_min_mtu
Override the minimum MTU (0 means don't override, nonzero overrides if it's smaller than the minimum ...
void flushImpl(lock_t &lock)
Tell the background BLE sender thread to send the current packet.
void begin() override
Initialize this updatable.
BLEMIDIPacketBuilder packetbuilder
Builds outgoing MIDI BLE packets.
MIDIMessageQueue queue
Queue for incoming MIDI messages.
void sendChannelMessageImpl2Bytes(ChannelMessage)
void stopSendingThread()
Tell the background BLE sender thread to stop gracefully, and join it.
void sendSysExImpl(SysExMessage) override
Low-level function for sending a system exclusive MIDI message.
static void midi_mtu_callback(uint16_t mtu)
void startSendingThread()
Launch a thread that sends the BLE packets in the background.
void sendChannelMessageImpl3Bytes(ChannelMessage)
void sendSysCommonImpl(SysCommonMessage) override
Low-level function for sending a MIDI system common message.
void setName(const char *name)
Set the BLE device name. Must be called before begin().
bool flushnow
Flag to tell the sender thread to send the packet immediately.
std::thread send_thread
Background thread that sends the actual MIDI BLE packets.
void notifyMIDIBLE(const std::vector< uint8_t > &packet)
std::mutex mtx
Mutex to lock the MIDI BLE packet builder and the flush flag.
void updateMTU(uint16_t mtu)
Set the maximum transmission unit of the Bluetooth link.
std::atomic_bool stop_sending
Flag to stop the background thread.
SysExMessage getSysExMessage() const
Return the received system exclusive message.
std::atomic_uint_fast16_t min_mtu
The minimum MTU of all connected clients.
SerialMIDI_Parser parser
MIDI Parser for incoming data.
uint16_t getTimestamp() const
Get the BLE-MIDI timestamp of the latest MIDI message.
static void midi_write_callback(const uint8_t *data, size_t length)
bool push(ChannelMessage message, uint16_t timestamp)
bool pop(MIDIMessageQueueElement &message)
ChannelMessage getChannelMessage() const
Get the latest MIDI channel voice message.
RealTimeMessage getRealTimeMessage() const
Get the latest MIDI real-time message.
SysCommonMessage getSysCommonMessage() const
Get the latest MIDI system common message.
MIDIReadEvent pull(BytePuller &&puller)
Parse one incoming MIDI message.
SysExMessage getSysExMessage() const
Get the latest SysEx message.
void cancelRunningStatus()
Clear the running status header for MIDI Channel messages.
#define NAMEDVALUE(x)
Macro for printing an expression as a string, followed by its value.
#define DEBUGFN(x)
Print an expression and its function (function name and line number) to the debug output if debugging...
constexpr auto min(const T &a, const U &b) -> decltype(b< a ? b :a)
Return the smaller of two numbers/objects.
Public MIDI over Bluetooth Low Energy API.
bool midi_deinit()
Cleanup the MIDI BLE application and de-initialize the Bluetooth stack.
bool midi_init()
Initialize the Bluetooth stack and register the MIDI BLE application with the Bluedroid driver.
void midi_set_write_callback(midi_write_callback_t cb)
Set the callback that is to be called when the client writes (sends) a MIDI packet.
void midi_set_mtu_callback(midi_mtu_callback_t cb)
Set the callback that is to be called when the MTU negotiation with the BLE client is finished.
bool midi_notify(const uint8_t *data, size_t len)
Send a MIDI BLE notification to the client.
void set_midi_ble_name(const char *name)
Set the name of the BLE device. Must be set before calling midi_init().
bool hasTwoDataBytes() const
Check whether this message has one or two data bytes.
union MIDIMessageQueue::MIDIMessageQueueElement::Message message
uint8_t data2
First MIDI data byte.
uint8_t header
MIDI status byte (message type and channel).
uint8_t data1
First MIDI data byte.
uint8_t getNumberOfDataBytes() const
Get the number of data bytes of this type of System Common message.
ChannelMessage channelmessage
RealTimeMessage realtimemessage
SysCommonMessage syscommonmessage
SysExMessage sysexmessage