Merge pull request #365 from FluidSynth/preset-stack-removal

Preset stack removal
This commit is contained in:
Tom M 2018-04-11 10:14:32 +02:00 committed by GitHub
commit f4f439180d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 263 additions and 307 deletions

View file

@ -1123,18 +1123,18 @@ fluidmax_print(t_object *o, Symbol *s, short ac, Atom *at)
if(sf != NULL)
{
fluid_preset_t preset;
fluid_preset_t *preset;
fluid_sfont_iteration_start(sf);
post("fluidsynth~ presets of soundfont '%s':", ftmax_symbol_name(name));
while(fluid_sfont_iteration_next(sf, &preset) > 0)
while((preset = fluid_sfont_iteration_next(sf)) != NULL)
{
char *preset_str = fluid_preset_get_name(&preset);
char *preset_str = fluid_preset_get_name(preset);
ftmax_symbol_t preset_name = ftmax_new_symbol(preset_str);
int bank_num = fluid_preset_get_banknum(&preset);
int prog_num = fluid_preset_get_num(&preset);
int bank_num = fluid_preset_get_banknum(preset);
int prog_num = fluid_preset_get_num(preset);
post(" '%s': bank %d, program %d", ftmax_symbol_name(preset_name), bank_num, prog_num);
}
@ -1340,16 +1340,16 @@ fluidmax_info(t_object *o, Symbol *s, short ac, Atom *at)
if(sf != NULL)
{
fluid_preset_t preset;
fluid_preset_t *preset;
fluid_sfont_iteration_start(sf);
while(fluid_sfont_iteration_next(sf, &preset) > 0)
while((preset = fluid_sfont_iteration_next(sf)) != NULL)
{
char *preset_str = fluid_preset_get_name(&preset);
char *preset_str = fluid_preset_get_name(preset);
ftmax_symbol_t preset_name = ftmax_new_symbol(preset_str);
int bank_num = fluid_preset_get_banknum(&preset);
int prog_num = fluid_preset_get_num(&preset);
int bank_num = fluid_preset_get_banknum(preset);
int prog_num = fluid_preset_get_num(preset);
ftmax_atom_t a[4];
ftmax_set_symbol(a , preset_name);

View file

@ -617,7 +617,7 @@ fluid_handle_inst(void* data, int ac, char** av, fluid_ostream_t out)
FLUID_ENTRY_COMMAND(data);
int font;
fluid_sfont_t* sfont;
fluid_preset_t preset;
fluid_preset_t* preset;
int offset;
if (ac < 1) {
@ -642,11 +642,11 @@ fluid_handle_inst(void* data, int ac, char** av, fluid_ostream_t out)
fluid_sfont_iteration_start(sfont);
while (fluid_sfont_iteration_next(sfont, &preset)) {
while ((preset = fluid_sfont_iteration_next(sfont)) != NULL) {
fluid_ostream_printf(out, "%03d-%03d %s\n",
fluid_preset_get_banknum(&preset) + offset,
fluid_preset_get_num(&preset),
fluid_preset_get_name(&preset));
fluid_preset_get_banknum(preset) + offset,
fluid_preset_get_num(preset),
fluid_preset_get_name(preset));
}
return FLUID_OK;

View file

@ -76,11 +76,6 @@ fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* file
return NULL;
}
if (fluid_defsfont_load(defsfont, &loader->file_callbacks, filename) == FLUID_FAILED) {
delete_fluid_defsfont(defsfont);
return NULL;
}
sfont = new_fluid_sfont(fluid_defsfont_sfont_get_name,
fluid_defsfont_sfont_get_preset,
fluid_defsfont_sfont_delete);
@ -89,6 +84,13 @@ fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* file
return NULL;
}
defsfont->sfont = sfont;
if (fluid_defsfont_load(defsfont, &loader->file_callbacks, filename) == FLUID_FAILED) {
delete_fluid_defsfont(defsfont);
return NULL;
}
fluid_sfont_set_iteration_start(sfont, fluid_defsfont_sfont_iteration_start);
fluid_sfont_set_iteration_next(sfont, fluid_defsfont_sfont_iteration_next);
fluid_sfont_set_data(sfont, defsfont);
@ -120,37 +122,7 @@ const char* fluid_defsfont_sfont_get_name(fluid_sfont_t* sfont)
fluid_preset_t*
fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum)
{
fluid_preset_t* preset = NULL;
fluid_defpreset_t* defpreset;
fluid_defsfont_t* defsfont = fluid_sfont_get_data(sfont);
defpreset = fluid_defsfont_get_preset(defsfont, bank, prenum);
if (defpreset == NULL) {
return NULL;
}
if (defsfont->preset_stack_size > 0) {
defsfont->preset_stack_size--;
preset = defsfont->preset_stack[defsfont->preset_stack_size];
}
if (!preset)
preset = FLUID_NEW(fluid_preset_t);
if (!preset) {
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
preset->sfont = sfont;
preset->data = defpreset;
preset->free = fluid_defpreset_preset_delete;
preset->get_name = fluid_defpreset_preset_get_name;
preset->get_banknum = fluid_defpreset_preset_get_banknum;
preset->get_num = fluid_defpreset_preset_get_num;
preset->noteon = fluid_defpreset_preset_noteon;
preset->notify = NULL;
return preset;
return fluid_defsfont_get_preset(fluid_sfont_get_data(sfont), bank, prenum);
}
void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont)
@ -158,29 +130,26 @@ void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont)
fluid_defsfont_iteration_start(fluid_sfont_get_data(sfont));
}
int fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset)
fluid_preset_t *fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont)
{
preset->free = fluid_defpreset_preset_delete;
preset->get_name = fluid_defpreset_preset_get_name;
preset->get_banknum = fluid_defpreset_preset_get_banknum;
preset->get_num = fluid_defpreset_preset_get_num;
preset->noteon = fluid_defpreset_preset_noteon;
preset->notify = NULL;
return fluid_defsfont_iteration_next(fluid_sfont_get_data(sfont), preset);
return fluid_defsfont_iteration_next(fluid_sfont_get_data(sfont));
}
void fluid_defpreset_preset_delete(fluid_preset_t* preset)
{
fluid_defpreset_t* defpreset = fluid_preset_get_data(preset);
fluid_defsfont_t* defsfont = defpreset ? defpreset->defsfont : NULL;
fluid_defsfont_t* defsfont;
fluid_defpreset_t* defpreset;
if (defsfont && defsfont->preset_stack_size < defsfont->preset_stack_capacity) {
defsfont->preset_stack[defsfont->preset_stack_size] = preset;
defsfont->preset_stack_size++;
defsfont = fluid_sfont_get_data(preset->sfont);
defpreset = fluid_preset_get_data(preset);
if (defsfont)
{
defsfont->preset = fluid_list_remove(defsfont->preset, defpreset);
}
else
delete_fluid_preset(preset);
delete_fluid_defpreset(defpreset);
delete_fluid_preset(preset);
}
const char* fluid_defpreset_preset_get_name(fluid_preset_t* preset)
@ -216,7 +185,6 @@ int fluid_defpreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth,
fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings)
{
fluid_defsfont_t* defsfont;
int i;
defsfont = FLUID_NEW(fluid_defsfont_t);
if (defsfont == NULL) {
@ -228,29 +196,6 @@ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings)
fluid_settings_getint(settings, "synth.lock-memory", &defsfont->mlock);
/* Initialise preset cache, so we don't have to call malloc on program changes.
Usually, we have at most one preset per channel plus one temporarily used,
so optimise for that case. */
fluid_settings_getint(settings, "synth.midi-channels", &defsfont->preset_stack_capacity);
defsfont->preset_stack_capacity++;
defsfont->preset_stack = FLUID_ARRAY(fluid_preset_t*, defsfont->preset_stack_capacity);
if (!defsfont->preset_stack) {
FLUID_LOG(FLUID_ERR, "Out of memory");
FLUID_FREE(defsfont);
return NULL;
}
for (i = 0; i < defsfont->preset_stack_capacity; i++) {
defsfont->preset_stack[i] = FLUID_NEW(fluid_preset_t);
if (!defsfont->preset_stack[i]) {
FLUID_LOG(FLUID_ERR, "Out of memory");
delete_fluid_defsfont(defsfont);
return NULL;
}
defsfont->preset_stack_size++;
}
return defsfont;
}
@ -260,7 +205,7 @@ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings)
int delete_fluid_defsfont(fluid_defsfont_t* defsfont)
{
fluid_list_t *list;
fluid_defpreset_t* defpreset;
fluid_preset_t* preset;
fluid_sample_t* sample;
fluid_return_val_if_fail(defsfont != NULL, FLUID_OK);
@ -289,16 +234,11 @@ int delete_fluid_defsfont(fluid_defsfont_t* defsfont)
fluid_samplecache_unload(defsfont->sampledata);
}
while (defsfont->preset_stack_size > 0)
FLUID_FREE(defsfont->preset_stack[--defsfont->preset_stack_size]);
FLUID_FREE(defsfont->preset_stack);
defpreset = defsfont->preset;
while (defpreset != NULL) {
defsfont->preset = defpreset->next;
delete_fluid_defpreset(defpreset);
defpreset = defsfont->preset;
for (list = defsfont->preset; list; list = fluid_list_next(list)) {
preset = (fluid_preset_t *)fluid_list_get(list);
fluid_defpreset_preset_delete(preset);
}
delete_fluid_list(defsfont->preset);
FLUID_FREE(defsfont);
return FLUID_OK;
@ -385,7 +325,10 @@ int fluid_defsfont_load(fluid_defsfont_t* defsfont, const fluid_file_callbacks_t
if (fluid_defpreset_import_sfont(defpreset, sfpreset, defsfont) != FLUID_OK)
goto err_exit;
fluid_defsfont_add_preset(defsfont, defpreset);
if (fluid_defsfont_add_preset(defsfont, defpreset) == FLUID_FAILED)
{
goto err_exit;
}
p = fluid_list_next(p);
}
fluid_sffile_close (sfdata);
@ -414,33 +357,24 @@ int fluid_defsfont_add_sample(fluid_defsfont_t* defsfont, fluid_sample_t* sample
*/
int fluid_defsfont_add_preset(fluid_defsfont_t* defsfont, fluid_defpreset_t* defpreset)
{
fluid_defpreset_t *cur, *prev;
if (defsfont->preset == NULL) {
defpreset->next = NULL;
defsfont->preset = defpreset;
} else {
/* sort them as we go along. very basic sorting trick. */
cur = defsfont->preset;
prev = NULL;
while (cur != NULL) {
if ((defpreset->bank < cur->bank)
|| ((defpreset->bank == cur->bank) && (defpreset->num < cur->num))) {
if (prev == NULL) {
defpreset->next = cur;
defsfont->preset = defpreset;
} else {
defpreset->next = cur;
prev->next = defpreset;
}
return FLUID_OK;
}
prev = cur;
cur = cur->next;
fluid_preset_t *preset;
preset = new_fluid_preset(defsfont->sfont,
fluid_defpreset_preset_get_name,
fluid_defpreset_preset_get_banknum,
fluid_defpreset_preset_get_num,
fluid_defpreset_preset_noteon,
fluid_defpreset_preset_delete);
if (preset == NULL) {
return FLUID_FAILED;
}
defpreset->next = NULL;
prev->next = defpreset;
}
return FLUID_OK;
fluid_preset_set_data(preset, defpreset);
defsfont->preset = fluid_list_append(defsfont->preset, preset);
return FLUID_OK;
}
/*
@ -469,16 +403,22 @@ fluid_defsfont_load_sampledata(fluid_defsfont_t* defsfont, const fluid_file_call
/*
* fluid_defsfont_get_preset
*/
fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, unsigned int bank, unsigned int num)
fluid_preset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, unsigned int bank, unsigned int num)
{
fluid_defpreset_t* defpreset = defsfont->preset;
while (defpreset != NULL) {
if ((defpreset->bank == bank) && ((defpreset->num == num))) {
return defpreset;
fluid_preset_t *preset;
fluid_list_t *list;
for(list = defsfont->preset; list != NULL; list = fluid_list_next(list))
{
preset = (fluid_preset_t *)fluid_list_get(list);
if ((fluid_preset_get_banknum(preset) == bank) && (fluid_preset_get_num(preset) == num))
{
return preset;
}
}
defpreset = defpreset->next;
}
return NULL;
return NULL;
}
/*
@ -486,21 +426,19 @@ fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, unsigne
*/
void fluid_defsfont_iteration_start(fluid_defsfont_t* defsfont)
{
defsfont->iter_cur = defsfont->preset;
defsfont->preset_iter_cur = defsfont->preset;
}
/*
* fluid_defsfont_iteration_next
*/
int fluid_defsfont_iteration_next(fluid_defsfont_t* defsfont, fluid_preset_t* preset)
fluid_preset_t *fluid_defsfont_iteration_next(fluid_defsfont_t* defsfont)
{
if (defsfont->iter_cur == NULL) {
return 0;
}
fluid_preset_t *preset = (fluid_preset_t *)fluid_list_get(defsfont->preset_iter_cur);
preset->data = (void*) defsfont->iter_cur;
defsfont->iter_cur = fluid_defpreset_next(defsfont->iter_cur);
return 1;
defsfont->preset_iter_cur = fluid_list_next(defsfont->preset_iter_cur);
return preset;
}
/***************************************************************

View file

@ -78,7 +78,7 @@ int fluid_defsfont_sfont_delete(fluid_sfont_t* sfont);
const char* fluid_defsfont_sfont_get_name(fluid_sfont_t* sfont);
fluid_preset_t* fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum);
void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont);
int fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset);
fluid_preset_t *fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont);
void fluid_defpreset_preset_delete(fluid_preset_t* preset);
@ -103,15 +103,12 @@ struct _fluid_defsfont_t
unsigned int sample24size; /* length within sffd of the sm24 chunk */
char* sample24data; /* if not NULL, the least significant byte of the 24bit sample data, loaded in ram */
fluid_sfont_t *sfont; /* pointer to parent sfont */
fluid_list_t* sample; /* the samples in this soundfont */
fluid_defpreset_t* preset; /* the presets of this soundfont */
fluid_list_t* preset; /* the presets of this soundfont */
int mlock; /* Should we try memlock (avoid swapping)? */
fluid_defpreset_t* iter_cur; /* the current preset in the iteration */
fluid_preset_t** preset_stack; /* List of presets that are available to use */
int preset_stack_capacity; /* Length of preset_stack array */
int preset_stack_size; /* Current number of items in the stack */
fluid_list_t *preset_iter_cur; /* the current preset in the iteration */
};
@ -119,9 +116,9 @@ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings);
int delete_fluid_defsfont(fluid_defsfont_t* defsfont);
int fluid_defsfont_load(fluid_defsfont_t* defsfont, const fluid_file_callbacks_t* file_callbacks, const char* file);
const char* fluid_defsfont_get_name(fluid_defsfont_t* defsfont);
fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, unsigned int bank, unsigned int prenum);
fluid_preset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, unsigned int bank, unsigned int prenum);
void fluid_defsfont_iteration_start(fluid_defsfont_t* defsfont);
int fluid_defsfont_iteration_next(fluid_defsfont_t* defsfont, fluid_preset_t* preset);
fluid_preset_t *fluid_defsfont_iteration_next(fluid_defsfont_t* defsfont);
int fluid_defsfont_load_sampledata(fluid_defsfont_t* defsfont, const fluid_file_callbacks_t* file_callbacks);
int fluid_defsfont_add_sample(fluid_defsfont_t* defsfont, fluid_sample_t* sample);
int fluid_defsfont_add_preset(fluid_defsfont_t* defsfont, fluid_defpreset_t* defpreset);

View file

@ -30,8 +30,8 @@ static fluid_preset_t *fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont,
unsigned int bank,
unsigned int prenum);
static void fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont);
static int fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont,
fluid_preset_t* preset);
static fluid_preset_t *fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont);
static void fluid_rampreset_preset_delete(fluid_preset_t* preset);
static const char *fluid_rampreset_preset_get_name(fluid_preset_t* preset);
static int fluid_rampreset_preset_get_banknum(fluid_preset_t* preset);
static int fluid_rampreset_preset_get_num(fluid_preset_t* preset);
@ -42,18 +42,16 @@ static fluid_ramsfont_t *new_fluid_ramsfont (void);
static int delete_fluid_ramsfont (fluid_ramsfont_t* sfont);
static const char *fluid_ramsfont_get_name(fluid_ramsfont_t* sfont);
static int fluid_ramsfont_add_preset (fluid_ramsfont_t* sfont,
fluid_rampreset_t* preset);
static fluid_rampreset_t *fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont,
fluid_rampreset_t* rampreset);
static fluid_preset_t *fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num);
static void fluid_ramsfont_iteration_start (fluid_ramsfont_t* sfont);
static int fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont,
fluid_preset_t* preset);
static fluid_preset_t *fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont);
static fluid_rampreset_t* new_fluid_rampreset(fluid_ramsfont_t* sfont);
static void delete_fluid_rampreset (fluid_rampreset_t* preset);
static int fluid_rampreset_get_banknum (fluid_rampreset_t* preset);
static int fluid_rampreset_get_num (fluid_rampreset_t* preset);
static const char *fluid_rampreset_get_name (fluid_rampreset_t* preset);
static fluid_rampreset_t *fluid_rampreset_next (fluid_rampreset_t* preset);
static int fluid_rampreset_add_zone(fluid_rampreset_t* preset,
fluid_preset_zone_t* zone);
static int fluid_rampreset_add_sample (fluid_rampreset_t* preset,
@ -100,6 +98,8 @@ fluid_ramsfont_create_sfont()
return NULL;
}
ramsfont->sfont = sfont;
fluid_sfont_set_iteration_start(sfont, fluid_ramsfont_sfont_iteration_start);
fluid_sfont_set_iteration_next(sfont, fluid_ramsfont_sfont_iteration_next);
fluid_sfont_set_data(sfont, ramsfont);
@ -128,27 +128,7 @@ fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont)
static fluid_preset_t *
fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum)
{
fluid_preset_t* preset;
fluid_rampreset_t* rampreset;
rampreset = fluid_ramsfont_get_preset((fluid_ramsfont_t*) sfont->data, bank, prenum);
if (rampreset == NULL) {
return NULL;
}
preset = new_fluid_preset(sfont,
fluid_rampreset_preset_get_name,
fluid_rampreset_preset_get_banknum,
fluid_rampreset_preset_get_num,
fluid_rampreset_preset_noteon,
delete_fluid_preset); /* TODO: free modulators */
if (preset == NULL) {
return NULL;
}
fluid_preset_set_data(preset, rampreset);
return preset;
return fluid_ramsfont_get_preset((fluid_ramsfont_t*) sfont->data, bank, prenum);
}
/* RAM SoundFont loader method to start preset iteration */
@ -159,17 +139,27 @@ fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont)
}
/* RAM SoundFont loader method to advance preset iteration */
static int
fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset)
static fluid_preset_t*
fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont)
{
preset->free = delete_fluid_preset;
preset->get_name = fluid_rampreset_preset_get_name;
preset->get_banknum = fluid_rampreset_preset_get_banknum;
preset->get_num = fluid_rampreset_preset_get_num;
preset->noteon = fluid_rampreset_preset_noteon;
preset->notify = NULL;
return fluid_ramsfont_iteration_next((fluid_ramsfont_t*) sfont->data);
}
return fluid_ramsfont_iteration_next((fluid_ramsfont_t*) sfont->data, preset);
void fluid_rampreset_preset_delete(fluid_preset_t* preset)
{
fluid_ramsfont_t* ramsfont;
fluid_rampreset_t* rampreset;
ramsfont = fluid_sfont_get_data(preset->sfont);
rampreset = fluid_preset_get_data(preset);
if (ramsfont)
{
ramsfont->preset = fluid_list_remove(ramsfont->preset, rampreset);
}
delete_fluid_rampreset(rampreset);
delete_fluid_preset(preset);
}
/* RAM SoundFont loader get preset name method */
@ -230,7 +220,7 @@ static int
delete_fluid_ramsfont (fluid_ramsfont_t* sfont)
{
fluid_list_t *list;
fluid_rampreset_t* preset;
fluid_preset_t* preset;
fluid_return_val_if_fail(sfont != NULL, FLUID_OK);
/* Check that no samples are currently used */
@ -251,12 +241,11 @@ delete_fluid_ramsfont (fluid_ramsfont_t* sfont)
delete_fluid_list(sfont->sample);
}
preset = sfont->preset;
while (preset != NULL) {
sfont->preset = preset->next;
delete_fluid_rampreset(preset);
preset = sfont->preset;
for (list = sfont->preset; list; list = fluid_list_next(list)) {
preset = (fluid_preset_t *)fluid_list_get(list);
fluid_rampreset_preset_delete(preset);
}
delete_fluid_list(sfont->preset);
FLUID_FREE(sfont);
return FLUID_OK;
@ -284,34 +273,23 @@ fluid_ramsfont_set_name (fluid_ramsfont_t *sfont, const char *name)
/* Add a preset to a RAM SoundFont */
static int
fluid_ramsfont_add_preset (fluid_ramsfont_t* sfont, fluid_rampreset_t* preset)
fluid_ramsfont_add_preset (fluid_ramsfont_t* sfont, fluid_rampreset_t* rampreset)
{
fluid_rampreset_t *cur, *prev;
if (sfont->preset == NULL) {
preset->next = NULL;
sfont->preset = preset;
} else {
/* sort them as we go along. very basic sorting trick. */
cur = sfont->preset;
prev = NULL;
while (cur != NULL) {
if ((preset->bank < cur->bank)
|| ((preset->bank == cur->bank) && (preset->num < cur->num))) {
if (prev == NULL) {
preset->next = cur;
sfont->preset = preset;
} else {
preset->next = cur;
prev->next = preset;
}
return FLUID_OK;
}
prev = cur;
cur = cur->next;
}
preset->next = NULL;
prev->next = preset;
fluid_preset_t *preset;
preset = new_fluid_preset(sfont->sfont,
fluid_rampreset_preset_get_name,
fluid_rampreset_preset_get_banknum,
fluid_rampreset_preset_get_num,
fluid_rampreset_preset_noteon,
fluid_rampreset_preset_delete); /* TODO: free modulators */
if (preset == NULL) {
return FLUID_FAILED;
}
fluid_preset_set_data(preset, rampreset);
sfont->preset = fluid_list_append(sfont->preset, preset);
return FLUID_OK;
}
@ -337,30 +315,34 @@ fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont, unsigned int bank,
*/
int err;
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
fluid_rampreset_t* rampreset;
fluid_preset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
// Create it
preset = new_fluid_rampreset(sfont);
if (preset == NULL) {
rampreset = new_fluid_rampreset(sfont);
if (rampreset == NULL) {
return FLUID_FAILED;
}
preset->bank = bank;
preset->num = num;
err = fluid_rampreset_add_sample(preset, sample, lokey, hikey);
if (err != FLUID_OK) {
delete_fluid_rampreset(preset);
return FLUID_FAILED;
}
rampreset->bank = bank;
rampreset->num = num;
// sort the preset
fluid_ramsfont_add_preset(sfont, preset);
fluid_ramsfont_add_preset(sfont, rampreset);
err = fluid_rampreset_add_sample(rampreset, sample, lokey, hikey);
if (err != FLUID_OK) {
// MWE: delete preset (also check that all preset delete also remove list item!)
fluid_rampreset_preset_delete(preset);
return FLUID_FAILED;
}
} else {
// just add it
err = fluid_rampreset_add_sample(preset, sample, lokey, hikey);
rampreset = fluid_preset_get_data(preset);
err = fluid_rampreset_add_sample(rampreset, sample, lokey, hikey);
if (err != FLUID_OK) {
return FLUID_FAILED;
}
@ -383,14 +365,17 @@ fluid_ramsfont_remove_izone (fluid_ramsfont_t* sfont, unsigned int bank,
unsigned int num, fluid_sample_t* sample)
{
int err;
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
fluid_rampreset_t *rampreset;
fluid_preset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
return FLUID_FAILED;
}
rampreset = fluid_preset_get_data(preset);
// Fixed a crash bug : remove the sample from the sfont list after
// removing the izone (aschmitt august 2005)
err = fluid_rampreset_remove_izone(preset, sample);
err = fluid_rampreset_remove_izone(rampreset, sample);
if (err != FLUID_OK)
return err;
@ -415,12 +400,15 @@ fluid_ramsfont_izone_set_gen (fluid_ramsfont_t* sfont, unsigned int bank,
unsigned int num, fluid_sample_t* sample,
int gen_type, float value)
{
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
fluid_rampreset_t* rampreset;
fluid_preset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
return FLUID_FAILED;
}
return fluid_rampreset_izone_set_gen(preset, sample, gen_type, value);
rampreset = fluid_preset_get_data(preset);
return fluid_rampreset_izone_set_gen(rampreset, sample, gen_type, value);
}
/**
@ -441,46 +429,53 @@ fluid_ramsfont_izone_set_loop (fluid_ramsfont_t *sfont, unsigned int bank,
unsigned int num, fluid_sample_t* sample,
int on, float loopstart, float loopend)
{
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
fluid_rampreset_t* rampreset;
fluid_preset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
return FLUID_FAILED;
}
return fluid_rampreset_izone_set_loop(preset, sample, on, loopstart, loopend);
rampreset = fluid_preset_get_data(preset);
return fluid_rampreset_izone_set_loop(rampreset, sample, on, loopstart, loopend);
}
/* Get a preset from a RAM SoundFont */
static fluid_rampreset_t *
static fluid_preset_t *
fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont, unsigned int bank, unsigned int num)
{
fluid_rampreset_t* preset = sfont->preset;
while (preset != NULL) {
if ((preset->bank == bank) && ((preset->num == num))) {
return preset;
fluid_preset_t *preset;
fluid_list_t *list;
for(list = sfont->preset; list != NULL; list = fluid_list_next(list))
{
preset = (fluid_preset_t *)fluid_list_get(list);
if ((fluid_preset_get_banknum(preset) == bank) && (fluid_preset_get_num(preset) == num))
{
return preset;
}
}
preset = preset->next;
}
return NULL;
return NULL;
}
/* Start preset iteration in a RAM SoundFont */
static void
fluid_ramsfont_iteration_start (fluid_ramsfont_t* sfont)
{
sfont->iter_cur = sfont->preset;
sfont->preset_iter_cur = sfont->preset;
}
/* Advance preset iteration in a RAM SoundFont */
static int
fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont, fluid_preset_t* preset)
static fluid_preset_t *
fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont)
{
if (sfont->iter_cur == NULL) {
return 0;
}
fluid_preset_t *preset = (fluid_preset_t *)fluid_list_get(sfont->preset_iter_cur);
preset->data = (void*) sfont->iter_cur;
sfont->iter_cur = fluid_rampreset_next(sfont->iter_cur);
return 1;
sfont->preset_iter_cur = fluid_list_next(sfont->preset_iter_cur);
return preset;
}
/***************************************************************
@ -570,13 +565,6 @@ fluid_rampreset_get_name (fluid_rampreset_t* preset)
return preset->name;
}
/* Advance to next preset */
static fluid_rampreset_t *
fluid_rampreset_next (fluid_rampreset_t* preset)
{
return preset->next;
}
/* Add a zone to a RAM SoundFont preset */
static int

View file

@ -41,11 +41,11 @@ extern "C" {
struct _fluid_ramsfont_t
{
char name[21]; /* the name of the soundfont */
fluid_sfont_t* sfont; /* parent sfont */
fluid_list_t* sample; /* the samples in this soundfont */
fluid_rampreset_t* preset; /* the presets of this soundfont */
fluid_list_t* preset; /* the presets of this soundfont */
fluid_preset_t iter_preset; /* preset interface used in the iteration */
fluid_rampreset_t* iter_cur; /* the current preset in the iteration */
fluid_list_t* preset_iter_cur; /* the current preset in the iteration */
};
/*

View file

@ -42,7 +42,7 @@ int fluid_sample_decompress_vorbis(fluid_sample_t *sample);
#define fluid_sfont_get_name(_sf) (*(_sf)->get_name)(_sf)
#define fluid_sfont_get_preset(_sf,_bank,_prenum) (*(_sf)->get_preset)(_sf,_bank,_prenum)
#define fluid_sfont_iteration_start(_sf) { if((_sf) && (_sf)->iteration_start) (*(_sf)->iteration_start)(_sf); }
#define fluid_sfont_iteration_next(_sf,_pr) (((_sf) && (_sf)->iteration_start) ? (*(_sf)->iteration_next)(_sf,_pr) : 0)
#define fluid_sfont_iteration_next(_sf) (((_sf) && (_sf)->iteration_start) ? (*(_sf)->iteration_next)(_sf) : 0)
#define fluid_preset_delete_internal(_preset) \
@ -112,7 +112,7 @@ typedef void (*fluid_sfont_iteration_start_t)(fluid_sfont_t* sfont);
* and advance the internal iteration state to the next preset for subsequent
* calls.
*/
typedef int (*fluid_sfont_iteration_next_t)(fluid_sfont_t* sfont, fluid_preset_t* preset);
typedef fluid_preset_t* (*fluid_sfont_iteration_next_t)(fluid_sfont_t* sfont);
void fluid_sfont_set_iteration_start(fluid_sfont_t* sfont, fluid_sfont_iteration_start_t iter_start);
void fluid_sfont_set_iteration_next(fluid_sfont_t* sfont, fluid_sfont_iteration_next_t iter_next);

View file

@ -204,7 +204,6 @@ delete_fluid_channel(fluid_channel_t* chan)
{
fluid_return_if_fail(chan != NULL);
fluid_preset_delete_internal (chan->preset);
FLUID_FREE(chan);
}
@ -220,18 +219,27 @@ fluid_channel_reset(fluid_channel_t* chan)
int
fluid_channel_set_preset(fluid_channel_t* chan, fluid_preset_t* preset)
{
fluid_sfont_t *sfont;
if (chan->preset == preset)
{
return FLUID_OK;
}
if (chan->preset) {
sfont = chan->preset->sfont;
sfont->refcount--;
}
fluid_preset_notify (chan->preset, FLUID_PRESET_UNSELECTED, chan->channum);
if (chan->preset) {
fluid_sfont_t *sfont;
sfont = chan->preset->sfont;
fluid_preset_delete_internal (chan->preset);
fluid_synth_sfont_unref (chan->synth, sfont); /* -- unref preset's SoundFont */
}
chan->preset = preset;
if (preset) {
sfont = preset->sfont;
sfont->refcount++;
}
fluid_preset_notify (preset, FLUID_PRESET_SELECTED, chan->channum);
return FLUID_OK;

View file

@ -2209,15 +2209,11 @@ fluid_synth_set_preset (fluid_synth_t *synth, int chan, fluid_preset_t *preset)
/* Get a preset by SoundFont, bank and program numbers.
* Returns preset pointer or NULL.
*
* @note The returned preset has been allocated, caller owns it and should
* free it when finished using it.
*/
static fluid_preset_t*
fluid_synth_get_preset(fluid_synth_t* synth, unsigned int sfontnum,
unsigned int banknum, unsigned int prognum)
{
fluid_preset_t *preset = NULL;
fluid_sfont_t *sfont;
fluid_list_t *list;
@ -2229,27 +2225,20 @@ fluid_synth_get_preset(fluid_synth_t* synth, unsigned int sfontnum,
if (fluid_sfont_get_id (sfont) == sfontnum)
{
preset = fluid_sfont_get_preset (sfont,
banknum - sfont->bankofs, prognum);
if (preset) sfont->refcount++; /* Add reference to SoundFont */
break;
return fluid_sfont_get_preset (sfont, banknum - sfont->bankofs, prognum);
}
}
return preset;
return NULL;
}
/* Get a preset by SoundFont name, bank and program.
* Returns preset pointer or NULL.
*
* @note The returned preset has been allocated, caller owns it and should
* free it when finished using it.
*/
static fluid_preset_t*
fluid_synth_get_preset_by_sfont_name(fluid_synth_t* synth, const char *sfontname,
unsigned int banknum, unsigned int prognum)
{
fluid_preset_t *preset = NULL;
fluid_sfont_t *sfont;
fluid_list_t *list;
@ -2258,42 +2247,35 @@ fluid_synth_get_preset_by_sfont_name(fluid_synth_t* synth, const char *sfontname
if (FLUID_STRCMP (fluid_sfont_get_name (sfont), sfontname) == 0)
{
preset = fluid_sfont_get_preset (sfont,
banknum - sfont->bankofs, prognum);
if (preset) sfont->refcount++; /* Add reference to SoundFont */
break;
return fluid_sfont_get_preset (sfont, banknum - sfont->bankofs, prognum);
}
}
return preset;
return NULL;
}
/* Find a preset by bank and program numbers.
* Returns preset pointer or NULL.
*
* @note The returned preset has been allocated, caller owns it and should
* free it when finished using it. */
*/
fluid_preset_t*
fluid_synth_find_preset(fluid_synth_t* synth, unsigned int banknum,
unsigned int prognum)
{
fluid_preset_t *preset = NULL;
fluid_preset_t *preset;
fluid_sfont_t *sfont;
fluid_list_t *list;
for (list = synth->sfont; list; list = fluid_list_next (list)) {
sfont = fluid_list_get (list);
preset = fluid_sfont_get_preset (sfont,
banknum - sfont->bankofs, prognum);
preset = fluid_sfont_get_preset (sfont, banknum - sfont->bankofs, prognum);
if (preset)
{
sfont->refcount++; /* Add reference to SoundFont */
break;
return preset;
}
}
return preset;
return NULL;
}
/**
@ -2512,7 +2494,7 @@ fluid_synth_program_select(fluid_synth_t* synth, int chan, unsigned int sfont_id
FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
channel = synth->channel[chan];
/* ++ Allocate preset */
preset = fluid_synth_get_preset (synth, sfont_id, bank_num, preset_num);
if (preset == NULL) {
@ -2554,7 +2536,7 @@ fluid_synth_program_select_by_sfont_name (fluid_synth_t* synth, int chan,
FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
channel = synth->channel[chan];
/* ++ Allocate preset */
preset = fluid_synth_get_preset_by_sfont_name (synth, sfont_name, bank_num,
preset_num);
if (preset == NULL) {

View file

@ -7,6 +7,7 @@ include ( FluidUnitTest )
## add unit tests here ##
ADD_FLUID_TEST(test_sample_cache)
ADD_FLUID_TEST(test_sfont_loading)
ADD_FLUID_TEST(test_defsfont_preset_iteration)
add_custom_target(check
@ -14,4 +15,5 @@ COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIG> --output-on-failure
DEPENDS
test_sample_cache
test_sfont_loading
test_defsfont_preset_iteration
)

View file

@ -0,0 +1,41 @@
#include "test.h"
#include "fluidsynth.h"
#include "sfloader/fluid_sfont.h"
#include "utils/fluidsynth_priv.h"
int main(void)
{
int id;
fluid_sfont_t *sfont;
fluid_preset_t *preset;
fluid_preset_t *prev_preset = NULL;
int count = 0;
/* setup */
fluid_settings_t *settings = new_fluid_settings();
fluid_synth_t *synth = new_fluid_synth(settings);
/* Load the VintageDreams soundfont */
id = fluid_synth_sfload(synth, DEFAULT_SOUNDFONT, 1);
sfont = fluid_synth_get_sfont_by_id(synth, id);
/* code under test */
fluid_sfont_iteration_start(sfont);
while ((preset = fluid_sfont_iteration_next(sfont)) != NULL) {
count++;
/* make sure we actually got a different preset */
TEST_ASSERT(preset != prev_preset);
prev_preset = preset;
}
/* VintageDreams has 136 presets */
TEST_ASSERT(count == 136);
/* teardown */
delete_fluid_synth(synth);
delete_fluid_settings(settings);
return EXIT_SUCCESS;
}