better BLE MIDI parser (incl SysEx)
This commit is contained in:
parent
f78f5a8f9c
commit
42cd91d79b
|
|
@ -45,6 +45,8 @@ public:
|
||||||
{
|
{
|
||||||
mBleClass.begin(mDeviceName, this);
|
mBleClass.begin(mDeviceName, this);
|
||||||
|
|
||||||
|
// To communicate between the 2 cores.
|
||||||
|
// Core_0 runs here, core_1 runs the BLE stack
|
||||||
mRxQueue = xQueueCreate(Settings::MaxBufferSize, sizeof(uint8_t));
|
mRxQueue = xQueueCreate(Settings::MaxBufferSize, sizeof(uint8_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,18 +103,6 @@ public:
|
||||||
return mRxIndex;
|
return mRxIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
void reverse(byte arr[], int n)
|
|
||||||
{
|
|
||||||
for (int low = 0, high = n - 1; low < high; low++, high--)
|
|
||||||
{
|
|
||||||
int temp = arr[low];
|
|
||||||
arr[low] = arr[high];
|
|
||||||
arr[high] = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QueueHandle_t mRxQueue;
|
QueueHandle_t mRxQueue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,12 @@ MIDI_NAMESPACE::MidiInterface<BLEMIDI_t> MIDI((BLEMIDI_t &)Name);
|
||||||
|
|
||||||
/*! \brief Create an instance for ESP32 named <DeviceName>
|
/*! \brief Create an instance for ESP32 named <DeviceName>
|
||||||
*/
|
*/
|
||||||
#define BLEMIDI_CREATE_ESP32_INSTANCE(DeviceName) \
|
#define BLEMIDI_CREATE_ESP32_INSTANCE(DeviceName) \
|
||||||
BLEMIDI_CREATE_INSTANCE(BLEMIDI_NAMESPACE::BLEMIDI_ESP32, DeviceName, bm);
|
BLEMIDI_CREATE_INSTANCE(BLEMIDI_NAMESPACE::BLEMIDI_ESP32, DeviceName, bm);
|
||||||
|
|
||||||
/*! \brief Create a default instance for ESP32 named BLE-MIDI
|
/*! \brief Create a default instance for ESP32 named BLE-MIDI
|
||||||
*/
|
*/
|
||||||
#define BLEMIDI_CREATE_DEFAULT_ESP32_INSTANCE() \
|
#define BLEMIDI_CREATE_DEFAULT_ESP32_INSTANCE() \
|
||||||
BLEMIDI_CREATE_ESP32_INSTANCE("BLE-MIDI")
|
BLEMIDI_CREATE_ESP32_INSTANCE("BLE-MIDI")
|
||||||
|
|
||||||
END_BLEMIDI_NAMESPACE
|
END_BLEMIDI_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -24,18 +24,80 @@ public:
|
||||||
|
|
||||||
bool begin(const char*, BLEMIDI<class BLEMIDI_ESP32>*);
|
bool begin(const char*, BLEMIDI<class BLEMIDI_ESP32>*);
|
||||||
|
|
||||||
void write(uint8_t* data, uint8_t length)
|
void write(uint8_t* buffer, size_t length)
|
||||||
{
|
{
|
||||||
_characteristic->setValue(data, length);
|
_characteristic->setValue(buffer, length);
|
||||||
_characteristic->notify();
|
_characteristic->notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
void receive(uint8_t* buffer, size_t length)
|
void receive(uint8_t* buffer, size_t length)
|
||||||
{
|
{
|
||||||
// Post the items to the back of the queue
|
// Pointers used to search through payload.
|
||||||
// (drop the first 2 items)
|
uint8_t lPtr = 0;
|
||||||
for (size_t i = 2; i < length; i++)
|
uint8_t rPtr = 0;
|
||||||
xQueueSend(_bleMidiTransport->mRxQueue, &buffer[i], portMAX_DELAY);
|
// 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(_bleMidiTransport->mRxQueue, &buffer[lPtr], portMAX_DELAY);
|
||||||
|
} else if( rPtr - lPtr < 2 ) {
|
||||||
|
xQueueSend(_bleMidiTransport->mRxQueue, &buffer[lPtr], portMAX_DELAY);
|
||||||
|
xQueueSend(_bleMidiTransport->mRxQueue, &buffer[lPtr + 1], portMAX_DELAY);
|
||||||
|
} else if( rPtr - lPtr < 3 ) {
|
||||||
|
xQueueSend(_bleMidiTransport->mRxQueue, &buffer[lPtr], portMAX_DELAY);
|
||||||
|
xQueueSend(_bleMidiTransport->mRxQueue, &buffer[lPtr + 1], portMAX_DELAY);
|
||||||
|
xQueueSend(_bleMidiTransport->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)
|
||||||
|
// transmitMIDIonDIN( lastStatus, buffer[i + 1], buffer[i + 2] );
|
||||||
|
break;
|
||||||
|
case 0xC0:
|
||||||
|
case 0xD0:
|
||||||
|
// for (auto i = lPtr; i < rPtr; i = i + 1)
|
||||||
|
// transmitMIDIonDIN( lastStatus, buffer[i + 1], 0 );
|
||||||
|
break;
|
||||||
|
case 0xF0:
|
||||||
|
xQueueSend(_bleMidiTransport->mRxQueue, &buffer[lPtr], portMAX_DELAY);
|
||||||
|
for (auto i = lPtr; i < rPtr; i++)
|
||||||
|
xQueueSend(_bleMidiTransport->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()
|
void connected()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue