Files
CelloEffects/Appli/Core/Src/remote_params.c
T
2026-10-24 00:14:53 +02:00

137 lines
3.8 KiB
C

#include "remote_params.h"
#include <stddef.h>
#include <math.h>
#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;
}