From 29c668683f43e3b8b4aab0b8aa73cb02aacd6fcb Mon Sep 17 00:00:00 2001 From: carlo-bramini <30959007+carlo-bramini@users.noreply.github.com> Date: Fri, 16 Nov 2018 16:48:25 +0100 Subject: [PATCH] Improve float calculations (#462) I tried to check the generated ASM code when WITH_FLOAT macro is defined and when it is undefined. In both cases I noticed that there are some points where the math number are converted from float to double and viceversa. Actually this happens whether the FPU is present or not, perhaps for granting the right precision in digits. I also noticed few points that could be simplified a bit by using integer math, so I also included them. * Since fluid_voice_get_actual_key() returns an integer value, the value 60 could be subtracted directly as integer, the code generated looks a bit better. * FLUID_NOISE_FLOOR needs to be cast to fluid_real_t to generate a bit more efficient code. * DC_OFFSET needs a cast to fluid_real_t to generate a bit more efficient code. * "last_fres" and "output_rate" are already fluid_real_t, so they do not need type cast. * "chan_add", "par1_add" and "par2_add" are integer types, so they can be added without FPU. "chan_mul", "par1_mul" and "par2_mul" are already fluid_real_t, so they do not need type cast. Instead, the constant 0.5 needs cast to fluid_real_t to be more efficient. --- src/midi/fluid_midi_router.c | 12 ++++++------ src/rvoice/fluid_iir_filter.c | 4 ++-- src/rvoice/fluid_rev.c | 2 +- src/rvoice/fluid_rvoice.h | 2 +- src/synth/fluid_voice.c | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/midi/fluid_midi_router.c b/src/midi/fluid_midi_router.c index c3bc8916..dfc32d75 100644 --- a/src/midi/fluid_midi_router.c +++ b/src/midi/fluid_midi_router.c @@ -678,18 +678,18 @@ fluid_midi_router_handle_midi_event(void *data, fluid_midi_event_t *event) * Note: rule->chan_mul will probably be 0 or 1. If it's 0, input from all * input channels is mapped to the same synth channel. */ - chan = (int)((fluid_real_t)event->channel * (fluid_real_t)rule->chan_mul - + (fluid_real_t)rule->chan_add + 0.5); + chan = rule->chan_add + (int)((fluid_real_t)event->channel * rule->chan_mul + + (fluid_real_t)0.5); /* Par 1 scaling / offset */ - par1 = (int)((fluid_real_t)event_par1 * (fluid_real_t)rule->par1_mul - + (fluid_real_t)rule->par1_add + 0.5); + par1 = rule->par1_add + (int)((fluid_real_t)event_par1 * rule->par1_mul + + (fluid_real_t)0.5); /* Par 2 scaling / offset, if applicable */ if(event_has_par2) { - par2 = (int)((fluid_real_t)event_par2 * (fluid_real_t)rule->par2_mul - + (fluid_real_t)rule->par2_add + 0.5); + par2 = rule->par2_add + (int)((fluid_real_t)event_par2 * rule->par2_mul + + (fluid_real_t)0.5); } else { diff --git a/src/rvoice/fluid_iir_filter.c b/src/rvoice/fluid_iir_filter.c index 0770ef62..d20c9a8e 100644 --- a/src/rvoice/fluid_iir_filter.c +++ b/src/rvoice/fluid_iir_filter.c @@ -275,8 +275,8 @@ fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t *iir_filter, * into account for both significant frequency relocation and for * bandwidth readjustment'. */ - fluid_real_t omega = (fluid_real_t)(2.0 * M_PI * - (iir_filter->last_fres / ((float) output_rate))); + fluid_real_t omega = (fluid_real_t)(2.0 * M_PI) * + (iir_filter->last_fres / output_rate); fluid_real_t sin_coeff = (fluid_real_t) sin(omega); fluid_real_t cos_coeff = (fluid_real_t) cos(omega); fluid_real_t alpha_coeff = sin_coeff / (2.0f * iir_filter->q_lin); diff --git a/src/rvoice/fluid_rev.c b/src/rvoice/fluid_rev.c index c025e105..198a06e5 100644 --- a/src/rvoice/fluid_rev.c +++ b/src/rvoice/fluid_rev.c @@ -34,7 +34,7 @@ * output. There is a very small turn-on transient response, which should not * cause problems. */ -#define DC_OFFSET 1e-8 +#define DC_OFFSET ((fluid_real_t)1e-8) typedef struct _fluid_allpass fluid_allpass; typedef struct _fluid_comb fluid_comb; diff --git a/src/rvoice/fluid_rvoice.h b/src/rvoice/fluid_rvoice.h index bae3ac93..56cd53f4 100644 --- a/src/rvoice/fluid_rvoice.h +++ b/src/rvoice/fluid_rvoice.h @@ -39,7 +39,7 @@ typedef struct _fluid_rvoice_t fluid_rvoice_t; * 24 bits => 144-4 = 140 dB dynamic range => 1.e-7 * 1.e-7 * 2 == 2.e-7 :) */ -#define FLUID_NOISE_FLOOR 2.e-7 +#define FLUID_NOISE_FLOOR ((fluid_real_t)2.e-7) enum fluid_loop { diff --git a/src/synth/fluid_voice.c b/src/synth/fluid_voice.c index 51c1ebf6..2f146ba0 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -685,7 +685,7 @@ calculate_hold_decay_buffers(fluid_voice_t *voice, int gen_base, * will cause (60-72)*100=-1200 timecents of time variation. * The time is cut in half. */ - timecents = (fluid_voice_gen_value(voice, gen_base) + fluid_voice_gen_value(voice, gen_key2base) * (60.0 - fluid_voice_get_actual_key(voice))); + timecents = (fluid_voice_gen_value(voice, gen_base) + fluid_voice_gen_value(voice, gen_key2base) * (fluid_real_t)(60 - fluid_voice_get_actual_key(voice))); /* Range checking */ if(is_decay)