#include "remote_params.h" #include #include #include "audio_effects.h" typedef enum { PARAM_BOOL, PARAM_FLOAT } ParamKind; typedef struct { uint8_t id; ParamKind kind; uint16_t offset; /* position du champ dans AudioEffectsParams */ float scale; /* valeur sur le fil = reel * scale */ float min; float max; } ParamDesc; #define P_BOOL(id, field) { (id), PARAM_BOOL, offsetof(AudioEffectsParams, field), 1.0f, 0.0f, 1.0f } #define P_UNIT(id, field) { (id), PARAM_FLOAT, offsetof(AudioEffectsParams, field), 1000.0f, 0.0f, 1.0f } #define P_UNIT_MAX(id, field, vmax) { (id), PARAM_FLOAT, offsetof(AudioEffectsParams, field), 1000.0f, 0.0f, (vmax) } #define P_EQ_GAIN(i) { (uint8_t)(0x30 + (i)), PARAM_FLOAT, \ offsetof(AudioEffectsParams, equalizer.bands[i].gain_db), 10.0f, -24.0f, 24.0f } static const ParamDesc k_params[] = { P_BOOL(0x00, audio_on_off), P_UNIT(0x01, master_volume), P_BOOL(0x10, octaver.enabled), P_UNIT(0x11, octaver.level_down2), P_UNIT(0x12, octaver.level_down1), P_UNIT(0x13, octaver.level_dry), P_UNIT(0x14, octaver.level_up1), P_UNIT(0x15, octaver.level_up2), P_BOOL(0x20, equalizer.enabled), P_EQ_GAIN(0), P_EQ_GAIN(1), P_EQ_GAIN(2), P_EQ_GAIN(3), P_EQ_GAIN(4), P_EQ_GAIN(5), P_EQ_GAIN(6), P_EQ_GAIN(7), P_EQ_GAIN(8), P_EQ_GAIN(9), P_BOOL(0x50, overdrive.enabled), P_UNIT(0x51, overdrive.drive), P_UNIT(0x52, overdrive.tone), P_UNIT(0x53, overdrive.level), P_BOOL(0x60, saturation.enabled), P_UNIT(0x61, saturation.drive), P_UNIT(0x62, saturation.level), P_BOOL(0x70, echo.enabled), { 0x71, PARAM_FLOAT, offsetof(AudioEffectsParams, echo.delay_ms), 1.0f, 0.0f, (float)FX_ECHO_MAX_DELAY_MS }, P_UNIT_MAX(0x72, echo.feedback, 0.95f), /* < 1.0 pour eviter l'emballement */ P_UNIT(0x73, echo.mix), P_BOOL(0x80, reverb.enabled), P_UNIT(0x81, reverb.room_size), P_UNIT(0x82, reverb.damping), P_UNIT(0x83, reverb.mix), }; #define PARAM_COUNT (sizeof(k_params) / sizeof(k_params[0])) _Static_assert(FX_EQ_NUM_BANDS == 10U, "la table des bandes d'egaliseur suppose 10 bandes"); _Static_assert(PARAM_COUNT < 256U, "RemoteParams_Count() tient sur un octet"); static const ParamDesc *find(uint8_t id) { for (size_t i = 0; i < PARAM_COUNT; i++) { if (k_params[i].id == id) { return &k_params[i]; } } return NULL; } bool RemoteParams_Set(uint8_t id, int16_t value) { const ParamDesc *d = find(id); if (d == NULL) { return false; } uint8_t *base = (uint8_t *)AudioEffects_GetParams(); if (d->kind == PARAM_BOOL) { *(bool *)(base + d->offset) = (value != 0); } else { float v = (float)value / d->scale; if (v < d->min) { v = d->min; } if (v > d->max) { v = d->max; } *(float *)(base + d->offset) = v; } return true; } bool RemoteParams_Get(uint8_t id, int16_t *value) { const ParamDesc *d = find(id); if (d == NULL || value == NULL) { return false; } const uint8_t *base = (const uint8_t *)AudioEffects_GetParams(); if (d->kind == PARAM_BOOL) { *value = *(const bool *)(base + d->offset) ? 1 : 0; } else { float raw = roundf(*(const float *)(base + d->offset) * d->scale); if (raw > 32767.0f) { raw = 32767.0f; } if (raw < -32768.0f) { raw = -32768.0f; } *value = (int16_t)raw; } return true; } uint8_t RemoteParams_Count(void) { return (uint8_t)PARAM_COUNT; } uint8_t RemoteParams_IdAt(uint8_t index) { return (index < PARAM_COUNT) ? k_params[index].id : 0xFFU; }