mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 23:11:41 +00:00
implement reading effect buffers from fluid_synth_nwrite_float()
This commit is contained in:
parent
54a7f5cae8
commit
1ff2002ab5
3 changed files with 89 additions and 10 deletions
|
@ -705,8 +705,8 @@ int fluid_rvoice_mixer_get_bufs(fluid_rvoice_mixer_t* mixer,
|
|||
int fluid_rvoice_mixer_get_fx_bufs(fluid_rvoice_mixer_t* mixer,
|
||||
fluid_real_t*** fx_left, fluid_real_t*** fx_right)
|
||||
{
|
||||
*left = mixer->buffers.fx_left_buf;
|
||||
*right = mixer->buffers.fx_right_buf;
|
||||
*fx_left = mixer->buffers.fx_left_buf;
|
||||
*fx_right = mixer->buffers.fx_right_buf;
|
||||
return mixer->buffers.fx_buf_count;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,9 @@ void fluid_rvoice_mixer_set_finished_voices_callback(
|
|||
|
||||
int fluid_rvoice_mixer_render(fluid_rvoice_mixer_t* mixer, int blockcount);
|
||||
int fluid_rvoice_mixer_get_bufs(fluid_rvoice_mixer_t* mixer,
|
||||
fluid_real_t*** left, fluid_real_t*** right);
|
||||
fluid_real_t*** left, fluid_real_t*** right);
|
||||
int fluid_rvoice_mixer_get_fx_bufs(fluid_rvoice_mixer_t* mixer,
|
||||
fluid_real_t*** fx_left, fluid_real_t*** fx_right);
|
||||
|
||||
fluid_rvoice_mixer_t* new_fluid_rvoice_mixer(int buf_count, int fx_buf_count,
|
||||
fluid_real_t sample_rate);
|
||||
|
|
|
@ -2421,24 +2421,60 @@ fluid_synth_program_reset(fluid_synth_t* synth)
|
|||
}
|
||||
|
||||
/**
|
||||
* Synthesize a block of floating point audio to audio buffers.
|
||||
* Synthesize a block of floating point audio to separate audio buffers (multichannel rendering).
|
||||
* @param synth FluidSynth instance
|
||||
* @param len Count of audio frames to synthesize
|
||||
* @param left Array of floats to store left channel of audio (\c len in size)
|
||||
* @param right Array of floats to store right channel of audio (\c len in size)
|
||||
* @param fx_left since 1.1.7: Array of floats to store left effect channel (reverb and chrous, \c len in size)
|
||||
* @param fx_right since 1.1.7: Array of floats to store right effect channel (reverb and chorus, \c len in size)
|
||||
* @param left Array of arrays of floats to store left channel of planar audio (\c len in size)
|
||||
* @param right Array of arrays of floats to store right channel of planar audio (\c len in size)
|
||||
* @param fx_left Since 1.1.7: If not \c NULL, array of arrays of floats to store left effect channel (reverb and chrous, \c len in size)
|
||||
* @param fx_right Since 1.1.7: If not \c NULL, array of arrays of floats to store right effect channel (reverb and chorus, \c len in size)
|
||||
* @return FLUID_OK on success, FLUID_FAIL otherwise
|
||||
*
|
||||
* @note Should only be called from synthesis thread.
|
||||
*
|
||||
* Usage example:
|
||||
* @code
|
||||
const int FramesToRender = 64;
|
||||
int channels;
|
||||
// retrieve number of stereo audio channels
|
||||
fluid_settings_getint(settings, "synth.audio-channels", &channels);
|
||||
|
||||
// we need twice as many (mono-)buffers
|
||||
channels *= 2;
|
||||
|
||||
// fluid_synth_process renders planar audio, i.e. each midi channel gets render to its own stereo buffer, rather than having one buffer and interleaving PCM
|
||||
float** mix_buf = new float*[channels];
|
||||
for(int i = 0; i < channels; i++)
|
||||
{
|
||||
mix_buf[i] = new float[FramesToRender];
|
||||
}
|
||||
|
||||
// retrieve number of (stereo) effect channels (internally hardcoded to reverb (first chan) and chrous (second chan))
|
||||
fluid_settings_getint(settings, "synth.effects-channels", &channels);
|
||||
channels *= 2;
|
||||
|
||||
float** fx_buf = new float*[channels];
|
||||
for(int i = 0; i < channels; i++)
|
||||
{
|
||||
fx_buf[i] = new float[FramesToRender];
|
||||
}
|
||||
|
||||
float** mix_buf_l = mix_buf;
|
||||
float** mix_buf_r = &mix_buf[channels/2];
|
||||
|
||||
float** fx_buf_l = fx_buf;
|
||||
float** fx_buf_r = &fx_buf[channels/2];
|
||||
|
||||
fluid_synth_nwrite_float(synth, FramesToRender, mix_buf_l, mix_buf_r, fx_buf_l, fx_buf_r)
|
||||
* @endcode
|
||||
*/
|
||||
int
|
||||
fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
|
||||
float** left, float** right,
|
||||
float** fx_left, float** fx_right)
|
||||
{
|
||||
fluid_real_t** left_in;
|
||||
fluid_real_t** right_in;
|
||||
fluid_real_t** left_in, **fx_left_in;
|
||||
fluid_real_t** right_in, **fx_right_in;
|
||||
double time = fluid_utime();
|
||||
int i, num, available, count;
|
||||
#ifdef WITH_FLOAT
|
||||
|
@ -2455,6 +2491,7 @@ fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
|
|||
if (synth->cur < FLUID_BUFSIZE) {
|
||||
available = FLUID_BUFSIZE - synth->cur;
|
||||
fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
|
||||
fluid_rvoice_mixer_get_fx_bufs(synth->eventhandler->mixer, &fx_left_in, &fx_right_in);
|
||||
|
||||
num = (available > len)? len : available;
|
||||
#ifdef WITH_FLOAT
|
||||
|
@ -2473,6 +2510,26 @@ fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
|
|||
}
|
||||
#endif //WITH_FLOAT
|
||||
}
|
||||
|
||||
for (i = 0; i < synth->effects_channels; i++)
|
||||
{
|
||||
#ifdef WITH_FLOAT
|
||||
if(fx_left != NULL)
|
||||
FLUID_MEMCPY(fx_left[i], fx_left_in[i] + synth->cur, bytes);
|
||||
|
||||
if(fx_right != NULL)
|
||||
FLUID_MEMCPY(fx_right[i], fx_right_in[i] + synth->cur, bytes);
|
||||
#else //WITH_FLOAT
|
||||
int j;
|
||||
for (j = 0; (fx_left != NULL) && (j < num); j++)
|
||||
fx_left[i][j] = (float) fx_left_in[i][j + synth->cur];
|
||||
|
||||
for (j = 0; (fx_right != NULL) && (j < num); j++)
|
||||
fx_right[i][j] = (float) fx_right_in[i][j + synth->cur];
|
||||
|
||||
#endif //WITH_FLOAT
|
||||
}
|
||||
|
||||
count += num;
|
||||
num += synth->cur; /* if we're now done, num becomes the new synth->cur below */
|
||||
}
|
||||
|
@ -2482,6 +2539,7 @@ fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
|
|||
fluid_rvoice_mixer_set_mix_fx(synth->eventhandler->mixer, 0);
|
||||
fluid_synth_render_blocks(synth, 1); // TODO:
|
||||
fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
|
||||
fluid_rvoice_mixer_get_fx_bufs(synth->eventhandler->mixer, &fx_left_in, &fx_right_in);
|
||||
|
||||
num = (FLUID_BUFSIZE > len - count)? len - count : FLUID_BUFSIZE;
|
||||
#ifdef WITH_FLOAT
|
||||
|
@ -2501,6 +2559,25 @@ fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
|
|||
#endif //WITH_FLOAT
|
||||
}
|
||||
|
||||
for (i = 0; i < synth->effects_channels; i++)
|
||||
{
|
||||
#ifdef WITH_FLOAT
|
||||
if(fx_left != NULL)
|
||||
FLUID_MEMCPY(fx_left[i + count], fx_left_in[i], bytes);
|
||||
|
||||
if(fx_right != NULL)
|
||||
FLUID_MEMCPY(fx_right[i + count], fx_right_in[i], bytes);
|
||||
#else //WITH_FLOAT
|
||||
int j;
|
||||
for (j = 0; (fx_left != NULL) && (j < num); j++)
|
||||
fx_left[i][j + count] = (float) fx_left_in[i][j];
|
||||
|
||||
for (j = 0; (fx_right != NULL) && (j < num); j++)
|
||||
fx_right[i][j + count] = (float) fx_right_in[i][j];
|
||||
|
||||
#endif //WITH_FLOAT
|
||||
}
|
||||
|
||||
count += num;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue