mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-02-26 05:40:49 +00:00
Only import instruments once from Soundfont
This changes the way instruments and their related information is imported from a Soundfont. Previously, each preset zone got a complete copy of the instrument and related information, wasting a lot of precious memory. After this change, an instrument and related information is only imported once and then linked into all preset zones that use this instrument.
This commit is contained in:
parent
c4003bef39
commit
df3bab0b40
4 changed files with 58 additions and 16 deletions
|
@ -39,6 +39,8 @@ static int unload_preset_samples(fluid_defsfont_t *defsfont, fluid_preset_t *pre
|
|||
static void unload_sample(fluid_sample_t *sample);
|
||||
static int dynamic_samples_preset_notify(fluid_preset_t *preset, int reason, int chan);
|
||||
static int dynamic_samples_sample_notify(fluid_sample_t *sample, int reason);
|
||||
static int fluid_preset_zone_create_voice_zones(fluid_preset_zone_t* preset_zone);
|
||||
static fluid_inst_t *find_inst_by_idx(fluid_defsfont_t *defsfont, int idx);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
|
@ -248,6 +250,11 @@ int delete_fluid_defsfont(fluid_defsfont_t* defsfont)
|
|||
}
|
||||
delete_fluid_list(defsfont->preset);
|
||||
|
||||
for (list = defsfont->inst; list; list = fluid_list_next(list)) {
|
||||
delete_fluid_inst(fluid_list_get(list));
|
||||
}
|
||||
delete_fluid_list(defsfont->inst);
|
||||
|
||||
FLUID_FREE(defsfont);
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
@ -962,6 +969,7 @@ new_fluid_preset_zone(char *name)
|
|||
return NULL;
|
||||
}
|
||||
zone->next = NULL;
|
||||
zone->voice_zone = NULL;
|
||||
zone->name = FLUID_STRDUP(name);
|
||||
if (zone->name == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
|
@ -1009,7 +1017,6 @@ delete_fluid_preset_zone(fluid_preset_zone_t* zone)
|
|||
delete_fluid_list(zone->voice_zone);
|
||||
|
||||
FLUID_FREE (zone->name);
|
||||
delete_fluid_inst (zone->inst);
|
||||
FLUID_FREE(zone);
|
||||
}
|
||||
|
||||
|
@ -1067,6 +1074,7 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_
|
|||
{
|
||||
fluid_list_t *r;
|
||||
SFGen* sfgen;
|
||||
SFInst* sfinst;
|
||||
int count;
|
||||
for (count = 0, r = sfzone->gen; r != NULL; count++) {
|
||||
sfgen = (SFGen *)fluid_list_get(r);
|
||||
|
@ -1094,13 +1102,16 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_
|
|||
r = fluid_list_next(r);
|
||||
}
|
||||
if ((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL)) {
|
||||
zone->inst = (fluid_inst_t*) new_fluid_inst();
|
||||
if (zone->inst == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return FLUID_FAILED;
|
||||
sfinst = sfzone->instsamp->data;
|
||||
|
||||
zone->inst = find_inst_by_idx(defsfont, sfinst->idx);
|
||||
if (zone->inst == NULL)
|
||||
{
|
||||
zone->inst = fluid_inst_import_sfont(zone, sfinst, defsfont);
|
||||
}
|
||||
if (fluid_inst_import_sfont(zone, zone->inst,
|
||||
(SFInst *) sfzone->instsamp->data, defsfont) != FLUID_OK) {
|
||||
|
||||
if (zone->inst == NULL)
|
||||
{
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
|
@ -1310,16 +1321,24 @@ fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone)
|
|||
/*
|
||||
* fluid_inst_import_sfont
|
||||
*/
|
||||
int
|
||||
fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_t* inst,
|
||||
SFInst *sfinst, fluid_defsfont_t* defsfont)
|
||||
fluid_inst_t *
|
||||
fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, SFInst *sfinst, fluid_defsfont_t* defsfont)
|
||||
{
|
||||
fluid_list_t *p;
|
||||
fluid_inst_t *inst;
|
||||
SFZone* sfzone;
|
||||
fluid_inst_zone_t* inst_zone;
|
||||
char zone_name[256];
|
||||
int count;
|
||||
|
||||
inst = (fluid_inst_t*) new_fluid_inst();
|
||||
if (inst == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inst->source_idx = sfinst->idx;
|
||||
|
||||
p = sfinst->zone;
|
||||
if (FLUID_STRLEN(sfinst->name) > 0) {
|
||||
FLUID_STRCPY(inst->name, sfinst->name);
|
||||
|
@ -1335,25 +1354,27 @@ fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_t* inst,
|
|||
|
||||
inst_zone = new_fluid_inst_zone(zone_name);
|
||||
if (inst_zone == NULL) {
|
||||
return FLUID_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fluid_inst_zone_import_sfont(inst_zone, sfzone, defsfont) != FLUID_OK) {
|
||||
delete_fluid_inst_zone(inst_zone);
|
||||
return FLUID_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((count == 0) && (fluid_inst_zone_get_sample(inst_zone) == NULL)) {
|
||||
fluid_inst_set_global_zone(inst, inst_zone);
|
||||
|
||||
} else if (fluid_inst_add_zone(inst, inst_zone) != FLUID_OK) {
|
||||
return FLUID_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = fluid_list_next(p);
|
||||
count++;
|
||||
}
|
||||
return FLUID_OK;
|
||||
|
||||
defsfont->inst = fluid_list_append(defsfont->inst, inst);
|
||||
return inst;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1875,3 +1896,21 @@ static void unload_sample(fluid_sample_t *sample)
|
|||
sample->data24 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static fluid_inst_t *find_inst_by_idx(fluid_defsfont_t *defsfont, int idx)
|
||||
{
|
||||
fluid_list_t *list;
|
||||
fluid_inst_t *inst;
|
||||
|
||||
for (list = defsfont->inst; list != NULL; list = fluid_list_next(list))
|
||||
{
|
||||
inst = fluid_list_get(list);
|
||||
|
||||
if (inst->source_idx == idx)
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ struct _fluid_defsfont_t
|
|||
fluid_sfont_t *sfont; /* pointer to parent sfont */
|
||||
fluid_list_t* sample; /* the samples in this soundfont */
|
||||
fluid_list_t* preset; /* the presets of this soundfont */
|
||||
fluid_list_t* inst; /* the instruments of this soundfont */
|
||||
int mlock; /* Should we try memlock (avoid swapping)? */
|
||||
int dynamic_samples; /* Enables dynamic sample loading if set */
|
||||
|
||||
|
@ -189,13 +190,13 @@ fluid_inst_t* fluid_preset_zone_get_inst(fluid_preset_zone_t* zone);
|
|||
struct _fluid_inst_t
|
||||
{
|
||||
char name[21];
|
||||
int source_idx; /* Index of instrument in source Soundfont */
|
||||
fluid_inst_zone_t* global_zone;
|
||||
fluid_inst_zone_t* zone;
|
||||
};
|
||||
|
||||
fluid_inst_t* new_fluid_inst(void);
|
||||
int fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_t* inst,
|
||||
SFInst *sfinst, fluid_defsfont_t* defsfont);
|
||||
fluid_inst_t* fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, SFInst *sfinst, fluid_defsfont_t* defsfont);
|
||||
void delete_fluid_inst(fluid_inst_t* inst);
|
||||
int fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone);
|
||||
int fluid_inst_add_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone);
|
||||
|
|
|
@ -1281,6 +1281,7 @@ static int load_ihdr(SFData *sf, int size)
|
|||
p = FLUID_NEW(SFInst);
|
||||
sf->inst = fluid_list_append(sf->inst, p);
|
||||
p->zone = NULL; /* For proper cleanup if fail (fluid_sffile_close) */
|
||||
p->idx = i;
|
||||
READSTR(sf, &p->name); /* Possible read failure ^ */
|
||||
READW(sf, zndx);
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ struct _SFSample
|
|||
struct _SFInst
|
||||
{ /* Instrument structure */
|
||||
char name[21]; /* Name of instrument */
|
||||
int idx; /* Index of this instrument in the Soundfont */
|
||||
fluid_list_t *zone; /* list of instrument zones */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue