mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 15:01:40 +00:00
Store mutable information about inst zones in new fluid_voice_zone_t struct
This change separates the static instrument zone information read from the Soundfont from the information that gets modified on import and later via the legato handling. It opens opens up the possibility of having unique instruments that only get imported once and then linked into the individual preset zones.
This commit is contained in:
parent
a95a4864fd
commit
c4003bef39
2 changed files with 79 additions and 25 deletions
|
@ -636,7 +636,8 @@ fluid_defpreset_noteon(fluid_defpreset_t* defpreset, fluid_synth_t* synth, int c
|
|||
fluid_preset_zone_t *preset_zone, *global_preset_zone;
|
||||
fluid_inst_t* inst;
|
||||
fluid_inst_zone_t *inst_zone, *global_inst_zone;
|
||||
fluid_sample_t* sample;
|
||||
fluid_voice_zone_t *voice_zone;
|
||||
fluid_list_t *list;
|
||||
fluid_voice_t* voice;
|
||||
fluid_mod_t * mod;
|
||||
fluid_mod_t * mod_list[FLUID_NUM_MOD]; /* list for 'sorting' preset modulators */
|
||||
|
@ -656,24 +657,20 @@ fluid_defpreset_noteon(fluid_defpreset_t* defpreset, fluid_synth_t* synth, int c
|
|||
inst = fluid_preset_zone_get_inst(preset_zone);
|
||||
global_inst_zone = fluid_inst_get_global_zone(inst);
|
||||
|
||||
/* run thru all the zones of this instrument */
|
||||
inst_zone = fluid_inst_get_zone(inst);
|
||||
while (inst_zone != NULL) {
|
||||
/* make sure this instrument zone has a valid sample */
|
||||
sample = fluid_inst_zone_get_sample(inst_zone);
|
||||
if ((sample == NULL) || fluid_sample_in_rom(sample)) {
|
||||
inst_zone = fluid_inst_zone_next(inst_zone);
|
||||
continue;
|
||||
}
|
||||
/* run thru all the zones of this instrument that could start a voice */
|
||||
for (list = preset_zone->voice_zone; list != NULL; list = fluid_list_next(list)) {
|
||||
voice_zone = fluid_list_get(list);
|
||||
|
||||
/* check if the instrument zone is ignored and the note falls into
|
||||
the key and velocity range of this instrument zone.
|
||||
An instrument zone must be ignored when its voice is already running
|
||||
played by a legato passage (see fluid_synth_noteon_monopoly_legato()) */
|
||||
if (fluid_zone_inside_range(&inst_zone->range, key, vel)) {
|
||||
if (fluid_zone_inside_range(&voice_zone->range, key, vel)) {
|
||||
|
||||
inst_zone = voice_zone->inst_zone;
|
||||
|
||||
/* this is a good zone. allocate a new synthesis process and initialize it */
|
||||
voice = fluid_synth_alloc_voice_LOCAL(synth, sample, chan, key, vel, &inst_zone->range);
|
||||
voice = fluid_synth_alloc_voice_LOCAL(synth, inst_zone->sample, chan, key, vel, &voice_zone->range);
|
||||
if (voice == NULL) {
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
@ -842,7 +839,6 @@ fluid_defpreset_noteon(fluid_defpreset_t* defpreset, fluid_synth_t* synth, int c
|
|||
*/
|
||||
}
|
||||
|
||||
inst_zone = fluid_inst_zone_next(inst_zone);
|
||||
}
|
||||
}
|
||||
preset_zone = fluid_preset_zone_next(preset_zone);
|
||||
|
@ -994,6 +990,7 @@ void
|
|||
delete_fluid_preset_zone(fluid_preset_zone_t* zone)
|
||||
{
|
||||
fluid_mod_t *mod, *tmp;
|
||||
fluid_list_t *list;
|
||||
|
||||
fluid_return_if_fail(zone != NULL);
|
||||
|
||||
|
@ -1005,11 +1002,63 @@ delete_fluid_preset_zone(fluid_preset_zone_t* zone)
|
|||
delete_fluid_mod (tmp);
|
||||
}
|
||||
|
||||
for (list = zone->voice_zone; list != NULL; list = fluid_list_next(list))
|
||||
{
|
||||
FLUID_FREE(fluid_list_get(list));
|
||||
}
|
||||
delete_fluid_list(zone->voice_zone);
|
||||
|
||||
FLUID_FREE (zone->name);
|
||||
delete_fluid_inst (zone->inst);
|
||||
FLUID_FREE(zone);
|
||||
}
|
||||
|
||||
static int fluid_preset_zone_create_voice_zones(fluid_preset_zone_t* preset_zone)
|
||||
{
|
||||
fluid_inst_zone_t *inst_zone;
|
||||
fluid_sample_t *sample;
|
||||
fluid_voice_zone_t *voice_zone;
|
||||
fluid_zone_range_t *irange;
|
||||
fluid_zone_range_t *prange = &preset_zone->range;
|
||||
|
||||
fluid_return_val_if_fail(preset_zone->inst != NULL, FLUID_FAILED);
|
||||
|
||||
inst_zone = fluid_inst_get_zone(preset_zone->inst);
|
||||
while (inst_zone != NULL) {
|
||||
|
||||
/* We only create voice ranges for zones that could actually start a voice,
|
||||
* i.e. that have a sample and don't point to ROM */
|
||||
sample = fluid_inst_zone_get_sample(inst_zone);
|
||||
if ((sample == NULL) || fluid_sample_in_rom(sample))
|
||||
{
|
||||
inst_zone = fluid_inst_zone_next(inst_zone);
|
||||
continue;
|
||||
}
|
||||
|
||||
voice_zone = FLUID_NEW(fluid_voice_zone_t);
|
||||
if (voice_zone == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
voice_zone->inst_zone = inst_zone;
|
||||
|
||||
irange = &inst_zone->range;
|
||||
|
||||
voice_zone->range.keylo = (prange->keylo > irange->keylo) ? prange->keylo : irange->keylo;
|
||||
voice_zone->range.keyhi = (prange->keyhi < irange->keyhi) ? prange->keyhi : irange->keyhi;
|
||||
voice_zone->range.vello = (prange->vello > irange->vello) ? prange->vello : irange->vello;
|
||||
voice_zone->range.velhi = (prange->velhi < irange->velhi) ? prange->velhi : irange->velhi;
|
||||
|
||||
preset_zone->voice_zone = fluid_list_append(preset_zone->voice_zone, voice_zone);
|
||||
|
||||
inst_zone = fluid_inst_zone_next(inst_zone);
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* fluid_preset_zone_import_sfont
|
||||
*/
|
||||
|
@ -1054,6 +1103,11 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_
|
|||
(SFInst *) sfzone->instsamp->data, defsfont) != FLUID_OK) {
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if (fluid_preset_zone_create_voice_zones(zone) == FLUID_FAILED)
|
||||
{
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Import the modulators (only SF2.1 and higher) */
|
||||
|
@ -1284,7 +1338,7 @@ fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_t* inst,
|
|||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if (fluid_inst_zone_import_sfont(preset_zone, inst_zone, sfzone, defsfont) != FLUID_OK) {
|
||||
if (fluid_inst_zone_import_sfont(inst_zone, sfzone, defsfont) != FLUID_OK) {
|
||||
delete_fluid_inst_zone(inst_zone);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
@ -1408,8 +1462,7 @@ fluid_inst_zone_next(fluid_inst_zone_t* zone)
|
|||
* fluid_inst_zone_import_sfont
|
||||
*/
|
||||
int
|
||||
fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, 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)
|
||||
{
|
||||
fluid_list_t *r;
|
||||
SFGen* sfgen;
|
||||
|
@ -1441,13 +1494,6 @@ fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t
|
|||
}
|
||||
r = fluid_list_next(r);
|
||||
}
|
||||
|
||||
/* adjust instrument zone keyrange to integrate preset zone keyrange */
|
||||
if (preset_zone->range.keylo > inst_zone->range.keylo) inst_zone->range.keylo = preset_zone->range.keylo;
|
||||
if (preset_zone->range.keyhi < inst_zone->range.keyhi) inst_zone->range.keyhi = preset_zone->range.keyhi;
|
||||
/* adjust instrument zone to integrate preset zone velrange */
|
||||
if (preset_zone->range.vello > inst_zone->range.vello) inst_zone->range.vello = preset_zone->range.vello;
|
||||
if (preset_zone->range.velhi < inst_zone->range.velhi) inst_zone->range.velhi = preset_zone->range.velhi;
|
||||
|
||||
/* FIXME */
|
||||
/* if (zone->gen[GEN_EXCLUSIVECLASS].flags == GEN_SET) { */
|
||||
|
|
|
@ -53,6 +53,7 @@ typedef struct _fluid_defpreset_t fluid_defpreset_t;
|
|||
typedef struct _fluid_preset_zone_t fluid_preset_zone_t;
|
||||
typedef struct _fluid_inst_t fluid_inst_t;
|
||||
typedef struct _fluid_inst_zone_t fluid_inst_zone_t; /**< Soundfont Instrument Zone */
|
||||
typedef struct _fluid_voice_zone_t fluid_voice_zone_t;
|
||||
|
||||
/* defines the velocity and key range for a zone */
|
||||
struct _fluid_zone_range_t
|
||||
|
@ -64,6 +65,13 @@ struct _fluid_zone_range_t
|
|||
unsigned char ignore; /* set to TRUE for legato playing to ignore this range zone */
|
||||
};
|
||||
|
||||
/* Stored on a preset zone to keep track of the inst zones that could start a voice
|
||||
* and their combined preset zone/instument zone ranges */
|
||||
struct _fluid_voice_zone_t
|
||||
{
|
||||
fluid_inst_zone_t *inst_zone;
|
||||
fluid_zone_range_t range;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
|
@ -163,6 +171,7 @@ struct _fluid_preset_zone_t
|
|||
fluid_preset_zone_t* next;
|
||||
char* name;
|
||||
fluid_inst_t* inst;
|
||||
fluid_list_t* voice_zone;
|
||||
fluid_zone_range_t range;
|
||||
fluid_gen_t gen[GEN_LAST];
|
||||
fluid_mod_t * mod; /* List of modulators */
|
||||
|
@ -210,8 +219,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_preset_zone_t* preset_zone,
|
||||
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);
|
||||
fluid_sample_t* fluid_inst_zone_get_sample(fluid_inst_zone_t* zone);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue