#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; }