diff options
author | Chris Robinson <[email protected]> | 2014-02-02 02:39:56 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2014-02-02 02:39:56 -0800 |
commit | 7c4339c195e29b17c8f76e6fbe9c8ee1b4f7b9b8 (patch) | |
tree | 728e3298bff7d7612ee6d7fcd88a2049d343d763 /Alc/midi/base.h | |
parent | 755f161fc58aec0b541c7783ed716bd5c861a615 (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.h | 17 |
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); |