Files
loopy_midi_controller/lib/controller/app_task.cpp
T
ash 9078001404 Convert to PlatformIO/Arduino format
- Replace ESP-IDF structure with PlatformIO (platformio.ini)
- Move source files to src/ and include/
- Move libraries to lib/ directory
- Replace FreeRTOS with Arduino task/vTaskDelay
- Use Arduino MIDI library instead of raw TinyUSB
- Dual-core: MIDI on core 0, controller on core 1
2026-06-23 12:55:12 +00:00

89 lines
2.8 KiB
C++

#include "app_task.h"
#include <Arduino.h>
AppTask::AppTask(LedStub* led, SwitchStub* sw, UsbMidiTransport* midi)
: led_driver(led), switch_driver(sw), midi_transport(midi) {
// Default pad mapping
for (uint8_t i = 0; i < NUM_PADS; i++) {
pad_mapping[i].physical_switch = i;
pad_mapping[i].midi_channel = 1;
pad_mapping[i].midi_note = i;
pad_mapping[i].led_index = i;
last_switch_state[i] = false;
}
}
void AppTask::begin() {
Serial.println("[APP] Controller task started");
// Register MIDI callback
midi_transport->on_midi_receive([this](const MidiEvent& event) {
process_midi_event(event);
});
}
void AppTask::update() {
// Poll switches
for (uint8_t i = 0; i < NUM_PADS; i++) {
bool is_pressed = switch_driver->is_pressed(i);
if (is_pressed && !last_switch_state[i]) {
process_switch_event(i, true);
last_switch_state[i] = true;
} else if (!is_pressed && last_switch_state[i]) {
process_switch_event(i, false);
last_switch_state[i] = false;
}
}
}
void AppTask::process_midi_event(const MidiEvent& event) {
uint8_t led_index = 0xFF;
uint8_t midi_channel = event.channel;
uint8_t midi_note = event.data1;
uint8_t midi_velocity = event.data2;
// Find matching LED index from pad mapping
for (uint8_t i = 0; i < NUM_PADS; i++) {
if (pad_mapping[i].midi_channel == midi_channel &&
pad_mapping[i].midi_note == midi_note) {
led_index = pad_mapping[i].led_index;
break;
}
}
if (led_index < NUM_PADS) {
led_driver->set_led_state(
pad_mapping[led_index].midi_note,
pad_mapping[led_index].midi_channel,
event.type == MidiEvent::NOTE_ON ? midi_velocity : 0
);
Serial.printf("[APP] MIDI -> LED: Ch%d Note%d Vel%d -> LED%d\n",
midi_channel, midi_note, midi_velocity, led_index);
}
}
void AppTask::process_switch_event(uint8_t switch_id, bool pressed) {
// Find mapping for this switch
for (uint8_t i = 0; i < NUM_PADS; i++) {
if (pad_mapping[i].physical_switch == switch_id) {
uint8_t channel = pad_mapping[i].midi_channel;
uint8_t note = pad_mapping[i].midi_note;
uint8_t velocity = pressed ? 127 : 0;
if (pressed) {
midi_transport->send_note_on(channel, note, velocity);
} else {
midi_transport->send_note_off(channel, note, velocity);
}
Serial.printf("[APP] Switch %d -> Ch%d Note%d Vel%d (%s)\n",
switch_id, channel, note, velocity,
pressed ? "PRESS" : "RELEASE");
break;
}
}
}