summaryrefslogtreecommitdiff
path: root/src/i_oplmusic.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/i_oplmusic.c')
-rw-r--r--src/i_oplmusic.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c
index f38e7162..5f9ab462 100644
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -47,7 +47,7 @@
#define PERCUSSION_LOG_LEN 16
// TODO: Figure out why this is needed.
-#define TEMPO_FUDGE_FACTOR 0.26
+#define TEMPO_FUDGE_FACTOR 260
typedef struct
{
@@ -1016,6 +1016,12 @@ static void PitchBendEvent(opl_track_data_t *track, midi_event_t *event)
}
}
+static void MetaSetTempo(unsigned int tempo)
+{
+ OPL_AdjustCallbacks((float) us_per_beat / tempo);
+ us_per_beat = tempo;
+}
+
// Process a meta event.
static void MetaEvent(opl_track_data_t *track, midi_event_t *event)
@@ -1041,7 +1047,7 @@ static void MetaEvent(opl_track_data_t *track, midi_event_t *event)
case MIDI_META_SET_TEMPO:
if (data_len == 3)
{
- us_per_beat = (data[0] << 16) | (data[1] << 8) | data[2];
+ MetaSetTempo((data[0] << 16) | (data[1] << 8) | data[2]);
}
break;
@@ -1154,7 +1160,7 @@ static void TrackTimerCallback(void *arg)
if (running_tracks <= 0 && song_looping)
{
- OPL_SetCallback(5, RestartSong, NULL);
+ OPL_SetCallback(5000, RestartSong, NULL);
}
return;
@@ -1168,19 +1174,18 @@ static void TrackTimerCallback(void *arg)
static void ScheduleTrack(opl_track_data_t *track)
{
unsigned int nticks;
- unsigned int ms;
- static int total = 0;
+ uint64_t us;
- // Get the number of milliseconds until the next event.
+ // Get the number of microseconds until the next event.
nticks = MIDI_GetDeltaTime(track->iter);
- ms = (nticks * us_per_beat * TEMPO_FUDGE_FACTOR) / ticks_per_beat;
- total += ms;
+ us = ((uint64_t) nticks * us_per_beat * TEMPO_FUDGE_FACTOR)
+ / ticks_per_beat;
// Set a timer to be invoked when the next event is
// ready to play.
- OPL_SetCallback(ms, TrackTimerCallback, track);
+ OPL_SetCallback(us, TrackTimerCallback, track);
}
// Initialize a channel.