115 lines
3.9 KiB
C
115 lines
3.9 KiB
C
#include "fx_reverb.h"
|
|
#include <string.h>
|
|
|
|
/* 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;
|
|
}
|