Merge pull request #823 from FluidSynth/refactor-and-fix-sffile-defsfont

Refactor of sffile and defsfont code, including some bugfixes
This commit is contained in:
Marcus Weseloh 2021-04-11 00:25:43 +02:00 committed by GitHub
commit aad6288955
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 269 additions and 455 deletions

View file

@ -533,7 +533,7 @@ int fluid_defsfont_load(fluid_defsfont_t *defsfont, const fluid_file_callbacks_t
goto err_exit; 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; goto err_exit;
} }
@ -562,7 +562,7 @@ err_exit:
*/ */
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)
{ {
defsfont->sample = fluid_list_append(defsfont->sample, sample); defsfont->sample = fluid_list_prepend(defsfont->sample, sample);
return FLUID_OK; return FLUID_OK;
} }
@ -1028,7 +1028,8 @@ fluid_defpreset_set_global_zone(fluid_defpreset_t *defpreset, fluid_preset_zone_
int int
fluid_defpreset_import_sfont(fluid_defpreset_t *defpreset, fluid_defpreset_import_sfont(fluid_defpreset_t *defpreset,
SFPreset *sfpreset, SFPreset *sfpreset,
fluid_defsfont_t *defsfont) fluid_defsfont_t *defsfont,
SFData *sfdata)
{ {
fluid_list_t *p; fluid_list_t *p;
SFZone *sfzone; SFZone *sfzone;
@ -1061,7 +1062,7 @@ fluid_defpreset_import_sfont(fluid_defpreset_t *defpreset,
return FLUID_FAILED; 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); delete_fluid_preset_zone(zone);
return FLUID_FAILED; 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; gen[sfgen->id].flags = GEN_SET;
break; 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: 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].val = (fluid_real_t) sfgen->amount.sword;
gen[sfgen->id].flags = GEN_SET; gen[sfgen->id].flags = GEN_SET;
break; break;
@ -1630,24 +1636,27 @@ fluid_zone_mod_import_sfont(char *zone_name, fluid_mod_t **mod, SFZone *sfzone)
* fluid_preset_zone_import_sfont * fluid_preset_zone_import_sfont
*/ */
int 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 */ /* import the generators */
fluid_zone_gen_import_sfont(zone->gen, &zone->range, sfzone); 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) 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) if(zone->inst == NULL)
{ {
FLUID_LOG(FLUID_ERR, "Preset zone %s: Invalid instrument reference",
zone->name);
return FLUID_FAILED; return FLUID_FAILED;
} }
@ -1655,6 +1664,9 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t *zone, SFZone *sfzone, fluid_
{ {
return FLUID_FAILED; 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) */ /* 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_import_sfont
*/ */
fluid_inst_t * 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 *p;
fluid_list_t *inst_list;
fluid_inst_t *inst; fluid_inst_t *inst;
SFZone *sfzone; SFZone *sfzone;
SFInst *sfinst;
fluid_inst_zone_t *inst_zone; fluid_inst_zone_t *inst_zone;
char zone_name[256]; char zone_name[256];
int count; 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(); inst = (fluid_inst_t *) new_fluid_inst();
if(inst == NULL) if(inst == NULL)
@ -1781,7 +1808,7 @@ fluid_inst_import_sfont(SFInst *sfinst, fluid_defsfont_t *defsfont)
return NULL; 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); delete_fluid_inst_zone(inst_zone);
return NULL; return NULL;
@ -1913,7 +1940,8 @@ fluid_inst_zone_next(fluid_inst_zone_t *zone)
* fluid_inst_zone_import_sfont * fluid_inst_zone_import_sfont
*/ */
int 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 */ /* import the generators */
fluid_zone_gen_import_sfont(inst_zone->gen, &inst_zone->range, sfzone); 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); */ /* FLUID_LOG(FLUID_DBG, "ExclusiveClass=%d\n", (int) zone->gen[GEN_EXCLUSIVECLASS].val); */
/* } */ /* } */
/* fixup sample pointer */ if (inst_zone->gen[GEN_SAMPLEID].flags == GEN_SET)
if((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL))
{ {
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) */ /* Import the modulators (only SF2.1 and higher) */

View file

@ -154,7 +154,7 @@ struct _fluid_defpreset_t
fluid_defpreset_t *new_fluid_defpreset(void); fluid_defpreset_t *new_fluid_defpreset(void);
void delete_fluid_defpreset(fluid_defpreset_t *defpreset); void delete_fluid_defpreset(fluid_defpreset_t *defpreset);
fluid_defpreset_t *fluid_defpreset_next(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_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); 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); 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_list_mod(fluid_mod_t *mod);
void delete_fluid_preset_zone(fluid_preset_zone_t *zone); void delete_fluid_preset_zone(fluid_preset_zone_t *zone);
fluid_preset_zone_t *fluid_preset_zone_next(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); 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 *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); 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_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); 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); fluid_inst_zone_t *new_fluid_inst_zone(char *name);
void delete_fluid_inst_zone(fluid_inst_zone_t *zone); void delete_fluid_inst_zone(fluid_inst_zone_t *zone);
fluid_inst_zone_t *fluid_inst_zone_next(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); fluid_sample_t *fluid_inst_zone_get_sample(fluid_inst_zone_t *zone);

View file

@ -112,39 +112,34 @@ static const uint32_t idlist[] =
SM24_FCC SM24_FCC
}; };
#define Gen_MaxValid Gen_Dummy - 1 /* maximum valid generator */
#define Gen_Count Gen_Dummy /* count of generators */
#define GenArrSize sizeof(SFGenAmount) * Gen_Count /* gen array size */
static const unsigned short invalid_inst_gen[] = static const unsigned short invalid_inst_gen[] =
{ {
Gen_Unused1, GEN_UNUSED1,
Gen_Unused2, GEN_UNUSED2,
Gen_Unused3, GEN_UNUSED3,
Gen_Unused4, GEN_UNUSED4,
Gen_Reserved1, GEN_RESERVED1,
Gen_Reserved2, GEN_RESERVED2,
Gen_Reserved3, GEN_RESERVED3,
0 GEN_INSTRUMENT,
}; };
static const unsigned short invalid_preset_gen[] = static const unsigned short invalid_preset_gen[] =
{ {
Gen_StartAddrOfs, GEN_STARTADDROFS,
Gen_EndAddrOfs, GEN_ENDADDROFS,
Gen_StartLoopAddrOfs, GEN_STARTLOOPADDROFS,
Gen_EndLoopAddrOfs, GEN_ENDLOOPADDROFS,
Gen_StartAddrCoarseOfs, GEN_STARTADDRCOARSEOFS,
Gen_EndAddrCoarseOfs, GEN_ENDADDRCOARSEOFS,
Gen_StartLoopAddrCoarseOfs, GEN_STARTLOOPADDRCOARSEOFS,
Gen_Keynum, GEN_KEYNUM,
Gen_Velocity, GEN_VELOCITY,
Gen_EndLoopAddrCoarseOfs, GEN_ENDLOOPADDRCOARSEOFS,
Gen_SampleModes, GEN_SAMPLEMODE,
Gen_ExclusiveClass, GEN_EXCLUSIVECLASS,
Gen_OverrideRootKey, GEN_OVERRIDEROOTKEY,
0 GEN_SAMPLEID,
}; };
@ -244,8 +239,6 @@ static int load_ibag(SFData *sf, int size);
static int load_imod(SFData *sf, int size); static int load_imod(SFData *sf, int size);
extern int load_igen(SFData *sf, int size); extern int load_igen(SFData *sf, int size);
static int load_shdr(SFData *sf, unsigned 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 chunkid(uint32_t id);
static int read_listchunk(SFData *sf, SFChunk *chunk); static int read_listchunk(SFData *sf, SFChunk *chunk);
@ -629,16 +622,6 @@ static int load_body(SFData *sf)
return FALSE; return FALSE;
} }
if(!fixup_pgen(sf))
{
return FALSE;
}
if(!fixup_igen(sf))
{
return FALSE;
}
/* sort preset list by bank, preset # */ /* sort preset list by bank, preset # */
sf->preset = fluid_list_sort(sf->preset, (fluid_compare_func_t)preset_compare_func); sf->preset = fluid_list_sort(sf->preset, (fluid_compare_func_t)preset_compare_func);
@ -1024,9 +1007,9 @@ static int load_phdr(SFData *sf, unsigned int size)
READW(sf, preset->prenum); READW(sf, preset->prenum);
READW(sf, preset->bank); READW(sf, preset->bank);
READW(sf, pbag_idx); READW(sf, pbag_idx);
READD(sf, preset->libr); FSKIP(sf, 4); /* library ignored */
READD(sf, preset->genre); FSKIP(sf, 4); /* genre ignored */
READD(sf, preset->morph); FSKIP(sf, 4); /* morphology ignored */
if(prev_preset) if(prev_preset)
{ {
@ -1091,14 +1074,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");
@ -1116,7 +1099,6 @@ static int load_pbag(SFData *sf, int size)
z->mod = NULL; /* to ensure proper cleanup (fluid_sffile_close) */ z->mod = NULL; /* to ensure proper cleanup (fluid_sffile_close) */
READW(sf, genndx); /* possible read failure ^ */ READW(sf, genndx); /* possible read failure ^ */
READW(sf, modndx); READW(sf, modndx);
z->instsamp = NULL;
if(pz) if(pz)
{ {
@ -1298,37 +1280,33 @@ static int load_pmod(SFData *sf, int size)
* ------------------------------------------------------------------- */ * ------------------------------------------------------------------- */
int load_pgen(SFData *sf, int size) 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)
{ {
@ -1345,7 +1323,7 @@ int load_pgen(SFData *sf, int size)
READW(sf, genid); READW(sf, genid);
if(genid == Gen_KeyRange) if(genid == GEN_KEYRANGE)
{ {
/* nothing precedes */ /* nothing precedes */
if(level == 0) if(level == 0)
@ -1359,7 +1337,7 @@ int load_pgen(SFData *sf, int size)
skip = TRUE; skip = TRUE;
} }
} }
else if(genid == Gen_VelRange) else if(genid == GEN_VELRANGE)
{ {
/* only KeyRange precedes */ /* only KeyRange precedes */
if(level <= 1) if(level <= 1)
@ -1373,13 +1351,11 @@ int load_pgen(SFData *sf, int size)
skip = TRUE; skip = TRUE;
} }
} }
else if(genid == Gen_Instrument) else if(genid == GEN_INSTRUMENT)
{ {
/* inst is last gen */ /* inst is last gen */
level = 3; level = 3;
READW(sf, genval.uword); READW(sf, genval.uword);
((SFZone *)(zone_list->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1);
break; /* break out of generator loop */
} }
else else
{ {
@ -1389,7 +1365,7 @@ 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
{ {
@ -1433,49 +1409,38 @@ 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 */
}
/* GEN_INSTRUMENT should be the last generator */
if (level == 3)
{
break;
} }
} /* 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 != preset->zone))
{ {
SLADVREM(z->gen, gen_list); /* zone has inst? */ /* advance to next zone before deleting the current list element */
} zone_list = fluid_list_next(zone_list);
else
{
/* congratulations its a global zone */
if(!gzone)
{
/* Prior global zones? */
gzone = TRUE;
/* if global zone is not 1st zone, relocate */ FLUID_LOG(FLUID_WARN, "Preset '%s': Discarding invalid global zone",
if(*hz != zone_list) preset->name);
{ preset->zone = fluid_list_remove(preset->zone, zone);
void *save = zone_list->data; delete_zone(zone);
FLUID_LOG(FLUID_WARN, "Preset '%s': Global zone is not first zone",
((SFPreset *)(preset_list->data))->name); /* we have already advanced the zone_list pointer, so continue with next zone */
SLADVREM(*hz, zone_list); continue;
*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",
((SFPreset *)(preset_list->data))->name);
fluid_list_remove(start_of_zone_list, z);
delete_zone(z);
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)
@ -1485,17 +1450,17 @@ 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);
@ -1645,7 +1610,6 @@ static int load_ibag(SFData *sf, int size)
z->mod = NULL; /* fluid_sffile_close can clean up */ z->mod = NULL; /* fluid_sffile_close can clean up */
READW(sf, genndx); /* READW = possible read failure */ READW(sf, genndx); /* READW = possible read failure */
READW(sf, modndx); READW(sf, modndx);
z->instsamp = NULL;
if(pz) if(pz)
{ {
@ -1817,37 +1781,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) */
int load_igen(SFData *sf, int size) 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)
{ {
@ -1864,7 +1825,7 @@ int load_igen(SFData *sf, int size)
READW(sf, genid); READW(sf, genid);
if(genid == Gen_KeyRange) if(genid == GEN_KEYRANGE)
{ {
/* nothing precedes */ /* nothing precedes */
if(level == 0) if(level == 0)
@ -1878,7 +1839,7 @@ int load_igen(SFData *sf, int size)
skip = TRUE; skip = TRUE;
} }
} }
else if(genid == Gen_VelRange) else if(genid == GEN_VELRANGE)
{ {
/* only KeyRange precedes */ /* only KeyRange precedes */
if(level <= 1) if(level <= 1)
@ -1892,13 +1853,11 @@ int load_igen(SFData *sf, int size)
skip = TRUE; skip = TRUE;
} }
} }
else if(genid == Gen_SampleId) else if(genid == GEN_SAMPLEID)
{ {
/* sample is last gen */ /* sample is last gen */
level = 3; level = 3;
READW(sf, genval.uword); READW(sf, genval.uword);
((SFZone *)(zone_list->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1);
break; /* break out of generator loop */
} }
else else
{ {
@ -1908,7 +1867,7 @@ 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
{ {
@ -1952,48 +1911,38 @@ 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)
{
break;
} }
} /* 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))
{ {
SLADVREM(z->gen, gen_list); /* zone has sample? */ /* advance to next zone before deleting the current list element */
} zone_list = fluid_list_next(zone_list);
else
{
/* its a global zone */
if(!gzone)
{
gzone = TRUE;
/* if global zone is not 1st zone, relocate */ FLUID_LOG(FLUID_WARN, "Instrument '%s': Discarding invalid global zone",
if(*hz != zone_list) inst->name);
{ inst->zone = fluid_list_remove(inst->zone, zone);
void *save = zone_list->data; delete_zone(zone);
FLUID_LOG(FLUID_WARN, "Instrument '%s': Global zone is not first zone",
((SFPreset *)(inst_list->data))->name); /* we have already advanced the zone_list pointer, so continue with next zone */
SLADVREM(*hz, zone_list); continue;
*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",
((SFInst *)(inst_list->data))->name);
fluid_list_remove(start_of_zone_list, z);
delete_zone(z);
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)
@ -2003,7 +1952,7 @@ 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 */
@ -2013,7 +1962,7 @@ 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);
@ -2068,8 +2017,9 @@ static int load_shdr(SFData *sf, unsigned int size)
FLUID_LOG(FLUID_ERR, "Out of memory"); FLUID_LOG(FLUID_ERR, "Out of memory");
return FALSE; return FALSE;
} }
p->idx = i;
sf->sample = fluid_list_append(sf->sample, p); sf->sample = fluid_list_prepend(sf->sample, p);
READSTR(sf, &p->name); READSTR(sf, &p->name);
READD(sf, p->start); READD(sf, p->start);
READD(sf, p->end); READD(sf, p->end);
@ -2087,98 +2037,6 @@ static int load_shdr(SFData *sf, unsigned int size)
return TRUE; 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;
}
void delete_preset(SFPreset *preset) void delete_preset(SFPreset *preset)
{ {
fluid_list_t *entry; fluid_list_t *entry;
@ -2304,37 +2162,46 @@ static fluid_list_t *find_gen_by_id(int gen, fluid_list_t *genlist)
/* check validity of instrument generator */ /* check validity of instrument generator */
static int valid_inst_genid(unsigned short genid) static int valid_inst_genid(unsigned short genid)
{ {
int i = 0; size_t i;
if(genid > Gen_MaxValid) /* OVERRIDEROOTKEY is the last official generator, everything
* following it are generators internal to FluidSynth and will
* never appear in a SoundFont file. */
if(genid > GEN_OVERRIDEROOTKEY)
{ {
return FALSE; return FALSE;
} }
while(invalid_inst_gen[i] && invalid_inst_gen[i] != genid) for(i = 0; i < FLUID_N_ELEMENTS(invalid_inst_gen); i++)
{ {
i++; if (invalid_inst_gen[i] == genid)
{
return FALSE;
}
} }
return (invalid_inst_gen[i] == 0); return TRUE;
} }
/* check validity of preset generator */ /* check validity of preset generator */
static int valid_preset_genid(unsigned short genid) static int valid_preset_genid(unsigned short genid)
{ {
int i = 0; size_t i;
if(!valid_inst_genid(genid)) if(!valid_inst_genid(genid))
{ {
return FALSE; return FALSE;
} }
while(invalid_preset_gen[i] && invalid_preset_gen[i] != genid) for(i = 0; i < FLUID_N_ELEMENTS(invalid_preset_gen); i++)
{ {
i++; if (invalid_preset_gen[i] == genid)
{
return FALSE;
}
} }
return (invalid_preset_gen[i] == 0); return TRUE;
} }

View file

@ -45,10 +45,6 @@ typedef struct _SFInst SFInst;
typedef struct _SFPreset SFPreset; typedef struct _SFPreset SFPreset;
typedef struct _SFData SFData; typedef struct _SFData SFData;
typedef struct _SFChunk SFChunk; typedef struct _SFChunk SFChunk;
typedef struct _SFPhdr SFPhdr;
typedef struct _SFBag SFBag;
typedef struct _SFIhdr SFIhdr;
typedef struct _SFShdr SFShdr;
struct _SFVersion struct _SFVersion
@ -89,7 +85,6 @@ struct _SFGen
struct _SFZone struct _SFZone
{ {
/* Sample/instrument zone structure */ /* Sample/instrument zone structure */
fluid_list_t *instsamp; /* instrument/sample pointer for zone */
fluid_list_t *gen; /* list of generators */ fluid_list_t *gen; /* list of generators */
fluid_list_t *mod; /* list of modulators */ fluid_list_t *mod; /* list of modulators */
}; };
@ -98,6 +93,7 @@ struct _SFSample
{ {
/* Sample structure */ /* Sample structure */
char name[21]; /* Name of sample */ 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 start; /* Offset in sample area to start of sample */
unsigned int end; /* Offset from start to end of sample, unsigned int end; /* Offset from start to end of sample,
this is the last point of the this is the last point of the
@ -130,9 +126,6 @@ struct _SFPreset
char name[21]; /* preset name */ char name[21]; /* preset name */
unsigned short prenum; /* preset number */ unsigned short prenum; /* preset number */
unsigned short bank; /* bank number */ unsigned short bank; /* bank number */
unsigned int libr; /* Not used (preserved) */
unsigned int genre; /* Not used (preserved) */
unsigned int morph; /* Not used (preserved) */
fluid_list_t *zone; /* list of preset zones */ fluid_list_t *zone; /* list of preset zones */
}; };
@ -183,44 +176,6 @@ struct _SFChunk
unsigned int size; /* size of the following chunk */ unsigned int size; /* size of the following chunk */
}; };
struct _SFPhdr
{
unsigned char name[20]; /* preset name */
unsigned short preset; /* preset number */
unsigned short bank; /* bank number */
unsigned short pbagndx; /* index into preset bag */
unsigned int library; /* just for preserving them */
unsigned int genre; /* Not used */
unsigned int morphology; /* Not used */
};
struct _SFBag
{
unsigned short genndx; /* index into generator list */
unsigned short modndx; /* index into modulator list */
};
struct _SFIhdr
{
char name[20]; /* Name of instrument */
unsigned short ibagndx; /* Instrument bag index */
};
struct _SFShdr
{
/* Sample header loading struct */
char name[20]; /* Sample name */
unsigned int start; /* Offset to start of sample */
unsigned int end; /* Offset to end of sample */
unsigned int loopstart; /* Offset to start of loop */
unsigned int loopend; /* Offset to end of loop */
unsigned int samplerate; /* Sample rate recorded at */
unsigned char origpitch; /* root midi key number */
signed char pitchadj; /* pitch correction in cents */
unsigned short samplelink; /* Not used */
unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */
};
/* Public functions */ /* Public functions */
SFData *fluid_sffile_open(const char *fname, const fluid_file_callbacks_t *fcbs); SFData *fluid_sffile_open(const char *fname, const fluid_file_callbacks_t *fcbs);
void fluid_sffile_close(SFData *sf); void fluid_sffile_close(SFData *sf);
@ -236,69 +191,4 @@ void delete_preset(SFPreset *preset);
void delete_inst(SFInst *inst); void delete_inst(SFInst *inst);
void delete_zone(SFZone *zone); void delete_zone(SFZone *zone);
/* generator types */
typedef enum
{
Gen_StartAddrOfs,
Gen_EndAddrOfs,
Gen_StartLoopAddrOfs,
Gen_EndLoopAddrOfs,
Gen_StartAddrCoarseOfs,
Gen_ModLFO2Pitch,
Gen_VibLFO2Pitch,
Gen_ModEnv2Pitch,
Gen_FilterFc,
Gen_FilterQ,
Gen_ModLFO2FilterFc,
Gen_ModEnv2FilterFc,
Gen_EndAddrCoarseOfs,
Gen_ModLFO2Vol,
Gen_Unused1,
Gen_ChorusSend,
Gen_ReverbSend,
Gen_Pan,
Gen_Unused2,
Gen_Unused3,
Gen_Unused4,
Gen_ModLFODelay,
Gen_ModLFOFreq,
Gen_VibLFODelay,
Gen_VibLFOFreq,
Gen_ModEnvDelay,
Gen_ModEnvAttack,
Gen_ModEnvHold,
Gen_ModEnvDecay,
Gen_ModEnvSustain,
Gen_ModEnvRelease,
Gen_Key2ModEnvHold,
Gen_Key2ModEnvDecay,
Gen_VolEnvDelay,
Gen_VolEnvAttack,
Gen_VolEnvHold,
Gen_VolEnvDecay,
Gen_VolEnvSustain,
Gen_VolEnvRelease,
Gen_Key2VolEnvHold,
Gen_Key2VolEnvDecay,
Gen_Instrument,
Gen_Reserved1,
Gen_KeyRange,
Gen_VelRange,
Gen_StartLoopAddrCoarseOfs,
Gen_Keynum,
Gen_Velocity,
Gen_Attenuation,
Gen_Reserved2,
Gen_EndLoopAddrCoarseOfs,
Gen_CoarseTune,
Gen_FineTune,
Gen_SampleId,
Gen_SampleModes,
Gen_Reserved3,
Gen_ScaleTune,
Gen_ExclusiveClass,
Gen_OverrideRootKey,
Gen_Dummy
} Gen_Type;
#endif /* _FLUID_SFFILE_H */ #endif /* _FLUID_SFFILE_H */

View file

@ -92,20 +92,20 @@ static void good_test_1zone_2gen_1termgen(int (*load_func)(SFData *sf, int size)
const SFGen *gen; const SFGen *gen;
static const unsigned char buf[] = static const unsigned char buf[] =
{ {
Gen_KeyRange, 0, 60, 127, Gen_VelRange, 0, 60, 127, 0, 0, 0, 0 GEN_KEYRANGE, 0, 60, 127, GEN_VELRANGE, 0, 60, 127, 0, 0, 0, 0
}; };
SET_BUF(buf); SET_BUF(buf);
TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf))); TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf)));
gen = fluid_list_get(fluid_list_nth(zone->gen, 0)); gen = fluid_list_get(fluid_list_nth(zone->gen, 0));
TEST_ASSERT(gen != NULL); TEST_ASSERT(gen != NULL);
TEST_ASSERT(gen->id == Gen_KeyRange); TEST_ASSERT(gen->id == GEN_KEYRANGE);
TEST_ASSERT(gen->amount.range.lo == 60); TEST_ASSERT(gen->amount.range.lo == 60);
TEST_ASSERT(gen->amount.range.hi == 127); TEST_ASSERT(gen->amount.range.hi == 127);
gen = fluid_list_get(fluid_list_nth(zone->gen, 1)); gen = fluid_list_get(fluid_list_nth(zone->gen, 1));
TEST_ASSERT(gen != NULL); TEST_ASSERT(gen != NULL);
TEST_ASSERT(gen->id == Gen_VelRange); TEST_ASSERT(gen->id == GEN_VELRANGE);
TEST_ASSERT(gen->amount.range.lo == 60); TEST_ASSERT(gen->amount.range.lo == 60);
TEST_ASSERT(gen->amount.range.hi == 127); TEST_ASSERT(gen->amount.range.hi == 127);
@ -116,22 +116,22 @@ static void good_test_1zone_2gen_1termgen(int (*load_func)(SFData *sf, int size)
// bad case: too few generators in buffer, triggering a chunk size mismatch // bad case: too few generators in buffer, triggering a chunk size mismatch
static void bad_test_too_short_gen_buffer(int (*load_func)(SFData *sf, int size), SFData *sf, SFZone *zone) static void bad_test_too_short_gen_buffer(int (*load_func)(SFData *sf, int size), SFData *sf, SFZone *zone)
{ {
const Gen_Type final_gen = (load_func == &load_pgen) ? Gen_Instrument : Gen_SampleId; const unsigned char final_gen = (load_func == &load_pgen) ? GEN_INSTRUMENT : GEN_SAMPLEID;
SFGen *gen; SFGen *gen;
unsigned int i; unsigned int i;
static const unsigned char buf1[] = { Gen_KeyRange, 0, 0 }; static const unsigned char buf1[] = { GEN_KEYRANGE, 0, 0 };
static const unsigned char buf2[] = { Gen_KeyRange, 0 }; static const unsigned char buf2[] = { GEN_KEYRANGE, 0 };
static const unsigned char buf3[] = { Gen_KeyRange }; static const unsigned char buf3[] = { GEN_KEYRANGE };
static const unsigned char buf8[] = { Gen_VelRange, 0, 0 }; static const unsigned char buf8[] = { GEN_VELRANGE, 0, 0 };
static const unsigned char buf9[] = { Gen_VelRange, 0 }; static const unsigned char buf9[] = { GEN_VELRANGE, 0 };
static const unsigned char buf10[] = { Gen_VelRange }; static const unsigned char buf10[] = { GEN_VELRANGE };
static const unsigned char buf4[] = { Gen_VelRange, 0, 0, 127, Gen_CoarseTune, 0, 4 }; static const unsigned char buf4[] = { GEN_VELRANGE, 0, 0, 127, GEN_COARSETUNE, 0, 4 };
static const unsigned char buf5[] = { Gen_VelRange, 0, 0, 127, Gen_CoarseTune, 0 }; static const unsigned char buf5[] = { GEN_VELRANGE, 0, 0, 127, GEN_COARSETUNE, 0 };
static const unsigned char buf6[] = { Gen_VelRange, 0, 0, 127, Gen_CoarseTune }; static const unsigned char buf6[] = { GEN_VELRANGE, 0, 0, 127, GEN_COARSETUNE };
const unsigned char buf11[] = { Gen_VelRange, 0, 0, 127, final_gen, 0, 4 }; const unsigned char buf11[] = { GEN_VELRANGE, 0, 0, 127, final_gen, 0, 4 };
const unsigned char buf12[] = { Gen_VelRange, 0, 0, 127, final_gen, 0 }; const unsigned char buf12[] = { GEN_VELRANGE, 0, 0, 127, final_gen, 0 };
const unsigned char buf13[] = { Gen_VelRange, 0, 0, 127, final_gen }; const unsigned char buf13[] = { GEN_VELRANGE, 0, 0, 127, final_gen };
static const unsigned char buf7[] = { Gen_KeyRange, 0, 60, 127, Gen_OverrideRootKey }; static const unsigned char buf7[] = { GEN_KEYRANGE, 0, 60, 127, GEN_OVERRIDEROOTKEY };
static const buf_t buf_with_one_gen[] = static const buf_t buf_with_one_gen[] =
{ {
@ -181,7 +181,7 @@ static void bad_test_too_short_gen_buffer(int (*load_func)(SFData *sf, int size)
TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf7)) == FALSE); TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf7)) == FALSE);
gen = fluid_list_get(fluid_list_nth(zone->gen, 0)); gen = fluid_list_get(fluid_list_nth(zone->gen, 0));
TEST_ASSERT(gen != NULL); TEST_ASSERT(gen != NULL);
TEST_ASSERT(gen->id == Gen_KeyRange); TEST_ASSERT(gen->id == GEN_KEYRANGE);
TEST_ASSERT(gen->amount.range.lo == 60); TEST_ASSERT(gen->amount.range.lo == 60);
TEST_ASSERT(gen->amount.range.hi == 127); TEST_ASSERT(gen->amount.range.hi == 127);
@ -193,14 +193,14 @@ static void bad_test_too_short_gen_buffer(int (*load_func)(SFData *sf, int size)
static void bad_test_duplicate_gen(int (*load_func)(SFData *sf, int size), SFData *sf, SFZone *zone) static void bad_test_duplicate_gen(int (*load_func)(SFData *sf, int size), SFData *sf, SFZone *zone)
{ {
const SFGen *gen; const SFGen *gen;
static const unsigned char buf[] = { Gen_CoarseTune, 0, 5, 0, Gen_CoarseTune, 0, 10, 0 }; static const unsigned char buf[] = { GEN_COARSETUNE, 0, 5, 0, GEN_COARSETUNE, 0, 10, 0 };
SET_BUF(buf); SET_BUF(buf);
TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf))); TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf)));
gen = fluid_list_get(fluid_list_nth(zone->gen, 0)); gen = fluid_list_get(fluid_list_nth(zone->gen, 0));
TEST_ASSERT(gen != NULL); TEST_ASSERT(gen != NULL);
TEST_ASSERT(gen->id == Gen_CoarseTune); TEST_ASSERT(gen->id == GEN_COARSETUNE);
TEST_ASSERT(gen->amount.range.lo == 10); TEST_ASSERT(gen->amount.range.lo == 10);
TEST_ASSERT(gen->amount.range.hi == 0); TEST_ASSERT(gen->amount.range.hi == 0);
@ -217,36 +217,34 @@ static void bad_test_gen_wrong_order(int (*load_func)(SFData *sf, int size), SFD
const SFGen *gen; const SFGen *gen;
static const unsigned char buf[] = static const unsigned char buf[] =
{ {
Gen_VelRange, 0, 60, 127, GEN_VELRANGE, 0, 60, 127,
Gen_KeyRange, 0, 60, 127, GEN_KEYRANGE, 0, 60, 127,
Gen_Instrument, 0, 0xDD, 0xDD GEN_INSTRUMENT, 0, 0xDD, 0xDD
}; };
SET_BUF(buf); SET_BUF(buf);
TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf))); TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf)));
gen = fluid_list_get(fluid_list_nth(zone->gen, 0)); gen = fluid_list_get(fluid_list_nth(zone->gen, 0));
TEST_ASSERT(gen != NULL); TEST_ASSERT(gen != NULL);
TEST_ASSERT(gen->id == Gen_VelRange); TEST_ASSERT(gen->id == GEN_VELRANGE);
TEST_ASSERT(gen->amount.range.lo == 60); TEST_ASSERT(gen->amount.range.lo == 60);
TEST_ASSERT(gen->amount.range.hi == 127); TEST_ASSERT(gen->amount.range.hi == 127);
// The INSTRUMENT generator is mistakenly accepted by load_igen. This will be fixed by Marcus' PR. gen = fluid_list_get(fluid_list_nth(zone->gen, 1));
// Once merge, this if clause should be removed. if (load_func == &load_igen)
if (load_func != &load_igen)
{ {
gen = fluid_list_get(fluid_list_nth(zone->gen, 1));
TEST_ASSERT(gen == NULL); TEST_ASSERT(gen == NULL);
} }
else
{
TEST_ASSERT(gen != NULL);
TEST_ASSERT(gen->id == GEN_INSTRUMENT);
TEST_ASSERT(gen->amount.uword == 0xDDDDu);
}
gen = fluid_list_get(fluid_list_nth(zone->gen, 2)); gen = fluid_list_get(fluid_list_nth(zone->gen, 2));
TEST_ASSERT(gen == NULL); TEST_ASSERT(gen == NULL);
if (load_func == &load_pgen)
{
TEST_ASSERT(FLUID_POINTER_TO_UINT(zone->instsamp) == 0xDDDD + 1);
zone->instsamp = NULL;
}
TEST_ASSERT(file_buf == buf + sizeof(buf)); TEST_ASSERT(file_buf == buf + sizeof(buf));
UNSET_BUF; UNSET_BUF;
} }
@ -258,14 +256,14 @@ static void bad_test_issue_808(int (*load_func)(SFData *sf, int size), SFData *s
static const unsigned char buf[] = static const unsigned char buf[] =
{ {
// zone 1 // zone 1
Gen_ReverbSend, 0, 50, 0, GEN_REVERBSEND, 0, 50, 0,
Gen_VolEnvRelease, 0, 206, 249, GEN_VOLENVRELEASE, 0, 206, 249,
// zone 2 // zone 2
Gen_KeyRange, 0, 0, 35, GEN_KEYRANGE, 0, 0, 35,
Gen_OverrideRootKey, 0, 43, 0, GEN_OVERRIDEROOTKEY, 0, 43, 0,
Gen_StartAddrCoarseOfs, 0, 0, 0, GEN_STARTADDRCOARSEOFS, 0, 0, 0,
Gen_SampleModes, 0, 1, 0, GEN_SAMPLEMODE, 0, 1, 0,
Gen_StartAddrOfs, 0, 0, 0 GEN_STARTADDROFS, 0, 0, 0
}; };
SET_BUF(buf); SET_BUF(buf);
@ -273,13 +271,13 @@ static void bad_test_issue_808(int (*load_func)(SFData *sf, int size), SFData *s
gen = fluid_list_get(fluid_list_nth(zone1->gen, 0)); gen = fluid_list_get(fluid_list_nth(zone1->gen, 0));
TEST_ASSERT(gen != NULL); TEST_ASSERT(gen != NULL);
TEST_ASSERT(gen->id == Gen_ReverbSend); TEST_ASSERT(gen->id == GEN_REVERBSEND);
TEST_ASSERT(gen->amount.range.lo == 50); TEST_ASSERT(gen->amount.range.lo == 50);
TEST_ASSERT(gen->amount.range.hi == 0); TEST_ASSERT(gen->amount.range.hi == 0);
gen = fluid_list_get(fluid_list_nth(zone1->gen, 1)); gen = fluid_list_get(fluid_list_nth(zone1->gen, 1));
TEST_ASSERT(gen != NULL); TEST_ASSERT(gen != NULL);
TEST_ASSERT(gen->id == Gen_VolEnvRelease); TEST_ASSERT(gen->id == GEN_VOLENVRELEASE);
TEST_ASSERT(gen->amount.range.lo == 206); TEST_ASSERT(gen->amount.range.lo == 206);
TEST_ASSERT(gen->amount.range.hi == 249); TEST_ASSERT(gen->amount.range.hi == 249);
@ -295,48 +293,48 @@ static void bad_test_additional_gens_after_final_gen(int (*load_func)(SFData *sf
{ {
unsigned int i; unsigned int i;
SFGen *gen; SFGen *gen;
const Gen_Type final_gen = (load_func == &load_pgen) ? Gen_Instrument : Gen_SampleId; const unsigned char final_gen = (load_func == &load_pgen) ? GEN_INSTRUMENT : GEN_SAMPLEID;
const unsigned char buf1[] = const unsigned char buf1[] =
{ {
// zone 1 // zone 1
Gen_KeyRange, 0, 60, 127, GEN_KEYRANGE, 0, 60, 127,
Gen_Unused1, 0, 0xFF, 0xFF, GEN_UNUSED1, 0, 0xFF, 0xFF,
final_gen, 0, 0xDD, 0xDD, final_gen, 0, 0xDD, 0xDD,
Gen_KeyRange, 0, 0, 35, GEN_KEYRANGE, 0, 0, 35,
Gen_OverrideRootKey, 0, 43, 0, GEN_OVERRIDEROOTKEY, 0, 43, 0,
0, 0, 0, 0 // terminal generator 0, 0, 0, 0 // terminal generator
}; };
const unsigned char buf2[] = const unsigned char buf2[] =
{ {
// zone 1 // zone 1
Gen_KeyRange, 0, 60, 127, GEN_KEYRANGE, 0, 60, 127,
Gen_Unused1, 0, 0xFF, 0xFF, GEN_UNUSED1, 0, 0xFF, 0xFF,
final_gen, 0, 0xDD, 0xDD, final_gen, 0, 0xDD, 0xDD,
Gen_KeyRange, 0, 0, 35, GEN_KEYRANGE, 0, 0, 35,
Gen_OverrideRootKey, 0, 43, 0, GEN_OVERRIDEROOTKEY, 0, 43, 0,
0, 0, 0 // incomplete terminal generator 0, 0, 0 // incomplete terminal generator
}; };
const unsigned char buf3[] = const unsigned char buf3[] =
{ {
// zone 1 // zone 1
Gen_KeyRange, 0, 60, 127, GEN_KEYRANGE, 0, 60, 127,
Gen_Unused1, 0, 0xFF, 0xFF, GEN_UNUSED1, 0, 0xFF, 0xFF,
final_gen, 0, 0xDD, 0xDD, final_gen, 0, 0xDD, 0xDD,
Gen_KeyRange, 0, 0, 35, GEN_KEYRANGE, 0, 0, 35,
Gen_OverrideRootKey, 0, 43 GEN_OVERRIDEROOTKEY, 0, 43
}; };
const unsigned char buf4[] = const unsigned char buf4[] =
{ {
// zone 1 // zone 1
Gen_KeyRange, 0, 60, 127, GEN_KEYRANGE, 0, 60, 127,
Gen_Unused1, 0, 0xFF, 0xFF, GEN_UNUSED1, 0, 0xFF, 0xFF,
final_gen, 0, 0xDD, 0xDD, final_gen, 0, 0xDD, 0xDD,
Gen_KeyRange, 0, 0, 35, GEN_KEYRANGE, 0, 0, 35,
Gen_OverrideRootKey, 0 GEN_OVERRIDEROOTKEY, 0
}; };
const buf_t buf[] = const buf_t buf[] =
@ -357,7 +355,7 @@ static void bad_test_additional_gens_after_final_gen(int (*load_func)(SFData *sf
gen = fluid_list_get(fluid_list_nth(zone1->gen, 0)); gen = fluid_list_get(fluid_list_nth(zone1->gen, 0));
TEST_ASSERT(gen != NULL); TEST_ASSERT(gen != NULL);
TEST_ASSERT(gen->id == Gen_KeyRange); TEST_ASSERT(gen->id == GEN_KEYRANGE);
TEST_ASSERT(gen->amount.range.lo == 60); TEST_ASSERT(gen->amount.range.lo == 60);
TEST_ASSERT(gen->amount.range.hi == 127); TEST_ASSERT(gen->amount.range.hi == 127);
@ -366,7 +364,19 @@ static void bad_test_additional_gens_after_final_gen(int (*load_func)(SFData *sf
zone1->gen->data = NULL; zone1->gen->data = NULL;
gen = fluid_list_get(fluid_list_nth(zone1->gen, 1)); gen = fluid_list_get(fluid_list_nth(zone1->gen, 1));
TEST_ASSERT(gen == NULL); TEST_ASSERT(gen != NULL);
if (load_func == &load_igen)
{
TEST_ASSERT(gen->id == GEN_SAMPLEID);
}
else
{
TEST_ASSERT(gen->id == GEN_INSTRUMENT);
}
TEST_ASSERT(gen->amount.uword == 0xDDDDu);
// delete this generator
FLUID_FREE(gen);
zone1->gen->data = NULL;
gen = fluid_list_get(fluid_list_nth(zone1->gen, 2)); gen = fluid_list_get(fluid_list_nth(zone1->gen, 2));
TEST_ASSERT(gen == NULL); TEST_ASSERT(gen == NULL);
@ -377,9 +387,6 @@ static void bad_test_additional_gens_after_final_gen(int (*load_func)(SFData *sf
gen = fluid_list_get(fluid_list_nth(zone1->gen, 4)); gen = fluid_list_get(fluid_list_nth(zone1->gen, 4));
TEST_ASSERT(gen == NULL); TEST_ASSERT(gen == NULL);
TEST_ASSERT(FLUID_POINTER_TO_UINT(zone1->instsamp) == 0xDDDD + 1);
zone1->instsamp = NULL;
TEST_ASSERT(file_buf == buf[i].end); TEST_ASSERT(file_buf == buf[i].end);
UNSET_BUF; UNSET_BUF;