110 lines
4.0 KiB
C++
110 lines
4.0 KiB
C++
// components/controller/app_task.cpp
|
|
#include "controller/app_task.h"
|
|
#include "midi/midi_transport.h"
|
|
#include "esp_log.h"
|
|
|
|
static const char* TAG = "app_task";
|
|
|
|
// Simple pad mapping table (Phase 1 - modifiable)
|
|
struct PadMapping {
|
|
uint8_t physical_switch; // 0-9
|
|
uint8_t midi_channel; // 1-3
|
|
uint8_t midi_note; // Note number (configurable)
|
|
uint8_t led_index; // LED index (0-9)
|
|
};
|
|
|
|
static PadMapping pad_mapping[] = {
|
|
{0, 1, 0, 0}, // Switch 0 -> Channel 1, Note 0, LED 0
|
|
{1, 1, 1, 1}, // Switch 1 -> Channel 1, Note 1, LED 1
|
|
{2, 1, 2, 2}, // Switch 2 -> Channel 1, Note 2, LED 2
|
|
{3, 1, 3, 3}, // Switch 3 -> Channel 1, Note 3, LED 3
|
|
{4, 1, 4, 4}, // Switch 4 -> Channel 1, Note 4, LED 4
|
|
{5, 1, 5, 5}, // Switch 5 -> Channel 1, Note 5, LED 5
|
|
{6, 1, 6, 6}, // Switch 6 -> Channel 1, Note 6, LED 6
|
|
{7, 1, 7, 7}, // Switch 7 -> Channel 1, Note 7, LED 7
|
|
{8, 1, 8, 8}, // Switch 8 -> Channel 1, Note 8, LED 8
|
|
{9, 1, 9, 9}, // Switch 9 -> Channel 1, Note 9, LED 9
|
|
};
|
|
|
|
static const uint8_t NUM_PADS = sizeof(pad_mapping) / sizeof(pad_mapping[0]);
|
|
|
|
BaseType_t app_task(void* parameters) {
|
|
AppTaskParams* params = (AppTaskParams*)parameters;
|
|
|
|
ESP_LOGI(TAG, "Controller task started");
|
|
|
|
while (true) {
|
|
// Check for MIDI events
|
|
MidiEvent midi_event;
|
|
if (xQueueReceive(params->midi_queue, &midi_event, 0) == pdPASS) {
|
|
app_process_midi_event(midi_event, params->led_driver);
|
|
}
|
|
|
|
// Check for switch events (Phase 1 stub)
|
|
for (uint8_t i = 0; i < NUM_PADS; i++) {
|
|
bool is_pressed = params->switch_driver->is_pressed(i);
|
|
static bool last_state[10] = {false};
|
|
|
|
if (is_pressed && !last_state[i]) {
|
|
// Switch press detected
|
|
app_process_switch_event(i, true);
|
|
last_state[i] = true;
|
|
} else if (!is_pressed && last_state[i]) {
|
|
// Switch release detected
|
|
app_process_switch_event(i, false);
|
|
last_state[i] = false;
|
|
}
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(10)); // 10ms task period
|
|
}
|
|
}
|
|
|
|
void app_process_midi_event(const MidiEvent& event, LedStub* led_driver) {
|
|
// Convert MIDI event to LED command
|
|
// This is where we map MIDI to LED state
|
|
uint8_t led_index = -1;
|
|
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 != 255) {
|
|
// Trigger LED state change
|
|
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
|
|
);
|
|
|
|
ESP_LOGI(TAG, "MIDI PROCESSED: Channel %d Note %d Velocity %d -> LED %d",
|
|
midi_channel, midi_note, midi_velocity, led_index);
|
|
}
|
|
}
|
|
|
|
void app_process_switch_event(uint8_t switch_id, bool pressed) {
|
|
// Convert switch event to MIDI event
|
|
MidiEvent midi_event;
|
|
|
|
// Find mapping for this switch
|
|
for (uint8_t i = 0; i < NUM_PADS; i++) {
|
|
if (pad_mapping[i].physical_switch == switch_id) {
|
|
midi_event.channel = pad_mapping[i].midi_channel;
|
|
midi_event.data1 = pad_mapping[i].midi_note;
|
|
midi_event.data2 = pressed ? 127 : 0; // Full velocity for press
|
|
midi_event.type = pressed ? MidiEvent::NOTE_ON : MidiEvent::NOTE_OFF;
|
|
|
|
ESP_LOGI(TAG, "SWITCH EVENT: Switch %d -> Channel %d Note %d Velocity %d",
|
|
switch_id, midi_event.channel, midi_event.data1, midi_event.data2);
|
|
break;
|
|
}
|
|
}
|
|
} |