mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 15:01:40 +00:00
Remove instsamp hack
This change removes the need for the instsamp hack in instrument and preset zones. The sampleid and instrument generators are treated as any other generator and simply passed to the defsfont import functions. Those read the two generators and use the index to look up valid samples and instruments. Both generators are then reset to GEN_UNUSED again, just to make sure that the rest of FluidSynth doesn't get confused. But that might not be necessary.
This commit is contained in:
parent
6ca9b21740
commit
dfbef11da0
4 changed files with 87 additions and 140 deletions
|
@ -533,7 +533,7 @@ int fluid_defsfont_load(fluid_defsfont_t *defsfont, const fluid_file_callbacks_t
|
|||
goto err_exit;
|
||||
}
|
||||
|
||||
if(fluid_defpreset_import_sfont(defpreset, sfpreset, defsfont) != FLUID_OK)
|
||||
if(fluid_defpreset_import_sfont(defpreset, sfpreset, defsfont, sfdata) != FLUID_OK)
|
||||
{
|
||||
goto err_exit;
|
||||
}
|
||||
|
@ -1028,7 +1028,8 @@ fluid_defpreset_set_global_zone(fluid_defpreset_t *defpreset, fluid_preset_zone_
|
|||
int
|
||||
fluid_defpreset_import_sfont(fluid_defpreset_t *defpreset,
|
||||
SFPreset *sfpreset,
|
||||
fluid_defsfont_t *defsfont)
|
||||
fluid_defsfont_t *defsfont,
|
||||
SFData *sfdata)
|
||||
{
|
||||
fluid_list_t *p;
|
||||
SFZone *sfzone;
|
||||
|
@ -1061,7 +1062,7 @@ fluid_defpreset_import_sfont(fluid_defpreset_t *defpreset,
|
|||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if(fluid_preset_zone_import_sfont(zone, sfzone, defsfont) != FLUID_OK)
|
||||
if(fluid_preset_zone_import_sfont(zone, sfzone, defsfont, sfdata) != FLUID_OK)
|
||||
{
|
||||
delete_fluid_preset_zone(zone);
|
||||
return FLUID_FAILED;
|
||||
|
@ -1424,8 +1425,13 @@ fluid_zone_gen_import_sfont(fluid_gen_t *gen, fluid_zone_range_t *range, SFZone
|
|||
gen[sfgen->id].flags = GEN_SET;
|
||||
break;
|
||||
|
||||
case GEN_INSTRUMENT:
|
||||
case GEN_SAMPLEID:
|
||||
gen[sfgen->id].val = (fluid_real_t) sfgen->amount.uword;
|
||||
gen[sfgen->id].flags = GEN_SET;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* FIXME: some generators have an unsigne word amount value but i don't know which ones */
|
||||
gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword;
|
||||
gen[sfgen->id].flags = GEN_SET;
|
||||
break;
|
||||
|
@ -1630,24 +1636,27 @@ fluid_zone_mod_import_sfont(char *zone_name, fluid_mod_t **mod, SFZone *sfzone)
|
|||
* fluid_preset_zone_import_sfont
|
||||
*/
|
||||
int
|
||||
fluid_preset_zone_import_sfont(fluid_preset_zone_t *zone, SFZone *sfzone, fluid_defsfont_t *defsfont)
|
||||
fluid_preset_zone_import_sfont(fluid_preset_zone_t *zone, SFZone *sfzone, fluid_defsfont_t *defsfont, SFData *sfdata)
|
||||
{
|
||||
/* import the generators */
|
||||
fluid_zone_gen_import_sfont(zone->gen, &zone->range, sfzone);
|
||||
|
||||
if((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL))
|
||||
if(zone->gen[GEN_INSTRUMENT].flags == GEN_SET)
|
||||
{
|
||||
SFInst *sfinst = sfzone->instsamp->data;
|
||||
int inst_idx = (int) zone->gen[GEN_INSTRUMENT].val;
|
||||
|
||||
zone->inst = find_inst_by_idx(defsfont, sfinst->idx);
|
||||
zone->inst = find_inst_by_idx(defsfont, inst_idx);
|
||||
|
||||
if(zone->inst == NULL)
|
||||
{
|
||||
zone->inst = fluid_inst_import_sfont(sfinst, defsfont);
|
||||
zone->inst = fluid_inst_import_sfont(inst_idx, defsfont, sfdata);
|
||||
}
|
||||
|
||||
if(zone->inst == NULL)
|
||||
{
|
||||
|
||||
FLUID_LOG(FLUID_ERR, "Preset zone %s: Invalid instrument reference",
|
||||
zone->name);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
|
@ -1655,6 +1664,9 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t *zone, SFZone *sfzone, fluid_
|
|||
{
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
/* We don't need this generator anymore */
|
||||
zone->gen[GEN_INSTRUMENT].flags = GEN_UNUSED;
|
||||
}
|
||||
|
||||
/* Import the modulators (only SF2.1 and higher) */
|
||||
|
@ -1735,15 +1747,30 @@ fluid_inst_set_global_zone(fluid_inst_t *inst, fluid_inst_zone_t *zone)
|
|||
* fluid_inst_import_sfont
|
||||
*/
|
||||
fluid_inst_t *
|
||||
fluid_inst_import_sfont(SFInst *sfinst, fluid_defsfont_t *defsfont)
|
||||
fluid_inst_import_sfont(int inst_idx, fluid_defsfont_t *defsfont, SFData *sfdata)
|
||||
{
|
||||
fluid_list_t *p;
|
||||
fluid_list_t *inst_list;
|
||||
fluid_inst_t *inst;
|
||||
SFZone *sfzone;
|
||||
SFInst *sfinst;
|
||||
fluid_inst_zone_t *inst_zone;
|
||||
char zone_name[256];
|
||||
int count;
|
||||
|
||||
for (inst_list = sfdata->inst; inst_list; inst_list = fluid_list_next(inst_list))
|
||||
{
|
||||
sfinst = fluid_list_get(inst_list);
|
||||
if (sfinst->idx == inst_idx)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (inst_list == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inst = (fluid_inst_t *) new_fluid_inst();
|
||||
|
||||
if(inst == NULL)
|
||||
|
@ -1781,7 +1808,7 @@ fluid_inst_import_sfont(SFInst *sfinst, fluid_defsfont_t *defsfont)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if(fluid_inst_zone_import_sfont(inst_zone, sfzone, defsfont) != FLUID_OK)
|
||||
if(fluid_inst_zone_import_sfont(inst_zone, sfzone, defsfont, sfdata) != FLUID_OK)
|
||||
{
|
||||
delete_fluid_inst_zone(inst_zone);
|
||||
return NULL;
|
||||
|
@ -1913,7 +1940,8 @@ fluid_inst_zone_next(fluid_inst_zone_t *zone)
|
|||
* fluid_inst_zone_import_sfont
|
||||
*/
|
||||
int
|
||||
fluid_inst_zone_import_sfont(fluid_inst_zone_t *inst_zone, SFZone *sfzone, fluid_defsfont_t *defsfont)
|
||||
fluid_inst_zone_import_sfont(fluid_inst_zone_t *inst_zone, SFZone *sfzone, fluid_defsfont_t *defsfont,
|
||||
SFData *sfdata)
|
||||
{
|
||||
/* import the generators */
|
||||
fluid_zone_gen_import_sfont(inst_zone->gen, &inst_zone->range, sfzone);
|
||||
|
@ -1923,10 +1951,32 @@ fluid_inst_zone_import_sfont(fluid_inst_zone_t *inst_zone, SFZone *sfzone, fluid
|
|||
/* FLUID_LOG(FLUID_DBG, "ExclusiveClass=%d\n", (int) zone->gen[GEN_EXCLUSIVECLASS].val); */
|
||||
/* } */
|
||||
|
||||
/* fixup sample pointer */
|
||||
if((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL))
|
||||
if (inst_zone->gen[GEN_SAMPLEID].flags == GEN_SET)
|
||||
{
|
||||
inst_zone->sample = ((SFSample *)(sfzone->instsamp->data))->fluid_sample;
|
||||
fluid_list_t *list;
|
||||
SFSample *sfsample;
|
||||
int sample_idx = (int) inst_zone->gen[GEN_SAMPLEID].val;
|
||||
|
||||
/* find the SFSample by index */
|
||||
for(list = sfdata->sample; list; list = fluid_list_next(list))
|
||||
{
|
||||
sfsample = fluid_list_get(list);
|
||||
if (sfsample->idx == sample_idx)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (list == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Instrument zone '%s': Invalid sample reference",
|
||||
inst_zone->name);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
inst_zone->sample = sfsample->fluid_sample;
|
||||
|
||||
/* we don't need this generator anymore, mark it as unused */
|
||||
inst_zone->gen[GEN_SAMPLEID].flags = GEN_UNUSED;
|
||||
}
|
||||
|
||||
/* Import the modulators (only SF2.1 and higher) */
|
||||
|
|
|
@ -154,7 +154,7 @@ struct _fluid_defpreset_t
|
|||
fluid_defpreset_t *new_fluid_defpreset(void);
|
||||
void delete_fluid_defpreset(fluid_defpreset_t *defpreset);
|
||||
fluid_defpreset_t *fluid_defpreset_next(fluid_defpreset_t *defpreset);
|
||||
int fluid_defpreset_import_sfont(fluid_defpreset_t *defpreset, SFPreset *sfpreset, fluid_defsfont_t *defsfont);
|
||||
int fluid_defpreset_import_sfont(fluid_defpreset_t *defpreset, SFPreset *sfpreset, fluid_defsfont_t *defsfont, SFData *sfdata);
|
||||
int fluid_defpreset_set_global_zone(fluid_defpreset_t *defpreset, fluid_preset_zone_t *zone);
|
||||
int fluid_defpreset_add_zone(fluid_defpreset_t *defpreset, fluid_preset_zone_t *zone);
|
||||
fluid_preset_zone_t *fluid_defpreset_get_zone(fluid_defpreset_t *defpreset);
|
||||
|
@ -182,7 +182,7 @@ fluid_preset_zone_t *new_fluid_preset_zone(char *name);
|
|||
void delete_fluid_list_mod(fluid_mod_t *mod);
|
||||
void delete_fluid_preset_zone(fluid_preset_zone_t *zone);
|
||||
fluid_preset_zone_t *fluid_preset_zone_next(fluid_preset_zone_t *zone);
|
||||
int fluid_preset_zone_import_sfont(fluid_preset_zone_t *zone, SFZone *sfzone, fluid_defsfont_t *defssfont);
|
||||
int fluid_preset_zone_import_sfont(fluid_preset_zone_t *zone, SFZone *sfzone, fluid_defsfont_t *defssfont, SFData *sfdata);
|
||||
fluid_inst_t *fluid_preset_zone_get_inst(fluid_preset_zone_t *zone);
|
||||
|
||||
/*
|
||||
|
@ -197,7 +197,7 @@ struct _fluid_inst_t
|
|||
};
|
||||
|
||||
fluid_inst_t *new_fluid_inst(void);
|
||||
fluid_inst_t *fluid_inst_import_sfont(SFInst *sfinst, fluid_defsfont_t *defsfont);
|
||||
fluid_inst_t *fluid_inst_import_sfont(int inst_idx, fluid_defsfont_t *defsfont, SFData *sfdata);
|
||||
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);
|
||||
|
@ -221,7 +221,7 @@ struct _fluid_inst_zone_t
|
|||
fluid_inst_zone_t *new_fluid_inst_zone(char *name);
|
||||
void delete_fluid_inst_zone(fluid_inst_zone_t *zone);
|
||||
fluid_inst_zone_t *fluid_inst_zone_next(fluid_inst_zone_t *zone);
|
||||
int fluid_inst_zone_import_sfont(fluid_inst_zone_t *inst_zone, SFZone *sfzone, fluid_defsfont_t *defsfont);
|
||||
int fluid_inst_zone_import_sfont(fluid_inst_zone_t *inst_zone, SFZone *sfzone, fluid_defsfont_t *defsfont, SFData *sfdata);
|
||||
fluid_sample_t *fluid_inst_zone_get_sample(fluid_inst_zone_t *zone);
|
||||
|
||||
|
||||
|
|
|
@ -239,8 +239,6 @@ static int load_ibag(SFData *sf, int size);
|
|||
static int load_imod(SFData *sf, int size);
|
||||
static int load_igen(SFData *sf, int size);
|
||||
static int load_shdr(SFData *sf, unsigned int size);
|
||||
static int fixup_pgen(SFData *sf);
|
||||
static int fixup_igen(SFData *sf);
|
||||
|
||||
static int chunkid(uint32_t id);
|
||||
static int read_listchunk(SFData *sf, SFChunk *chunk);
|
||||
|
@ -629,16 +627,6 @@ static int load_body(SFData *sf)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if(!fixup_pgen(sf))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!fixup_igen(sf))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* sort preset list by bank, preset # */
|
||||
sf->preset = fluid_list_sort(sf->preset, (fluid_compare_func_t)preset_compare_func);
|
||||
|
||||
|
@ -1116,7 +1104,6 @@ static int load_pbag(SFData *sf, int size)
|
|||
z->mod = NULL; /* to ensure proper cleanup (fluid_sffile_close) */
|
||||
READW(sf, genndx); /* possible read failure ^ */
|
||||
READW(sf, modndx);
|
||||
z->instsamp = NULL;
|
||||
|
||||
if(pz)
|
||||
{
|
||||
|
@ -1378,8 +1365,6 @@ static int load_pgen(SFData *sf, int size)
|
|||
/* inst is last gen */
|
||||
level = 3;
|
||||
READW(sf, genval.uword);
|
||||
((SFZone *)(zone_list->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1);
|
||||
break; /* break out of generator loop */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1436,13 +1421,18 @@ static int load_pgen(SFData *sf, int size)
|
|||
SLADVREM(z->gen, gen_list); /* drop place holder */
|
||||
}
|
||||
|
||||
/* Level 3 means we found an instrument generator, which
|
||||
* should be the last generator in the list. */
|
||||
if (level == 3)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
} /* generator loop */
|
||||
|
||||
if(level == 3)
|
||||
{
|
||||
SLADVREM(z->gen, gen_list); /* zone has inst? */
|
||||
}
|
||||
else
|
||||
/* Level 3 means we found an instrument generator, so any zone
|
||||
* with a lower level is by definition a global zone */
|
||||
if(level < 3)
|
||||
{
|
||||
/* congratulations its a global zone */
|
||||
if(!gzone)
|
||||
|
@ -1645,7 +1635,6 @@ static int load_ibag(SFData *sf, int size)
|
|||
z->mod = NULL; /* fluid_sffile_close can clean up */
|
||||
READW(sf, genndx); /* READW = possible read failure */
|
||||
READW(sf, modndx);
|
||||
z->instsamp = NULL;
|
||||
|
||||
if(pz)
|
||||
{
|
||||
|
@ -1897,8 +1886,6 @@ static int load_igen(SFData *sf, int size)
|
|||
/* sample is last gen */
|
||||
level = 3;
|
||||
READW(sf, genval.uword);
|
||||
((SFZone *)(zone_list->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1);
|
||||
break; /* break out of generator loop */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1955,13 +1942,14 @@ static int load_igen(SFData *sf, int size)
|
|||
SLADVREM(z->gen, gen_list);
|
||||
}
|
||||
|
||||
if (level == 3)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
} /* generator loop */
|
||||
|
||||
if(level == 3)
|
||||
{
|
||||
SLADVREM(z->gen, gen_list); /* zone has sample? */
|
||||
}
|
||||
else
|
||||
if (level < 3)
|
||||
{
|
||||
/* its a global zone */
|
||||
if(!gzone)
|
||||
|
@ -2068,6 +2056,7 @@ static int load_shdr(SFData *sf, unsigned int size)
|
|||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return FALSE;
|
||||
}
|
||||
p->idx = i;
|
||||
|
||||
sf->sample = fluid_list_append(sf->sample, p);
|
||||
READSTR(sf, &p->name);
|
||||
|
@ -2087,98 +2076,6 @@ static int load_shdr(SFData *sf, unsigned int size)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* "fixup" (inst # -> inst ptr) instrument references in preset list */
|
||||
static int fixup_pgen(SFData *sf)
|
||||
{
|
||||
fluid_list_t *p;
|
||||
fluid_list_t *zone_list;
|
||||
fluid_list_t *inst_list;
|
||||
SFZone *z;
|
||||
int i;
|
||||
|
||||
p = sf->preset;
|
||||
|
||||
while(p)
|
||||
{
|
||||
zone_list = ((SFPreset *)(p->data))->zone;
|
||||
|
||||
while(zone_list)
|
||||
{
|
||||
/* traverse this preset's zones */
|
||||
z = (SFZone *)(zone_list->data);
|
||||
|
||||
if((i = FLUID_POINTER_TO_INT(z->instsamp)))
|
||||
{
|
||||
/* load instrument # */
|
||||
inst_list = fluid_list_nth(sf->inst, i - 1);
|
||||
|
||||
if(!inst_list)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Preset %03d %03d: Invalid instrument reference",
|
||||
((SFPreset *)(p->data))->bank, ((SFPreset *)(p->data))->prenum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
z->instsamp = inst_list;
|
||||
}
|
||||
else
|
||||
{
|
||||
z->instsamp = NULL;
|
||||
}
|
||||
|
||||
zone_list = fluid_list_next(zone_list);
|
||||
}
|
||||
|
||||
p = fluid_list_next(p);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* "fixup" (sample # -> sample ptr) sample references in instrument list */
|
||||
static int fixup_igen(SFData *sf)
|
||||
{
|
||||
fluid_list_t *p;
|
||||
fluid_list_t *zone_list;
|
||||
fluid_list_t *inst_list;
|
||||
SFZone *z;
|
||||
int i;
|
||||
|
||||
p = sf->inst;
|
||||
|
||||
while(p)
|
||||
{
|
||||
zone_list = ((SFInst *)(p->data))->zone;
|
||||
|
||||
while(zone_list)
|
||||
{
|
||||
/* traverse instrument's zones */
|
||||
z = (SFZone *)(zone_list->data);
|
||||
|
||||
if((i = FLUID_POINTER_TO_INT(z->instsamp)))
|
||||
{
|
||||
/* load sample # */
|
||||
inst_list = fluid_list_nth(sf->sample, i - 1);
|
||||
|
||||
if(!inst_list)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Instrument '%s': Invalid sample reference",
|
||||
((SFInst *)(p->data))->name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
z->instsamp = inst_list;
|
||||
}
|
||||
|
||||
zone_list = fluid_list_next(zone_list);
|
||||
}
|
||||
|
||||
p = fluid_list_next(p);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void delete_preset(SFPreset *preset)
|
||||
{
|
||||
fluid_list_t *entry;
|
||||
|
|
|
@ -85,7 +85,6 @@ struct _SFGen
|
|||
struct _SFZone
|
||||
{
|
||||
/* Sample/instrument zone structure */
|
||||
fluid_list_t *instsamp; /* instrument/sample pointer for zone */
|
||||
fluid_list_t *gen; /* list of generators */
|
||||
fluid_list_t *mod; /* list of modulators */
|
||||
};
|
||||
|
@ -94,6 +93,7 @@ struct _SFSample
|
|||
{
|
||||
/* Sample structure */
|
||||
char name[21]; /* Name of sample */
|
||||
int idx; /* Index of this instrument in the Soundfont */
|
||||
unsigned int start; /* Offset in sample area to start of sample */
|
||||
unsigned int end; /* Offset from start to end of sample,
|
||||
this is the last point of the
|
||||
|
|
Loading…
Reference in a new issue