#include #include "pico/stdlib.h" #include "pico/cyw43_arch.h" #include #include "spp_midi.h" using namespace cs; // SPP constructed first — its begin() registers Classic BT services before BLE starts HCI SPPStreamMIDI_Interface spp_midi; BluetoothMIDI_Interface ble_midi; // State toggle on encoder 1's button — fixed CC, sends 127/0 to indicate active map CCButtonLatched toggle_btn {1, {80, Channel_1}}; // Encoders (A/B swapped on hardware) CCRotaryEncoder enc1 {{2, 0}, {16, Channel_1}, 1, 4}; CCRotaryEncoder enc2 {{5, 3}, {17, Channel_1}, 1, 4}; CCRotaryEncoder enc3 {{8, 6}, {18, Channel_1}, 1, 4}; CCRotaryEncoder enc4 {{9, 11}, {19, Channel_1}, 1, 4}; // Remaining encoder push buttons CCButton btn2 {4, {20, Channel_1}}; CCButton btn3 {7, {21, Channel_1}}; CCButton btn4 {10, {22, Channel_1}}; // CC mappings per state struct CCMap { uint8_t enc[4]; uint8_t btn[3]; }; constexpr CCMap maps[2] = { {{16, 17, 18, 19}, {20, 21, 22}}, // state 0 {{23, 24, 25, 26}, {27, 28, 29}}, // state 1 }; void apply_map(const CCMap &m) { enc1.setAddress({m.enc[0], Channel_1}); enc2.setAddress({m.enc[1], Channel_1}); enc3.setAddress({m.enc[2], Channel_1}); enc4.setAddress({m.enc[3], Channel_1}); btn2.setAddressUnsafe({m.btn[0], Channel_1}); btn3.setAddressUnsafe({m.btn[1], Channel_1}); btn4.setAddressUnsafe({m.btn[2], Channel_1}); } int main() { stdio_init_all(); if (cyw43_arch_init()) { printf("CYW43 init failed\n"); return 1; } RelativeCCSender::setMode(relativeCCmode::MACKIE_CONTROL_RELATIVE); ble_midi.setName("FractionalLooper"); Control_Surface.begin(); bool last_state = false; while (true) { Control_Surface.loop(); bool state = toggle_btn.getState(); if (state != last_state) { last_state = state; apply_map(maps[state]); } sleep_ms(1); } }