Refactor fluid_preset_t handling in defsfont and ramsfont

Removes the need for a pre-allocated stack of fluid_preset_t's. Upon
adding a loader specific preset, a fluid_preset_t is automatically
created. defsfont and ramsfont now keep track of the fluid_preset_t's,
not the loader specific ones.

Also changes the sfont::iteration_next signature to directly return
the next preset. This is possible as presets are now only created once
and returned as a pointer.
This commit is contained in:
Marcus Weseloh 2018-04-07 22:25:01 +02:00
parent 189433a757
commit 66610abcb9
8 changed files with 193 additions and 241 deletions

View file

@ -1123,18 +1123,18 @@ fluidmax_print(t_object *o, Symbol *s, short ac, Atom *at)
if(sf != NULL) if(sf != NULL)
{ {
fluid_preset_t preset; fluid_preset_t *preset;
fluid_sfont_iteration_start(sf); fluid_sfont_iteration_start(sf);
post("fluidsynth~ presets of soundfont '%s':", ftmax_symbol_name(name)); 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); ftmax_symbol_t preset_name = ftmax_new_symbol(preset_str);
int bank_num = fluid_preset_get_banknum(&preset); int bank_num = fluid_preset_get_banknum(preset);
int prog_num = fluid_preset_get_num(&preset); int prog_num = fluid_preset_get_num(preset);
post(" '%s': bank %d, program %d", ftmax_symbol_name(preset_name), bank_num, prog_num); 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) if(sf != NULL)
{ {
fluid_preset_t preset; fluid_preset_t *preset;
fluid_sfont_iteration_start(sf); 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); ftmax_symbol_t preset_name = ftmax_new_symbol(preset_str);
int bank_num = fluid_preset_get_banknum(&preset); int bank_num = fluid_preset_get_banknum(preset);
int prog_num = fluid_preset_get_num(&preset); int prog_num = fluid_preset_get_num(preset);
ftmax_atom_t a[4]; ftmax_atom_t a[4];
ftmax_set_symbol(a , preset_name); 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); FLUID_ENTRY_COMMAND(data);
int font; int font;
fluid_sfont_t* sfont; fluid_sfont_t* sfont;
fluid_preset_t preset; fluid_preset_t* preset;
int offset; int offset;
if (ac < 1) { 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); 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_ostream_printf(out, "%03d-%03d %s\n",
fluid_preset_get_banknum(&preset) + offset, fluid_preset_get_banknum(preset) + offset,
fluid_preset_get_num(&preset), fluid_preset_get_num(preset),
fluid_preset_get_name(&preset)); fluid_preset_get_name(preset));
} }
return FLUID_OK; return FLUID_OK;

View file

@ -76,11 +76,6 @@ fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* file
return NULL; 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, sfont = new_fluid_sfont(fluid_defsfont_sfont_get_name,
fluid_defsfont_sfont_get_preset, fluid_defsfont_sfont_get_preset,
fluid_defsfont_sfont_delete); fluid_defsfont_sfont_delete);
@ -89,6 +84,13 @@ fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* file
return NULL; 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_start(sfont, fluid_defsfont_sfont_iteration_start);
fluid_sfont_set_iteration_next(sfont, fluid_defsfont_sfont_iteration_next); fluid_sfont_set_iteration_next(sfont, fluid_defsfont_sfont_iteration_next);
fluid_sfont_set_data(sfont, defsfont); 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_preset_t*
fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum) fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum)
{ {
fluid_preset_t* preset = NULL; return fluid_defsfont_get_preset(fluid_sfont_get_data(sfont), bank, prenum);
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;
} }
void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont) void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont)
@ -158,28 +130,25 @@ void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont)
fluid_defsfont_iteration_start(fluid_sfont_get_data(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; return fluid_defsfont_iteration_next(fluid_sfont_get_data(sfont));
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);
} }
void fluid_defpreset_preset_delete(fluid_preset_t* preset) void fluid_defpreset_preset_delete(fluid_preset_t* preset)
{ {
fluid_defpreset_t* defpreset = fluid_preset_get_data(preset); fluid_defsfont_t* defsfont;
fluid_defsfont_t* defsfont = defpreset ? defpreset->defsfont : NULL; fluid_defpreset_t* defpreset;
if (defsfont && defsfont->preset_stack_size < defsfont->preset_stack_capacity) { defsfont = fluid_sfont_get_data(preset->sfont);
defsfont->preset_stack[defsfont->preset_stack_size] = preset; defpreset = fluid_preset_get_data(preset);
defsfont->preset_stack_size++;
if (defsfont)
{
defsfont->preset = fluid_list_remove(defsfont->preset, defpreset);
} }
else
delete_fluid_defpreset(defpreset);
delete_fluid_preset(preset); delete_fluid_preset(preset);
} }
@ -260,7 +229,7 @@ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings)
int delete_fluid_defsfont(fluid_defsfont_t* defsfont) int delete_fluid_defsfont(fluid_defsfont_t* defsfont)
{ {
fluid_list_t *list; fluid_list_t *list;
fluid_defpreset_t* defpreset; fluid_preset_t* preset;
fluid_sample_t* sample; fluid_sample_t* sample;
fluid_return_val_if_fail(defsfont != NULL, FLUID_OK); fluid_return_val_if_fail(defsfont != NULL, FLUID_OK);
@ -293,12 +262,11 @@ int delete_fluid_defsfont(fluid_defsfont_t* defsfont)
FLUID_FREE(defsfont->preset_stack[--defsfont->preset_stack_size]); FLUID_FREE(defsfont->preset_stack[--defsfont->preset_stack_size]);
FLUID_FREE(defsfont->preset_stack); FLUID_FREE(defsfont->preset_stack);
defpreset = defsfont->preset; for (list = defsfont->preset; list; list = fluid_list_next(list)) {
while (defpreset != NULL) { preset = (fluid_preset_t *)fluid_list_get(list);
defsfont->preset = defpreset->next; fluid_defpreset_preset_delete(preset);
delete_fluid_defpreset(defpreset);
defpreset = defsfont->preset;
} }
delete_fluid_list(defsfont->preset);
FLUID_FREE(defsfont); FLUID_FREE(defsfont);
return FLUID_OK; return FLUID_OK;
@ -385,7 +353,10 @@ int fluid_defsfont_load(fluid_defsfont_t* defsfont, const fluid_file_callbacks_t
if (fluid_defpreset_import_sfont(defpreset, sfpreset, defsfont) != FLUID_OK) if (fluid_defpreset_import_sfont(defpreset, sfpreset, defsfont) != FLUID_OK)
goto err_exit; 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); p = fluid_list_next(p);
} }
fluid_sffile_close (sfdata); fluid_sffile_close (sfdata);
@ -414,32 +385,23 @@ 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) int fluid_defsfont_add_preset(fluid_defsfont_t* defsfont, fluid_defpreset_t* defpreset)
{ {
fluid_defpreset_t *cur, *prev; fluid_preset_t *preset;
if (defsfont->preset == NULL) {
defpreset->next = NULL; preset = new_fluid_preset(defsfont->sfont,
defsfont->preset = defpreset; fluid_defpreset_preset_get_name,
} else { fluid_defpreset_preset_get_banknum,
/* sort them as we go along. very basic sorting trick. */ fluid_defpreset_preset_get_num,
cur = defsfont->preset; fluid_defpreset_preset_noteon,
prev = NULL; fluid_defpreset_preset_delete);
while (cur != NULL) {
if ((defpreset->bank < cur->bank) if (preset == NULL) {
|| ((defpreset->bank == cur->bank) && (defpreset->num < cur->num))) { return FLUID_FAILED;
if (prev == NULL) {
defpreset->next = cur;
defsfont->preset = defpreset;
} else {
defpreset->next = cur;
prev->next = defpreset;
}
return FLUID_OK;
}
prev = cur;
cur = cur->next;
}
defpreset->next = NULL;
prev->next = defpreset;
} }
fluid_preset_set_data(preset, defpreset);
defsfont->preset = fluid_list_append(defsfont->preset, preset);
return FLUID_OK; return FLUID_OK;
} }
@ -469,15 +431,21 @@ fluid_defsfont_load_sampledata(fluid_defsfont_t* defsfont, const fluid_file_call
/* /*
* fluid_defsfont_get_preset * 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; fluid_preset_t *preset;
while (defpreset != NULL) { fluid_list_t *list;
if ((defpreset->bank == bank) && ((defpreset->num == num))) {
return defpreset; 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 +454,19 @@ fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, unsigne
*/ */
void fluid_defsfont_iteration_start(fluid_defsfont_t* defsfont) void fluid_defsfont_iteration_start(fluid_defsfont_t* defsfont)
{ {
defsfont->iter_cur = defsfont->preset; defsfont->preset_iter_cur = defsfont->preset;
} }
/* /*
* fluid_defsfont_iteration_next * 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) { fluid_preset_t *preset = (fluid_preset_t *)fluid_list_get(defsfont->preset_iter_cur);
return 0;
}
preset->data = (void*) defsfont->iter_cur; defsfont->preset_iter_cur = fluid_list_next(defsfont->preset_iter_cur);
defsfont->iter_cur = fluid_defpreset_next(defsfont->iter_cur);
return 1; 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); 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* 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); 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); void fluid_defpreset_preset_delete(fluid_preset_t* preset);
@ -103,11 +103,12 @@ struct _fluid_defsfont_t
unsigned int sample24size; /* length within sffd of the sm24 chunk */ 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 */ 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_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)? */ int mlock; /* Should we try memlock (avoid swapping)? */
fluid_defpreset_t* iter_cur; /* the current preset in the iteration */ fluid_list_t *preset_iter_cur; /* the current preset in the iteration */
fluid_preset_t** preset_stack; /* List of presets that are available to use */ 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_capacity; /* Length of preset_stack array */
@ -119,9 +120,9 @@ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings);
int delete_fluid_defsfont(fluid_defsfont_t* defsfont); 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); 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); 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); 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_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_sample(fluid_defsfont_t* defsfont, fluid_sample_t* sample);
int fluid_defsfont_add_preset(fluid_defsfont_t* defsfont, fluid_defpreset_t* defpreset); 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 bank,
unsigned int prenum); unsigned int prenum);
static void fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont); static void fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont);
static int fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont, static fluid_preset_t *fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont);
fluid_preset_t* preset); static void fluid_rampreset_preset_delete(fluid_preset_t* preset);
static const char *fluid_rampreset_preset_get_name(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_banknum(fluid_preset_t* preset);
static int fluid_rampreset_preset_get_num(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 int delete_fluid_ramsfont (fluid_ramsfont_t* sfont);
static const char *fluid_ramsfont_get_name(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, static int fluid_ramsfont_add_preset (fluid_ramsfont_t* sfont,
fluid_rampreset_t* preset); fluid_rampreset_t* rampreset);
static fluid_rampreset_t *fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont, static fluid_preset_t *fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num); unsigned int bank, unsigned int num);
static void fluid_ramsfont_iteration_start (fluid_ramsfont_t* sfont); static void fluid_ramsfont_iteration_start (fluid_ramsfont_t* sfont);
static int fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont, static fluid_preset_t *fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont);
fluid_preset_t* preset);
static fluid_rampreset_t* new_fluid_rampreset(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 void delete_fluid_rampreset (fluid_rampreset_t* preset);
static int fluid_rampreset_get_banknum (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 int fluid_rampreset_get_num (fluid_rampreset_t* preset);
static const char *fluid_rampreset_get_name (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, static int fluid_rampreset_add_zone(fluid_rampreset_t* preset,
fluid_preset_zone_t* zone); fluid_preset_zone_t* zone);
static int fluid_rampreset_add_sample (fluid_rampreset_t* preset, static int fluid_rampreset_add_sample (fluid_rampreset_t* preset,
@ -100,6 +98,8 @@ fluid_ramsfont_create_sfont()
return NULL; return NULL;
} }
ramsfont->sfont = sfont;
fluid_sfont_set_iteration_start(sfont, fluid_ramsfont_sfont_iteration_start); 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_iteration_next(sfont, fluid_ramsfont_sfont_iteration_next);
fluid_sfont_set_data(sfont, ramsfont); fluid_sfont_set_data(sfont, ramsfont);
@ -128,27 +128,7 @@ fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont)
static fluid_preset_t * static fluid_preset_t *
fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum) fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum)
{ {
fluid_preset_t* preset; return fluid_ramsfont_get_preset((fluid_ramsfont_t*) sfont->data, bank, prenum);
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;
} }
/* RAM SoundFont loader method to start preset iteration */ /* 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 */ /* RAM SoundFont loader method to advance preset iteration */
static int static fluid_preset_t*
fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset) fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont)
{ {
preset->free = delete_fluid_preset; return fluid_ramsfont_iteration_next((fluid_ramsfont_t*) sfont->data);
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, 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 */ /* RAM SoundFont loader get preset name method */
@ -230,7 +220,7 @@ static int
delete_fluid_ramsfont (fluid_ramsfont_t* sfont) delete_fluid_ramsfont (fluid_ramsfont_t* sfont)
{ {
fluid_list_t *list; fluid_list_t *list;
fluid_rampreset_t* preset; fluid_preset_t* preset;
fluid_return_val_if_fail(sfont != NULL, FLUID_OK); fluid_return_val_if_fail(sfont != NULL, FLUID_OK);
/* Check that no samples are currently used */ /* Check that no samples are currently used */
@ -251,12 +241,11 @@ delete_fluid_ramsfont (fluid_ramsfont_t* sfont)
delete_fluid_list(sfont->sample); delete_fluid_list(sfont->sample);
} }
preset = sfont->preset; for (list = sfont->preset; list; list = fluid_list_next(list)) {
while (preset != NULL) { preset = (fluid_preset_t *)fluid_list_get(list);
sfont->preset = preset->next; fluid_rampreset_preset_delete(preset);
delete_fluid_rampreset(preset);
preset = sfont->preset;
} }
delete_fluid_list(sfont->preset);
FLUID_FREE(sfont); FLUID_FREE(sfont);
return FLUID_OK; 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 */ /* Add a preset to a RAM SoundFont */
static int 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; fluid_preset_t *preset;
if (sfont->preset == NULL) {
preset->next = NULL; preset = new_fluid_preset(sfont->sfont,
sfont->preset = preset; fluid_rampreset_preset_get_name,
} else { fluid_rampreset_preset_get_banknum,
/* sort them as we go along. very basic sorting trick. */ fluid_rampreset_preset_get_num,
cur = sfont->preset; fluid_rampreset_preset_noteon,
prev = NULL; fluid_rampreset_preset_delete); /* TODO: free modulators */
while (cur != NULL) { if (preset == NULL) {
if ((preset->bank < cur->bank) return FLUID_FAILED;
|| ((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_set_data(preset, rampreset);
sfont->preset = fluid_list_append(sfont->preset, preset);
return FLUID_OK; return FLUID_OK;
} }
@ -337,30 +315,34 @@ fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont, unsigned int bank,
*/ */
int err; 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) { if (preset == NULL) {
// Create it // Create it
preset = new_fluid_rampreset(sfont); rampreset = new_fluid_rampreset(sfont);
if (preset == NULL) { if (rampreset == NULL) {
return FLUID_FAILED; return FLUID_FAILED;
} }
preset->bank = bank; rampreset->bank = bank;
preset->num = num; rampreset->num = num;
err = fluid_rampreset_add_sample(preset, sample, lokey, hikey);
if (err != FLUID_OK) {
delete_fluid_rampreset(preset);
return FLUID_FAILED;
}
// sort the preset // 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 { } else {
// just add it // 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) { if (err != FLUID_OK) {
return FLUID_FAILED; 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) unsigned int num, fluid_sample_t* sample)
{ {
int err; 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) { if (preset == NULL) {
return FLUID_FAILED; return FLUID_FAILED;
} }
rampreset = fluid_preset_get_data(preset);
// Fixed a crash bug : remove the sample from the sfont list after // Fixed a crash bug : remove the sample from the sfont list after
// removing the izone (aschmitt august 2005) // removing the izone (aschmitt august 2005)
err = fluid_rampreset_remove_izone(preset, sample); err = fluid_rampreset_remove_izone(rampreset, sample);
if (err != FLUID_OK) if (err != FLUID_OK)
return err; 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, unsigned int num, fluid_sample_t* sample,
int gen_type, float value) 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) { if (preset == NULL) {
return FLUID_FAILED; 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,25 +429,34 @@ fluid_ramsfont_izone_set_loop (fluid_ramsfont_t *sfont, unsigned int bank,
unsigned int num, fluid_sample_t* sample, unsigned int num, fluid_sample_t* sample,
int on, float loopstart, float loopend) 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) { if (preset == NULL) {
return FLUID_FAILED; 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 */ /* 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_ramsfont_get_preset (fluid_ramsfont_t* sfont, unsigned int bank, unsigned int num)
{ {
fluid_rampreset_t* preset = sfont->preset; fluid_preset_t *preset;
while (preset != NULL) { fluid_list_t *list;
if ((preset->bank == bank) && ((preset->num == num))) {
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; return preset;
} }
preset = preset->next;
} }
return NULL; return NULL;
} }
@ -467,20 +464,18 @@ fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont, unsigned int bank, unsigned
static void static void
fluid_ramsfont_iteration_start (fluid_ramsfont_t* sfont) 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 */ /* Advance preset iteration in a RAM SoundFont */
static int static fluid_preset_t *
fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont, fluid_preset_t* preset) fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont)
{ {
if (sfont->iter_cur == NULL) { fluid_preset_t *preset = (fluid_preset_t *)fluid_list_get(sfont->preset_iter_cur);
return 0;
}
preset->data = (void*) sfont->iter_cur; sfont->preset_iter_cur = fluid_list_next(sfont->preset_iter_cur);
sfont->iter_cur = fluid_rampreset_next(sfont->iter_cur);
return 1; return preset;
} }
/*************************************************************** /***************************************************************
@ -570,13 +565,6 @@ fluid_rampreset_get_name (fluid_rampreset_t* preset)
return preset->name; 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 */ /* Add a zone to a RAM SoundFont preset */
static int static int

View file

@ -41,11 +41,11 @@ extern "C" {
struct _fluid_ramsfont_t struct _fluid_ramsfont_t
{ {
char name[21]; /* the name of the soundfont */ char name[21]; /* the name of the soundfont */
fluid_sfont_t* sfont; /* parent sfont */
fluid_list_t* sample; /* the samples in this soundfont */ 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_list_t* preset_iter_cur; /* the current preset in the iteration */
fluid_rampreset_t* 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_name(_sf) (*(_sf)->get_name)(_sf)
#define fluid_sfont_get_preset(_sf,_bank,_prenum) (*(_sf)->get_preset)(_sf,_bank,_prenum) #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_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) \ #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 * and advance the internal iteration state to the next preset for subsequent
* calls. * 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_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); 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_return_if_fail(chan != NULL);
fluid_preset_delete_internal (chan->preset);
FLUID_FREE(chan); FLUID_FREE(chan);
} }
@ -220,13 +219,11 @@ fluid_channel_reset(fluid_channel_t* chan)
int int
fluid_channel_set_preset(fluid_channel_t* chan, fluid_preset_t* preset) fluid_channel_set_preset(fluid_channel_t* chan, fluid_preset_t* preset)
{ {
fluid_preset_notify (chan->preset, FLUID_PRESET_UNSELECTED, chan->channum); fluid_preset_notify (chan->preset, FLUID_PRESET_UNSELECTED, chan->channum);
if (chan->preset) { if (chan->preset) {
fluid_sfont_t *sfont; fluid_sfont_t *sfont;
sfont = chan->preset->sfont; sfont = chan->preset->sfont;
fluid_preset_delete_internal (chan->preset);
fluid_synth_sfont_unref (chan->synth, sfont); /* -- unref preset's SoundFont */ fluid_synth_sfont_unref (chan->synth, sfont); /* -- unref preset's SoundFont */
} }