From 44a43828f1fdeae9713736cf3580b49fd5bd6919 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 5 Sep 2026 08:49:49 +0200 Subject: [PATCH] ajout effets audio --- Appli/Core/Inc/audio_effects.h | 26 ++++++++ Appli/Core/Inc/fx_echo.h | 28 ++++++++ Appli/Core/Inc/fx_equalizer.h | 44 +++++++++++++ Appli/Core/Inc/fx_overdrive.h | 22 +++++++ Appli/Core/Inc/fx_reverb.h | 42 ++++++++++++ Appli/Core/Inc/fx_saturation.h | 22 +++++++ Appli/Core/Src/audio_effects.c | 34 ++++++++++ Appli/Core/Src/fx_echo.c | 38 +++++++++++ Appli/Core/Src/fx_equalizer.c | 77 ++++++++++++++++++++++ Appli/Core/Src/fx_overdrive.c | 39 +++++++++++ Appli/Core/Src/fx_reverb.c | 114 +++++++++++++++++++++++++++++++++ Appli/Core/Src/fx_saturation.c | 32 +++++++++ Appli/Core/Src/main.c | 21 ++++-- gcc/makefile_appli | 8 ++- 14 files changed, 541 insertions(+), 6 deletions(-) create mode 100644 Appli/Core/Inc/audio_effects.h create mode 100644 Appli/Core/Inc/fx_echo.h create mode 100644 Appli/Core/Inc/fx_equalizer.h create mode 100644 Appli/Core/Inc/fx_overdrive.h create mode 100644 Appli/Core/Inc/fx_reverb.h create mode 100644 Appli/Core/Inc/fx_saturation.h create mode 100644 Appli/Core/Src/audio_effects.c create mode 100644 Appli/Core/Src/fx_echo.c create mode 100644 Appli/Core/Src/fx_equalizer.c create mode 100644 Appli/Core/Src/fx_overdrive.c create mode 100644 Appli/Core/Src/fx_reverb.c create mode 100644 Appli/Core/Src/fx_saturation.c diff --git a/Appli/Core/Inc/audio_effects.h b/Appli/Core/Inc/audio_effects.h new file mode 100644 index 0000000..c1c9119 --- /dev/null +++ b/Appli/Core/Inc/audio_effects.h @@ -0,0 +1,26 @@ +#ifndef AUDIO_EFFECTS_H +#define AUDIO_EFFECTS_H + +#include "fx_equalizer.h" +#include "fx_overdrive.h" +#include "fx_saturation.h" +#include "fx_echo.h" +#include "fx_reverb.h" + +/* Structure regroupant les parametres de tous les effets. Modifiable directement + * (ex: depuis l'IHM) via AudioEffects_GetParams(). L'ordre de traitement fixe est : + * egaliseur -> overdrive -> saturation -> echo -> reverberation. */ +typedef struct +{ + FxEqualizerParams equalizer; + FxOverdriveParams overdrive; + FxSaturationParams saturation; + FxEchoParams echo; + FxReverbParams reverb; +} AudioEffectsParams; + +void AudioEffects_Init(void); +float AudioEffects_Process(float input); +AudioEffectsParams *AudioEffects_GetParams(void); + +#endif /* AUDIO_EFFECTS_H */ diff --git a/Appli/Core/Inc/fx_echo.h b/Appli/Core/Inc/fx_echo.h new file mode 100644 index 0000000..7f83a98 --- /dev/null +++ b/Appli/Core/Inc/fx_echo.h @@ -0,0 +1,28 @@ +#ifndef FX_ECHO_H +#define FX_ECHO_H + +#include +#include + +#define FX_ECHO_SAMPLE_RATE 48000U +#define FX_ECHO_MAX_DELAY_MS 1000U +#define FX_ECHO_BUFFER_SIZE (FX_ECHO_SAMPLE_RATE * FX_ECHO_MAX_DELAY_MS / 1000U) + +typedef struct +{ + bool enabled; + float delay_ms; /* 0 a FX_ECHO_MAX_DELAY_MS */ + float feedback; /* 0.0 a <1.0 */ + float mix; /* 0.0 (sec) a 1.0 (100% repetitions) */ +} FxEchoParams; + +typedef struct +{ + int16_t buffer[FX_ECHO_BUFFER_SIZE]; + uint32_t write_idx; +} FxEchoState; + +void FxEcho_Init(FxEchoState *state, FxEchoParams *params); +float FxEcho_Process(FxEchoState *state, const FxEchoParams *params, float input); + +#endif /* FX_ECHO_H */ diff --git a/Appli/Core/Inc/fx_equalizer.h b/Appli/Core/Inc/fx_equalizer.h new file mode 100644 index 0000000..5e714f9 --- /dev/null +++ b/Appli/Core/Inc/fx_equalizer.h @@ -0,0 +1,44 @@ +#ifndef FX_EQUALIZER_H +#define FX_EQUALIZER_H + +#include + +#define FX_EQ_NUM_BANDS 10U + +typedef struct +{ + float freq_hz; /* frequence centrale de la bande */ + float gain_db; /* -24.0 a +24.0 dB */ + float q; /* facteur de qualite, typiquement 0.5 a 5.0 */ +} FxEqBand; + +typedef struct +{ + bool enabled; + FxEqBand bands[FX_EQ_NUM_BANDS]; +} FxEqualizerParams; + +typedef struct +{ + /* coefficients biquad mis en cache, recalcules seulement si les parametres changent */ + float b0, b1, b2, a1, a2; + /* dernieres valeurs de parametres utilisees pour calculer les coefficients ci-dessus */ + float last_freq_hz; + float last_gain_db; + float last_q; +} FxEqBandState; + +typedef struct +{ + FxEqBandState band_state[FX_EQ_NUM_BANDS]; + /* etat du filtre (direct form 1), par bande */ + float x1[FX_EQ_NUM_BANDS]; + float x2[FX_EQ_NUM_BANDS]; + float y1[FX_EQ_NUM_BANDS]; + float y2[FX_EQ_NUM_BANDS]; +} FxEqualizerState; + +void FxEqualizer_Init(FxEqualizerState *state, FxEqualizerParams *params); +float FxEqualizer_Process(FxEqualizerState *state, const FxEqualizerParams *params, float input); + +#endif /* FX_EQUALIZER_H */ diff --git a/Appli/Core/Inc/fx_overdrive.h b/Appli/Core/Inc/fx_overdrive.h new file mode 100644 index 0000000..0d50b48 --- /dev/null +++ b/Appli/Core/Inc/fx_overdrive.h @@ -0,0 +1,22 @@ +#ifndef FX_OVERDRIVE_H +#define FX_OVERDRIVE_H + +#include + +typedef struct +{ + bool enabled; + float drive; /* 0.0 a 1.0 : quantite de distorsion */ + float tone; /* 0.0 (sombre) a 1.0 (brillant) : filtre passe-bas post-distorsion */ + float level; /* gain de compensation en sortie */ +} FxOverdriveParams; + +typedef struct +{ + float tone_lp_state; +} FxOverdriveState; + +void FxOverdrive_Init(FxOverdriveState *state, FxOverdriveParams *params); +float FxOverdrive_Process(FxOverdriveState *state, const FxOverdriveParams *params, float input); + +#endif /* FX_OVERDRIVE_H */ diff --git a/Appli/Core/Inc/fx_reverb.h b/Appli/Core/Inc/fx_reverb.h new file mode 100644 index 0000000..962eae5 --- /dev/null +++ b/Appli/Core/Inc/fx_reverb.h @@ -0,0 +1,42 @@ +#ifndef FX_REVERB_H +#define FX_REVERB_H + +#include +#include + +#define FX_REVERB_NUM_COMBS 8U +#define FX_REVERB_NUM_ALLPASS 4U + +typedef struct +{ + bool enabled; + float room_size; /* 0.0 a 1.0 */ + float damping; /* 0.0 (brillant) a 1.0 (etouffe) */ + float mix; /* 0.0 (sec) a 1.0 (100% reverbere) */ +} FxReverbParams; + +typedef struct +{ + float *buffer; + uint32_t size; + uint32_t idx; + float filter_store; +} FxCombState; + +typedef struct +{ + float *buffer; + uint32_t size; + uint32_t idx; +} FxAllpassState; + +typedef struct +{ + FxCombState combs[FX_REVERB_NUM_COMBS]; + FxAllpassState allpass[FX_REVERB_NUM_ALLPASS]; +} FxReverbState; + +void FxReverb_Init(FxReverbState *state, FxReverbParams *params); +float FxReverb_Process(FxReverbState *state, const FxReverbParams *params, float input); + +#endif /* FX_REVERB_H */ diff --git a/Appli/Core/Inc/fx_saturation.h b/Appli/Core/Inc/fx_saturation.h new file mode 100644 index 0000000..eb9fdef --- /dev/null +++ b/Appli/Core/Inc/fx_saturation.h @@ -0,0 +1,22 @@ +#ifndef FX_SATURATION_H +#define FX_SATURATION_H + +#include + +typedef struct +{ + bool enabled; + float drive; /* 0.0 (aucun effet) a 1.0 (saturation maximale) */ + float level; /* gain de compensation en sortie, typiquement 0.0 - 1.0 */ +} FxSaturationParams; + +typedef struct +{ + float dc_block_x1; + float dc_block_y1; +} FxSaturationState; + +void FxSaturation_Init(FxSaturationState *state, FxSaturationParams *params); +float FxSaturation_Process(FxSaturationState *state, const FxSaturationParams *params, float input); + +#endif /* FX_SATURATION_H */ diff --git a/Appli/Core/Src/audio_effects.c b/Appli/Core/Src/audio_effects.c new file mode 100644 index 0000000..b876e9e --- /dev/null +++ b/Appli/Core/Src/audio_effects.c @@ -0,0 +1,34 @@ +#include "audio_effects.h" + +static AudioEffectsParams g_params; + +static FxEqualizerState g_eqState; +static FxOverdriveState g_overdriveState; +static FxSaturationState g_saturationState; +static FxEchoState g_echoState; +static FxReverbState g_reverbState; + +void AudioEffects_Init(void) +{ + FxEqualizer_Init(&g_eqState, &g_params.equalizer); + FxOverdrive_Init(&g_overdriveState, &g_params.overdrive); + FxSaturation_Init(&g_saturationState, &g_params.saturation); + FxEcho_Init(&g_echoState, &g_params.echo); + FxReverb_Init(&g_reverbState, &g_params.reverb); +} + +float AudioEffects_Process(float input) +{ + float sample = input; + sample = FxEqualizer_Process(&g_eqState, &g_params.equalizer, sample); + sample = FxOverdrive_Process(&g_overdriveState, &g_params.overdrive, sample); + sample = FxSaturation_Process(&g_saturationState, &g_params.saturation, sample); + sample = FxEcho_Process(&g_echoState, &g_params.echo, sample); + sample = FxReverb_Process(&g_reverbState, &g_params.reverb, sample); + return sample; +} + +AudioEffectsParams *AudioEffects_GetParams(void) +{ + return &g_params; +} diff --git a/Appli/Core/Src/fx_echo.c b/Appli/Core/Src/fx_echo.c new file mode 100644 index 0000000..8addef0 --- /dev/null +++ b/Appli/Core/Src/fx_echo.c @@ -0,0 +1,38 @@ +#include "fx_echo.h" +#include + +void FxEcho_Init(FxEchoState *state, FxEchoParams *params) +{ + memset(state->buffer, 0, sizeof(state->buffer)); + state->write_idx = 0; + + params->enabled = false; + params->delay_ms = 300.0f; + params->feedback = 0.35f; + params->mix = 0.3f; +} + +float FxEcho_Process(FxEchoState *state, const FxEchoParams *params, float input) +{ + if (!params->enabled) + { + return input; + } + + uint32_t delay_samples = (uint32_t)(params->delay_ms * (FX_ECHO_SAMPLE_RATE / 1000.0f)); + if (delay_samples >= FX_ECHO_BUFFER_SIZE) + { + delay_samples = FX_ECHO_BUFFER_SIZE - 1U; + } + + uint32_t read_idx = (state->write_idx + FX_ECHO_BUFFER_SIZE - delay_samples) % FX_ECHO_BUFFER_SIZE; + float delayed = (float)state->buffer[read_idx] / 32768.0f; + + float to_store = input + delayed * params->feedback; + if (to_store > 1.0f) to_store = 1.0f; + if (to_store < -1.0f) to_store = -1.0f; + state->buffer[state->write_idx] = (int16_t)(to_store * 32767.0f); + state->write_idx = (state->write_idx + 1U) % FX_ECHO_BUFFER_SIZE; + + return input * (1.0f - params->mix) + delayed * params->mix; +} diff --git a/Appli/Core/Src/fx_equalizer.c b/Appli/Core/Src/fx_equalizer.c new file mode 100644 index 0000000..18c7b27 --- /dev/null +++ b/Appli/Core/Src/fx_equalizer.c @@ -0,0 +1,77 @@ +#include "fx_equalizer.h" +#include +#include + +#define FX_EQ_SAMPLE_RATE 48000.0f + +static const float fx_eq_default_freqs[FX_EQ_NUM_BANDS] = +{ + 31.0f, 62.0f, 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, 4000.0f, 8000.0f, 16000.0f +}; + +void FxEqualizer_Init(FxEqualizerState *state, FxEqualizerParams *params) +{ + params->enabled = false; + for (uint32_t i = 0; i < FX_EQ_NUM_BANDS; i++) + { + params->bands[i].freq_hz = fx_eq_default_freqs[i]; + params->bands[i].gain_db = 0.0f; + params->bands[i].q = 1.0f; + + state->band_state[i].last_freq_hz = -1.0f; /* force le calcul des coefficients au 1er sample */ + state->band_state[i].last_gain_db = 0.0f; + state->band_state[i].last_q = 0.0f; + state->x1[i] = state->x2[i] = state->y1[i] = state->y2[i] = 0.0f; + } +} + +/* Filtre "peaking EQ" (cloche), formule de l'Audio EQ Cookbook (Robert Bristow-Johnson). */ +static void FxEq_ComputeBandCoeffs(FxEqBandState *bs, const FxEqBand *band) +{ + float A = powf(10.0f, band->gain_db / 40.0f); + float w0 = 2.0f * (float)M_PI * band->freq_hz / FX_EQ_SAMPLE_RATE; + float alpha = sinf(w0) / (2.0f * band->q); + float cosw0 = cosf(w0); + + float a0 = 1.0f + alpha / A; + bs->b0 = (1.0f + alpha * A) / a0; + bs->b1 = (-2.0f * cosw0) / a0; + bs->b2 = (1.0f - alpha * A) / a0; + bs->a1 = (-2.0f * cosw0) / a0; + bs->a2 = (1.0f - alpha / A) / a0; + + bs->last_freq_hz = band->freq_hz; + bs->last_gain_db = band->gain_db; + bs->last_q = band->q; +} + +float FxEqualizer_Process(FxEqualizerState *state, const FxEqualizerParams *params, float input) +{ + if (!params->enabled) + { + return input; + } + + float y = input; + for (uint32_t i = 0; i < FX_EQ_NUM_BANDS; i++) + { + const FxEqBand *band = ¶ms->bands[i]; + FxEqBandState *bs = &state->band_state[i]; + + if (band->freq_hz != bs->last_freq_hz || band->gain_db != bs->last_gain_db || band->q != bs->last_q) + { + FxEq_ComputeBandCoeffs(bs, band); + } + + float x = y; + y = bs->b0 * x + bs->b1 * state->x1[i] + bs->b2 * state->x2[i] + - bs->a1 * state->y1[i] - bs->a2 * state->y2[i]; + + state->x2[i] = state->x1[i]; + state->x1[i] = x; + state->y2[i] = state->y1[i]; + state->y1[i] = y; + } + + return y; +} diff --git a/Appli/Core/Src/fx_overdrive.c b/Appli/Core/Src/fx_overdrive.c new file mode 100644 index 0000000..3a02481 --- /dev/null +++ b/Appli/Core/Src/fx_overdrive.c @@ -0,0 +1,39 @@ +#include "fx_overdrive.h" +#include + +void FxOverdrive_Init(FxOverdriveState *state, FxOverdriveParams *params) +{ + state->tone_lp_state = 0.0f; + + params->enabled = false; + params->drive = 0.4f; + params->tone = 0.6f; + params->level = 0.7f; +} + +float FxOverdrive_Process(FxOverdriveState *state, const FxOverdriveParams *params, float input) +{ + if (!params->enabled) + { + return input; + } + + float driven = input * (1.0f + params->drive * 20.0f); + + /* Ecretage asymetrique (exponentiel) : plus caracteristique/agressif qu'un tanh symetrique. */ + float shaped; + if (driven >= 0.0f) + { + shaped = 1.0f - expf(-driven); + } + else + { + shaped = -1.0f + expf(driven); + } + + /* Filtre passe-bas une pole pour la tonalite : coefficient = tone (0..1). */ + float coeff = 0.05f + params->tone * 0.9f; + state->tone_lp_state += coeff * (shaped - state->tone_lp_state); + + return state->tone_lp_state * params->level; +} diff --git a/Appli/Core/Src/fx_reverb.c b/Appli/Core/Src/fx_reverb.c new file mode 100644 index 0000000..4c83274 --- /dev/null +++ b/Appli/Core/Src/fx_reverb.c @@ -0,0 +1,114 @@ +#include "fx_reverb.h" +#include + +/* Lignes a retard inspirees de Freeverb (Jezar), redimensionnees de 44.1kHz vers 48kHz. */ +#define FX_REVERB_COMB0 1215U +#define FX_REVERB_COMB1 1293U +#define FX_REVERB_COMB2 1390U +#define FX_REVERB_COMB3 1476U +#define FX_REVERB_COMB4 1548U +#define FX_REVERB_COMB5 1623U +#define FX_REVERB_COMB6 1695U +#define FX_REVERB_COMB7 1761U + +#define FX_REVERB_ALLPASS0 605U +#define FX_REVERB_ALLPASS1 480U +#define FX_REVERB_ALLPASS2 371U +#define FX_REVERB_ALLPASS3 245U + +static float fx_reverb_comb_buf0[FX_REVERB_COMB0]; +static float fx_reverb_comb_buf1[FX_REVERB_COMB1]; +static float fx_reverb_comb_buf2[FX_REVERB_COMB2]; +static float fx_reverb_comb_buf3[FX_REVERB_COMB3]; +static float fx_reverb_comb_buf4[FX_REVERB_COMB4]; +static float fx_reverb_comb_buf5[FX_REVERB_COMB5]; +static float fx_reverb_comb_buf6[FX_REVERB_COMB6]; +static float fx_reverb_comb_buf7[FX_REVERB_COMB7]; + +static float fx_reverb_allpass_buf0[FX_REVERB_ALLPASS0]; +static float fx_reverb_allpass_buf1[FX_REVERB_ALLPASS1]; +static float fx_reverb_allpass_buf2[FX_REVERB_ALLPASS2]; +static float fx_reverb_allpass_buf3[FX_REVERB_ALLPASS3]; + +static float FxComb_Process(FxCombState *c, float input, float feedback, float damp1, float damp2) +{ + float output = c->buffer[c->idx]; + c->filter_store = (output * damp2) + (c->filter_store * damp1); + c->buffer[c->idx] = input + (c->filter_store * feedback); + c->idx = (c->idx + 1U) % c->size; + return output; +} + +static float FxAllpass_Process(FxAllpassState *a, float input, float feedback) +{ + float buf_out = a->buffer[a->idx]; + float output = -input + buf_out; + a->buffer[a->idx] = input + buf_out * feedback; + a->idx = (a->idx + 1U) % a->size; + return output; +} + +void FxReverb_Init(FxReverbState *state, FxReverbParams *params) +{ + params->enabled = false; + params->room_size = 0.5f; + params->damping = 0.5f; + params->mix = 0.3f; + + float *comb_buffers[FX_REVERB_NUM_COMBS] = { + fx_reverb_comb_buf0, fx_reverb_comb_buf1, fx_reverb_comb_buf2, fx_reverb_comb_buf3, + fx_reverb_comb_buf4, fx_reverb_comb_buf5, fx_reverb_comb_buf6, fx_reverb_comb_buf7 + }; + uint32_t comb_sizes[FX_REVERB_NUM_COMBS] = { + FX_REVERB_COMB0, FX_REVERB_COMB1, FX_REVERB_COMB2, FX_REVERB_COMB3, + FX_REVERB_COMB4, FX_REVERB_COMB5, FX_REVERB_COMB6, FX_REVERB_COMB7 + }; + for (uint32_t i = 0; i < FX_REVERB_NUM_COMBS; i++) + { + state->combs[i].buffer = comb_buffers[i]; + state->combs[i].size = comb_sizes[i]; + state->combs[i].idx = 0; + state->combs[i].filter_store = 0.0f; + memset(comb_buffers[i], 0, comb_sizes[i] * sizeof(float)); + } + + float *allpass_buffers[FX_REVERB_NUM_ALLPASS] = { + fx_reverb_allpass_buf0, fx_reverb_allpass_buf1, fx_reverb_allpass_buf2, fx_reverb_allpass_buf3 + }; + uint32_t allpass_sizes[FX_REVERB_NUM_ALLPASS] = { + FX_REVERB_ALLPASS0, FX_REVERB_ALLPASS1, FX_REVERB_ALLPASS2, FX_REVERB_ALLPASS3 + }; + for (uint32_t i = 0; i < FX_REVERB_NUM_ALLPASS; i++) + { + state->allpass[i].buffer = allpass_buffers[i]; + state->allpass[i].size = allpass_sizes[i]; + state->allpass[i].idx = 0; + memset(allpass_buffers[i], 0, allpass_sizes[i] * sizeof(float)); + } +} + +float FxReverb_Process(FxReverbState *state, const FxReverbParams *params, float input) +{ + if (!params->enabled) + { + return input; + } + + float feedback = 0.28f + params->room_size * 0.7f; + float damp1 = params->damping * 0.4f; + float damp2 = 1.0f - damp1; + + float out = 0.0f; + for (uint32_t i = 0; i < FX_REVERB_NUM_COMBS; i++) + { + out += FxComb_Process(&state->combs[i], input, feedback, damp1, damp2); + } + out /= (float)FX_REVERB_NUM_COMBS; + + for (uint32_t i = 0; i < FX_REVERB_NUM_ALLPASS; i++) + { + out = FxAllpass_Process(&state->allpass[i], out, 0.5f); + } + + return input * (1.0f - params->mix) + out * params->mix; +} diff --git a/Appli/Core/Src/fx_saturation.c b/Appli/Core/Src/fx_saturation.c new file mode 100644 index 0000000..4c9ab6d --- /dev/null +++ b/Appli/Core/Src/fx_saturation.c @@ -0,0 +1,32 @@ +#include "fx_saturation.h" +#include + +#define FX_SATURATION_DC_BLOCK_R 0.995f + +void FxSaturation_Init(FxSaturationState *state, FxSaturationParams *params) +{ + state->dc_block_x1 = 0.0f; + state->dc_block_y1 = 0.0f; + + params->enabled = false; + params->drive = 0.3f; + params->level = 0.8f; +} + +float FxSaturation_Process(FxSaturationState *state, const FxSaturationParams *params, float input) +{ + if (!params->enabled) + { + return input; + } + + float driven = input * (1.0f + params->drive * 12.0f); + float shaped = tanhf(driven); + + /* Le tanh sur un signal non symetrique introduit un leger DC : filtre bloqueur de DC. */ + float y = shaped - state->dc_block_x1 + FX_SATURATION_DC_BLOCK_R * state->dc_block_y1; + state->dc_block_x1 = shaped; + state->dc_block_y1 = y; + + return y * params->level; +} diff --git a/Appli/Core/Src/main.c b/Appli/Core/Src/main.c index 8cc26b4..e4ee3aa 100644 --- a/Appli/Core/Src/main.c +++ b/Appli/Core/Src/main.c @@ -25,6 +25,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "stm32h7s78_discovery_audio.h" +#include "audio_effects.h" #include /* USER CODE END Includes */ @@ -186,6 +187,8 @@ int main(void) fifo_write_idx = FIFO_SIZE / 2; fifo_read_idx = 0; + AudioEffects_Init(); + sDmaConfig.Address = (uint32_t)adf_buf; sDmaConfig.DataLength = AUDIO_SAMPLES * sizeof(int32_t); /* OCTETS */ sDmaConfig.MsbOnly = DISABLE; /* 32-bit/sample ; ENABLE si buffer int16 */ @@ -768,11 +771,17 @@ static void MX_GPIO_Init(void) /* USER CODE BEGIN 4 */ -static inline int16_t adf_sample_to_pcm16(int32_t raw) +static inline float adf_sample_to_float(int32_t raw) { - int32_t v = raw >> 8; // 24 bits -> 16 bits (comme le fait le BSP) - if (v > 32767) v = 32767; - if (v < -32768) v = -32768; + int32_t v = raw >> 8; // 24 bits -> valeur signee sur 24 bits + return (float)v / 8388608.0f; // normalisation en [-1.0, 1.0] +} + +static inline int16_t float_to_pcm16(float x) +{ + float v = x * 32767.0f; + if (v > 32767.0f) v = 32767.0f; + if (v < -32768.0f) v = -32768.0f; return (int16_t)v; } @@ -782,7 +791,9 @@ static void push_to_fifo(int32_t raw) { return; // FIFO pleine : on jette l'échantillon plutôt que d'écraser du non-lu } - int16_t s = adf_sample_to_pcm16(raw); + float sample = adf_sample_to_float(raw); + sample = AudioEffects_Process(sample); + int16_t s = float_to_pcm16(sample); uint32_t idx = fifo_write_idx & (FIFO_SIZE - 1); audio_fifo[idx * 2] = s; audio_fifo[idx * 2 + 1] = s; diff --git a/gcc/makefile_appli b/gcc/makefile_appli index 4f8ab88..6d9c0e2 100644 --- a/gcc/makefile_appli +++ b/gcc/makefile_appli @@ -298,7 +298,13 @@ board_c_files += \ Appli/Core/Src/stm32h7rsxx_it.c \ Appli/Core/Src/stm32h7rsxx_hal_msp.c \ Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c \ - Appli/Core/Src/system_stm32h7rsxx.c + Appli/Core/Src/system_stm32h7rsxx.c \ + Appli/Core/Src/audio_effects.c \ + Appli/Core/Src/fx_equalizer.c \ + Appli/Core/Src/fx_overdrive.c \ + Appli/Core/Src/fx_saturation.c \ + Appli/Core/Src/fx_echo.c \ + Appli/Core/Src/fx_reverb.c # Drivers board_include_paths := \