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;
|
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_counter = 0;
|
||||||
mpx->sample = 0;
|
mpx->sample = 0;
|
||||||
mpx->sample_rate = sample_rate;
|
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
|
#ifdef BS412_DEBUG
|
||||||
debug_printf("Initialized MPX power measurement with sample rate: %d\n", sample_rate);
|
debug_printf("Initialized MPX power measurement with sample rate: %d\n", sample_rate);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
float measure_mpx(MPXPowerMeasurement* mpx, float deviation) {
|
float bs412_compress(BS412Compressor* mpx, float deviation) {
|
||||||
mpx->sample += deviation * deviation; // rmS
|
mpx->sample += deviation * deviation; // rmS
|
||||||
mpx->sample_counter++;
|
mpx->sample_counter++;
|
||||||
|
|
||||||
@@ -42,5 +46,12 @@ float measure_mpx(MPXPowerMeasurement* mpx, float deviation) {
|
|||||||
mpx->sample_counter = 1;
|
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_counter;
|
||||||
int sample_rate;
|
int sample_rate;
|
||||||
|
float target;
|
||||||
|
float attack;
|
||||||
|
float release;
|
||||||
|
float gain;
|
||||||
double sample;
|
double sample;
|
||||||
} MPXPowerMeasurement;
|
} BS412Compressor;
|
||||||
|
|
||||||
float dbr_to_deviation(float dbr);
|
float dbr_to_deviation(float dbr);
|
||||||
float deviation_to_dbr(float deviation);
|
float deviation_to_dbr(float deviation);
|
||||||
|
|
||||||
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);
|
||||||
float measure_mpx(MPXPowerMeasurement *mpx, float deviation);
|
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_l, config.preemphasis, config.sample_rate, config.preemp_unity_freq);
|
||||||
init_preemphasis(&preemp_r, config.preemphasis, config.sample_rate, config.preemp_unity_freq);
|
init_preemphasis(&preemp_r, config.preemphasis, config.sample_rate, config.preemp_unity_freq);
|
||||||
|
|
||||||
MPXPowerMeasurement power;
|
BS412Compressor bs412;
|
||||||
init_modulation_power_measure(&power, config.sample_rate);
|
init_bs412(&bs412, config.mpx_power, config.bs412_attack, config.bs412_release, config.sample_rate);
|
||||||
|
|
||||||
TiltCorrectionFilter tilter;
|
TiltCorrectionFilter tilter;
|
||||||
tilt_init(&tilter, config.tilt);
|
tilt_init(&tilter, config.tilt);
|
||||||
@@ -175,10 +175,6 @@ int run_fm95(const FM95_Config config, FM95_Runtime* runtime) {
|
|||||||
StereoEncoder stencode;
|
StereoEncoder stencode;
|
||||||
init_stereo_encoder(&stencode, 4.0f, &osc, (config.stereo == 2), config.volumes.mono, config.volumes.pilot, config.volumes.stereo);
|
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;
|
AGC agc;
|
||||||
initAGC(&agc, config.sample_rate, config.agc_target, config.agc_min, config.agc_max, config.agc_attack, config.agc_release);
|
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);
|
mpx = bs412_compress(&bs412, 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;
|
|
||||||
|
|
||||||
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)
|
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);
|
advance_oscillator(&osc);
|
||||||
|
|||||||
Reference in New Issue
Block a user