Skip to content

Commit fe08081

Browse files
authored
Merge pull request #266 from lucastephann/midi-cc-ab-preset-selection
feat: add MIDI CC 120/121 for independent A/B slot preset loading
2 parents 3947048 + eaa810c commit fe08081

File tree

7 files changed

+124
-8
lines changed

7 files changed

+124
-8
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,3 @@ ui_design_480x320land/cache
2424
ui_design_480x320land/autosave
2525

2626

27-

MidiCommands.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,6 @@ This project uses a low-cost embedded controller (Espressif ESP32-S3) to form a
116116
| Cab Sim Bypass | 117 | On: 127, Off: 0 |
117117
| Global Tempo Source | 118 | Global: 127, Local: 0 |
118118
| Global Tuning Reference | 119 | 0-127 |
119+
| Load Preset to Slot A | 120 | 0-19 |
120+
| Load Preset to Slot B | 121 | 0-19 |
119121
| Select Preset | 127 | 0-19 |

source/main/midi_helper.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,16 +1229,34 @@ esp_err_t midi_helper_adjust_param_via_midi(uint8_t change_num, uint8_t midi_val
12291229

12301230
case 120:
12311231
{
1232-
// reserved for setting preset in slot A
1233-
ESP_LOGW(TAG, "CC Not implemented yet %d", change_num);
1234-
return ESP_FAIL;
1232+
// Load preset to Slot A without switching to it
1233+
if (midi_value >= (usb_get_max_presets_for_connected_modeller()))
1234+
{
1235+
ESP_LOGW(TAG, "Unsupported Midi CC 120 value %d (max %d)", midi_value, usb_get_max_presets_for_connected_modeller() - 1);
1236+
}
1237+
else
1238+
{
1239+
usb_load_preset_to_slot_a(midi_value);
1240+
}
1241+
1242+
// no param change needed
1243+
return ESP_OK;
12351244
} break;
12361245

12371246
case 121:
12381247
{
1239-
// reserved for setting preset in slot B
1240-
ESP_LOGW(TAG, "CC Not implemented yet %d", change_num);
1241-
return ESP_FAIL;
1248+
// Load preset to Slot B without switching to it
1249+
if (midi_value >= (usb_get_max_presets_for_connected_modeller()))
1250+
{
1251+
ESP_LOGW(TAG, "Unsupported Midi CC 121 value %d (max %d)", midi_value, usb_get_max_presets_for_connected_modeller() - 1);
1252+
}
1253+
else
1254+
{
1255+
usb_load_preset_to_slot_b(midi_value);
1256+
}
1257+
1258+
// no param change needed
1259+
return ESP_OK;
12421260
} break;
12431261

12441262
case 122:

source/main/usb_comms.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,62 @@ void usb_modify_parameter(uint16_t index, float value)
441441
}
442442
}
443443

444+
/****************************************************************************
445+
* NAME:
446+
* DESCRIPTION:
447+
* PARAMETERS:
448+
* RETURN:
449+
* NOTES:
450+
*****************************************************************************/
451+
void usb_load_preset_to_slot_a(uint32_t preset)
452+
{
453+
tUSBMessage message;
454+
455+
if (usb_input_queue == NULL)
456+
{
457+
ESP_LOGE(TAG, "usb_load_preset_to_slot_a queue null");
458+
}
459+
else
460+
{
461+
message.Command = USB_COMMAND_LOAD_PRESET_TO_SLOT_A;
462+
message.Payload = preset;
463+
464+
// send to queue
465+
if (xQueueSend(usb_input_queue, (void*)&message, 0) != pdPASS)
466+
{
467+
ESP_LOGE(TAG, "usb_load_preset_to_slot_a queue send failed!");
468+
}
469+
}
470+
}
471+
472+
/****************************************************************************
473+
* NAME:
474+
* DESCRIPTION:
475+
* PARAMETERS:
476+
* RETURN:
477+
* NOTES:
478+
*****************************************************************************/
479+
void usb_load_preset_to_slot_b(uint32_t preset)
480+
{
481+
tUSBMessage message;
482+
483+
if (usb_input_queue == NULL)
484+
{
485+
ESP_LOGE(TAG, "usb_load_preset_to_slot_b queue null");
486+
}
487+
else
488+
{
489+
message.Command = USB_COMMAND_LOAD_PRESET_TO_SLOT_B;
490+
message.Payload = preset;
491+
492+
// send to queue
493+
if (xQueueSend(usb_input_queue, (void*)&message, 0) != pdPASS)
494+
{
495+
ESP_LOGE(TAG, "usb_load_preset_to_slot_b queue send failed!");
496+
}
497+
}
498+
}
499+
444500
/****************************************************************************
445501
* NAME:
446502
* DESCRIPTION:

source/main/usb_comms.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ enum AmpModellers
3838
enum USB_Commands
3939
{
4040
USB_COMMAND_SET_PRESET,
41-
USB_COMMAND_MODIFY_PARAMETER
41+
USB_COMMAND_MODIFY_PARAMETER,
42+
USB_COMMAND_LOAD_PRESET_TO_SLOT_A,
43+
USB_COMMAND_LOAD_PRESET_TO_SLOT_B
4244
};
4345

4446
typedef struct
@@ -61,6 +63,8 @@ void init_usb_comms(void);
6163
// thread safe public API
6264
void usb_set_preset(uint32_t preset);
6365
void usb_modify_parameter(uint16_t index, float value);
66+
void usb_load_preset_to_slot_a(uint32_t preset);
67+
void usb_load_preset_to_slot_b(uint32_t preset);
6468
uint8_t usb_get_max_presets_for_connected_modeller(void);
6569
uint8_t usb_get_first_preset_index_for_connected_modeller(void);
6670

source/main/usb_tonex_one.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ static esp_err_t __attribute__((unused)) usb_tonex_one_set_active_slot(Slot newS
431431
return tonex_common_transmit(cdc_dev, FramedBuffer, framed_length, TONEX_USB_TX_BUFFER_SIZE);
432432
}
433433

434+
434435
/****************************************************************************
435436
* NAME:
436437
* DESCRIPTION:
@@ -1316,6 +1317,38 @@ void usb_tonex_one_handle(class_driver_t* driver_obj)
13161317
// failed return to queue?
13171318
}
13181319
}
1320+
} break;
1321+
1322+
case USB_COMMAND_LOAD_PRESET_TO_SLOT_A:
1323+
{
1324+
if (message.Payload < MAX_PRESETS_TONEX_ONE)
1325+
{
1326+
ESP_LOGI(TAG, "Loading preset %d to Slot A via MIDI CC 120", (int)message.Payload);
1327+
if (usb_tonex_one_set_preset_in_slot(message.Payload, A, 0) != ESP_OK)
1328+
{
1329+
ESP_LOGE(TAG, "Failed to load preset %d to Slot A", (int)message.Payload);
1330+
}
1331+
}
1332+
else
1333+
{
1334+
ESP_LOGW(TAG, "Invalid preset index %d for Slot A (max %d)", (int)message.Payload, MAX_PRESETS_TONEX_ONE - 1);
1335+
}
1336+
} break;
1337+
1338+
case USB_COMMAND_LOAD_PRESET_TO_SLOT_B:
1339+
{
1340+
if (message.Payload < MAX_PRESETS_TONEX_ONE)
1341+
{
1342+
ESP_LOGI(TAG, "Loading preset %d to Slot B via MIDI CC 121", (int)message.Payload);
1343+
if (usb_tonex_one_set_preset_in_slot(message.Payload, B, 0) != ESP_OK)
1344+
{
1345+
ESP_LOGE(TAG, "Failed to load preset %d to Slot B", (int)message.Payload);
1346+
}
1347+
}
1348+
else
1349+
{
1350+
ESP_LOGW(TAG, "Invalid preset index %d for Slot B (max %d)", (int)message.Payload, MAX_PRESETS_TONEX_ONE - 1);
1351+
}
13191352
} break;
13201353

13211354
case USB_COMMAND_MODIFY_PARAMETER:

source/main/usb_tonex_one.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ void usb_tonex_one_init(class_driver_t* driver_obj, QueueHandle_t comms_queue);
3030
void usb_tonex_one_deinit(void);
3131
void usb_tonex_one_preallocate_memory(void);
3232

33+
// MIDI CC slot targeting functions
34+
esp_err_t usb_tonex_one_load_preset_to_slot_a(uint16_t preset);
35+
esp_err_t usb_tonex_one_load_preset_to_slot_b(uint16_t preset);
36+
3337
#ifdef __cplusplus
3438
} /*extern "C"*/
3539
#endif

0 commit comments

Comments
 (0)