aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWohlstand <admin@wohlnet.ru>2017-02-28 15:50:16 +0300
committerWohlstand <admin@wohlnet.ru>2017-02-28 15:50:16 +0300
commit285fd4e367ca7383ab57fc81f9e84731a67825bb (patch)
tree9aec429c49110ab872bc2da4dfdb5ee06ab3dd71 /src
parent1f905ede543e7c59323875562a815ab8034a5c79 (diff)
downloadlibADLMIDI-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.cpp2
-rw-r--r--src/adlmidi.h8
-rw-r--r--src/adlmidi_load.cpp6
-rw-r--r--src/adlmidi_midiplay.cpp28
-rw-r--r--src/adlmidi_private.hpp16
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);