mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-12-02 17:12:15 +00:00
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:
commit
aad6288955
5 changed files with 269 additions and 455 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;
|
||||
}
|
||||
|
@ -562,7 +562,7 @@ err_exit:
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -112,39 +112,34 @@ static const uint32_t idlist[] =
|
|||
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[] =
|
||||
{
|
||||
Gen_Unused1,
|
||||
Gen_Unused2,
|
||||
Gen_Unused3,
|
||||
Gen_Unused4,
|
||||
Gen_Reserved1,
|
||||
Gen_Reserved2,
|
||||
Gen_Reserved3,
|
||||
0
|
||||
GEN_UNUSED1,
|
||||
GEN_UNUSED2,
|
||||
GEN_UNUSED3,
|
||||
GEN_UNUSED4,
|
||||
GEN_RESERVED1,
|
||||
GEN_RESERVED2,
|
||||
GEN_RESERVED3,
|
||||
GEN_INSTRUMENT,
|
||||
};
|
||||
|
||||
static const unsigned short invalid_preset_gen[] =
|
||||
{
|
||||
Gen_StartAddrOfs,
|
||||
Gen_EndAddrOfs,
|
||||
Gen_StartLoopAddrOfs,
|
||||
Gen_EndLoopAddrOfs,
|
||||
Gen_StartAddrCoarseOfs,
|
||||
Gen_EndAddrCoarseOfs,
|
||||
Gen_StartLoopAddrCoarseOfs,
|
||||
Gen_Keynum,
|
||||
Gen_Velocity,
|
||||
Gen_EndLoopAddrCoarseOfs,
|
||||
Gen_SampleModes,
|
||||
Gen_ExclusiveClass,
|
||||
Gen_OverrideRootKey,
|
||||
0
|
||||
GEN_STARTADDROFS,
|
||||
GEN_ENDADDROFS,
|
||||
GEN_STARTLOOPADDROFS,
|
||||
GEN_ENDLOOPADDROFS,
|
||||
GEN_STARTADDRCOARSEOFS,
|
||||
GEN_ENDADDRCOARSEOFS,
|
||||
GEN_STARTLOOPADDRCOARSEOFS,
|
||||
GEN_KEYNUM,
|
||||
GEN_VELOCITY,
|
||||
GEN_ENDLOOPADDRCOARSEOFS,
|
||||
GEN_SAMPLEMODE,
|
||||
GEN_EXCLUSIVECLASS,
|
||||
GEN_OVERRIDEROOTKEY,
|
||||
GEN_SAMPLEID,
|
||||
};
|
||||
|
||||
|
||||
|
@ -244,8 +239,6 @@ static int load_ibag(SFData *sf, int size);
|
|||
static int load_imod(SFData *sf, int size);
|
||||
extern 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 +622,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);
|
||||
|
||||
|
@ -1024,9 +1007,9 @@ static int load_phdr(SFData *sf, unsigned int size)
|
|||
READW(sf, preset->prenum);
|
||||
READW(sf, preset->bank);
|
||||
READW(sf, pbag_idx);
|
||||
READD(sf, preset->libr);
|
||||
READD(sf, preset->genre);
|
||||
READD(sf, preset->morph);
|
||||
FSKIP(sf, 4); /* library ignored */
|
||||
FSKIP(sf, 4); /* genre ignored */
|
||||
FSKIP(sf, 4); /* morphology ignored */
|
||||
|
||||
if(prev_preset)
|
||||
{
|
||||
|
@ -1091,14 +1074,14 @@ static int load_pbag(SFData *sf, int size)
|
|||
|
||||
preset_list = sf->preset;
|
||||
|
||||
/* traverse through presets */
|
||||
while(preset_list)
|
||||
{
|
||||
/* traverse through presets */
|
||||
zone_list = ((SFPreset *)(preset_list->data))->zone;
|
||||
|
||||
/* traverse preset's zones */
|
||||
while(zone_list)
|
||||
{
|
||||
/* traverse preset's zones */
|
||||
if((size -= SF_BAG_SIZE) < 0)
|
||||
{
|
||||
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) */
|
||||
READW(sf, genndx); /* possible read failure ^ */
|
||||
READW(sf, modndx);
|
||||
z->instsamp = NULL;
|
||||
|
||||
if(pz)
|
||||
{
|
||||
|
@ -1298,37 +1280,33 @@ static int load_pmod(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 *zone_list;
|
||||
fluid_list_t *gen_list;
|
||||
fluid_list_t *start_of_zone_list;
|
||||
SFZone *z;
|
||||
SFZone *zone;
|
||||
SFGen *g;
|
||||
SFPreset *preset;
|
||||
SFGenAmount genval;
|
||||
unsigned short genid;
|
||||
int level, skip, drop, gzone, discarded;
|
||||
int level, skip, drop, discarded;
|
||||
|
||||
preset_list = sf->preset;
|
||||
|
||||
while(preset_list)
|
||||
{
|
||||
preset = fluid_list_get(preset_list);
|
||||
|
||||
/* traverse through all presets */
|
||||
gzone = FALSE;
|
||||
discarded = FALSE;
|
||||
start_of_zone_list = zone_list = ((SFPreset *)(preset_list->data))->zone;
|
||||
|
||||
if(zone_list)
|
||||
{
|
||||
hz = &zone_list;
|
||||
}
|
||||
zone_list = preset->zone;
|
||||
|
||||
/* traverse preset's zones */
|
||||
while(zone_list)
|
||||
{
|
||||
/* traverse preset's zones */
|
||||
zone = fluid_list_get(zone_list);
|
||||
level = 0;
|
||||
z = (SFZone *)(zone_list->data);
|
||||
gen_list = z->gen;
|
||||
gen_list = zone->gen;
|
||||
|
||||
while(gen_list)
|
||||
{
|
||||
|
@ -1345,7 +1323,7 @@ int load_pgen(SFData *sf, int size)
|
|||
|
||||
READW(sf, genid);
|
||||
|
||||
if(genid == Gen_KeyRange)
|
||||
if(genid == GEN_KEYRANGE)
|
||||
{
|
||||
/* nothing precedes */
|
||||
if(level == 0)
|
||||
|
@ -1359,7 +1337,7 @@ int load_pgen(SFData *sf, int size)
|
|||
skip = TRUE;
|
||||
}
|
||||
}
|
||||
else if(genid == Gen_VelRange)
|
||||
else if(genid == GEN_VELRANGE)
|
||||
{
|
||||
/* only KeyRange precedes */
|
||||
if(level <= 1)
|
||||
|
@ -1373,13 +1351,11 @@ int load_pgen(SFData *sf, int size)
|
|||
skip = TRUE;
|
||||
}
|
||||
}
|
||||
else if(genid == Gen_Instrument)
|
||||
else if(genid == GEN_INSTRUMENT)
|
||||
{
|
||||
/* 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
|
||||
{
|
||||
|
@ -1389,7 +1365,7 @@ int load_pgen(SFData *sf, int size)
|
|||
{
|
||||
/* generator valid? */
|
||||
READW(sf, genval.sword);
|
||||
dup = find_gen_by_id(genid, z->gen);
|
||||
dup = find_gen_by_id(genid, zone->gen);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1433,49 +1409,38 @@ int load_pgen(SFData *sf, int size)
|
|||
}
|
||||
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 */
|
||||
|
||||
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? */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* congratulations its a global zone */
|
||||
if(!gzone)
|
||||
{
|
||||
/* Prior global zones? */
|
||||
gzone = TRUE;
|
||||
/* advance to next zone before deleting the current list element */
|
||||
zone_list = fluid_list_next(zone_list);
|
||||
|
||||
/* 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",
|
||||
((SFPreset *)(preset_list->data))->name);
|
||||
fluid_list_remove(start_of_zone_list, z);
|
||||
delete_zone(z);
|
||||
continue;
|
||||
}
|
||||
FLUID_LOG(FLUID_WARN, "Preset '%s': Discarding invalid global zone",
|
||||
preset->name);
|
||||
preset->zone = fluid_list_remove(preset->zone, zone);
|
||||
delete_zone(zone);
|
||||
|
||||
/* we have already advanced the zone_list pointer, so continue with next zone */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* All remaining generators are invalid and should be discarded
|
||||
* (because they come after an instrument generator) */
|
||||
while(gen_list)
|
||||
{
|
||||
/* Kill any zones following an instrument */
|
||||
discarded = TRUE;
|
||||
|
||||
if((size -= SF_GEN_SIZE) < 0)
|
||||
|
@ -1485,17 +1450,17 @@ int load_pgen(SFData *sf, int 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)
|
||||
{
|
||||
FLUID_LOG(FLUID_WARN,
|
||||
"Preset '%s': Some invalid generators were discarded",
|
||||
((SFPreset *)(preset_list->data))->name);
|
||||
preset->name);
|
||||
}
|
||||
|
||||
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 */
|
||||
READW(sf, genndx); /* READW = possible read failure */
|
||||
READW(sf, modndx);
|
||||
z->instsamp = NULL;
|
||||
|
||||
if(pz)
|
||||
{
|
||||
|
@ -1817,37 +1781,34 @@ static int load_imod(SFData *sf, int size)
|
|||
/* load instrument generators (see load_pgen for loading rules) */
|
||||
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 *zone_list;
|
||||
fluid_list_t *gen_list;
|
||||
fluid_list_t *start_of_zone_list;
|
||||
SFZone *z;
|
||||
SFZone *zone;
|
||||
SFGen *g;
|
||||
SFInst *inst;
|
||||
SFGenAmount genval;
|
||||
unsigned short genid;
|
||||
int level, skip, drop, gzone, discarded;
|
||||
int level, skip, drop, discarded;
|
||||
|
||||
inst_list = sf->inst;
|
||||
|
||||
/* traverse through all instruments */
|
||||
while(inst_list)
|
||||
{
|
||||
/* traverse through all instruments */
|
||||
gzone = FALSE;
|
||||
inst = fluid_list_get(inst_list);
|
||||
|
||||
discarded = FALSE;
|
||||
start_of_zone_list = zone_list = ((SFInst *)(inst_list->data))->zone;
|
||||
|
||||
if(zone_list)
|
||||
{
|
||||
hz = &zone_list;
|
||||
}
|
||||
zone_list = inst->zone;
|
||||
|
||||
/* traverse this instrument's zones */
|
||||
while(zone_list)
|
||||
{
|
||||
/* traverse this instrument's zones */
|
||||
zone = fluid_list_get(zone_list);
|
||||
|
||||
level = 0;
|
||||
z = (SFZone *)(zone_list->data);
|
||||
gen_list = z->gen;
|
||||
gen_list = zone->gen;
|
||||
|
||||
while(gen_list)
|
||||
{
|
||||
|
@ -1864,7 +1825,7 @@ int load_igen(SFData *sf, int size)
|
|||
|
||||
READW(sf, genid);
|
||||
|
||||
if(genid == Gen_KeyRange)
|
||||
if(genid == GEN_KEYRANGE)
|
||||
{
|
||||
/* nothing precedes */
|
||||
if(level == 0)
|
||||
|
@ -1878,7 +1839,7 @@ int load_igen(SFData *sf, int size)
|
|||
skip = TRUE;
|
||||
}
|
||||
}
|
||||
else if(genid == Gen_VelRange)
|
||||
else if(genid == GEN_VELRANGE)
|
||||
{
|
||||
/* only KeyRange precedes */
|
||||
if(level <= 1)
|
||||
|
@ -1892,13 +1853,11 @@ int load_igen(SFData *sf, int size)
|
|||
skip = TRUE;
|
||||
}
|
||||
}
|
||||
else if(genid == Gen_SampleId)
|
||||
else if(genid == GEN_SAMPLEID)
|
||||
{
|
||||
/* 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
|
||||
{
|
||||
|
@ -1908,7 +1867,7 @@ int load_igen(SFData *sf, int size)
|
|||
{
|
||||
/* gen valid? */
|
||||
READW(sf, genval.sword);
|
||||
dup = find_gen_by_id(genid, z->gen);
|
||||
dup = find_gen_by_id(genid, zone->gen);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1952,48 +1911,38 @@ int load_igen(SFData *sf, int size)
|
|||
}
|
||||
else
|
||||
{
|
||||
SLADVREM(z->gen, gen_list);
|
||||
SLADVREM(zone->gen, gen_list);
|
||||
}
|
||||
|
||||
/* GEN_SAMPLEID should be last generator */
|
||||
if (level == 3)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
} /* 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? */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* its a global zone */
|
||||
if(!gzone)
|
||||
{
|
||||
gzone = TRUE;
|
||||
/* advance to next zone before deleting the current list element */
|
||||
zone_list = fluid_list_next(zone_list);
|
||||
|
||||
/* 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",
|
||||
((SFInst *)(inst_list->data))->name);
|
||||
fluid_list_remove(start_of_zone_list, z);
|
||||
delete_zone(z);
|
||||
continue;
|
||||
}
|
||||
FLUID_LOG(FLUID_WARN, "Instrument '%s': Discarding invalid global zone",
|
||||
inst->name);
|
||||
inst->zone = fluid_list_remove(inst->zone, zone);
|
||||
delete_zone(zone);
|
||||
|
||||
/* we have already advanced the zone_list pointer, so continue with next zone */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* All remaining generators must be invalid and should be discarded
|
||||
* (because they come after a sampleid generator) */
|
||||
while(gen_list)
|
||||
{
|
||||
/* Kill any zones following a sample */
|
||||
discarded = TRUE;
|
||||
|
||||
if((size -= SF_GEN_SIZE) < 0)
|
||||
|
@ -2003,7 +1952,7 @@ int load_igen(SFData *sf, int 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 */
|
||||
|
@ -2013,7 +1962,7 @@ int load_igen(SFData *sf, int size)
|
|||
{
|
||||
FLUID_LOG(FLUID_WARN,
|
||||
"Instrument '%s': Some invalid generators were discarded",
|
||||
((SFInst *)(inst_list->data))->name);
|
||||
inst->name);
|
||||
}
|
||||
|
||||
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");
|
||||
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);
|
||||
READD(sf, p->start);
|
||||
READD(sf, p->end);
|
||||
|
@ -2087,98 +2037,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;
|
||||
}
|
||||
|
||||
void delete_preset(SFPreset *preset)
|
||||
{
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
static int valid_preset_genid(unsigned short genid)
|
||||
{
|
||||
int i = 0;
|
||||
size_t i;
|
||||
|
||||
if(!valid_inst_genid(genid))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,10 +45,6 @@ typedef struct _SFInst SFInst;
|
|||
typedef struct _SFPreset SFPreset;
|
||||
typedef struct _SFData SFData;
|
||||
typedef struct _SFChunk SFChunk;
|
||||
typedef struct _SFPhdr SFPhdr;
|
||||
typedef struct _SFBag SFBag;
|
||||
typedef struct _SFIhdr SFIhdr;
|
||||
typedef struct _SFShdr SFShdr;
|
||||
|
||||
|
||||
struct _SFVersion
|
||||
|
@ -89,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 */
|
||||
};
|
||||
|
@ -98,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
|
||||
|
@ -130,9 +126,6 @@ struct _SFPreset
|
|||
char name[21]; /* preset name */
|
||||
unsigned short prenum; /* preset 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 */
|
||||
};
|
||||
|
||||
|
@ -183,44 +176,6 @@ struct _SFChunk
|
|||
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 */
|
||||
SFData *fluid_sffile_open(const char *fname, const fluid_file_callbacks_t *fcbs);
|
||||
void fluid_sffile_close(SFData *sf);
|
||||
|
@ -236,69 +191,4 @@ void delete_preset(SFPreset *preset);
|
|||
void delete_inst(SFInst *inst);
|
||||
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 */
|
||||
|
|
|
@ -92,20 +92,20 @@ static void good_test_1zone_2gen_1termgen(int (*load_func)(SFData *sf, int size)
|
|||
const SFGen *gen;
|
||||
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);
|
||||
TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf)));
|
||||
|
||||
gen = fluid_list_get(fluid_list_nth(zone->gen, 0));
|
||||
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.hi == 127);
|
||||
|
||||
gen = fluid_list_get(fluid_list_nth(zone->gen, 1));
|
||||
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.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
|
||||
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;
|
||||
unsigned int i;
|
||||
static const unsigned char buf1[] = { Gen_KeyRange, 0, 0 };
|
||||
static const unsigned char buf2[] = { Gen_KeyRange, 0 };
|
||||
static const unsigned char buf3[] = { Gen_KeyRange };
|
||||
static const unsigned char buf8[] = { Gen_VelRange, 0, 0 };
|
||||
static const unsigned char buf9[] = { Gen_VelRange, 0 };
|
||||
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 buf5[] = { Gen_VelRange, 0, 0, 127, Gen_CoarseTune, 0 };
|
||||
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 buf12[] = { Gen_VelRange, 0, 0, 127, final_gen, 0 };
|
||||
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 buf1[] = { GEN_KEYRANGE, 0, 0 };
|
||||
static const unsigned char buf2[] = { GEN_KEYRANGE, 0 };
|
||||
static const unsigned char buf3[] = { GEN_KEYRANGE };
|
||||
static const unsigned char buf8[] = { GEN_VELRANGE, 0, 0 };
|
||||
static const unsigned char buf9[] = { GEN_VELRANGE, 0 };
|
||||
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 buf5[] = { GEN_VELRANGE, 0, 0, 127, GEN_COARSETUNE, 0 };
|
||||
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 buf12[] = { GEN_VELRANGE, 0, 0, 127, final_gen, 0 };
|
||||
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 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);
|
||||
gen = fluid_list_get(fluid_list_nth(zone->gen, 0));
|
||||
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.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)
|
||||
{
|
||||
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);
|
||||
TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf)));
|
||||
|
||||
gen = fluid_list_get(fluid_list_nth(zone->gen, 0));
|
||||
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.hi == 0);
|
||||
|
||||
|
@ -217,36 +217,34 @@ static void bad_test_gen_wrong_order(int (*load_func)(SFData *sf, int size), SFD
|
|||
const SFGen *gen;
|
||||
static const unsigned char buf[] =
|
||||
{
|
||||
Gen_VelRange, 0, 60, 127,
|
||||
Gen_KeyRange, 0, 60, 127,
|
||||
Gen_Instrument, 0, 0xDD, 0xDD
|
||||
GEN_VELRANGE, 0, 60, 127,
|
||||
GEN_KEYRANGE, 0, 60, 127,
|
||||
GEN_INSTRUMENT, 0, 0xDD, 0xDD
|
||||
};
|
||||
SET_BUF(buf);
|
||||
TEST_ASSERT(load_func(sf, FLUID_N_ELEMENTS(buf)));
|
||||
|
||||
gen = fluid_list_get(fluid_list_nth(zone->gen, 0));
|
||||
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.hi == 127);
|
||||
|
||||
// The INSTRUMENT generator is mistakenly accepted by load_igen. This will be fixed by Marcus' PR.
|
||||
// Once merge, this if clause should be removed.
|
||||
if (load_func != &load_igen)
|
||||
gen = fluid_list_get(fluid_list_nth(zone->gen, 1));
|
||||
if (load_func == &load_igen)
|
||||
{
|
||||
gen = fluid_list_get(fluid_list_nth(zone->gen, 1));
|
||||
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));
|
||||
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));
|
||||
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[] =
|
||||
{
|
||||
// zone 1
|
||||
Gen_ReverbSend, 0, 50, 0,
|
||||
Gen_VolEnvRelease, 0, 206, 249,
|
||||
GEN_REVERBSEND, 0, 50, 0,
|
||||
GEN_VOLENVRELEASE, 0, 206, 249,
|
||||
// zone 2
|
||||
Gen_KeyRange, 0, 0, 35,
|
||||
Gen_OverrideRootKey, 0, 43, 0,
|
||||
Gen_StartAddrCoarseOfs, 0, 0, 0,
|
||||
Gen_SampleModes, 0, 1, 0,
|
||||
Gen_StartAddrOfs, 0, 0, 0
|
||||
GEN_KEYRANGE, 0, 0, 35,
|
||||
GEN_OVERRIDEROOTKEY, 0, 43, 0,
|
||||
GEN_STARTADDRCOARSEOFS, 0, 0, 0,
|
||||
GEN_SAMPLEMODE, 0, 1, 0,
|
||||
GEN_STARTADDROFS, 0, 0, 0
|
||||
};
|
||||
|
||||
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));
|
||||
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.hi == 0);
|
||||
|
||||
gen = fluid_list_get(fluid_list_nth(zone1->gen, 1));
|
||||
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.hi == 249);
|
||||
|
||||
|
@ -295,48 +293,48 @@ static void bad_test_additional_gens_after_final_gen(int (*load_func)(SFData *sf
|
|||
{
|
||||
unsigned int i;
|
||||
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[] =
|
||||
{
|
||||
// zone 1
|
||||
Gen_KeyRange, 0, 60, 127,
|
||||
Gen_Unused1, 0, 0xFF, 0xFF,
|
||||
GEN_KEYRANGE, 0, 60, 127,
|
||||
GEN_UNUSED1, 0, 0xFF, 0xFF,
|
||||
final_gen, 0, 0xDD, 0xDD,
|
||||
Gen_KeyRange, 0, 0, 35,
|
||||
Gen_OverrideRootKey, 0, 43, 0,
|
||||
GEN_KEYRANGE, 0, 0, 35,
|
||||
GEN_OVERRIDEROOTKEY, 0, 43, 0,
|
||||
0, 0, 0, 0 // terminal generator
|
||||
};
|
||||
|
||||
const unsigned char buf2[] =
|
||||
{
|
||||
// zone 1
|
||||
Gen_KeyRange, 0, 60, 127,
|
||||
Gen_Unused1, 0, 0xFF, 0xFF,
|
||||
GEN_KEYRANGE, 0, 60, 127,
|
||||
GEN_UNUSED1, 0, 0xFF, 0xFF,
|
||||
final_gen, 0, 0xDD, 0xDD,
|
||||
Gen_KeyRange, 0, 0, 35,
|
||||
Gen_OverrideRootKey, 0, 43, 0,
|
||||
GEN_KEYRANGE, 0, 0, 35,
|
||||
GEN_OVERRIDEROOTKEY, 0, 43, 0,
|
||||
0, 0, 0 // incomplete terminal generator
|
||||
};
|
||||
|
||||
const unsigned char buf3[] =
|
||||
{
|
||||
// zone 1
|
||||
Gen_KeyRange, 0, 60, 127,
|
||||
Gen_Unused1, 0, 0xFF, 0xFF,
|
||||
GEN_KEYRANGE, 0, 60, 127,
|
||||
GEN_UNUSED1, 0, 0xFF, 0xFF,
|
||||
final_gen, 0, 0xDD, 0xDD,
|
||||
Gen_KeyRange, 0, 0, 35,
|
||||
Gen_OverrideRootKey, 0, 43
|
||||
GEN_KEYRANGE, 0, 0, 35,
|
||||
GEN_OVERRIDEROOTKEY, 0, 43
|
||||
};
|
||||
|
||||
const unsigned char buf4[] =
|
||||
{
|
||||
// zone 1
|
||||
Gen_KeyRange, 0, 60, 127,
|
||||
Gen_Unused1, 0, 0xFF, 0xFF,
|
||||
GEN_KEYRANGE, 0, 60, 127,
|
||||
GEN_UNUSED1, 0, 0xFF, 0xFF,
|
||||
final_gen, 0, 0xDD, 0xDD,
|
||||
Gen_KeyRange, 0, 0, 35,
|
||||
Gen_OverrideRootKey, 0
|
||||
GEN_KEYRANGE, 0, 0, 35,
|
||||
GEN_OVERRIDEROOTKEY, 0
|
||||
};
|
||||
|
||||
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));
|
||||
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.hi == 127);
|
||||
|
||||
|
@ -366,7 +364,19 @@ static void bad_test_additional_gens_after_final_gen(int (*load_func)(SFData *sf
|
|||
zone1->gen->data = NULL;
|
||||
|
||||
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));
|
||||
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));
|
||||
TEST_ASSERT(gen == NULL);
|
||||
|
||||
TEST_ASSERT(FLUID_POINTER_TO_UINT(zone1->instsamp) == 0xDDDD + 1);
|
||||
zone1->instsamp = NULL;
|
||||
|
||||
TEST_ASSERT(file_buf == buf[i].end);
|
||||
UNSET_BUF;
|
||||
|
||||
|
|
Loading…
Reference in a new issue