summaryrefslogtreecommitdiffstats
path: root/Alc/midi/base.h
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2014-02-02 02:39:56 -0800
committerChris Robinson <[email protected]>2014-02-02 02:39:56 -0800
commit7c4339c195e29b17c8f76e6fbe9c8ee1b4f7b9b8 (patch)
tree728e3298bff7d7612ee6d7fcd88a2049d343d763 /Alc/midi/base.h
parent755f161fc58aec0b541c7783ed716bd5c861a615 (diff)
Rework MIDI clock timing
It's best to avoid using doubles in the mixer since the FPU's set to single- precision mode. The new clock timing is similar to the device clock timing, and should hopefully be less prone to drift caused by fp rounding errors.
Diffstat (limited to 'Alc/midi/base.h')
-rw-r--r--Alc/midi/base.h17
1 files changed, 9 insertions, 8 deletions
diff --git a/Alc/midi/base.h b/Alc/midi/base.h
index f900c941..4d13a054 100644
--- a/Alc/midi/base.h
+++ b/Alc/midi/base.h
@@ -23,17 +23,17 @@ typedef struct Reader {
ALboolean loadSf2(Reader *stream, struct ALsoundfont *sfont, ALCcontext *context);
+#define MIDI_CLOCK_RES U64(1000000000)
+
+
struct MidiSynthVtable;
typedef struct MidiSynth {
EvtQueue EventQueue;
- ALuint64 LastEvtTime;
- ALuint64 NextEvtTime;
- ALdouble SamplesSinceLast;
- ALdouble SamplesToNext;
-
- ALdouble SamplesPerTick;
+ ALuint64 ClockBase;
+ ALuint SamplesDone;
+ ALuint SampleRate;
/* NOTE: This rwlock is for the state and soundfont. The EventQueue and
* related must instead use the device lock as they're used in the mixer
@@ -59,14 +59,15 @@ inline void MidiSynth_setState(MidiSynth *self, ALenum state) { ExchangeInt(&sel
inline ALenum MidiSynth_getState(const MidiSynth *self) { return self->State; }
void MidiSynth_stop(MidiSynth *self);
inline void MidiSynth_reset(MidiSynth *self) { MidiSynth_stop(self); }
-ALuint64 MidiSynth_getTime(const MidiSynth *self);
+inline ALuint64 MidiSynth_getTime(const MidiSynth *self)
+{ return self->ClockBase + (self->SamplesDone*MIDI_CLOCK_RES/self->SampleRate); }
inline ALuint64 MidiSynth_getNextEvtTime(const MidiSynth *self)
{
if(self->EventQueue.pos == self->EventQueue.size)
return UINT64_MAX;
return self->EventQueue.events[self->EventQueue.pos].time;
}
-void MidiSynth_setSampleRate(MidiSynth *self, ALdouble srate);
+void MidiSynth_setSampleRate(MidiSynth *self, ALuint srate);
inline void MidiSynth_update(MidiSynth *self, ALCdevice *device)
{ MidiSynth_setSampleRate(self, device->Frequency); }
ALenum MidiSynth_insertEvent(MidiSynth *self, ALuint64 time, ALuint event, ALsizei param1, ALsizei param2);