mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 15:01:40 +00:00
add a unit test for complex modulator amounts
This commit is contained in:
parent
392ae1518c
commit
3d33a0b7f6
3 changed files with 109 additions and 23 deletions
|
@ -506,6 +506,35 @@ fluid_voice_calculate_gen_pitch(fluid_voice_t *voice)
|
|||
voice->gen[GEN_PITCH].val = fluid_voice_calculate_pitch(voice, fluid_voice_get_actual_key(voice));
|
||||
}
|
||||
|
||||
/* outsourced function that calculates modulator contributions to make it unit testable */
|
||||
void fluid_voice_calculate_modulator_contributions(fluid_voice_t *voice)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* The voice contains unlinked modulators + possible complex linked modulators.
|
||||
We scan modulators from the last member of possible complex linked
|
||||
modulator to the first member (i.e the one connected to a generator).
|
||||
*/
|
||||
for (i = voice->mod_count - 1; i >= 0; i--)
|
||||
{
|
||||
fluid_mod_t* mod = &voice->mod[i];
|
||||
fluid_real_t modval = fluid_mod_get_value(mod, voice);
|
||||
int dest_index = mod->dest;
|
||||
if(dest_index & FLUID_MOD_LINK_DEST)
|
||||
{
|
||||
/* destination is a modulator */
|
||||
voice->mod[dest_index & ~FLUID_MOD_LINK_DEST].link += modval;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* destination is a generator */
|
||||
fluid_gen_t* dest_gen = &voice->gen[dest_index];
|
||||
dest_gen->mod += modval;
|
||||
}
|
||||
/* fluid_dump_modulator(mod); */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fluid_voice_calculate_runtime_synthesis_parameters
|
||||
*
|
||||
|
@ -519,7 +548,6 @@ fluid_voice_calculate_gen_pitch(fluid_voice_t *voice)
|
|||
static int
|
||||
fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t *voice)
|
||||
{
|
||||
int i;
|
||||
unsigned int n;
|
||||
|
||||
static int const list_of_generators_to_initialize[] =
|
||||
|
@ -598,28 +626,7 @@ fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t *voice)
|
|||
* fluid_gen_init().
|
||||
*/
|
||||
|
||||
/* The voice contains unlinked modulators + possible complex linked modulators.
|
||||
We scan modulators from the last member of possible complex linked
|
||||
modulator to the first member (i.e the one connected to a generator).
|
||||
*/
|
||||
for (i = voice->mod_count - 1; i >= 0; i--)
|
||||
{
|
||||
fluid_mod_t* mod = &voice->mod[i];
|
||||
fluid_real_t modval = fluid_mod_get_value(mod, voice);
|
||||
int dest_index = mod->dest;
|
||||
if(dest_index & FLUID_MOD_LINK_DEST)
|
||||
{
|
||||
/* destination is a modulator */
|
||||
voice->mod[dest_index & ~FLUID_MOD_LINK_DEST].link += modval;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* destination is a generator */
|
||||
fluid_gen_t* dest_gen = &voice->gen[dest_index];
|
||||
dest_gen->mod += modval;
|
||||
}
|
||||
/* fluid_dump_modulator(mod); */
|
||||
}
|
||||
fluid_voice_calculate_modulator_contributions(voice);
|
||||
|
||||
/* Now the generators are initialized, nominal and modulation value.
|
||||
* The voice parameters (which depend on generators) are calculated
|
||||
|
|
|
@ -16,6 +16,7 @@ ADD_FLUID_TEST(test_seqbind_unregister)
|
|||
ADD_FLUID_TEST(test_synth_chorus_reverb)
|
||||
ADD_FLUID_TEST(test_snprintf)
|
||||
ADD_FLUID_TEST(test_modulator_links)
|
||||
ADD_FLUID_TEST(test_modulator_amount)
|
||||
|
||||
if ( LIBSNDFILE_HASVORBIS )
|
||||
ADD_FLUID_TEST(test_sf3_sfont_loading)
|
||||
|
|
78
test/test_modulator_amount.c
Normal file
78
test/test_modulator_amount.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
|
||||
#include "test.h"
|
||||
#include "fluidsynth.h"
|
||||
#include "utils/fluid_sys.h"
|
||||
#include "synth/fluid_voice.h"
|
||||
#include "synth/fluid_chan.h"
|
||||
|
||||
void fluid_voice_calculate_modulator_contributions(fluid_voice_t *voice);
|
||||
|
||||
// test modulators (amount, source, linked modulators...)
|
||||
int main(void)
|
||||
{
|
||||
static const int CC = 20;
|
||||
|
||||
fluid_settings_t* set = new_fluid_settings();
|
||||
fluid_synth_t* synth = new_fluid_synth(set);
|
||||
fluid_channel_t *ch = new_fluid_channel(synth, 0);
|
||||
fluid_voice_t *v = new_fluid_voice(NULL, 22050);
|
||||
|
||||
fluid_mod_t *mod0 = &v->mod[0];
|
||||
fluid_mod_t *mod1 = &v->mod[1];
|
||||
fluid_mod_t *mod2 = &v->mod[2];
|
||||
fluid_mod_t *mod3 = &v->mod[3];
|
||||
v->mod_count = 3;
|
||||
|
||||
fluid_channel_set_cc(ch, CC, 127);
|
||||
v->channel = ch;
|
||||
|
||||
// set up a valid list of complex modulators
|
||||
{
|
||||
fluid_mod_set_source1(mod0, FLUID_MOD_LINK_SRC, FLUID_MOD_GC);
|
||||
fluid_mod_set_source2(mod0, FLUID_MOD_NONE, FLUID_MOD_GC);
|
||||
fluid_mod_set_amount (mod0, 100);
|
||||
fluid_mod_set_dest (mod0, GEN_FILTERFC);
|
||||
|
||||
fluid_mod_set_source1(mod1, CC,
|
||||
FLUID_MOD_CC | FLUID_MOD_CONCAVE | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE);
|
||||
fluid_mod_set_source2(mod1, FLUID_MOD_NONE, FLUID_MOD_GC);
|
||||
fluid_mod_set_amount (mod1, 200);
|
||||
fluid_mod_set_dest (mod1, FLUID_MOD_LINK_DEST | 0);
|
||||
|
||||
fluid_mod_set_source1(mod2, CC, FLUID_MOD_CC | FLUID_MOD_LINEAR | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE);
|
||||
fluid_mod_set_source2(mod2, FLUID_MOD_NONE, FLUID_MOD_GC);
|
||||
fluid_mod_set_amount (mod2, 300);
|
||||
fluid_mod_set_dest (mod2, FLUID_MOD_LINK_DEST | 0);
|
||||
|
||||
fluid_voice_calculate_modulator_contributions(v);
|
||||
|
||||
TEST_ASSERT(mod0->link == fluid_mod_get_amount(mod1) + fluid_mod_get_amount(mod2));
|
||||
TEST_ASSERT(v->gen[GEN_FILTERFC].mod == mod0->link * fluid_mod_get_amount(mod0));
|
||||
}
|
||||
|
||||
// same list, with additional mod3
|
||||
{
|
||||
v->mod_count++;
|
||||
v->gen[GEN_FILTERFC].mod = mod0->link = 0;
|
||||
|
||||
fluid_mod_set_source1(mod1, FLUID_MOD_LINK_SRC, FLUID_MOD_GC);
|
||||
|
||||
fluid_mod_set_source1(mod3, CC, FLUID_MOD_CC | FLUID_MOD_LINEAR | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE);
|
||||
fluid_mod_set_source2(mod3, FLUID_MOD_NONE, FLUID_MOD_GC);
|
||||
fluid_mod_set_amount (mod3, 50);
|
||||
fluid_mod_set_dest (mod3, FLUID_MOD_LINK_DEST | 1); // link to mod1
|
||||
|
||||
fluid_voice_calculate_modulator_contributions(v);
|
||||
|
||||
TEST_ASSERT(mod1->link == 50);
|
||||
TEST_ASSERT(mod0->link == fluid_mod_get_amount(mod2) + fluid_mod_get_amount(mod1) * mod1->link);
|
||||
TEST_ASSERT(v->gen[GEN_FILTERFC].mod == mod0->link * fluid_mod_get_amount(mod0));
|
||||
}
|
||||
|
||||
delete_fluid_voice(v);
|
||||
delete_fluid_channel(ch);
|
||||
delete_fluid_synth(synth);
|
||||
delete_fluid_settings(set);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in a new issue