Skip to content

Commit

Permalink
do not read from sample buffer when voice is in delay
Browse files Browse the repository at this point in the history
  • Loading branch information
derselbst committed Jan 11, 2025
1 parent 25ed0fa commit a8961d2
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/rvoice/fluid_rvoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
//
// Currently, this does access the sample buffers, which is redundant and could be optimized away.
// On the other hand, entering this if-clause is not supposed to happen often.
return fluid_rvoice_dsp_interpolate_none(voice, dsp_buf, is_looping);
return fluid_rvoice_dsp_silence(voice, dsp_buf, is_looping);
}

switch(voice->dsp.interp_method)
Expand Down
1 change: 1 addition & 0 deletions src/rvoice/fluid_rvoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_sample);

/* defined in fluid_rvoice_dsp.c */
void fluid_rvoice_dsp_config(void);
int fluid_rvoice_dsp_silence(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping);
int fluid_rvoice_dsp_interpolate_none(fluid_rvoice_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
int fluid_rvoice_dsp_interpolate_linear(fluid_rvoice_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
int fluid_rvoice_dsp_interpolate_4th_order(fluid_rvoice_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
Expand Down
75 changes: 75 additions & 0 deletions src/rvoice/fluid_rvoice_dsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,66 @@ fluid_rvoice_get_float_sample(const short int *FLUID_RESTRICT dsp_msb, const cha
return (fluid_real_t)sample;
}

/* Special case of interpolate_none for rendering silent voices, i.e. in delay phase or zero volume */
template<bool LOOPING>
static int fluid_rvoice_dsp_silence_local(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf)
{
fluid_rvoice_dsp_t *voice = &rvoice->dsp;
fluid_phase_t dsp_phase = voice->phase;
fluid_phase_t dsp_phase_incr;
fluid_real_t dsp_amp = voice->amp;
fluid_real_t dsp_amp_incr = voice->amp_incr;
unsigned short dsp_i = 0;
unsigned int dsp_phase_index;
unsigned int end_index;

/* Convert playback "speed" floating point value to phase index/fract */
fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);

end_index = LOOPING ? voice->loopend - 1 : voice->end;

while (1)
{
dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */

/* interpolate sequence of sample points */
for (; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
{
fluid_real_t sample = 0;
dsp_buf[dsp_i] = sample;

/* increment phase and amplitude */
fluid_phase_incr(dsp_phase, dsp_phase_incr);
dsp_amp += dsp_amp_incr;
}

/* break out if not looping (buffer may not be full) */
if (!LOOPING)
{
break;
}

dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */
/* go back to loop start */
if (dsp_phase_index > end_index)
{
fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
voice->has_looped = 1;
}

/* break out if filled buffer */
if (dsp_i >= FLUID_BUFSIZE)
{
break;
}
}

voice->phase = dsp_phase;
voice->amp = dsp_amp;

return (dsp_i);
}

/* No interpolation. Just take the sample, which is closest to
* the playback pointer. Questionable quality, but very
* efficient. */
Expand Down Expand Up @@ -767,6 +827,15 @@ fluid_rvoice_dsp_interpolate_7th_order_local(fluid_rvoice_t *rvoice, fluid_real_
return (dsp_i);
}

struct ProcessSilence
{
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
int operator()(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf) const
{
return fluid_rvoice_dsp_silence_local<LOOPING>(rvoice, dsp_buf);
}
};

struct InterpolateNone
{
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
Expand Down Expand Up @@ -862,6 +931,12 @@ int dsp_invoker(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, in
}
}

extern "C" int
fluid_rvoice_dsp_silence(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
{
return dsp_invoker<ProcessSilence>(rvoice, dsp_buf, looping);
}

extern "C" int
fluid_rvoice_dsp_interpolate_none(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
{
Expand Down

0 comments on commit a8961d2

Please sign in to comment.