mirror of
https://github.com/radio95-rnt/fm95.git
synced 2026-02-26 19:23:51 +01:00
try another bs412 compressor implementation
This commit is contained in:
@@ -11,16 +11,20 @@ inline float deviation_to_dbr(float deviation) {
|
||||
return 10.0f * (log2f(deviation) - LOG2_19000) * 0.30103f;
|
||||
}
|
||||
|
||||
void init_modulation_power_measure(MPXPowerMeasurement* mpx, int sample_rate) {
|
||||
void init_bs412(BS412Compressor* mpx, float target_power, float attack, float release, int sample_rate) {
|
||||
mpx->sample_counter = 0;
|
||||
mpx->sample = 0;
|
||||
mpx->sample_rate = sample_rate;
|
||||
mpx->attack = expf(-1.0f / (attack * sample_rate));
|
||||
mpx->release = expf(-1.0f / (release * sample_rate));
|
||||
mpx->target = target_power;
|
||||
mpx->gain = 1.0f;
|
||||
#ifdef BS412_DEBUG
|
||||
debug_printf("Initialized MPX power measurement with sample rate: %d\n", sample_rate);
|
||||
#endif
|
||||
}
|
||||
|
||||
float measure_mpx(MPXPowerMeasurement* mpx, float deviation) {
|
||||
float bs412_compress(BS412Compressor* mpx, float deviation) {
|
||||
mpx->sample += deviation * deviation; // rmS
|
||||
mpx->sample_counter++;
|
||||
|
||||
@@ -42,5 +46,12 @@ float measure_mpx(MPXPowerMeasurement* mpx, float deviation) {
|
||||
mpx->sample_counter = 1;
|
||||
}
|
||||
|
||||
return modulation_power;
|
||||
float gain_target = powf(10.0f, (mpx->target - modulation_power) / 20.0f); // dB to linear
|
||||
if (gain_target > mpx->gain)
|
||||
mpx->gain = mpx->gain * mpx->attack + (1.0f - mpx->attack) * gain_target;
|
||||
else
|
||||
mpx->gain = mpx->gain * mpx->release + (1.0f - mpx->release) * gain_target;
|
||||
|
||||
|
||||
return deviation*mpx->gain;
|
||||
}
|
||||
|
||||
@@ -13,11 +13,15 @@ typedef struct
|
||||
{
|
||||
int sample_counter;
|
||||
int sample_rate;
|
||||
float target;
|
||||
float attack;
|
||||
float release;
|
||||
float gain;
|
||||
double sample;
|
||||
} MPXPowerMeasurement;
|
||||
} BS412Compressor;
|
||||
|
||||
float dbr_to_deviation(float dbr);
|
||||
float deviation_to_dbr(float deviation);
|
||||
|
||||
void init_modulation_power_measure(MPXPowerMeasurement *mpx, int sample_rate);
|
||||
float measure_mpx(MPXPowerMeasurement *mpx, float deviation);
|
||||
void init_bs412(BS412Compressor *mpx, float target_power, float attack, float release, int sample_rate);
|
||||
float bs412_compress(BS412Compressor *mpx, float deviation);
|
||||
24
src/fm95.c
24
src/fm95.c
@@ -166,8 +166,8 @@ int run_fm95(const FM95_Config config, FM95_Runtime* runtime) {
|
||||
init_preemphasis(&preemp_l, config.preemphasis, config.sample_rate, config.preemp_unity_freq);
|
||||
init_preemphasis(&preemp_r, config.preemphasis, config.sample_rate, config.preemp_unity_freq);
|
||||
|
||||
MPXPowerMeasurement power;
|
||||
init_modulation_power_measure(&power, config.sample_rate);
|
||||
BS412Compressor bs412;
|
||||
init_bs412(&bs412, config.mpx_power, config.bs412_attack, config.bs412_release, config.sample_rate);
|
||||
|
||||
TiltCorrectionFilter tilter;
|
||||
tilt_init(&tilter, config.tilt);
|
||||
@@ -175,10 +175,6 @@ int run_fm95(const FM95_Config config, FM95_Runtime* runtime) {
|
||||
StereoEncoder stencode;
|
||||
init_stereo_encoder(&stencode, 4.0f, &osc, (config.stereo == 2), config.volumes.mono, config.volumes.pilot, config.volumes.stereo);
|
||||
|
||||
float bs412_audio_gain = 1.0f;
|
||||
float bs412_attack_alpha = expf(-1.0f / (config.bs412_attack * config.sample_rate));
|
||||
float bs412_release_alpha = expf(-1.0f / (config.bs412_release * config.sample_rate));
|
||||
|
||||
AGC agc;
|
||||
initAGC(&agc, config.sample_rate, config.agc_target, config.agc_min, config.agc_max, config.agc_attack, config.agc_release);
|
||||
|
||||
@@ -236,21 +232,7 @@ int run_fm95(const FM95_Config config, FM95_Runtime* runtime) {
|
||||
}
|
||||
}
|
||||
|
||||
float mpx_power = measure_mpx(&power, mpx * config.mpx_deviation);
|
||||
if (mpx_power > config.mpx_power) {
|
||||
float excess_power = mpx_power - config.mpx_power;
|
||||
|
||||
if (excess_power > 0.0f && excess_power < 10.0f) {
|
||||
float target_gain = dbr_to_deviation(-excess_power) / config.mpx_deviation;
|
||||
|
||||
target_gain = fmaxf(target_gain, 0.1f);
|
||||
target_gain = fminf(target_gain, 1.0f);
|
||||
|
||||
bs412_audio_gain = bs412_attack_alpha * bs412_audio_gain + (1 - bs412_attack_alpha) * target_gain;
|
||||
}
|
||||
} else bs412_audio_gain = fminf(1.0f, bs412_release_alpha * bs412_audio_gain + (1 - bs412_release_alpha) * 1.0f);
|
||||
|
||||
mpx *= bs412_audio_gain;
|
||||
mpx = bs412_compress(&bs412, mpx*config.mpx_deviation);
|
||||
|
||||
output[i] = hard_clip(tilt(&tilter, (mpx_in[i]+mpx))*config.master_volume, 1.0); // Ensure peak deviation of 75 khz, assuming we're calibrated correctly (lower)
|
||||
advance_oscillator(&osc);
|
||||
|
||||
Reference in New Issue
Block a user