diff --git a/src/rvoice/fluid_rvoice.h b/src/rvoice/fluid_rvoice.h index 2b6cba0d..aeca0168 100644 --- a/src/rvoice/fluid_rvoice.h +++ b/src/rvoice/fluid_rvoice.h @@ -36,9 +36,10 @@ typedef struct _fluid_rvoice_t fluid_rvoice_t; /* Smallest amplitude that can be perceived (full scale is +/- 0.5) * 16 bits => 96+4=100 dB dynamic range => 0.00001 - * 0.00001 * 2 is approximately 0.00003 :) + * 24 bits => 144-4 = 140 dB dynamic range => 1.e-7 + * 1.e-7 * 2 == 2.e-7 :) */ -#define FLUID_NOISE_FLOOR 0.00003 +#define FLUID_NOISE_FLOOR 2.e-7 enum fluid_loop { @@ -197,4 +198,27 @@ int fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice); int fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice); int fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice); + +/* + * Combines the most significant 16 bit part of a sample with a potentially present + * least sig. 8 bit part in order to create a 24 bit sample. + */ +static FLUID_INLINE int32_t +fluid_rvoice_get_sample(const short int* dsp_msb, const char* dsp_lsb, unsigned int idx) +{ + /* cast sample to unsigned type, so we can safely shift and bitwise or + * without relying on undefined behaviour (should never happen anyway ofc...) */ + uint32_t msb = (uint32_t)dsp_msb[idx]; + uint8_t lsb = 0U; + + /* most soundfonts have 16 bit samples, assume that it's unlikely we + * experience 24 bit samples here */ + if(FLUID_UNLIKELY(dsp_lsb != NULL)) + { + lsb = (uint8_t)dsp_lsb[idx]; + } + + return (int32_t)((msb << 8) | lsb); +} + #endif diff --git a/src/rvoice/fluid_rvoice_dsp.c b/src/rvoice/fluid_rvoice_dsp.c index 7b9475cf..8ae64046 100644 --- a/src/rvoice/fluid_rvoice_dsp.c +++ b/src/rvoice/fluid_rvoice_dsp.c @@ -119,26 +119,11 @@ void fluid_rvoice_dsp_config (void) fluid_check_fpe("interpolation table calculation"); } -/* - * Combines the most significant 16 bit part of a sample with a potentially present - * least sig. 8 bit part in order to create a 24 bit sample. - */ static FLUID_INLINE fluid_real_t -fluid_rvoice_get_sample(const short int* dsp_msb, const char* dsp_lsb, unsigned int idx) +fluid_rvoice_get_float_sample(const short int* dsp_msb, const char* dsp_lsb, unsigned int idx) { - /* cast sample to unsigned type, so we can safely shift and bitwise or - * without relying on undefined behaviour (should never happen anyway ofc...) */ - uint32_t msb = (uint32_t)dsp_msb[idx]; - uint8_t lsb = 0U; - - /* most soundfonts have 16 bit samples, assume that it's unlikely we - * experience 24 bit samples here */ - if(FLUID_UNLIKELY(dsp_lsb != NULL)) - { - lsb = (uint8_t)dsp_lsb[idx]; - } - - return (fluid_real_t)((int32_t)((msb << 8) | lsb)); + int32_t sample = fluid_rvoice_get_sample(dsp_msb, dsp_lsb, idx); + return (fluid_real_t)sample; } /* No interpolation. Just take the sample, which is closest to @@ -174,7 +159,7 @@ fluid_rvoice_dsp_interpolate_none (fluid_rvoice_dsp_t *voice) /* interpolate sequence of sample points */ for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) { - dsp_buf[dsp_i] = dsp_amp * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index); + dsp_buf[dsp_i] = dsp_amp * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -233,8 +218,8 @@ fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice) end_index = (looping ? voice->loopend - 1 : voice->end) - 1; /* 2nd interpolation point to use at end of loop or sample */ - if (looping) point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart); /* loop start */ - else point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->end); /* duplicate end for samples no longer looping */ + if (looping) point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart); /* loop start */ + else point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end); /* duplicate end for samples no longer looping */ while (1) { @@ -244,8 +229,8 @@ fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice) for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) { coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1)); + dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+1)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -262,7 +247,7 @@ fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice) for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) { coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + coeffs[1] * point); /* increment phase and amplitude */ @@ -325,23 +310,23 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) if (voice->has_looped) /* set start_index and start point if looped or not */ { start_index = voice->loopstart; - start_point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 1); /* last point in loop (wrap around) */ + start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1); /* last point in loop (wrap around) */ } else { start_index = voice->start; - start_point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the point */ + start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the point */ } /* get points off the end (loop start if looping, duplicate point if end) */ if (looping) { - end_point1 = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart); - end_point2 = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart + 1); + end_point1 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart); + end_point2 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 1); } else { - end_point1 = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->end); + end_point1 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end); end_point2 = end_point1; } @@ -355,9 +340,9 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp * ( coeffs[0] * start_point - + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2)); + + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+2)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -370,10 +355,10 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) { coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp * - ( coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2)); + ( coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+2)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -391,9 +376,9 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) { coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp * - ( coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + ( coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+1) + coeffs[3] * end_point1); /* increment phase and amplitude */ @@ -409,8 +394,8 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) { coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp * - ( coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + ( coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + coeffs[2] * end_point1 + coeffs[3] * end_point2); @@ -431,7 +416,7 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) { voice->has_looped = 1; start_index = voice->loopstart; - start_point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend-1); + start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend-1); } } @@ -484,14 +469,14 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) if (voice->has_looped) /* set start_index and start point if looped or not */ { start_index = voice->loopstart; - start_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 1); - start_points[1] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 2); - start_points[2] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 3); + start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1); + start_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 2); + start_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 3); } else { start_index = voice->start; - start_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the start point */ + start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the start point */ start_points[1] = start_points[0]; start_points[2] = start_points[0]; } @@ -499,13 +484,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) /* get the 3 points off the end (loop start if looping, duplicate point if end) */ if (looping) { - end_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart); - end_points[1] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart + 1); - end_points[2] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart + 2); + end_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart); + end_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 1); + end_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 2); } else { - end_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->end); + end_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end); end_points[1] = end_points[0]; end_points[2] = end_points[0]; } @@ -523,10 +508,10 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) * (coeffs[0] * start_points[2] + coeffs[1] * start_points[1] + coeffs[2] * start_points[0] - + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) - + coeffs[6] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); + + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -544,11 +529,11 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * start_points[1] + coeffs[1] * start_points[0] - + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) - + coeffs[6] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); + + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -565,12 +550,12 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * start_points[0] - + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) - + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) - + coeffs[6] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); + + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -587,13 +572,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) - + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) - + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) - + coeffs[6] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); + * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -612,12 +597,12 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) - + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) - + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+2) + coeffs[6] * end_points[0]); /* increment phase and amplitude */ @@ -634,11 +619,11 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) - + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) - + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index+1) + coeffs[5] * end_points[0] + coeffs[6] * end_points[1]); @@ -656,10 +641,10 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) - + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) - + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index) + coeffs[4] * end_points[0] + coeffs[5] * end_points[1] + coeffs[6] * end_points[2]); @@ -681,9 +666,9 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) { voice->has_looped = 1; start_index = voice->loopstart; - start_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 1); - start_points[1] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 2); - start_points[2] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 3); + start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1); + start_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 2); + start_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 3); } } diff --git a/src/synth/fluid_voice.c b/src/synth/fluid_voice.c index fd6dada4..df25a38a 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -36,6 +36,9 @@ /* min vol envelope release (to stop clicks) in SoundFont timecents */ #define FLUID_MIN_VOLENVRELEASE -7200.0f /* ~16ms */ + +static const int32_t INT24_MAX = (1 << (16+8-1)); + static int fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice); static int calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base, int gen_key2base, int is_decay); @@ -442,8 +445,7 @@ fluid_voice_calculate_gain_amplitude(const fluid_voice_t* voice, fluid_real_t ga /* we use 24bit samples in fluid_rvoice_dsp. in order to normalize float * samples to [0.0;1.0] divide samples by the max. value of an int24 and * amplify them with the gain */ - const fluid_real_t INT24_MAX = (1 << (16+8-1)) * 1.0f; - return gain * voice->synth_gain / INT24_MAX; + return gain * voice->synth_gain / (INT24_MAX * 1.0f); } void @@ -1635,20 +1637,21 @@ int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain) int fluid_voice_optimize_sample(fluid_sample_t* s) { - signed short peak_max = 0; - signed short peak_min = 0; - signed short peak; + int32_t peak_max = 0; + int32_t peak_min = 0; + int32_t peak; fluid_real_t normalized_amplitude_during_loop; double result; - int i; + unsigned int i; /* ignore ROM and other(?) invalid samples */ if (!s->valid) return (FLUID_OK); if (!s->amplitude_that_reaches_noise_floor_is_valid) { /* Only once */ /* Scan the loop */ - for (i = (int)s->loopstart; i < (int)s->loopend; i++){ - signed short val = s->data[i]; + for (i = s->loopstart; i < s->loopend; i++){ + int32_t val = fluid_rvoice_get_sample(s->data, s->data24, i); + if (val > peak_max) { peak_max = val; } else if (val < peak_min) { @@ -1675,7 +1678,7 @@ fluid_voice_optimize_sample(fluid_sample_t* s) */ /* 16 bits => 96+4=100 dB dynamic range => 0.00001 */ - normalized_amplitude_during_loop = ((fluid_real_t)peak)/32768.; + normalized_amplitude_during_loop = ((fluid_real_t)peak)/ (INT24_MAX * 1.0f); result = FLUID_NOISE_FLOOR / normalized_amplitude_during_loop; /* Store in sample */