fluidsynth/test/test_preset_pinning.c

195 lines
7.1 KiB
C

#include "test.h"
#include "fluidsynth.h"
#include "sfloader/fluid_sfont.h"
#include "sfloader/fluid_defsfont.h"
#include "sfloader/fluid_samplecache.h"
#include "utils/fluid_sys.h"
#include "utils/fluid_list.h"
static int count_loaded_samples(fluid_synth_t *synth, int sfont_id);
/* Test the preset pinning and unpinning feature */
int main(void)
{
int id;
fluid_synth_t *synth;
fluid_sfont_t *sfont;
fluid_defsfont_t *defsfont;
/* Setup */
fluid_settings_t *settings = new_fluid_settings();
/* Test that pinning and unpinning has no effect and throws no errors
* when dynamic-sample-loading is disabled */
fluid_settings_setint(settings, "synth.dynamic-sample-loading", 0);
synth = new_fluid_synth(settings);
id = fluid_synth_sfload(synth, TEST_SOUNDFONT, 0);
TEST_ASSERT(count_loaded_samples(synth, id) == 123);
TEST_ASSERT(fluid_samplecache_count_entries() == 1);
/* Attempt to pin and unpin an exising preset should succeed (but have no effect) */
TEST_ASSERT(fluid_synth_pin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 123);
TEST_ASSERT(fluid_synth_unpin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 123);
/* Attempt to pin and unpin a non-existant preset should fail */
TEST_ASSERT(fluid_synth_pin_preset(synth, id, 42, 42) == FLUID_FAILED);
TEST_ASSERT(count_loaded_samples(synth, id) == 123);
TEST_ASSERT(fluid_synth_unpin_preset(synth, id, 42, 42) == FLUID_FAILED);
TEST_ASSERT(count_loaded_samples(synth, id) == 123);
delete_fluid_synth(synth);
/* Test pinning and unpinning with dyamic-sample loading enabled */
fluid_settings_setint(settings, "synth.dynamic-sample-loading", 1);
synth = new_fluid_synth(settings);
id = fluid_synth_sfload(synth, TEST_SOUNDFONT, 0);
TEST_ASSERT(count_loaded_samples(synth, id) == 0);
TEST_ASSERT(fluid_samplecache_count_entries() == 0);
/* For the following tests, preset 42 (Lead Synth 2) consists of 4 samples,
* preset 40 (Aluminum Plate) consists of 1 sample */
/* Simple pin and unpin */
TEST_ASSERT(fluid_synth_pin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 4);
TEST_ASSERT(fluid_samplecache_count_entries() == 4);
TEST_ASSERT(fluid_synth_unpin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 0);
TEST_ASSERT(fluid_samplecache_count_entries() == 0);
/* Pinning and unpinning twice should have exactly the same effect */
TEST_ASSERT(fluid_synth_pin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 4);
TEST_ASSERT(fluid_samplecache_count_entries() == 4);
TEST_ASSERT(fluid_synth_pin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 4);
TEST_ASSERT(fluid_samplecache_count_entries() == 4);
TEST_ASSERT(fluid_synth_unpin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 0);
TEST_ASSERT(fluid_samplecache_count_entries() == 0);
TEST_ASSERT(fluid_synth_unpin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 0);
TEST_ASSERT(fluid_samplecache_count_entries() == 0);
/* Pin a single preset, select both presets, unselect both, ensure the pinned
* is still in memory and gone after unpinning */
TEST_ASSERT(fluid_synth_pin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 4);
TEST_ASSERT(fluid_samplecache_count_entries() == 4);
TEST_ASSERT(fluid_synth_program_select(synth, 0, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 4);
TEST_ASSERT(fluid_samplecache_count_entries() == 4);
TEST_ASSERT(fluid_synth_program_select(synth, 1, id, 0, 40) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 5);
TEST_ASSERT(fluid_samplecache_count_entries() == 5);
TEST_ASSERT(fluid_synth_unset_program(synth, 0) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 5);
TEST_ASSERT(fluid_samplecache_count_entries() == 5);
TEST_ASSERT(fluid_synth_unset_program(synth, 1) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 4);
TEST_ASSERT(fluid_samplecache_count_entries() == 4);
TEST_ASSERT(fluid_synth_unpin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 0);
TEST_ASSERT(fluid_samplecache_count_entries() == 0);
/* Unpinning an unpinned and selected preset should not remove it from memory */
TEST_ASSERT(fluid_synth_program_select(synth, 0, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 4);
TEST_ASSERT(fluid_samplecache_count_entries() == 4);
TEST_ASSERT(fluid_synth_unpin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 4);
TEST_ASSERT(fluid_samplecache_count_entries() == 4);
TEST_ASSERT(fluid_synth_unset_program(synth, 0) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 0);
TEST_ASSERT(fluid_samplecache_count_entries() == 0);
/* Test unload of soundfont with pinned sample automatically unpins
* the sample and removes all samples from cache */
TEST_ASSERT(fluid_synth_pin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 4);
TEST_ASSERT(fluid_samplecache_count_entries() == 4);
TEST_ASSERT(fluid_synth_sfunload(synth, id, 0) == FLUID_OK);
TEST_ASSERT(fluid_samplecache_count_entries() == 0);
/* Ensure that failures during load of preset results in an
* error returned by pinning function */
id = fluid_synth_sfload(synth, TEST_SOUNDFONT, 0);
// hack the soundfont filename so the next load won't find the file anymore
sfont = fluid_synth_get_sfont_by_id(synth, id);
defsfont = fluid_sfont_get_data(sfont);
defsfont->filename[0]++;
TEST_ASSERT(fluid_synth_pin_preset(synth, id, 0, 42) == FLUID_FAILED);
defsfont->filename[0]--;
TEST_ASSERT(fluid_synth_sfunload(synth, id, 0) == FLUID_OK);
/* Test that deleting the synth with a pinned preset also leaves no
* samples in cache */
id = fluid_synth_sfload(synth, TEST_SOUNDFONT, 0);
TEST_ASSERT(fluid_synth_pin_preset(synth, id, 0, 42) == FLUID_OK);
TEST_ASSERT(count_loaded_samples(synth, id) == 4);
TEST_ASSERT(fluid_samplecache_count_entries() == 4);
delete_fluid_synth(synth);
TEST_ASSERT(fluid_samplecache_count_entries() == 0);
/* Tear down */
delete_fluid_settings(settings);
return EXIT_SUCCESS;
}
static int count_loaded_samples(fluid_synth_t *synth, int sfont_id)
{
fluid_list_t *list;
int count = 0;
fluid_sfont_t *sfont = fluid_synth_get_sfont_by_id(synth, sfont_id);
fluid_defsfont_t *defsfont = fluid_sfont_get_data(sfont);
for(list = defsfont->sample; list; list = fluid_list_next(list))
{
fluid_sample_t *sample = fluid_list_get(list);
if(sample->data != NULL)
{
count++;
}
}
FLUID_LOG(FLUID_INFO, "Loaded samples on sfont %d: %d\n", sfont_id, count);
return count;
}