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.
This commit is contained in:
carlo-bramini 2018-11-16 16:48:25 +01:00 committed by derselbst
parent bd41795263
commit 29c668683f
5 changed files with 11 additions and 11 deletions

View file

@ -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 * 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. * input channels is mapped to the same synth channel.
*/ */
chan = (int)((fluid_real_t)event->channel * (fluid_real_t)rule->chan_mul chan = rule->chan_add + (int)((fluid_real_t)event->channel * rule->chan_mul
+ (fluid_real_t)rule->chan_add + 0.5); + (fluid_real_t)0.5);
/* Par 1 scaling / offset */ /* Par 1 scaling / offset */
par1 = (int)((fluid_real_t)event_par1 * (fluid_real_t)rule->par1_mul par1 = rule->par1_add + (int)((fluid_real_t)event_par1 * rule->par1_mul
+ (fluid_real_t)rule->par1_add + 0.5); + (fluid_real_t)0.5);
/* Par 2 scaling / offset, if applicable */ /* Par 2 scaling / offset, if applicable */
if(event_has_par2) if(event_has_par2)
{ {
par2 = (int)((fluid_real_t)event_par2 * (fluid_real_t)rule->par2_mul par2 = rule->par2_add + (int)((fluid_real_t)event_par2 * rule->par2_mul
+ (fluid_real_t)rule->par2_add + 0.5); + (fluid_real_t)0.5);
} }
else else
{ {

View file

@ -275,8 +275,8 @@ fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t *iir_filter,
* into account for both significant frequency relocation and for * into account for both significant frequency relocation and for
* bandwidth readjustment'. */ * bandwidth readjustment'. */
fluid_real_t omega = (fluid_real_t)(2.0 * M_PI * fluid_real_t omega = (fluid_real_t)(2.0 * M_PI) *
(iir_filter->last_fres / ((float) output_rate))); (iir_filter->last_fres / output_rate);
fluid_real_t sin_coeff = (fluid_real_t) sin(omega); fluid_real_t sin_coeff = (fluid_real_t) sin(omega);
fluid_real_t cos_coeff = (fluid_real_t) cos(omega); fluid_real_t cos_coeff = (fluid_real_t) cos(omega);
fluid_real_t alpha_coeff = sin_coeff / (2.0f * iir_filter->q_lin); fluid_real_t alpha_coeff = sin_coeff / (2.0f * iir_filter->q_lin);

View file

@ -34,7 +34,7 @@
* output. There is a very small turn-on transient response, which should not * output. There is a very small turn-on transient response, which should not
* cause problems. * cause problems.
*/ */
#define DC_OFFSET 1e-8 #define DC_OFFSET ((fluid_real_t)1e-8)
typedef struct _fluid_allpass fluid_allpass; typedef struct _fluid_allpass fluid_allpass;
typedef struct _fluid_comb fluid_comb; typedef struct _fluid_comb fluid_comb;

View file

@ -39,7 +39,7 @@ typedef struct _fluid_rvoice_t fluid_rvoice_t;
* 24 bits => 144-4 = 140 dB dynamic range => 1.e-7 * 24 bits => 144-4 = 140 dB dynamic range => 1.e-7
* 1.e-7 * 2 == 2.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 enum fluid_loop
{ {

View file

@ -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. * will cause (60-72)*100=-1200 timecents of time variation.
* The time is cut in half. * 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 */ /* Range checking */
if(is_decay) if(is_decay)