mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 15:01:40 +00:00
commit
af0301ae3b
7 changed files with 256 additions and 130 deletions
1
TODO
1
TODO
|
@ -1,6 +1,5 @@
|
|||
New features
|
||||
------------
|
||||
- 24 bit sample support
|
||||
- Non-realtime MIDI file rendering
|
||||
- Sample streaming, load/unload sample on demand
|
||||
- Synth sample rate change after initial creation
|
||||
|
|
|
@ -114,6 +114,7 @@ Changes in FluidSynth 2.0.0 concerning developers:
|
|||
- add seek support to midi-player, see fluid_player_seek()
|
||||
- expose functions to manipulate the ladspa effects unit (see ladspa.h)
|
||||
- add support for text and lyrics midi events, see fluid_midi_event_set_lyrics() and fluid_midi_event_set_text()
|
||||
- add 24 bit sample support, see _fluid_sample_t::data24
|
||||
|
||||
\section NewIn1_1_9 Whats new in 1.1.9?
|
||||
|
||||
|
|
|
@ -297,7 +297,8 @@ struct _fluid_sample_t
|
|||
int pitchadj; /**< Fine pitch adjustment (+/- 99 cents) */
|
||||
int sampletype; /**< Specifies the type of this sample as indicated by the #fluid_sample_type enum */
|
||||
int valid; /**< Should be TRUE if sample data is valid, FALSE otherwise (in which case it will not be synthesized) */
|
||||
short* data; /**< Pointer to the sample's data */
|
||||
short* data; /**< Pointer to the sample's 16 bit PCM data */
|
||||
char* data24; /**< If not NULL, pointer to the least significant byte counterparts of each sample data point in order to create 24 bit audio samples */
|
||||
|
||||
int amplitude_that_reaches_noise_floor_is_valid; /**< Indicates if \a amplitude_that_reaches_noise_floor is valid (TRUE), set to FALSE initially to calculate. */
|
||||
double amplitude_that_reaches_noise_floor; /**< The amplitude at which the sample's loop will be below the noise floor. For voice off optimization, calculated automatically. */
|
||||
|
|
|
@ -119,6 +119,28 @@ 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)
|
||||
{
|
||||
/* 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(G_UNLIKELY(dsp_lsb != NULL))
|
||||
{
|
||||
lsb = (uint8_t)dsp_lsb[idx];
|
||||
}
|
||||
|
||||
return (fluid_real_t)((int32_t)((msb << 8) | lsb));
|
||||
}
|
||||
|
||||
/* No interpolation. Just take the sample, which is closest to
|
||||
* the playback pointer. Questionable quality, but very
|
||||
* efficient. */
|
||||
|
@ -128,6 +150,7 @@ fluid_rvoice_dsp_interpolate_none (fluid_rvoice_dsp_t *voice)
|
|||
fluid_phase_t dsp_phase = voice->phase;
|
||||
fluid_phase_t dsp_phase_incr;
|
||||
short int *dsp_data = voice->sample->data;
|
||||
char *dsp_data24 = voice->sample->data24;
|
||||
fluid_real_t *dsp_buf = voice->dsp_buf;
|
||||
fluid_real_t dsp_amp = voice->amp;
|
||||
fluid_real_t dsp_amp_incr = voice->amp_incr;
|
||||
|
@ -151,7 +174,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 * dsp_data[dsp_phase_index];
|
||||
dsp_buf[dsp_i] = dsp_amp * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index);
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -189,13 +212,14 @@ fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice)
|
|||
fluid_phase_t dsp_phase = voice->phase;
|
||||
fluid_phase_t dsp_phase_incr;
|
||||
short int *dsp_data = voice->sample->data;
|
||||
char *dsp_data24 = voice->sample->data24;
|
||||
fluid_real_t *dsp_buf = voice->dsp_buf;
|
||||
fluid_real_t dsp_amp = voice->amp;
|
||||
fluid_real_t dsp_amp_incr = voice->amp_incr;
|
||||
unsigned int dsp_i = 0;
|
||||
unsigned int dsp_phase_index;
|
||||
unsigned int end_index;
|
||||
short int point;
|
||||
fluid_real_t point;
|
||||
fluid_real_t *coeffs;
|
||||
int looping;
|
||||
|
||||
|
@ -209,8 +233,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 = dsp_data[voice->loopstart]; /* loop start */
|
||||
else point = dsp_data[voice->end]; /* duplicate end for samples no longer looping */
|
||||
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 */
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -220,8 +244,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] * dsp_data[dsp_phase_index]
|
||||
+ coeffs[1] * dsp_data[dsp_phase_index+1]);
|
||||
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));
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -238,8 +262,8 @@ 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] * dsp_data[dsp_phase_index]
|
||||
+ coeffs[1] * point);
|
||||
dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index)
|
||||
+ coeffs[1] * point);
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -278,13 +302,14 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice)
|
|||
fluid_phase_t dsp_phase = voice->phase;
|
||||
fluid_phase_t dsp_phase_incr;
|
||||
short int *dsp_data = voice->sample->data;
|
||||
char *dsp_data24 = voice->sample->data24;
|
||||
fluid_real_t *dsp_buf = voice->dsp_buf;
|
||||
fluid_real_t dsp_amp = voice->amp;
|
||||
fluid_real_t dsp_amp_incr = voice->amp_incr;
|
||||
unsigned int dsp_i = 0;
|
||||
unsigned int dsp_phase_index;
|
||||
unsigned int start_index, end_index;
|
||||
short int start_point, end_point1, end_point2;
|
||||
fluid_real_t start_point, end_point1, end_point2;
|
||||
fluid_real_t *coeffs;
|
||||
int looping;
|
||||
|
||||
|
@ -300,23 +325,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 = dsp_data[voice->loopend - 1]; /* last point in loop (wrap around) */
|
||||
start_point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 1); /* last point in loop (wrap around) */
|
||||
}
|
||||
else
|
||||
{
|
||||
start_index = voice->start;
|
||||
start_point = dsp_data[voice->start]; /* just duplicate the point */
|
||||
start_point = fluid_rvoice_get_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 = dsp_data[voice->loopstart];
|
||||
end_point2 = dsp_data[voice->loopstart + 1];
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
end_point1 = dsp_data[voice->end];
|
||||
end_point1 = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->end);
|
||||
end_point2 = end_point1;
|
||||
}
|
||||
|
||||
|
@ -328,10 +353,11 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice)
|
|||
for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
|
||||
{
|
||||
coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)];
|
||||
dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * start_point
|
||||
+ coeffs[1] * dsp_data[dsp_phase_index]
|
||||
+ coeffs[2] * dsp_data[dsp_phase_index+1]
|
||||
+ coeffs[3] * dsp_data[dsp_phase_index+2]);
|
||||
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));
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -343,10 +369,11 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice)
|
|||
for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
|
||||
{
|
||||
coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)];
|
||||
dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1]
|
||||
+ coeffs[1] * dsp_data[dsp_phase_index]
|
||||
+ coeffs[2] * dsp_data[dsp_phase_index+1]
|
||||
+ coeffs[3] * dsp_data[dsp_phase_index+2]);
|
||||
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));
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -363,10 +390,11 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice)
|
|||
for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
|
||||
{
|
||||
coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)];
|
||||
dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1]
|
||||
+ coeffs[1] * dsp_data[dsp_phase_index]
|
||||
+ coeffs[2] * dsp_data[dsp_phase_index+1]
|
||||
+ coeffs[3] * end_point1);
|
||||
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] * end_point1);
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -380,10 +408,11 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice)
|
|||
for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
|
||||
{
|
||||
coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)];
|
||||
dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1]
|
||||
+ coeffs[1] * dsp_data[dsp_phase_index]
|
||||
+ coeffs[2] * end_point1
|
||||
+ coeffs[3] * end_point2);
|
||||
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] * end_point1
|
||||
+ coeffs[3] * end_point2);
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -402,7 +431,7 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice)
|
|||
{
|
||||
voice->has_looped = 1;
|
||||
start_index = voice->loopstart;
|
||||
start_point = dsp_data[voice->loopend - 1];
|
||||
start_point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,14 +457,14 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice)
|
|||
fluid_phase_t dsp_phase = voice->phase;
|
||||
fluid_phase_t dsp_phase_incr;
|
||||
short int *dsp_data = voice->sample->data;
|
||||
char *dsp_data24 = voice->sample->data24;
|
||||
fluid_real_t *dsp_buf = voice->dsp_buf;
|
||||
fluid_real_t dsp_amp = voice->amp;
|
||||
fluid_real_t dsp_amp_incr = voice->amp_incr;
|
||||
unsigned int dsp_i = 0;
|
||||
unsigned int dsp_phase_index;
|
||||
unsigned int start_index, end_index;
|
||||
short int start_points[3];
|
||||
short int end_points[3];
|
||||
fluid_real_t start_points[3], end_points[3];
|
||||
fluid_real_t *coeffs;
|
||||
int looping;
|
||||
|
||||
|
@ -455,14 +484,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] = dsp_data[voice->loopend - 1];
|
||||
start_points[1] = dsp_data[voice->loopend - 2];
|
||||
start_points[2] = dsp_data[voice->loopend - 3];
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
start_index = voice->start;
|
||||
start_points[0] = dsp_data[voice->start]; /* just duplicate the start point */
|
||||
start_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the start point */
|
||||
start_points[1] = start_points[0];
|
||||
start_points[2] = start_points[0];
|
||||
}
|
||||
|
@ -470,13 +499,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] = dsp_data[voice->loopstart];
|
||||
end_points[1] = dsp_data[voice->loopstart + 1];
|
||||
end_points[2] = dsp_data[voice->loopstart + 2];
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
end_points[0] = dsp_data[voice->end];
|
||||
end_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->end);
|
||||
end_points[1] = end_points[0];
|
||||
end_points[2] = end_points[0];
|
||||
}
|
||||
|
@ -491,13 +520,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_real_t)start_points[2]
|
||||
+ coeffs[1] * (fluid_real_t)start_points[1]
|
||||
+ coeffs[2] * (fluid_real_t)start_points[0]
|
||||
+ coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
|
||||
+ coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
|
||||
+ coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2]
|
||||
+ coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]);
|
||||
* (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));
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -513,13 +542,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_real_t)start_points[1]
|
||||
+ coeffs[1] * (fluid_real_t)start_points[0]
|
||||
+ coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
|
||||
+ coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
|
||||
+ coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
|
||||
+ coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2]
|
||||
+ coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]);
|
||||
* (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));
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -535,13 +564,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_real_t)start_points[0]
|
||||
+ coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2]
|
||||
+ coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
|
||||
+ coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
|
||||
+ coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
|
||||
+ coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2]
|
||||
+ coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]);
|
||||
* (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));
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -558,13 +587,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_real_t)dsp_data[dsp_phase_index-3]
|
||||
+ coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2]
|
||||
+ coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
|
||||
+ coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
|
||||
+ coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
|
||||
+ coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2]
|
||||
+ coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]);
|
||||
* (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));
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -583,13 +612,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_real_t)dsp_data[dsp_phase_index-3]
|
||||
+ coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2]
|
||||
+ coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
|
||||
+ coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
|
||||
+ coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
|
||||
+ coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2]
|
||||
+ coeffs[6] * (fluid_real_t)end_points[0]);
|
||||
* (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] * end_points[0]);
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -605,13 +634,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_real_t)dsp_data[dsp_phase_index-3]
|
||||
+ coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2]
|
||||
+ coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
|
||||
+ coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
|
||||
+ coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
|
||||
+ coeffs[5] * (fluid_real_t)end_points[0]
|
||||
+ coeffs[6] * (fluid_real_t)end_points[1]);
|
||||
* (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] * end_points[0]
|
||||
+ coeffs[6] * end_points[1]);
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -627,13 +656,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_real_t)dsp_data[dsp_phase_index-3]
|
||||
+ coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2]
|
||||
+ coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
|
||||
+ coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
|
||||
+ coeffs[4] * (fluid_real_t)end_points[0]
|
||||
+ coeffs[5] * (fluid_real_t)end_points[1]
|
||||
+ coeffs[6] * (fluid_real_t)end_points[2]);
|
||||
* (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] * end_points[0]
|
||||
+ coeffs[5] * end_points[1]
|
||||
+ coeffs[6] * end_points[2]);
|
||||
|
||||
/* increment phase and amplitude */
|
||||
fluid_phase_incr (dsp_phase, dsp_phase_incr);
|
||||
|
@ -652,9 +681,9 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice)
|
|||
{
|
||||
voice->has_looped = 1;
|
||||
start_index = voice->loopstart;
|
||||
start_points[0] = dsp_data[voice->loopend - 1];
|
||||
start_points[1] = dsp_data[voice->loopend - 2];
|
||||
start_points[2] = dsp_data[voice->loopend - 3];
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -275,8 +275,11 @@ typedef struct _fluid_cached_sampledata_t {
|
|||
int num_references;
|
||||
int mlock;
|
||||
|
||||
const short* sampledata;
|
||||
short* sampledata;
|
||||
unsigned int samplesize;
|
||||
|
||||
char* sample24data;
|
||||
unsigned int sample24size;
|
||||
} fluid_cached_sampledata_t;
|
||||
|
||||
static fluid_cached_sampledata_t* all_cached_sampledata = NULL;
|
||||
|
@ -299,11 +302,19 @@ static int fluid_get_file_modification_time(char *filename, time_t *modification
|
|||
#endif
|
||||
}
|
||||
|
||||
static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
||||
unsigned int samplesize, short **sampledata, int try_mlock, const fluid_file_callbacks_t* fcbs)
|
||||
static int fluid_cached_sampledata_load(char *filename,
|
||||
unsigned int samplepos,
|
||||
unsigned int samplesize,
|
||||
short **sampledata,
|
||||
unsigned int sample24pos,
|
||||
unsigned int sample24size,
|
||||
char **sample24data,
|
||||
int try_mlock,
|
||||
const fluid_file_callbacks_t* fcbs)
|
||||
{
|
||||
fluid_file fd = NULL;
|
||||
short *loaded_sampledata = NULL;
|
||||
char *loaded_sample24data = NULL;
|
||||
fluid_cached_sampledata_t* cached_sampledata = NULL;
|
||||
time_t modification_time;
|
||||
|
||||
|
@ -319,7 +330,7 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
|||
continue;
|
||||
if (cached_sampledata->modification_time != modification_time)
|
||||
continue;
|
||||
if (cached_sampledata->samplesize != samplesize) {
|
||||
if (cached_sampledata->samplesize != samplesize || cached_sampledata->sample24size != sample24size) {
|
||||
FLUID_LOG(FLUID_ERR, "Cached size of soundfont doesn't match actual size of soundfont (cached: %u. actual: %u)",
|
||||
cached_sampledata->samplesize, samplesize);
|
||||
continue;
|
||||
|
@ -330,10 +341,15 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
|||
FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible.");
|
||||
else
|
||||
cached_sampledata->mlock = try_mlock;
|
||||
|
||||
if (cached_sampledata->sample24data != NULL)
|
||||
if(fluid_mlock(cached_sampledata->sample24data, sample24size) != 0)
|
||||
FLUID_LOG(FLUID_WARN, "Failed to pin the sample24 data to RAM; swapping is possible.");
|
||||
}
|
||||
|
||||
cached_sampledata->num_references++;
|
||||
loaded_sampledata = (short*) cached_sampledata->sampledata;
|
||||
loaded_sampledata = cached_sampledata->sampledata;
|
||||
loaded_sample24data = cached_sampledata->sample24data;
|
||||
goto success_exit;
|
||||
}
|
||||
|
||||
|
@ -348,7 +364,6 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
|||
goto error_exit;
|
||||
}
|
||||
|
||||
|
||||
loaded_sampledata = (short*) FLUID_MALLOC(samplesize);
|
||||
if (loaded_sampledata == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
|
@ -359,6 +374,25 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
|||
goto error_exit;
|
||||
}
|
||||
|
||||
if(sample24pos > 0)
|
||||
{
|
||||
if (fcbs->fseek(fd, sample24pos, SEEK_SET) == FLUID_FAILED) {
|
||||
perror("error");
|
||||
FLUID_LOG(FLUID_ERR, "Failed to seek position in data file");
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
loaded_sample24data = (char*) FLUID_MALLOC(sample24size);
|
||||
if (loaded_sample24data == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory when allocating 24bit sample, ignoring");
|
||||
}
|
||||
else if (fcbs->fread(loaded_sample24data, sample24size, fd) == FLUID_FAILED) {
|
||||
FLUID_LOG(FLUID_ERR, "Failed to read sample24 data");
|
||||
FLUID_FREE(loaded_sample24data);
|
||||
loaded_sample24data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
fcbs->fclose(fd);
|
||||
fd = NULL;
|
||||
|
||||
|
@ -370,7 +404,7 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
|||
}
|
||||
|
||||
/* Lock the memory to disable paging. It's okay if this fails. It
|
||||
probably means that the user doesn't have to required permission. */
|
||||
probably means that the user doesn't have the required permission. */
|
||||
cached_sampledata->mlock = 0;
|
||||
if (try_mlock) {
|
||||
if (fluid_mlock(loaded_sampledata, samplesize) != 0)
|
||||
|
@ -394,17 +428,18 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
|||
}
|
||||
}
|
||||
|
||||
cached_sampledata->filename = (char*) FLUID_MALLOC(strlen(filename) + 1);
|
||||
cached_sampledata->filename = FLUID_STRDUP(filename);
|
||||
if (cached_sampledata->filename == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory.");
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
sprintf(cached_sampledata->filename, "%s", filename);
|
||||
cached_sampledata->modification_time = modification_time;
|
||||
cached_sampledata->num_references = 1;
|
||||
cached_sampledata->sampledata = loaded_sampledata;
|
||||
cached_sampledata->samplesize = samplesize;
|
||||
cached_sampledata->sample24data = loaded_sample24data;
|
||||
cached_sampledata->sample24size = sample24size;
|
||||
|
||||
cached_sampledata->next = all_cached_sampledata;
|
||||
all_cached_sampledata = cached_sampledata;
|
||||
|
@ -413,25 +448,25 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
|||
success_exit:
|
||||
fluid_mutex_unlock(cached_sampledata_mutex);
|
||||
*sampledata = loaded_sampledata;
|
||||
*sample24data = loaded_sample24data;
|
||||
return FLUID_OK;
|
||||
|
||||
error_exit:
|
||||
if (fd != NULL) {
|
||||
fcbs->fclose(fd);
|
||||
}
|
||||
if (loaded_sampledata != NULL) {
|
||||
FLUID_FREE(loaded_sampledata);
|
||||
}
|
||||
|
||||
FLUID_FREE(loaded_sampledata);
|
||||
FLUID_FREE(loaded_sample24data);
|
||||
|
||||
if (cached_sampledata != NULL) {
|
||||
if (cached_sampledata->filename != NULL) {
|
||||
FLUID_FREE(cached_sampledata->filename);
|
||||
}
|
||||
FLUID_FREE(cached_sampledata);
|
||||
}
|
||||
FLUID_FREE(cached_sampledata);
|
||||
|
||||
fluid_mutex_unlock(cached_sampledata_mutex);
|
||||
*sampledata = NULL;
|
||||
*sample24data = NULL;
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
|
@ -450,8 +485,12 @@ static int fluid_cached_sampledata_unload(const short *sampledata)
|
|||
|
||||
if (cached_sampledata->num_references == 0) {
|
||||
if (cached_sampledata->mlock)
|
||||
{
|
||||
fluid_munlock(cached_sampledata->sampledata, cached_sampledata->samplesize);
|
||||
FLUID_FREE((short*) cached_sampledata->sampledata);
|
||||
fluid_munlock(cached_sampledata->sample24data, cached_sampledata->sample24size);
|
||||
}
|
||||
FLUID_FREE(cached_sampledata->sampledata);
|
||||
FLUID_FREE(cached_sampledata->sample24data);
|
||||
FLUID_FREE(cached_sampledata->filename);
|
||||
|
||||
if (prev != NULL) {
|
||||
|
@ -504,12 +543,8 @@ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sfont->filename = NULL;
|
||||
sfont->samplepos = 0;
|
||||
sfont->samplesize = 0;
|
||||
sfont->sample = NULL;
|
||||
sfont->sampledata = NULL;
|
||||
sfont->preset = NULL;
|
||||
FLUID_MEMSET(sfont, 0, sizeof(*sfont));
|
||||
|
||||
fluid_settings_getint(settings, "synth.lock-memory", &sfont->mlock);
|
||||
|
||||
/* Initialise preset cache, so we don't have to call malloc on program changes.
|
||||
|
@ -517,7 +552,7 @@ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings)
|
|||
so optimise for that case. */
|
||||
fluid_settings_getint(settings, "synth.midi-channels", &sfont->preset_stack_capacity);
|
||||
sfont->preset_stack_capacity++;
|
||||
sfont->preset_stack_size = 0;
|
||||
|
||||
sfont->preset_stack = FLUID_ARRAY(fluid_preset_t*, sfont->preset_stack_capacity);
|
||||
if (!sfont->preset_stack) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
|
@ -627,6 +662,8 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f
|
|||
it's loaded separately (and might be unoaded/reloaded in future) */
|
||||
sfont->samplepos = sfdata->samplepos;
|
||||
sfont->samplesize = sfdata->samplesize;
|
||||
sfont->sample24pos = sfdata->sample24pos;
|
||||
sfont->sample24size = sfdata->sample24size;
|
||||
|
||||
/* load sample data in one block */
|
||||
if (fluid_defsfont_load_sampledata(sfont, fcbs) != FLUID_OK)
|
||||
|
@ -725,8 +762,11 @@ int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset
|
|||
int
|
||||
fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* fcbs)
|
||||
{
|
||||
return fluid_cached_sampledata_load(sfont->filename, sfont->samplepos,
|
||||
sfont->samplesize, &sfont->sampledata, sfont->mlock, fcbs);
|
||||
return fluid_cached_sampledata_load(sfont->filename,
|
||||
sfont->samplepos, sfont->samplesize, &sfont->sampledata,
|
||||
sfont->sample24pos, sfont->sample24size, &sfont->sample24data,
|
||||
sfont->mlock,
|
||||
fcbs);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1936,6 +1976,7 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs
|
|||
{
|
||||
FLUID_STRCPY(sample->name, sfsample->name);
|
||||
sample->data = sfont->sampledata;
|
||||
sample->data24 = sfont->sample24data;
|
||||
sample->start = sfsample->start;
|
||||
sample->end = sfsample->start + sfsample->end;
|
||||
sample->loopstart = sfsample->start + sfsample->loopstart;
|
||||
|
@ -2155,11 +2196,9 @@ static int fixup_sample (SFData * sf);
|
|||
|
||||
static const char idlist[] = {
|
||||
"RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD"
|
||||
"ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdr"
|
||||
"ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24"
|
||||
};
|
||||
|
||||
static unsigned int sdtachunk_size;
|
||||
|
||||
/* sound font file load functions */
|
||||
static int
|
||||
chunkid (unsigned int id)
|
||||
|
@ -2429,9 +2468,50 @@ process_sdta (unsigned int size, SFData * sf, void * fd, const fluid_file_callba
|
|||
sf->samplepos = fcbs->ftell (fd);
|
||||
|
||||
/* used in fixup_sample() to check validity of sample headers */
|
||||
sdtachunk_size = chunk.size;
|
||||
sf->samplesize = chunk.size;
|
||||
|
||||
FSKIP (chunk.size, fd, fcbs);
|
||||
size -= chunk.size;
|
||||
|
||||
if(sf->version.major >= 2 && sf->version.minor >= 4)
|
||||
{
|
||||
/* any chance to find another chunk here? */
|
||||
if(size > 8)
|
||||
{
|
||||
/* read sub chunk */
|
||||
READCHUNK (&chunk, fd, fcbs);
|
||||
size -= 8;
|
||||
|
||||
if (chunkid (chunk.id) == SM24_ID)
|
||||
{
|
||||
int sm24size, sdtahalfsize;
|
||||
|
||||
FLUID_LOG(FLUID_DBG, "Found SM24 chunk");
|
||||
if (chunk.size > size)
|
||||
{
|
||||
FLUID_LOG(FLUID_WARN, "SM24 exeeds SDTA chunk, ignoring SM24");
|
||||
goto ret; // no error
|
||||
}
|
||||
|
||||
sdtahalfsize = sf->samplesize/2;
|
||||
/* + 1 byte in the case that half the size of smpl chunk is an odd value */
|
||||
sdtahalfsize += sdtahalfsize%2;
|
||||
sm24size = chunk.size;
|
||||
|
||||
if (sdtahalfsize != sm24size)
|
||||
{
|
||||
FLUID_LOG(FLUID_WARN, "SM24 not equal to half the size of SMPL chunk (0x%X != 0x%X), ignoring SM24", sm24size, sdtahalfsize);
|
||||
goto ret; // no error
|
||||
}
|
||||
|
||||
/* sample data24 follows */
|
||||
sf->sample24pos = fcbs->ftell (fd);
|
||||
sf->sample24size = sm24size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret:
|
||||
FSKIP (size, fd, fcbs);
|
||||
|
||||
return (OK);
|
||||
|
@ -3352,6 +3432,7 @@ fixup_sample (SFData * sf)
|
|||
int invalid_loops=FALSE;
|
||||
int invalid_loopstart;
|
||||
int invalid_loopend, loopend_end_mismatch;
|
||||
unsigned int sdtachunk_size = sf->samplesize;
|
||||
|
||||
p = sf->sample;
|
||||
while (p)
|
||||
|
|
|
@ -143,8 +143,13 @@ typedef struct _SFData
|
|||
{ /* Sound font data structure */
|
||||
SFVersion version; /* sound font version */
|
||||
SFVersion romver; /* ROM version */
|
||||
|
||||
unsigned int samplepos; /* position within sffd of the sample chunk */
|
||||
unsigned int samplesize; /* length within sffd of the sample chunk */
|
||||
|
||||
unsigned int sample24pos; /* position within sffd of the sm24 chunk, set to zero if no 24 bit sample support */
|
||||
unsigned int sample24size; /* length within sffd of the sm24 chunk */
|
||||
|
||||
char *fname; /* file name */
|
||||
FILE *sffd; /* loaded sfont file descriptor */
|
||||
fluid_list_t *info; /* linked list of info strings (1st byte is ID) */
|
||||
|
@ -166,7 +171,8 @@ enum
|
|||
SNAM_ID, SMPL_ID, /* sample ids */
|
||||
PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID, /* preset ids */
|
||||
IHDR_ID, IBAG_ID, IMOD_ID, IGEN_ID, /* instrument ids */
|
||||
SHDR_ID /* sample info */
|
||||
SHDR_ID, /* sample info */
|
||||
SM24_ID
|
||||
};
|
||||
|
||||
/* generator types */
|
||||
|
@ -370,13 +376,17 @@ struct _fluid_defsfont_t
|
|||
{
|
||||
char* filename; /* the filename of this soundfont */
|
||||
unsigned int samplepos; /* the position in the file at which the sample data starts */
|
||||
unsigned int samplesize; /* the size of the sample data */
|
||||
unsigned int samplesize; /* the size of the sample data in bytes */
|
||||
short* sampledata; /* the sample data, loaded in ram */
|
||||
|
||||
unsigned int sample24pos; /* position within sffd of the sm24 chunk, set to zero if no 24 bit sample support */
|
||||
unsigned int sample24size; /* length within sffd of the sm24 chunk */
|
||||
char* sample24data; /* if not NULL, the least significant byte of the 24bit sample data, loaded in ram */
|
||||
|
||||
fluid_list_t* sample; /* the samples in this soundfont */
|
||||
fluid_defpreset_t* preset; /* the presets of this soundfont */
|
||||
int mlock; /* Should we try memlock (avoid swapping)? */
|
||||
|
||||
fluid_preset_t iter_preset; /* preset interface used in the iteration */
|
||||
fluid_defpreset_t* iter_cur; /* the current preset in the iteration */
|
||||
|
||||
fluid_preset_t** preset_stack; /* List of presets that are available to use */
|
||||
|
|
|
@ -436,9 +436,14 @@ void fluid_voice_start(fluid_voice_t* voice)
|
|||
* @param gain The gain value in the range [0.0 ; 1.0]
|
||||
* @return An amplitude used by rvoice_mixer's buffers
|
||||
*/
|
||||
static fluid_real_t fluid_voice_calculate_gain_amplitude(const fluid_voice_t* voice, fluid_real_t gain)
|
||||
static FLUID_INLINE fluid_real_t
|
||||
fluid_voice_calculate_gain_amplitude(const fluid_voice_t* voice, fluid_real_t gain)
|
||||
{
|
||||
return gain * voice->synth_gain / 32768.0f;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue