From 20ff691133fa2517a43f2809b98fc73b9df841f5 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sun, 27 Sep 2020 14:02:42 +0200 Subject: [PATCH] cleaned esp32 (& NimBLE implementation), moved parser down --- examples/MidiBle/MidiBle.ino | 6 +- library.properties | 9 +- src/BLE-MIDI.h | 107 +++++++++++++ src/hardware/ESP32_NimBLE.h | 248 ------------------------------- src/hardware/MIDI_ESP32.h | 115 ++------------ src/hardware/MIDI_ESP32_NimBLE.h | 115 ++------------ 6 files changed, 139 insertions(+), 461 deletions(-) delete mode 100644 src/hardware/ESP32_NimBLE.h diff --git a/examples/MidiBle/MidiBle.ino b/examples/MidiBle/MidiBle.ino index d7d60cb..6da41cc 100644 --- a/examples/MidiBle/MidiBle.ino +++ b/examples/MidiBle/MidiBle.ino @@ -1,6 +1,6 @@ #include -#include -//#include +//#include +#include //#include //#include @@ -15,7 +15,7 @@ bool isConnected = false; // ----------------------------------------------------------------------------- void setup() { - Serial.begin(115200); // initialize serial communication + Serial.begin(115200); while (!Serial); MIDI.begin(); diff --git a/library.properties b/library.properties index f07e99e..2b13cc6 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,11 @@ name=BLE-MIDI -version=2.0.1 +version=2.1.0 author=lathoub maintainer=lathoub -sentence=MIDI over Bluetooth Low Energy (BLE-MIDI) 1.0 for Arduino -paragraph=MIDI over Bluetooth Low Energy +sentence=BLE-MIDI I/Os for Arduino +paragraph=MIDI over Bluetooth Low Energy (BLE-MIDI) 1.0 for Arduino category=Communication url=https://github.com/lathoub/Arduino-BLE-MIDI -architectures=* +architectures=esp32,samd,megaavr,mbed includes=BLE-MIDI.h +depends=MIDI Library, NimBLE-Arduino, ArduinoBLE diff --git a/src/BLE-MIDI.h b/src/BLE-MIDI.h index d7b42ce..c987115 100755 --- a/src/BLE-MIDI.h +++ b/src/BLE-MIDI.h @@ -162,6 +162,113 @@ public: _disconnectedCallback = fptr; } + /* + The general form of a MIDI message follows: + n-byte MIDI Message + Byte 0 MIDI message Status byte, Bit 7 is Set to 1. + Bytes 1 to n-1 MIDI message Data bytes, if n > 1. Bit 7 is Set to 0 + There are two types of MIDI messages that can appear in a single packet: full MIDI messages and + Running Status MIDI messages. Each is encoded differently. + A full MIDI message is simply the MIDI message with the Status byte included. + A Running Status MIDI message is a MIDI message with the Status byte omitted. Running Status + MIDI messages may only be placed in the data stream if the following criteria are met: + 1. The original MIDI message is 2 bytes or greater and is not a System Common or System + Real-Time message. + 2. The omitted Status byte matches the most recently preceding full MIDI message’s Status + byte within the same BLE packet. + In addition, the following rules apply with respect to Running Status: + 1. A Running Status MIDI message is allowed within the packet after at least one full MIDI + message. + 2. Every MIDI Status byte must be preceded by a timestamp byte. Running Status MIDI + messages may be preceded by a timestamp byte. If a Running Status MIDI message is not + preceded by a timestamp byte, the timestamp byte of the most recently preceding message + in the same packet is used. + 3. System Common and System Real-Time messages do not cancel Running Status if + interspersed between Running Status MIDI messages. However, a timestamp byte must + precede the Running Status MIDI message that follows. + 4. The end of a BLE packet does cancel Running Status. + In the MIDI 1.0 protocol, System Real-Time messages can be sent at any time and may be + inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other + MIDI messages. In the MIDI BLE protocol, the System Real-Time messages must be deinterleaved + from other messages – except for System Exclusive messages. + */ + void receive(uint8_t* buffer, size_t length) + { + // Pointers used to search through payload. + uint8_t lPtr = 0; + uint8_t rPtr = 0; + // lastStatus used to capture runningStatus + uint8_t lastStatus; + // Decode first packet -- SHALL be "Full MIDI message" + lPtr = 2; //Start at first MIDI status -- SHALL be "MIDI status" + + //While statement contains incrementing pointers and breaks when buffer size exceeded. + while (true) + { + lastStatus = buffer[lPtr]; + + if( (buffer[lPtr] < 0x80)) + return; // Status message not present, bail + + // Point to next non-data byte + rPtr = lPtr; + while( (buffer[rPtr + 1] < 0x80) && (rPtr < (length - 1)) ) + rPtr++; + if (buffer[rPtr + 1] == 0xF7) rPtr++; + + // look at l and r pointers and decode by size. + if( rPtr - lPtr < 1 ) { + // Time code or system + mBleClass.add(&lastStatus); + } else if( rPtr - lPtr < 2 ) { + mBleClass.add(&lastStatus); + mBleClass.add(&buffer[lPtr + 1]); + } else if( rPtr - lPtr < 3 ) { + mBleClass.add(&lastStatus); + mBleClass.add(&buffer[lPtr + 1]); + mBleClass.add(&buffer[lPtr + 2]); + } else { + // Too much data + // If not System Common or System Real-Time, send it as running status + switch(buffer[lPtr] & 0xF0) + { + case 0x80: + case 0x90: + case 0xA0: + case 0xB0: + case 0xE0: + for (auto i = lPtr; i < rPtr; i = i + 2) + { + mBleClass.add(&lastStatus); + mBleClass.add(&buffer[i + 1]); + mBleClass.add(&buffer[i + 2]); + } + break; + case 0xC0: + case 0xD0: + for (auto i = lPtr; i < rPtr; i = i + 1) + { + mBleClass.add(&lastStatus); + mBleClass.add(&buffer[i + 1]); + } + break; + case 0xF0: + mBleClass.add(&buffer[lPtr]); + for (auto i = lPtr; i < rPtr; i++) + mBleClass.add(&buffer[i + 1]); + break; + default: + break; + } + } + + // Point to next status + lPtr = rPtr + 2; + if(lPtr >= length) + return; //end of packet + } + } + }; END_BLEMIDI_NAMESPACE diff --git a/src/hardware/ESP32_NimBLE.h b/src/hardware/ESP32_NimBLE.h deleted file mode 100644 index e7c266d..0000000 --- a/src/hardware/ESP32_NimBLE.h +++ /dev/null @@ -1,248 +0,0 @@ -#pragma once - -// Headers for ESP32 NimBLE -#include - -BEGIN_BLEMIDI_NAMESPACE - -class BLEMIDI_ESP32 -{ -private: - BLEServer* _server = nullptr; - BLEAdvertising* _advertising = nullptr; - BLECharacteristic* _characteristic = nullptr; - - BLEMIDITransport* _bleMidiTransport = nullptr; - -protected: - QueueHandle_t mRxQueue; - -public: - BLEMIDI_ESP32() - { - } - - bool begin(const char*, BLEMIDITransport*); - - void write(uint8_t* buffer, size_t length) - { - _characteristic->setValue(buffer, length); - _characteristic->notify(); - } - - bool available(void *pvBuffer) - { - return xQueueReceive(mRxQueue, pvBuffer, 0); // return immediately when the queue is empty - } - - /* - The general form of a MIDI message follows: - n-byte MIDI Message - Byte 0 MIDI message Status byte, Bit 7 is Set to 1. - Bytes 1 to n-1 MIDI message Data bytes, if n > 1. Bit 7 is Set to 0 - There are two types of MIDI messages that can appear in a single packet: full MIDI messages and - Running Status MIDI messages. Each is encoded differently. - A full MIDI message is simply the MIDI message with the Status byte included. - A Running Status MIDI message is a MIDI message with the Status byte omitted. Running Status - MIDI messages may only be placed in the data stream if the following criteria are met: - 1. The original MIDI message is 2 bytes or greater and is not a System Common or System - Real-Time message. - 2. The omitted Status byte matches the most recently preceding full MIDI message’s Status - byte within the same BLE packet. - In addition, the following rules apply with respect to Running Status: - 1. A Running Status MIDI message is allowed within the packet after at least one full MIDI - message. - 2. Every MIDI Status byte must be preceded by a timestamp byte. Running Status MIDI - messages may be preceded by a timestamp byte. If a Running Status MIDI message is not - preceded by a timestamp byte, the timestamp byte of the most recently preceding message - in the same packet is used. - 3. System Common and System Real-Time messages do not cancel Running Status if - interspersed between Running Status MIDI messages. However, a timestamp byte must - precede the Running Status MIDI message that follows. - 4. The end of a BLE packet does cancel Running Status. - In the MIDI 1.0 protocol, System Real-Time messages can be sent at any time and may be - inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other - MIDI messages. In the MIDI BLE protocol, the System Real-Time messages must be deinterleaved - from other messages – except for System Exclusive messages. - */ - void receive(uint8_t* buffer, size_t length) - { - // Pointers used to search through payload. - uint8_t lPtr = 0; - uint8_t rPtr = 0; - // lastStatus used to capture runningStatus - uint8_t lastStatus; - // Decode first packet -- SHALL be "Full MIDI message" - lPtr = 2; //Start at first MIDI status -- SHALL be "MIDI status" - - //While statement contains incrementing pointers and breaks when buffer size exceeded. - while (true) - { - lastStatus = buffer[lPtr]; - - if( (buffer[lPtr] < 0x80)) - return; // Status message not present, bail - - // Point to next non-data byte - rPtr = lPtr; - while( (buffer[rPtr + 1] < 0x80) && (rPtr < (length - 1)) ) - rPtr++; - if (buffer[rPtr + 1] == 0xF7) rPtr++; - - // look at l and r pointers and decode by size. - if( rPtr - lPtr < 1 ) { - // Time code or system - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - } else if( rPtr - lPtr < 2 ) { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[lPtr + 1], portMAX_DELAY); - } else if( rPtr - lPtr < 3 ) { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[lPtr + 1], portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[lPtr + 2], portMAX_DELAY); - } else { - // Too much data - // If not System Common or System Real-Time, send it as running status - switch(buffer[lPtr] & 0xF0) - { - case 0x80: - case 0x90: - case 0xA0: - case 0xB0: - case 0xE0: - for (auto i = lPtr; i < rPtr; i = i + 2) - { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[i + 1], portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[i + 2], portMAX_DELAY); - } - break; - case 0xC0: - case 0xD0: - for (auto i = lPtr; i < rPtr; i = i + 1) - { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[i + 1], portMAX_DELAY); - } - break; - case 0xF0: - xQueueSend(mRxQueue, &buffer[lPtr], portMAX_DELAY); - for (auto i = lPtr; i < rPtr; i++) - xQueueSend(mRxQueue, &buffer[i + 1], portMAX_DELAY); - break; - default: - break; - } - } - - // Point to next status - lPtr = rPtr + 2; - if(lPtr >= length) - return; //end of packet - } - } - - void connected() - { - if (_bleMidiTransport->_connectedCallback) - _bleMidiTransport->_connectedCallback(); - } - - void disconnected() - { - if (_bleMidiTransport->_disconnectedCallback) - _bleMidiTransport->_disconnectedCallback(); - } -}; - -class MyServerCallbacks: public BLEServerCallbacks { -public: - MyServerCallbacks(BLEMIDI_ESP32* bluetoothEsp32) - : _bluetoothEsp32(bluetoothEsp32) { - } - -protected: - BLEMIDI_ESP32* _bluetoothEsp32 = nullptr; - - void onConnect(BLEServer*) { - if (_bluetoothEsp32) - _bluetoothEsp32->connected(); - }; - - void onDisconnect(BLEServer*) { - if (_bluetoothEsp32) - _bluetoothEsp32->disconnected(); - } -}; - -class MyCharacteristicCallbacks: public BLECharacteristicCallbacks { -public: - MyCharacteristicCallbacks(BLEMIDI_ESP32* bluetoothEsp32) - : _bluetoothEsp32(bluetoothEsp32 ) { - } - -protected: - BLEMIDI_ESP32* _bluetoothEsp32 = nullptr; - - void onWrite(BLECharacteristic * characteristic) { - std::string rxValue = characteristic->getValue(); - if (rxValue.length() > 0) { - _bluetoothEsp32->receive((uint8_t *)(rxValue.c_str()), rxValue.length()); - } - } -}; - -bool BLEMIDI_ESP32::begin(const char* deviceName, BLEMIDITransport* bleMidiTransport) -{ - _bleMidiTransport = bleMidiTransport; - - BLEDevice::init(deviceName); - - // To communicate between the 2 cores. - // Core_0 runs here, core_1 runs the BLE stack - mRxQueue = xQueueCreate(64, sizeof(uint8_t)); // TODO Settings::MaxBufferSize - - _server = BLEDevice::createServer(); - _server->setCallbacks(new MyServerCallbacks(this)); - - // Create the BLE Service - auto service = _server->createService(BLEUUID(SERVICE_UUID)); - - // Create a BLE Characteristic - _characteristic = service->createCharacteristic( - BLEUUID(CHARACTERISTIC_UUID), - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE | - NIMBLE_PROPERTY::NOTIFY | - NIMBLE_PROPERTY::WRITE_NR - ); - - _characteristic->setCallbacks(new MyCharacteristicCallbacks(this)); - // Start the service - service->start(); - - auto advertisementData = BLEAdvertisementData(); - advertisementData.setFlags(0x04); - advertisementData.setCompleteServices(BLEUUID(SERVICE_UUID)); - advertisementData.setName(deviceName); - - // Start advertising - _advertising = _server->getAdvertising(); - _advertising->setAdvertisementData(advertisementData); - _advertising->start(); - - return true; -} - - /*! \brief Create an instance for ESP32 named - */ -#define BLEMIDI_CREATE_INSTANCE(DeviceName, Name) \ -BLEMIDI_NAMESPACE::BLEMIDITransport BLE##Name(DeviceName); \ -MIDI_NAMESPACE::MidiInterface, MySettings> Name((BLEMIDI_NAMESPACE::BLEMIDITransport &)BLE##Name); - - /*! \brief Create a default instance for ESP32 named BLE-MIDI - */ -#define BLEMIDI_CREATE_DEFAULT_INSTANCE() \ -BLEMIDI_CREATE_INSTANCE("BLE-MIDI", MIDI) - -END_BLEMIDI_NAMESPACE diff --git a/src/hardware/MIDI_ESP32.h b/src/hardware/MIDI_ESP32.h index 591eff2..0cb32b1 100644 --- a/src/hardware/MIDI_ESP32.h +++ b/src/hardware/MIDI_ESP32.h @@ -17,6 +17,9 @@ private: BLEMIDITransport* _bleMidiTransport = nullptr; + friend class MyServerCallbacks; + friend class MyCharacteristicCallbacks; + protected: QueueHandle_t mRxQueue; @@ -38,111 +41,17 @@ public: return xQueueReceive(mRxQueue, pvBuffer, 0); // return immediately when the queue is empty } - /* - The general form of a MIDI message follows: - n-byte MIDI Message - Byte 0 MIDI message Status byte, Bit 7 is Set to 1. - Bytes 1 to n-1 MIDI message Data bytes, if n > 1. Bit 7 is Set to 0 - There are two types of MIDI messages that can appear in a single packet: full MIDI messages and - Running Status MIDI messages. Each is encoded differently. - A full MIDI message is simply the MIDI message with the Status byte included. - A Running Status MIDI message is a MIDI message with the Status byte omitted. Running Status - MIDI messages may only be placed in the data stream if the following criteria are met: - 1. The original MIDI message is 2 bytes or greater and is not a System Common or System - Real-Time message. - 2. The omitted Status byte matches the most recently preceding full MIDI message’s Status - byte within the same BLE packet. - In addition, the following rules apply with respect to Running Status: - 1. A Running Status MIDI message is allowed within the packet after at least one full MIDI - message. - 2. Every MIDI Status byte must be preceded by a timestamp byte. Running Status MIDI - messages may be preceded by a timestamp byte. If a Running Status MIDI message is not - preceded by a timestamp byte, the timestamp byte of the most recently preceding message - in the same packet is used. - 3. System Common and System Real-Time messages do not cancel Running Status if - interspersed between Running Status MIDI messages. However, a timestamp byte must - precede the Running Status MIDI message that follows. - 4. The end of a BLE packet does cancel Running Status. - In the MIDI 1.0 protocol, System Real-Time messages can be sent at any time and may be - inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other - MIDI messages. In the MIDI BLE protocol, the System Real-Time messages must be deinterleaved - from other messages – except for System Exclusive messages. - */ + void add(const void* value) + { + // called from BLE-MIDI, to add it to a buffer here + xQueueSend(mRxQueue, value, portMAX_DELAY); + } + +protected: void receive(uint8_t* buffer, size_t length) { - // Pointers used to search through payload. - uint8_t lPtr = 0; - uint8_t rPtr = 0; - // lastStatus used to capture runningStatus - uint8_t lastStatus; - // Decode first packet -- SHALL be "Full MIDI message" - lPtr = 2; //Start at first MIDI status -- SHALL be "MIDI status" - - // While statement contains incrementing pointers and breaks when buffer size exceeded. - while (true) - { - lastStatus = buffer[lPtr]; - - if( (buffer[lPtr] < 0x80)) - return; // Status message not present, bail - - // Point to next non-data byte - rPtr = lPtr; - while( (buffer[rPtr + 1] < 0x80) && (rPtr < (length - 1)) ) - rPtr++; - if (buffer[rPtr + 1] == 0xF7) rPtr++; - - // look at l and r pointers and decode by size. - if( rPtr - lPtr < 1 ) { - // Time code or system - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - } else if( rPtr - lPtr < 2 ) { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[lPtr + 1], portMAX_DELAY); - } else if( rPtr - lPtr < 3 ) { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[lPtr + 1], portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[lPtr + 2], portMAX_DELAY); - } else { - // Too much data - // If not System Common or System Real-Time, send it as running status - switch(buffer[lPtr] & 0xF0) - { - case 0x80: - case 0x90: - case 0xA0: - case 0xB0: - case 0xE0: - for (auto i = lPtr; i < rPtr; i = i + 2) - { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[i + 1], portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[i + 2], portMAX_DELAY); - } - break; - case 0xC0: - case 0xD0: - for (auto i = lPtr; i < rPtr; i = i + 1) - { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[i + 1], portMAX_DELAY); - } - break; - case 0xF0: - xQueueSend(mRxQueue, &buffer[lPtr], portMAX_DELAY); - for (auto i = lPtr; i < rPtr; i++) - xQueueSend(mRxQueue, &buffer[i + 1], portMAX_DELAY); - break; - default: - break; - } - } - - // Point to next status - lPtr = rPtr + 2; - if(lPtr >= length) - return; //end of packet - } + // parse the incoming buffer + _bleMidiTransport->receive(buffer, length); } void connected() diff --git a/src/hardware/MIDI_ESP32_NimBLE.h b/src/hardware/MIDI_ESP32_NimBLE.h index 2f4b2fe..14d1feb 100644 --- a/src/hardware/MIDI_ESP32_NimBLE.h +++ b/src/hardware/MIDI_ESP32_NimBLE.h @@ -14,6 +14,9 @@ private: BLEMIDITransport* _bleMidiTransport = nullptr; + friend class MyServerCallbacks; + friend class MyCharacteristicCallbacks; + protected: QueueHandle_t mRxQueue; @@ -35,111 +38,17 @@ public: return xQueueReceive(mRxQueue, pvBuffer, 0); // return immediately when the queue is empty } - /* - The general form of a MIDI message follows: - n-byte MIDI Message - Byte 0 MIDI message Status byte, Bit 7 is Set to 1. - Bytes 1 to n-1 MIDI message Data bytes, if n > 1. Bit 7 is Set to 0 - There are two types of MIDI messages that can appear in a single packet: full MIDI messages and - Running Status MIDI messages. Each is encoded differently. - A full MIDI message is simply the MIDI message with the Status byte included. - A Running Status MIDI message is a MIDI message with the Status byte omitted. Running Status - MIDI messages may only be placed in the data stream if the following criteria are met: - 1. The original MIDI message is 2 bytes or greater and is not a System Common or System - Real-Time message. - 2. The omitted Status byte matches the most recently preceding full MIDI message’s Status - byte within the same BLE packet. - In addition, the following rules apply with respect to Running Status: - 1. A Running Status MIDI message is allowed within the packet after at least one full MIDI - message. - 2. Every MIDI Status byte must be preceded by a timestamp byte. Running Status MIDI - messages may be preceded by a timestamp byte. If a Running Status MIDI message is not - preceded by a timestamp byte, the timestamp byte of the most recently preceding message - in the same packet is used. - 3. System Common and System Real-Time messages do not cancel Running Status if - interspersed between Running Status MIDI messages. However, a timestamp byte must - precede the Running Status MIDI message that follows. - 4. The end of a BLE packet does cancel Running Status. - In the MIDI 1.0 protocol, System Real-Time messages can be sent at any time and may be - inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other - MIDI messages. In the MIDI BLE protocol, the System Real-Time messages must be deinterleaved - from other messages – except for System Exclusive messages. - */ + void add(const void* value) + { + // called from BLE-MIDI, to add it to a buffer here + xQueueSend(mRxQueue, value, portMAX_DELAY); + } + +protected: void receive(uint8_t* buffer, size_t length) { - // Pointers used to search through payload. - uint8_t lPtr = 0; - uint8_t rPtr = 0; - // lastStatus used to capture runningStatus - uint8_t lastStatus; - // Decode first packet -- SHALL be "Full MIDI message" - lPtr = 2; //Start at first MIDI status -- SHALL be "MIDI status" - - //While statement contains incrementing pointers and breaks when buffer size exceeded. - while (true) - { - lastStatus = buffer[lPtr]; - - if( (buffer[lPtr] < 0x80)) - return; // Status message not present, bail - - // Point to next non-data byte - rPtr = lPtr; - while( (buffer[rPtr + 1] < 0x80) && (rPtr < (length - 1)) ) - rPtr++; - if (buffer[rPtr + 1] == 0xF7) rPtr++; - - // look at l and r pointers and decode by size. - if( rPtr - lPtr < 1 ) { - // Time code or system - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - } else if( rPtr - lPtr < 2 ) { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[lPtr + 1], portMAX_DELAY); - } else if( rPtr - lPtr < 3 ) { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[lPtr + 1], portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[lPtr + 2], portMAX_DELAY); - } else { - // Too much data - // If not System Common or System Real-Time, send it as running status - switch(buffer[lPtr] & 0xF0) - { - case 0x80: - case 0x90: - case 0xA0: - case 0xB0: - case 0xE0: - for (auto i = lPtr; i < rPtr; i = i + 2) - { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[i + 1], portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[i + 2], portMAX_DELAY); - } - break; - case 0xC0: - case 0xD0: - for (auto i = lPtr; i < rPtr; i = i + 1) - { - xQueueSend(mRxQueue, &lastStatus, portMAX_DELAY); - xQueueSend(mRxQueue, &buffer[i + 1], portMAX_DELAY); - } - break; - case 0xF0: - xQueueSend(mRxQueue, &buffer[lPtr], portMAX_DELAY); - for (auto i = lPtr; i < rPtr; i++) - xQueueSend(mRxQueue, &buffer[i + 1], portMAX_DELAY); - break; - default: - break; - } - } - - // Point to next status - lPtr = rPtr + 2; - if(lPtr >= length) - return; //end of packet - } + // parse the incoming buffer + _bleMidiTransport->receive(buffer, length); } void connected()