diff --git a/fluidsynth/src/rvoice/fluid_iir_filter.c b/fluidsynth/src/rvoice/fluid_iir_filter.c index 0e5133d5..c29e6a7b 100644 --- a/fluidsynth/src/rvoice/fluid_iir_filter.c +++ b/fluidsynth/src/rvoice/fluid_iir_filter.c @@ -97,7 +97,7 @@ fluid_iir_filter_apply(fluid_iir_filter_t* iir_filter, dsp_b1 += dsp_b1_incr; /* Compensate history to avoid the filter going havoc with large frequency changes */ - if (fabs(dsp_b02) > 0.001) { + if (iir_filter->compensate_incr && fabs(dsp_b02) > 0.001) { fluid_real_t compensate = old_b02 / dsp_b02; dsp_centernode *= compensate; dsp_hist1 *= compensate; @@ -211,6 +211,8 @@ fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t* iir_filter, /* both b0 -and- b2 */ fluid_real_t b02_temp = b1_temp * 0.5f; + iir_filter->compensate_incr = 0; + if (iir_filter->filter_startup || (transition_samples == 0)) { /* The filter is calculated, because the voice was started up. @@ -240,6 +242,10 @@ fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t* iir_filter, iir_filter->a2_incr = (a2_temp - iir_filter->a2) / transition_samples; iir_filter->b02_incr = (b02_temp - iir_filter->b02) / transition_samples; iir_filter->b1_incr = (b1_temp - iir_filter->b1) / transition_samples; + if (fabs(iir_filter->b02) > 0.0001) { + fluid_real_t quota = b02_temp / iir_filter->b02; + iir_filter->compensate_incr = quota < 0.5 || quota > 2; + } /* Have to add the increments filter_coeff_incr_count times. */ iir_filter->filter_coeff_incr_count = transition_samples; } diff --git a/fluidsynth/src/rvoice/fluid_iir_filter.h b/fluidsynth/src/rvoice/fluid_iir_filter.h index b59fdf37..e17903b2 100644 --- a/fluidsynth/src/rvoice/fluid_iir_filter.h +++ b/fluidsynth/src/rvoice/fluid_iir_filter.h @@ -58,6 +58,7 @@ struct _fluid_iir_filter_t fluid_real_t a1_incr; fluid_real_t a2_incr; int filter_coeff_incr_count; + int compensate_incr; /* Flag: If set, must compensate history */ fluid_real_t hist1, hist2; /* Sample history for the IIR filter */ int filter_startup; /* Flag: If set, the filter will be set directly. Else it changes smoothly. */