mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-12-11 05:11:33 +00:00
Refactor load_igen and load_pgen
Cleanup of the code structure and fix of the ineffective check for global zones that are not first in list. Fixes #813
This commit is contained in:
parent
dfbef11da0
commit
0f8e2c7fde
1 changed files with 65 additions and 99 deletions
|
@ -1079,14 +1079,14 @@ static int load_pbag(SFData *sf, int size)
|
||||||
|
|
||||||
preset_list = sf->preset;
|
preset_list = sf->preset;
|
||||||
|
|
||||||
|
/* traverse through presets */
|
||||||
while(preset_list)
|
while(preset_list)
|
||||||
{
|
{
|
||||||
/* traverse through presets */
|
|
||||||
zone_list = ((SFPreset *)(preset_list->data))->zone;
|
zone_list = ((SFPreset *)(preset_list->data))->zone;
|
||||||
|
|
||||||
|
/* traverse preset's zones */
|
||||||
while(zone_list)
|
while(zone_list)
|
||||||
{
|
{
|
||||||
/* traverse preset's zones */
|
|
||||||
if((size -= SF_BAG_SIZE) < 0)
|
if((size -= SF_BAG_SIZE) < 0)
|
||||||
{
|
{
|
||||||
FLUID_LOG(FLUID_ERR, "Preset bag chunk size mismatch");
|
FLUID_LOG(FLUID_ERR, "Preset bag chunk size mismatch");
|
||||||
|
@ -1285,37 +1285,33 @@ static int load_pmod(SFData *sf, int size)
|
||||||
* ------------------------------------------------------------------- */
|
* ------------------------------------------------------------------- */
|
||||||
static int load_pgen(SFData *sf, int size)
|
static int load_pgen(SFData *sf, int size)
|
||||||
{
|
{
|
||||||
fluid_list_t *dup, **hz = NULL;
|
fluid_list_t *dup;
|
||||||
fluid_list_t *preset_list;
|
fluid_list_t *preset_list;
|
||||||
fluid_list_t *zone_list;
|
fluid_list_t *zone_list;
|
||||||
fluid_list_t *gen_list;
|
fluid_list_t *gen_list;
|
||||||
fluid_list_t *start_of_zone_list;
|
SFZone *zone;
|
||||||
SFZone *z;
|
|
||||||
SFGen *g;
|
SFGen *g;
|
||||||
|
SFPreset *preset;
|
||||||
SFGenAmount genval;
|
SFGenAmount genval;
|
||||||
unsigned short genid;
|
unsigned short genid;
|
||||||
int level, skip, drop, gzone, discarded;
|
int level, skip, drop, discarded;
|
||||||
|
|
||||||
preset_list = sf->preset;
|
preset_list = sf->preset;
|
||||||
|
|
||||||
while(preset_list)
|
while(preset_list)
|
||||||
{
|
{
|
||||||
|
preset = fluid_list_get(preset_list);
|
||||||
|
|
||||||
/* traverse through all presets */
|
/* traverse through all presets */
|
||||||
gzone = FALSE;
|
|
||||||
discarded = FALSE;
|
discarded = FALSE;
|
||||||
start_of_zone_list = zone_list = ((SFPreset *)(preset_list->data))->zone;
|
zone_list = preset->zone;
|
||||||
|
|
||||||
if(zone_list)
|
|
||||||
{
|
|
||||||
hz = &zone_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* traverse preset's zones */
|
||||||
while(zone_list)
|
while(zone_list)
|
||||||
{
|
{
|
||||||
/* traverse preset's zones */
|
zone = fluid_list_get(zone_list);
|
||||||
level = 0;
|
level = 0;
|
||||||
z = (SFZone *)(zone_list->data);
|
gen_list = zone->gen;
|
||||||
gen_list = z->gen;
|
|
||||||
|
|
||||||
while(gen_list)
|
while(gen_list)
|
||||||
{
|
{
|
||||||
|
@ -1374,7 +1370,7 @@ static int load_pgen(SFData *sf, int size)
|
||||||
{
|
{
|
||||||
/* generator valid? */
|
/* generator valid? */
|
||||||
READW(sf, genval.sword);
|
READW(sf, genval.sword);
|
||||||
dup = find_gen_by_id(genid, z->gen);
|
dup = find_gen_by_id(genid, zone->gen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1418,11 +1414,10 @@ static int load_pgen(SFData *sf, int size)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SLADVREM(z->gen, gen_list); /* drop place holder */
|
SLADVREM(zone->gen, gen_list); /* drop place holder */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Level 3 means we found an instrument generator, which
|
/* GEN_INSTRUMENT should be the last generator */
|
||||||
* should be the last generator in the list. */
|
|
||||||
if (level == 3)
|
if (level == 3)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -1430,42 +1425,27 @@ static int load_pgen(SFData *sf, int size)
|
||||||
|
|
||||||
} /* generator loop */
|
} /* generator loop */
|
||||||
|
|
||||||
/* Level 3 means we found an instrument generator, so any zone
|
/* Anything below level 3 means it's a global zone. The global zone
|
||||||
* with a lower level is by definition a global zone */
|
* should always be the first zone in the list, so discard any
|
||||||
if(level < 3)
|
* other global zones we encounter */
|
||||||
|
if(level < 3 && (zone_list != preset->zone))
|
||||||
{
|
{
|
||||||
/* congratulations its a global zone */
|
/* advance to next zone before deleting the current list element */
|
||||||
if(!gzone)
|
zone_list = fluid_list_next(zone_list);
|
||||||
{
|
|
||||||
/* Prior global zones? */
|
|
||||||
gzone = TRUE;
|
|
||||||
|
|
||||||
/* if global zone is not 1st zone, relocate */
|
|
||||||
if(*hz != zone_list)
|
|
||||||
{
|
|
||||||
void *save = zone_list->data;
|
|
||||||
FLUID_LOG(FLUID_WARN, "Preset '%s': Global zone is not first zone",
|
|
||||||
((SFPreset *)(preset_list->data))->name);
|
|
||||||
SLADVREM(*hz, zone_list);
|
|
||||||
*hz = fluid_list_prepend(*hz, save);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
zone_list = fluid_list_next(zone_list); /* advance to next zone before deleting the current list element */
|
|
||||||
/* previous global zone exists, discard */
|
|
||||||
FLUID_LOG(FLUID_WARN, "Preset '%s': Discarding invalid global zone",
|
FLUID_LOG(FLUID_WARN, "Preset '%s': Discarding invalid global zone",
|
||||||
((SFPreset *)(preset_list->data))->name);
|
preset->name);
|
||||||
fluid_list_remove(start_of_zone_list, z);
|
preset->zone = fluid_list_remove(preset->zone, zone);
|
||||||
delete_zone(z);
|
delete_zone(zone);
|
||||||
|
|
||||||
|
/* we have already advanced the zone_list pointer, so continue with next zone */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/* All remaining generators are invalid and should be discarded
|
||||||
|
* (because they come after an instrument generator) */
|
||||||
while(gen_list)
|
while(gen_list)
|
||||||
{
|
{
|
||||||
/* Kill any zones following an instrument */
|
|
||||||
discarded = TRUE;
|
discarded = TRUE;
|
||||||
|
|
||||||
if((size -= SF_GEN_SIZE) < 0)
|
if((size -= SF_GEN_SIZE) < 0)
|
||||||
|
@ -1475,17 +1455,17 @@ static int load_pgen(SFData *sf, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
FSKIP(sf, SF_GEN_SIZE);
|
FSKIP(sf, SF_GEN_SIZE);
|
||||||
SLADVREM(z->gen, gen_list);
|
SLADVREM(zone->gen, gen_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
zone_list = fluid_list_next(zone_list); /* next zone */
|
zone_list = fluid_list_next(zone_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(discarded)
|
if(discarded)
|
||||||
{
|
{
|
||||||
FLUID_LOG(FLUID_WARN,
|
FLUID_LOG(FLUID_WARN,
|
||||||
"Preset '%s': Some invalid generators were discarded",
|
"Preset '%s': Some invalid generators were discarded",
|
||||||
((SFPreset *)(preset_list->data))->name);
|
preset->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
preset_list = fluid_list_next(preset_list);
|
preset_list = fluid_list_next(preset_list);
|
||||||
|
@ -1806,37 +1786,34 @@ static int load_imod(SFData *sf, int size)
|
||||||
/* load instrument generators (see load_pgen for loading rules) */
|
/* load instrument generators (see load_pgen for loading rules) */
|
||||||
static int load_igen(SFData *sf, int size)
|
static int load_igen(SFData *sf, int size)
|
||||||
{
|
{
|
||||||
fluid_list_t *dup, **hz = NULL;
|
fluid_list_t *dup;
|
||||||
fluid_list_t *inst_list;
|
fluid_list_t *inst_list;
|
||||||
fluid_list_t *zone_list;
|
fluid_list_t *zone_list;
|
||||||
fluid_list_t *gen_list;
|
fluid_list_t *gen_list;
|
||||||
fluid_list_t *start_of_zone_list;
|
SFZone *zone;
|
||||||
SFZone *z;
|
|
||||||
SFGen *g;
|
SFGen *g;
|
||||||
|
SFInst *inst;
|
||||||
SFGenAmount genval;
|
SFGenAmount genval;
|
||||||
unsigned short genid;
|
unsigned short genid;
|
||||||
int level, skip, drop, gzone, discarded;
|
int level, skip, drop, discarded;
|
||||||
|
|
||||||
inst_list = sf->inst;
|
inst_list = sf->inst;
|
||||||
|
|
||||||
|
/* traverse through all instruments */
|
||||||
while(inst_list)
|
while(inst_list)
|
||||||
{
|
{
|
||||||
/* traverse through all instruments */
|
inst = fluid_list_get(inst_list);
|
||||||
gzone = FALSE;
|
|
||||||
discarded = FALSE;
|
discarded = FALSE;
|
||||||
start_of_zone_list = zone_list = ((SFInst *)(inst_list->data))->zone;
|
zone_list = inst->zone;
|
||||||
|
|
||||||
if(zone_list)
|
|
||||||
{
|
|
||||||
hz = &zone_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* traverse this instrument's zones */
|
||||||
while(zone_list)
|
while(zone_list)
|
||||||
{
|
{
|
||||||
/* traverse this instrument's zones */
|
zone = fluid_list_get(zone_list);
|
||||||
|
|
||||||
level = 0;
|
level = 0;
|
||||||
z = (SFZone *)(zone_list->data);
|
gen_list = zone->gen;
|
||||||
gen_list = z->gen;
|
|
||||||
|
|
||||||
while(gen_list)
|
while(gen_list)
|
||||||
{
|
{
|
||||||
|
@ -1895,7 +1872,7 @@ static int load_igen(SFData *sf, int size)
|
||||||
{
|
{
|
||||||
/* gen valid? */
|
/* gen valid? */
|
||||||
READW(sf, genval.sword);
|
READW(sf, genval.sword);
|
||||||
dup = find_gen_by_id(genid, z->gen);
|
dup = find_gen_by_id(genid, zone->gen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1939,9 +1916,10 @@ static int load_igen(SFData *sf, int size)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SLADVREM(z->gen, gen_list);
|
SLADVREM(zone->gen, gen_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* GEN_SAMPLEID should be last generator */
|
||||||
if (level == 3)
|
if (level == 3)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -1949,39 +1927,27 @@ static int load_igen(SFData *sf, int size)
|
||||||
|
|
||||||
} /* generator loop */
|
} /* generator loop */
|
||||||
|
|
||||||
if (level < 3)
|
/* Anything below level 3 means it's a global zone. The global zone
|
||||||
|
* should always be the first zone in the list, so discard any
|
||||||
|
* other global zones we encounter */
|
||||||
|
if(level < 3 && (zone_list != inst->zone))
|
||||||
{
|
{
|
||||||
/* its a global zone */
|
/* advance to next zone before deleting the current list element */
|
||||||
if(!gzone)
|
zone_list = fluid_list_next(zone_list);
|
||||||
{
|
|
||||||
gzone = TRUE;
|
|
||||||
|
|
||||||
/* if global zone is not 1st zone, relocate */
|
|
||||||
if(*hz != zone_list)
|
|
||||||
{
|
|
||||||
void *save = zone_list->data;
|
|
||||||
FLUID_LOG(FLUID_WARN, "Instrument '%s': Global zone is not first zone",
|
|
||||||
((SFPreset *)(inst_list->data))->name);
|
|
||||||
SLADVREM(*hz, zone_list);
|
|
||||||
*hz = fluid_list_prepend(*hz, save);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
zone_list = fluid_list_next(zone_list); /* advance to next zone before deleting the current list element */
|
|
||||||
/* previous global zone exists, discard */
|
|
||||||
FLUID_LOG(FLUID_WARN, "Instrument '%s': Discarding invalid global zone",
|
FLUID_LOG(FLUID_WARN, "Instrument '%s': Discarding invalid global zone",
|
||||||
((SFInst *)(inst_list->data))->name);
|
inst->name);
|
||||||
fluid_list_remove(start_of_zone_list, z);
|
inst->zone = fluid_list_remove(inst->zone, zone);
|
||||||
delete_zone(z);
|
delete_zone(zone);
|
||||||
|
|
||||||
|
/* we have already advanced the zone_list pointer, so continue with next zone */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/* All remaining generators must be invalid and should be discarded
|
||||||
|
* (because they come after a sampleid generator) */
|
||||||
while(gen_list)
|
while(gen_list)
|
||||||
{
|
{
|
||||||
/* Kill any zones following a sample */
|
|
||||||
discarded = TRUE;
|
discarded = TRUE;
|
||||||
|
|
||||||
if((size -= SF_GEN_SIZE) < 0)
|
if((size -= SF_GEN_SIZE) < 0)
|
||||||
|
@ -1991,7 +1957,7 @@ static int load_igen(SFData *sf, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
FSKIP(sf, SF_GEN_SIZE);
|
FSKIP(sf, SF_GEN_SIZE);
|
||||||
SLADVREM(z->gen, gen_list);
|
SLADVREM(zone->gen, gen_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
zone_list = fluid_list_next(zone_list); /* next zone */
|
zone_list = fluid_list_next(zone_list); /* next zone */
|
||||||
|
@ -2001,7 +1967,7 @@ static int load_igen(SFData *sf, int size)
|
||||||
{
|
{
|
||||||
FLUID_LOG(FLUID_WARN,
|
FLUID_LOG(FLUID_WARN,
|
||||||
"Instrument '%s': Some invalid generators were discarded",
|
"Instrument '%s': Some invalid generators were discarded",
|
||||||
((SFInst *)(inst_list->data))->name);
|
inst->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
inst_list = fluid_list_next(inst_list);
|
inst_list = fluid_list_next(inst_list);
|
||||||
|
|
Loading…
Reference in a new issue