Fixed vel2fc default modulator.

This commit is contained in:
Bernat Arlandis i Mañó 2009-01-24 16:46:59 +00:00
parent 15322a71ba
commit e4409a8641
5 changed files with 38 additions and 58 deletions

View file

@ -143,6 +143,7 @@ struct _fluid_preset_t {
struct _fluid_sample_t
{
char name[21];
unsigned int version; /* Sound font version in the form 0xMMmm */
unsigned int start;
unsigned int end; /* Note: Index of last valid sample point (contrary to SF spec) */
unsigned int loopstart;

View file

@ -136,7 +136,7 @@ fluid_real_t
fluid_ct2hz(fluid_real_t cents)
{
/* Filter fc limit: SF2.01 page 48 # 8 */
if (cents >= 13500){
if (cents > 13500){
cents = 13500; /* 20 kHz */
} else if (cents < 1500){
cents = 1500; /* 20 Hz */

View file

@ -270,7 +270,6 @@ char* fluid_defsfont_get_name(fluid_defsfont_t* sfont)
return sfont->filename;
}
/*
* fluid_defsfont_load
*/
@ -282,6 +281,7 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file)
SFSample* sfsample;
fluid_sample_t* sample;
fluid_defpreset_t* preset;
unsigned int sample_version;
sfont->filename = FLUID_MALLOC(1 + FLUID_STRLEN(file));
if (sfont->filename == NULL) {
@ -297,6 +297,9 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file)
return FLUID_FAILED;
}
/* Calculate sound font version for samples, it's used later */
sample_version = 0x100*sfdata->version.major + sfdata->version.minor;
/* Keep track of the position and size of the sample data because
it's loaded separately (and might be unoaded/reloaded in future) */
sfont->samplepos = sfdata->samplepos;
@ -314,6 +317,8 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file)
sample = new_fluid_sample();
if (sample == NULL) goto err_exit;
sample->version = sample_version;
if (fluid_sample_import_sfont(sample, sfsample, sfont) != FLUID_OK)
goto err_exit;

View file

@ -118,46 +118,6 @@ fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voic
return 0.0f;
}
/* 'special treatment' for default controller
*
* Reference: SF2.01 section 8.4.2
*
* The GM default controller 'vel-to-filter cut off' is not clearly
* defined: If implemented according to the specs, the filter
* frequency jumps between vel=63 and vel=64. To maintain
* compatibility with existing sound fonts, the implementation is
* 'hardcoded', it is impossible to implement using only one
* modulator otherwise.
*
* I assume here, that the 'intention' of the paragraph is one
* octave (1200 cents) filter frequency shift between vel=127 and
* vel=64. 'amount' is (-2400), at least as long as the controller
* is set to default.
*
* Further, the 'appearance' of the modulator (source enumerator,
* destination enumerator, flags etc) is different from that
* described in section 8.4.2, but it matches the definition used in
* several SF2.1 sound fonts (where it is used only to turn it off).
* */
if ((mod->src2 == FLUID_MOD_VELOCITY) &&
(mod->src1 == FLUID_MOD_VELOCITY) &&
(mod->flags1 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR
| FLUID_MOD_NEGATIVE | FLUID_MOD_LINEAR)) &&
(mod->flags2 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR
| FLUID_MOD_POSITIVE | FLUID_MOD_SWITCH)) &&
(mod->dest == GEN_FILTERFC)) {
// S. Christian Collins' mod, to stop forcing velocity based filtering
/*
if (voice->vel < 64){
return (fluid_real_t) mod->amount / 2.0;
} else {
return (fluid_real_t) mod->amount * (127 - voice->vel) / 127;
}
*/
return 0; // (fluid_real_t) mod->amount / 2.0;
}
// end S. Christian Collins' mod
/* get the initial value of the first source */
if (mod->src1 > 0) {
if (mod->flags1 & FLUID_MOD_CC) {

View file

@ -77,7 +77,8 @@ static void init_dither(void);
*/
fluid_mod_t default_vel2att_mod; /* SF2.01 section 8.4.1 */
fluid_mod_t default_vel2filter_mod; /* SF2.01 section 8.4.2 */
fluid_mod_t default_vel2filter_mod_v201;/* SF2.01 section 8.4.2 */
fluid_mod_t default_vel2filter_mod_v204;/* SF2.04 section 8.4.2 */
fluid_mod_t default_at2viblfo_mod; /* SF2.01 section 8.4.3 */
fluid_mod_t default_mod2viblfo_mod; /* SF2.01 section 8.4.4 */
fluid_mod_t default_att_mod; /* SF2.01 section 8.4.5 */
@ -189,28 +190,34 @@ fluid_synth_init()
/* SF2.01 page 53 section 8.4.2: MIDI Note-On Velocity to Filter Cutoff
* Have to make a design decision here. The specs don't make any sense this way or another.
* One sound font, 'Kingston Piano', which has been praised for its quality, tries to
* override this modulator with an amount of 0 and positive polarity (instead of what
* the specs say, D=1) for the secondary source.
* So if we change the polarity to 'positive', one of the best free sound fonts works...
*/
fluid_mod_set_source1(&default_vel2filter_mod, FLUID_MOD_VELOCITY, /* Index=2 */
/* SF2.01 page 53 section 8.4.2: MIDI Note-On Velocity to Filter Cutoff */
fluid_mod_set_source1(&default_vel2filter_mod_v201, FLUID_MOD_VELOCITY, /* Index=2 */
FLUID_MOD_GC /* CC=0 */
| FLUID_MOD_LINEAR /* type=0 */
| FLUID_MOD_UNIPOLAR /* P=0 */
| FLUID_MOD_NEGATIVE /* D=1 */
);
fluid_mod_set_source2(&default_vel2filter_mod, FLUID_MOD_VELOCITY, /* Index=2 */
fluid_mod_set_source2(&default_vel2filter_mod_v201, FLUID_MOD_VELOCITY, /* Index=2 */
FLUID_MOD_GC /* CC=0 */
| FLUID_MOD_SWITCH /* type=3 */
| FLUID_MOD_UNIPOLAR /* P=0 */
// do not remove | FLUID_MOD_NEGATIVE /* D=1 */
| FLUID_MOD_POSITIVE /* D=0 */
| FLUID_MOD_NEGATIVE /* D=1 */
);
fluid_mod_set_dest(&default_vel2filter_mod, GEN_FILTERFC); /* Target: Initial filter cutoff */
fluid_mod_set_amount(&default_vel2filter_mod, -2400);
fluid_mod_set_dest(&default_vel2filter_mod_v201, GEN_FILTERFC); /* Target: Initial filter cutoff */
fluid_mod_set_amount(&default_vel2filter_mod_v201, -2400);
/* SF2.04 page 42 section 8.4.2: MIDI Note-On Velocity to Filter Cutoff */
fluid_mod_set_source1(&default_vel2filter_mod_v204, FLUID_MOD_VELOCITY, /* Index=2 */
FLUID_MOD_GC /* CC=0 */
| FLUID_MOD_LINEAR /* type=0 */
| FLUID_MOD_UNIPOLAR /* P=0 */
| FLUID_MOD_NEGATIVE /* D=1 */
);
fluid_mod_set_source2(&default_vel2filter_mod_v204, 0, 0); /* No 2nd source */
fluid_mod_set_dest(&default_vel2filter_mod_v204, GEN_FILTERFC); /* Target: Initial filter cutoff */
fluid_mod_set_amount(&default_vel2filter_mod_v204, -2400);
@ -2144,7 +2151,14 @@ fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, int chan,
/* add the default modulators to the synthesis process. */
fluid_voice_add_mod(voice, &default_vel2att_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.1 */
fluid_voice_add_mod(voice, &default_vel2filter_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.2 */
if (sample->version>0x201)
{
fluid_voice_add_mod(voice, &default_vel2filter_mod_v204, FLUID_VOICE_DEFAULT); /* SF2.04 $8.4.2 */
}
else
{
fluid_voice_add_mod(voice, &default_vel2filter_mod_v201, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.2 */
}
fluid_voice_add_mod(voice, &default_at2viblfo_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.3 */
fluid_voice_add_mod(voice, &default_mod2viblfo_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.4 */
fluid_voice_add_mod(voice, &default_att_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.5 */