Add a unit test for fluid_synth_write_float

This commit is contained in:
derselbst 2019-10-22 14:32:35 +02:00
parent 5a42e8147f
commit dfcf5c019f
3 changed files with 86 additions and 25 deletions

View file

@ -3800,6 +3800,16 @@ int
fluid_synth_write_float(fluid_synth_t *synth, int len, fluid_synth_write_float(fluid_synth_t *synth, int len,
void *lout, int loff, int lincr, void *lout, int loff, int lincr,
void *rout, int roff, int rincr) void *rout, int roff, int rincr)
{
return fluid_synth_write_float_LOCAL(synth, len, lout, loff, lincr, rout, roff, rincr, fluid_synth_render_blocks);
}
int
fluid_synth_write_float_LOCAL(fluid_synth_t *synth, int len,
void *lout, int loff, int lincr,
void *rout, int roff, int rincr,
int (*block_render_func)(fluid_synth_t *, int)
)
{ {
int i, j, k, l; int i, j, k, l;
float *left_out = (float *) lout; float *left_out = (float *) lout;
@ -3825,7 +3835,7 @@ fluid_synth_write_float(fluid_synth_t *synth, int len,
if(l >= synth->curmax) if(l >= synth->curmax)
{ {
int blocksleft = (len - i + FLUID_BUFSIZE - 1) / FLUID_BUFSIZE; int blocksleft = (len - i + FLUID_BUFSIZE - 1) / FLUID_BUFSIZE;
synth->curmax = FLUID_BUFSIZE * fluid_synth_render_blocks(synth, blocksleft); synth->curmax = FLUID_BUFSIZE * block_render_func(synth, blocksleft);
fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in); fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
l = 0; l = 0;

View file

@ -216,6 +216,11 @@ int fluid_synth_set_gen2(fluid_synth_t *synth, int chan,
int int
fluid_synth_process_LOCAL(fluid_synth_t *synth, int len, int nfx, float *fx[], fluid_synth_process_LOCAL(fluid_synth_t *synth, int len, int nfx, float *fx[],
int nout, float *out[], int (*block_render_func)(fluid_synth_t *, int)); int nout, float *out[], int (*block_render_func)(fluid_synth_t *, int));
int
fluid_synth_write_float_LOCAL(fluid_synth_t *synth, int len,
void *lout, int loff, int lincr,
void *rout, int roff, int rincr,
int (*block_render_func)(fluid_synth_t *, int));
/* /*
* misc * misc
*/ */

View file

@ -8,18 +8,17 @@
// static const int CHANNELS=16; // static const int CHANNELS=16;
enum { SAMPLES=1024 }; enum { SAMPLES=1024 };
static int smpl;
int render_one_mock(fluid_synth_t *synth, int blocks) int render_one_mock(fluid_synth_t *synth, int blocks)
{ {
static int smpl;
fluid_real_t *left_in, *fx_left_in; fluid_real_t *left_in, *fx_left_in;
fluid_real_t *right_in, *fx_right_in; fluid_real_t *right_in, *fx_right_in;
int i, j; int i, j;
int nfxchan = fluid_synth_count_effects_channels(synth), int naudchan = fluid_synth_count_audio_channels(synth);
nfxunits = fluid_synth_count_effects_groups(synth),
naudchan = fluid_synth_count_audio_channels(synth);
fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in); 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); fluid_rvoice_mixer_get_fx_bufs(synth->eventhandler->mixer, &fx_left_in, &fx_right_in);
@ -37,27 +36,61 @@ int render_one_mock(fluid_synth_t *synth, int blocks)
return blocks; return blocks;
} }
int render_and_check(fluid_synth_t* synth, int number_of_samples, int offset) int process_and_check(fluid_synth_t* synth, int number_of_samples, int offset)
{ {
int i; int i;
float left[SAMPLES], right[SAMPLES]; float left[SAMPLES], right[SAMPLES];
float *dry[1 * 2]; float *dry[1 * 2];
dry[0] = left; dry[0] = left;
dry[1] = right; dry[1] = right;
memset(left, 0, sizeof(left)); FLUID_MEMSET(left, 0, sizeof(left));
memset(right, 0, sizeof(right)); FLUID_MEMSET(right, 0, sizeof(right));
TEST_SUCCESS(fluid_synth_process_LOCAL(synth, number_of_samples, 0, NULL, 2, dry, render_one_mock)); TEST_SUCCESS(fluid_synth_process_LOCAL(synth, number_of_samples, 0, NULL, 2, dry, render_one_mock));
for(i=0; i<number_of_samples; i++) for(i=0; i<number_of_samples; i++)
{ {
TEST_ASSERT(left[i]==i+offset); TEST_ASSERT(left[i]==offset);
TEST_ASSERT(right[i]==i+offset); TEST_ASSERT(right[i]==offset);
offset++;
} }
return i+offset; return offset;
} }
int write_and_check(fluid_synth_t* synth, int number_of_samples, int offset)
{
int i;
float buf[2*SAMPLES];
FLUID_MEMSET(buf, 0, sizeof(buf));
// one buffer, interleaved writing
TEST_SUCCESS(fluid_synth_write_float_LOCAL(synth, number_of_samples, buf, 0, 2, buf, 1, 2, render_one_mock));
for(i=0; i< 2*number_of_samples; i+=2)
{
TEST_ASSERT(buf[i+0] == offset);
TEST_ASSERT(buf[i+1] == offset);
offset++;
}
FLUID_MEMSET(buf, 0, sizeof(buf));
// "two" buffers, planar writing
TEST_SUCCESS(fluid_synth_write_float_LOCAL(synth, number_of_samples, buf, 0, 1, buf, SAMPLES, 1, render_one_mock));
for(i=0; i< number_of_samples; i++)
{
TEST_ASSERT(buf[i+0] == offset);
TEST_ASSERT(buf[i+SAMPLES] == offset);
offset++;
}
return offset;
}
// this test should make sure that sample rate changed are handled correctly // this test should make sure that sample rate changed are handled correctly
int main(void) int main(void)
{ {
@ -66,19 +99,32 @@ int main(void)
fluid_settings_t *settings = new_fluid_settings(); fluid_settings_t *settings = new_fluid_settings();
TEST_ASSERT(settings != NULL); TEST_ASSERT(settings != NULL);
// TEST_SUCCESS(fluid_settings_setint(settings, "synth.audio-channels", CHANNELS));
// TEST_SUCCESS(fluid_settings_setint(settings, "synth.audio-groups", CHANNELS));
synth = new_fluid_synth(settings); synth = new_fluid_synth(settings);
TEST_ASSERT(synth != NULL); TEST_ASSERT(synth != NULL);
off = render_and_check(synth, 100, off); off = process_and_check(synth, 100, off);
off = render_and_check(synth, 200, off); off = process_and_check(synth, 200, off);
off = render_and_check(synth, 300, off); off = process_and_check(synth, 300, off);
off = render_and_check(synth, 1000, off); // next statement should not result in a call to render_one_mock() and therefore not increase the static "smpl" var
off = render_and_check(synth, 900, off); off = process_and_check(synth, 0, off);
off = render_and_check(synth, 800, off); off = process_and_check(synth, 1000, off);
off = process_and_check(synth, SAMPLES, off);
off = process_and_check(synth, 900, off);
off = process_and_check(synth, 800, off);
off = process_and_check(synth, FLUID_BUFSIZE, off);
// currently it is not possible to call different rendering functions subsequently
off = smpl;
off = write_and_check(synth, 100, off);
off = write_and_check(synth, 200, off);
off = write_and_check(synth, 300, off);
off = write_and_check(synth, 0, off);
off = write_and_check(synth, 1000, off);
off = write_and_check(synth, SAMPLES, off);
off = write_and_check(synth, 900, off);
off = write_and_check(synth, 800, off);
off = write_and_check(synth, FLUID_BUFSIZE, off);
delete_fluid_synth(synth); delete_fluid_synth(synth);
delete_fluid_settings(settings); delete_fluid_settings(settings);