diff options
author | Wohlstand <admin@wohlnet.ru> | 2017-02-28 15:50:16 +0300 |
---|---|---|
committer | Wohlstand <admin@wohlnet.ru> | 2017-02-28 15:50:16 +0300 |
commit | 285fd4e367ca7383ab57fc81f9e84731a67825bb (patch) | |
tree | 9aec429c49110ab872bc2da4dfdb5ee06ab3dd71 /src | |
parent | 1f905ede543e7c59323875562a815ab8034a5c79 (diff) | |
download | libADLMIDI-285fd4e367ca7383ab57fc81f9e84731a67825bb.tar.gz libADLMIDI-285fd4e367ca7383ab57fc81f9e84731a67825bb.tar.bz2 libADLMIDI-285fd4e367ca7383ab57fc81f9e84731a67825bb.zip |
Fixed wrong very long inter-note delays on 32-bit platforms
Diffstat (limited to 'src')
-rw-r--r-- | src/adlmidi.cpp | 2 | ||||
-rw-r--r-- | src/adlmidi.h | 8 | ||||
-rw-r--r-- | src/adlmidi_load.cpp | 6 | ||||
-rw-r--r-- | src/adlmidi_midiplay.cpp | 28 | ||||
-rw-r--r-- | src/adlmidi_private.hpp | 16 |
5 files changed, 31 insertions, 29 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index 5bb384d..dd42fb6 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -383,7 +383,7 @@ ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out) } else { - const double eat_delay = device->delay < device->maxdelay ? device->delay : device->maxdelay; + const long double eat_delay = device->delay < device->maxdelay ? device->delay : device->maxdelay; device->delay -= eat_delay; device->carry += device->PCM_RATE * eat_delay; n_periodCountStereo = static_cast<ssize_t>(device->carry); diff --git a/src/adlmidi.h b/src/adlmidi.h index 89e853f..0a4ed91 100644 --- a/src/adlmidi.h +++ b/src/adlmidi.h @@ -52,13 +52,13 @@ struct ADL_MIDIPlayer unsigned int SkipForward; unsigned int QuitWithoutLooping; unsigned int ScaleModulators; - double delay; - double carry; + long double delay; + long double carry; /* The lag between visual content and audio content equals */ /* the sum of these two buffers. */ - double mindelay; - double maxdelay; + long double mindelay; + long double maxdelay; /* For internal usage */ int stored_samples; /* num of collected samples */ diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp index a39c191..b819819 100644 --- a/src/adlmidi_load.cpp +++ b/src/adlmidi_load.cpp @@ -381,9 +381,9 @@ InvFmt: TrackData.resize(TrackCount, std::vector<uint8_t>()); CurrentPosition.track.clear(); CurrentPosition.track.resize(TrackCount); - InvDeltaTicks = fraction<long>(1, 1000000l * static_cast<long>(DeltaTicks)); + InvDeltaTicks = fraction<uint64_t>(1, 1000000l * static_cast<uint64_t>(DeltaTicks)); //Tempo = 1000000l * InvDeltaTicks; - Tempo = fraction<long>(1, static_cast<long>(DeltaTicks)); + Tempo = fraction<uint64_t>(1, static_cast<uint64_t>(DeltaTicks)); static const unsigned char EndTag[4] = {0xFF, 0x2F, 0x00, 0x00}; int totalGotten = 0; @@ -478,7 +478,7 @@ InvFmt: uint64_t tkDelay = ReadVarLenEx(tk, ok); if(ok) - CurrentPosition.track[tk].delay = static_cast<long>(tkDelay); + CurrentPosition.track[tk].delay = tkDelay; else { std::stringstream msg; diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 4863bef..f0c3f00 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -158,24 +158,24 @@ uint64_t MIDIplay::ReadVarLen(size_t tk) } -double MIDIplay::Tick(double s, double granularity) +long double MIDIplay::Tick(long double s, long double granularity) { if(CurrentPosition.began) CurrentPosition.wait -= s; int AntiFreezeCounter = 10000;//Limit 10000 loops to avoid freezing - while((CurrentPosition.wait <= granularity * 0.5) && (AntiFreezeCounter > 0)) + while((CurrentPosition.wait <= granularity * 0.5l) && (AntiFreezeCounter > 0)) { //std::fprintf(stderr, "wait = %g...\n", CurrentPosition.wait); ProcessEvents(); - if(CurrentPosition.wait <= 0.0) + if(CurrentPosition.wait <= 0.0l) AntiFreezeCounter--; } if(AntiFreezeCounter <= 0) - CurrentPosition.wait += 1.0;/* Add extra 1 second when over 10000 events + CurrentPosition.wait += 1.0l;/* Add extra 1 second when over 10000 events with zero delay are been detected */ @@ -405,13 +405,15 @@ void MIDIplay::ProcessEvents() } // Find shortest delay from all track - long shortest = -1; + uint64_t shortest = 0; + bool shortest_no = true; for(size_t tk = 0; tk < TrackCount; ++tk) - if(CurrentPosition.track[tk].status >= 0 - && (shortest == -1 - || CurrentPosition.track[tk].delay < shortest)) + if((CurrentPosition.track[tk].status >= 0) && (shortest_no || CurrentPosition.track[tk].delay < shortest)) + { shortest = CurrentPosition.track[tk].delay; + shortest_no = false; + } //if(shortest > 0) UI.PrintLn("shortest: %ld", shortest); @@ -419,7 +421,7 @@ void MIDIplay::ProcessEvents() for(size_t tk = 0; tk < TrackCount; ++tk) CurrentPosition.track[tk].delay -= shortest; - fraction<long> t = shortest * Tempo; + fraction<uint64_t> t = shortest * Tempo; if(CurrentPosition.began) CurrentPosition.wait += t.valuel(); @@ -453,7 +455,7 @@ void MIDIplay::ProcessEvents() loopStart_hit = true; } - if(shortest < 0 || loopEnd) + if(shortest_no || loopEnd) { // Loop if song end reached loopEnd = false; @@ -496,7 +498,7 @@ void MIDIplay::HandleEvent(size_t tk) if(evtype == 0x51) { - Tempo = InvDeltaTicks * fraction<long>((long) ReadBEint(data.data(), data.size())); + Tempo = InvDeltaTicks * fraction<uint64_t>(ReadBEint(data.data(), data.size())); return; } @@ -1262,7 +1264,7 @@ void MIDIplay::NoteOff(uint16_t MidCh, uint8_t note) } -void MIDIplay::UpdateVibrato(double amount) +void MIDIplay::UpdateVibrato(long double amount) { for(size_t a = 0, b = Ch.size(); a < b; ++a) if(Ch[a].vibrato && !Ch[a].activenotes.empty()) @@ -1290,7 +1292,7 @@ uint64_t MIDIplay::ChooseDevice(const std::string &name) return n; } -void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed +void MIDIplay::UpdateArpeggio(long double) // amount = amount of time passed { // If there is an adlib channel that has multiple notes // simulated on the same channel, arpeggio them. diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 2d6ecae..907dcb4 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -173,18 +173,18 @@ class MIDIplay { bool began; char padding[7]; - double wait; + long double wait; struct TrackInfo { size_t ptr; - long delay; + uint64_t delay; int status; char padding2[4]; TrackInfo(): ptr(0), delay(0), status(0) {} }; std::vector<TrackInfo> track; - Position(): began(false), wait(0.0), track() { } + Position(): began(false), wait(0.0l), track() { } } CurrentPosition, LoopBeginPosition, trackBeginPosition; std::map<std::string, uint64_t> devices; @@ -200,7 +200,7 @@ class MIDIplay uint8_t panning, vibrato, sustain; char ____padding[6]; double bend, bendsense; - double vibpos, vibspeed, vibdepth; + long double vibpos, vibspeed, vibdepth; int64_t vibdelay; uint8_t lastlrpn, lastmrpn; bool nrpn; @@ -287,7 +287,7 @@ public: ADL_MIDIPlayer *config; std::string musTitle; - fraction<long> InvDeltaTicks, Tempo; + fraction<uint64_t> InvDeltaTicks, Tempo; bool trackStart, loopStart, loopEnd, @@ -454,7 +454,7 @@ public: * Input: granularity = don't expect intervals smaller than this, in seconds * Output: desired number of seconds until next call */ - double Tick(double s, double granularity); + long double Tick(long double s, long double granularity); private: enum @@ -491,8 +491,8 @@ private: //void UpdatePortamento(unsigned MidCh) void NoteUpdate_All(uint16_t MidCh, unsigned props_mask); void NoteOff(uint16_t MidCh, uint8_t note); - void UpdateVibrato(double amount); - void UpdateArpeggio(double /*amount*/); + void UpdateVibrato(long double amount); + void UpdateArpeggio(long double /*amount*/); public: uint64_t ChooseDevice(const std::string &name); |