From aed6ba3742b895a963b6564b2010d4318d0f6d9e Mon Sep 17 00:00:00 2001 From: "Tom M." Date: Sun, 1 Dec 2024 14:13:36 +0100 Subject: [PATCH] Reenable AWE32 NRPN 23 and 24 (#1430) --- src/synth/fluid_synth.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index 23ca6e333..e356982ee 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -7715,7 +7715,7 @@ static void fluid_synth_process_awe32_nrpn_LOCAL(fluid_synth_t *synth, int chan, }; enum fluid_gen_type sf2_gen = awe32_to_sf2_gen[gen]; - int is_realtime = FALSE, i, coef; + int is_realtime = FALSE, i; fluid_real_t converted_sf2_generator_value, q; // The AWE32 NRPN docs say that a value of 8192 is considered to be the middle, i.e. zero. @@ -7790,7 +7790,7 @@ static void fluid_synth_process_awe32_nrpn_LOCAL(fluid_synth_t *synth, int chan, case GEN_FILTERFC: fluid_clip(data_lsb, 0, 127); - // Yes, DO NOT use data here, Uplift.mid doesn't set MSB=64, therefore we would always get a negative value after subtracting 8192. + // Yes, DO NOT use data here, Uplift.mid doesn't set DATA_MSB=64, therefore we would always get a negative value after subtracting 8192. // Since Uplift.mid sounds fine on hardware though, it seems like AWE32 only inspects DATA_LSB in this case. // conversion continues below! converted_sf2_generator_value = (data_lsb * 62 /* Hz */); @@ -7803,20 +7803,25 @@ static void fluid_synth_process_awe32_nrpn_LOCAL(fluid_synth_t *synth, int chan, synth->channel[chan]->awe32_filter_coeff = data_lsb; return; + // Note: The description in the official "SB AWE32 Developer's Information Pack" is probably wrong. + // There it says: "Positive data value causes a positive phase (from 0 to maximum) filter modulation + // [...] negative data value causes a negative phase [...]" + // That doesn't make sense. A filter is a causual system - you cannot change its phase independently + // of the rest. The text a few section above has it correct, there they speak of the filter's + // cutoff frequency. In that sense, this is probably intended to behave similar to the logic in SF2. + // PS: Same applies to the GEN_MODENVTOFILTERFC below! case GEN_MODLFOTOFILTERFC: fluid_clip(data, -64, 63); converted_sf2_generator_value = data * (fluid_real_t)56.25 /* cents */; FLUID_LOG(FLUID_DBG, "AWE32 MOD LFO TO FILTER Fc: %f cents", converted_sf2_generator_value); is_realtime = TRUE; - // not supported, as this modulates the "phase" rather than the filters cutoff frequency - return; + break; case GEN_MODENVTOFILTERFC: fluid_clip(data, -127, 127); converted_sf2_generator_value = data * (fluid_real_t)56.25 /* cents */; FLUID_LOG(FLUID_DBG, "AWE32 MOD ENV TO FILTER Fc: %f cents", converted_sf2_generator_value); - // not supported, as this modulates the "phase" rather than the filters cutoff frequency - return; + break; case GEN_REVERBSEND: fluid_clip(data, 0, 255); @@ -7840,9 +7845,9 @@ static void fluid_synth_process_awe32_nrpn_LOCAL(fluid_synth_t *synth, int chan, return; } - coef = synth->channel[chan]->awe32_filter_coeff; if(sf2_gen == GEN_FILTERFC) { + int coef = synth->channel[chan]->awe32_filter_coeff; // The cutoff at fc seems to be very steep for SoundBlaster! hardware. Listening tests have shown that lowering the cutoff frequency by 1000Hz gives a closer signal to the SB! hardware filter... converted_sf2_generator_value -= 1000; q = calc_awe32_filter_q(coef, &converted_sf2_generator_value);