FractionalLooper/main.cpp

73 lines
1.9 KiB
C++

#include <cstdio>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include <cs_midi.h>
#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);
}
}