Fix scaletune error (ticket #26) and synth reset between songs (ticket #31)

This commit is contained in:
David Henningsson 2009-08-14 19:37:07 +00:00
parent bacd8dbe37
commit c914b41476
4 changed files with 47 additions and 29 deletions

View file

@ -1098,7 +1098,6 @@ fluid_track_send_events(fluid_track_t* track,
fluid_player_t* new_fluid_player(fluid_synth_t* synth)
{
int i;
char* timing_source;
fluid_player_t* player;
player = FLUID_NEW(fluid_player_t);
if (player == NULL) {
@ -1121,12 +1120,10 @@ fluid_player_t* new_fluid_player(fluid_synth_t* synth)
player->miditempo = 480000;
player->deltatime = 4.0;
player->use_system_timer = 0;
if (fluid_settings_getstr(synth->settings, "player.timing-source", &timing_source) != 0) {
if (strcmp(timing_source, "system") == 0) {
player->use_system_timer = 1;
}
}
player->use_system_timer =
fluid_settings_str_equal(synth->settings, "player.timing-source", "system");
player->reset_synth_between_songs =
fluid_settings_str_equal(synth->settings, "player.reset-synth", "yes");
return player;
}
@ -1165,6 +1162,9 @@ void fluid_player_settings(fluid_settings_t* settings)
/* player.timing-source can be either "system" (use system timer)
or "sample" (use timer based on number of written samples) */
fluid_settings_register_str(settings, "player.timing-source", "sample", 0, NULL, NULL);
/* Selects whether the player should reset the synth between
songs, or not. */
fluid_settings_register_str(settings, "player.reset-synth", "yes", 0, NULL, NULL);
}
@ -1295,6 +1295,10 @@ void fluid_player_playlist_load(fluid_player_t* player, unsigned int msec)
player->start_ticks = 0;
player->cur_ticks = 0;
if (player->reset_synth_between_songs) {
fluid_synth_system_reset(player->synth);
}
for (i = 0; i < player->ntracks; i++) {
if (player->track[i] != NULL) {
fluid_track_reset(player->track[i]);

View file

@ -250,6 +250,7 @@ struct _fluid_player_t {
char send_program_change; /* should we ignore the program changes? */
char use_system_timer; /* if zero, use sample timers, otherwise use system clock timer */
char reset_synth_between_songs; /* 1 if system reset should be sent to the synth between songs. */
int start_ticks; /* the number of tempo ticks passed at the last tempo change */
int cur_ticks; /* the number of tempo ticks passed */
int begin_msec; /* the time (msec) of the beginning of the file */

View file

@ -475,7 +475,7 @@ fluid_voice_write(fluid_voice_t* voice,
voice->phase_incr = fluid_ct2hz_real
(voice->pitch + voice->modlfo_val * voice->modlfo_to_pitch
+ voice->viblfo_val * voice->viblfo_to_pitch
+ voice->modenv_val * voice->modenv_to_pitch) / voice->root_pitch;
+ voice->modenv_val * voice->modenv_to_pitch) / voice->root_pitch_hz;
fluid_check_fpe ("voice_write phase calculation");
@ -813,6 +813,33 @@ void fluid_voice_start(fluid_voice_t* voice)
voice->status = FLUID_VOICE_ON;
}
static void
fluid_voice_calculate_gen_pitch(fluid_voice_t* voice)
{
fluid_real_t x;
/* The GEN_PITCH is a hack to fit the pitch bend controller into the
* modulator paradigm. Now the nominal pitch of the key is set.
* Note about SCALETUNE: SF2.01 8.1.3 says, that this generator is a
* non-realtime parameter. So we don't allow modulation (as opposed
* to _GEN(voice, GEN_SCALETUNE) When the scale tuning is varied,
* one key remains fixed. Here C3 (MIDI number 60) is used.
*/
if (fluid_channel_has_tuning(voice->channel)) {
/* pitch(scalekey) + scale * (pitch(key) - pitch(scalekey)) */
#define __pitch(_k) fluid_tuning_get_pitch(tuning, _k)
fluid_tuning_t* tuning = fluid_channel_get_tuning(voice->channel);
x = __pitch((int) (voice->root_pitch / 100.0f));
voice->gen[GEN_PITCH].val = (x + (voice->gen[GEN_SCALETUNE].val / 100.0f *
(__pitch(voice->key) - x)));
} else {
voice->gen[GEN_PITCH].val = (voice->gen[GEN_SCALETUNE].val * (voice->key - voice->root_pitch / 100.0f)
+ voice->root_pitch);
}
fprintf(stderr, "%d: %f %f\n", voice->id, voice->gen[GEN_PITCH].val, voice->root_pitch);
}
/*
* fluid_voice_calculate_runtime_synthesis_parameters
*
@ -911,24 +938,6 @@ fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice)
/* fluid_dump_modulator(mod); */
}
/* The GEN_PITCH is a hack to fit the pitch bend controller into the
* modulator paradigm. Now the nominal pitch of the key is set.
* Note about SCALETUNE: SF2.01 8.1.3 says, that this generator is a
* non-realtime parameter. So we don't allow modulation (as opposed
* to _GEN(voice, GEN_SCALETUNE) When the scale tuning is varied,
* one key remains fixed. Here C3 (MIDI number 60) is used.
*/
if (fluid_channel_has_tuning(voice->channel)) {
/* pitch(60) + scale * (pitch(key) - pitch(60)) */
#define __pitch(_k) fluid_tuning_get_pitch(tuning, _k)
fluid_tuning_t* tuning = fluid_channel_get_tuning(voice->channel);
voice->gen[GEN_PITCH].val = (__pitch(60) + (voice->gen[GEN_SCALETUNE].val / 100.0f *
(__pitch(voice->key) - __pitch(60))));
} else {
voice->gen[GEN_PITCH].val = (voice->gen[GEN_SCALETUNE].val * (voice->key - 60.0f)
+ 100.0f * 60.0f);
}
/* Now the generators are initialized, nominal and modulation value.
* The voice parameters (which depend on generators) are calculated
* with fluid_voice_update_param. Processing the list of generator
@ -1103,10 +1112,13 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
} else {
voice->root_pitch = voice->sample->origpitch * 100.0f - voice->sample->pitchadj;
}
voice->root_pitch = fluid_ct2hz(voice->root_pitch);
fprintf(stderr, "%d: %f\n", voice->id, voice->root_pitch);
voice->root_pitch_hz = fluid_ct2hz(voice->root_pitch);
if (voice->sample != NULL) {
voice->root_pitch *= (fluid_real_t) voice->output_rate / voice->sample->samplerate;
voice->root_pitch_hz *= (fluid_real_t) voice->output_rate / voice->sample->samplerate;
}
/* voice->pitch depends on voice->root_pitch, so calculate voice->pitch now */
fluid_voice_calculate_gen_pitch(voice);
break;
case GEN_FILTERFC:

View file

@ -124,7 +124,8 @@ struct _fluid_voice_t
fluid_real_t attenuation; /* the attenuation in centibels */
fluid_real_t min_attenuation_cB; /* Estimate on the smallest possible attenuation
* during the lifetime of the voice */
fluid_real_t root_pitch;
fluid_real_t root_pitch, root_pitch_hz;
/* sample and loop start and end points (offset in sample memory). */
int start;