implement 24 bit sample support for fluid_voice_optimize_sample()

This commit is contained in:
derselbst 2018-01-18 17:13:50 +01:00 committed by Tom M
parent 92baab7dac
commit 4a655de242
3 changed files with 113 additions and 101 deletions

View file

@ -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

View file

@ -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);
}
}

View file

@ -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 */