FractionalLooper/main.cpp

118 lines
3.4 KiB
C++

#include <cstdio>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include <cs_midi.h>
#include "encoder.h"
#include "spp_midi.h"
// Two CC sets, toggled by SW1 button.
// Set A: encoders CC 16-19, buttons CC 20-22 (SW2-SW4)
// Set B: encoders CC 24-27, buttons CC 28-30 (SW2-SW4)
static constexpr uint8_t SET_A_ENC_CC = 16;
static constexpr uint8_t SET_A_BTN_CC = 20;
static constexpr uint8_t SET_B_ENC_CC = 24;
static constexpr uint8_t SET_B_BTN_CC = 28;
static constexpr uint8_t TOGGLE_CC = 23;
static uint8_t enc_cc_base = SET_A_ENC_CC;
static uint8_t btn_cc_base = SET_A_BTN_CC;
static bool set_b_active = false;
// LED state
enum LedState { LED_IDLE_BLINK, LED_CONNECT_FLASH, LED_OFF };
static LedState led_state = LED_IDLE_BLINK;
static uint16_t led_counter = 0;
static uint8_t led_flash_count = 0;
static bool was_connected = false;
static void led_set(bool on) {
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, on);
}
int main() {
stdio_init_all();
if (cyw43_arch_init()) {
printf("CYW43 init failed\n");
return 1;
}
printf("FractionalLooper: CYW43 initialized\n");
cs::BluetoothMIDI_Interface ble;
ble.begin();
printf("BLE MIDI started\n");
SPPStreamMIDI_Interface spp;
spp.begin();
cs::BidirectionalMIDI_PipeFactory<2> pipes;
ble | pipes | spp;
encoders_init();
printf("Encoders initialized\n");
ble.setAsDefault();
while (true) {
bool connected = ble.isConnected() || spp.isConnected();
if (connected && !was_connected) {
led_state = LED_CONNECT_FLASH;
led_flash_count = 0;
led_counter = 0;
} else if (!connected && was_connected) {
led_state = LED_IDLE_BLINK;
led_counter = 0;
}
was_connected = connected;
switch (led_state) {
case LED_IDLE_BLINK:
led_set(led_counter < 500);
if (++led_counter >= 1000) led_counter = 0;
break;
case LED_CONNECT_FLASH:
led_set(led_counter < 50);
if (++led_counter >= 100) {
led_counter = 0;
if (++led_flash_count >= 6) {
led_state = LED_OFF;
led_set(false);
}
}
break;
case LED_OFF:
break;
}
for (int i = 0; i < NUM_ENCODERS; i++) {
int32_t delta = encoder_get_delta(i);
if (delta != 0) {
int32_t clamped = delta;
if (clamped > 63) clamped = 63;
if (clamped < -63) clamped = -63;
uint8_t val = (clamped > 0) ? (uint8_t)clamped
: (uint8_t)(128 + clamped);
ble.sendControlChange({enc_cc_base + i, cs::Channel_1}, val);
}
if (button_pressed(i)) {
if (i == 0) {
set_b_active = !set_b_active;
enc_cc_base = set_b_active ? SET_B_ENC_CC : SET_A_ENC_CC;
btn_cc_base = set_b_active ? SET_B_BTN_CC : SET_A_BTN_CC;
ble.sendControlChange({TOGGLE_CC, cs::Channel_1},
set_b_active ? 127 : 0);
} else {
ble.sendControlChange({btn_cc_base + (i - 1), cs::Channel_1}, 127);
}
}
}
ble.update();
spp.update();
sleep_ms(1);
}
}