Root cause: Arduino Core 3.x breaks cross-core NimBLE API calls. Calling BLEMidiServer.controlChange() from loop() on Core 1 while NimBLE host runs on Core 0 causes immediate crash. Fix: - Move ble_midi_transport.begin() to ble_init_task on Core 0 - All BLE MIDI sends use queue_cc() (cross-core safe flag setter) - ble_midi_transport.update() processes queued sends on Core 0 - Pin NimBLE-Arduino to v1.4.3 (stable LTS for BLE MIDI) - Keep CONFIG_BT_ENABLED out of sdkconfig.h (causes double-init)
41 lines
1.1 KiB
C++
41 lines
1.1 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include "midi_transport.h"
|
|
|
|
class BleMidiTransport {
|
|
public:
|
|
BleMidiTransport();
|
|
~BleMidiTransport();
|
|
|
|
bool begin();
|
|
void update();
|
|
|
|
void on_midi_receive(std::function<void(const MidiEvent&)> callback);
|
|
|
|
void send_note_on(uint8_t channel, uint8_t note, uint8_t velocity);
|
|
void send_note_off(uint8_t channel, uint8_t note, uint8_t velocity);
|
|
void send_cc(uint8_t channel, uint8_t cc, uint8_t value);
|
|
|
|
bool is_connected();
|
|
|
|
void queue_cc(uint8_t channel, uint8_t cc, uint8_t value);
|
|
|
|
private:
|
|
static void on_control_change(uint8_t channel, uint8_t controller, uint8_t value, uint16_t timestamp);
|
|
static void on_note_on(uint8_t channel, uint8_t note, uint8_t velocity, uint16_t timestamp);
|
|
static void on_note_off(uint8_t channel, uint8_t note, uint8_t velocity, uint16_t timestamp);
|
|
static void on_connect();
|
|
static void on_disconnect();
|
|
|
|
std::function<void(const MidiEvent&)> receive_callback;
|
|
bool initialized;
|
|
bool client_connected;
|
|
|
|
uint8_t queued_channel;
|
|
uint8_t queued_cc;
|
|
uint8_t queued_value;
|
|
bool queued;
|
|
};
|