mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-02-25 21:31:49 +00:00
This commit is contained in:
parent
bacd8dbe37
commit
c914b41476
4 changed files with 47 additions and 29 deletions
|
@ -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]);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue