diff --git a/common/rateest.cpp b/common/rateest.cpp index 98afe53..e64c980 100644 --- a/common/rateest.cpp +++ b/common/rateest.cpp @@ -19,25 +19,35 @@ #include "rateest.h" #include -void RateEst::init(const long srate) { - this->srate.est = srate; - this->srate.var = srate >> 13; +static long limit(long est, const long reference) { + if (est > reference + (reference >> 4)) + est = reference + (reference >> 4); + else if (est < reference - (reference >> 4)) + est = reference - (reference >> 4); + + return est; +} + +void RateEst::init(long srate, const long reference) { + this->srate.est = limit(srate, reference); + this->srate.var = srate >> 12; last = 0; + this->reference = reference; samples = 0; - count = 16; + count = 32; } void RateEst::feed(const long samplesIn) { samples += samplesIn; if (--count == 0) { - count = 16; + count = 32; const usec_t now = getusecs(); if (last) { long est = samples * 1000000.0f / (now - last) + 0.5f; - est = (srate.est * 15 + est + 8) >> 4; + est = limit((srate.est * 31 + est + 16) >> 5, reference); srate.var = (srate.var * 15 + std::abs(est - srate.est) + 8) >> 4; srate.est = est; } diff --git a/common/rateest.h b/common/rateest.h index 646ca86..dad95aa 100644 --- a/common/rateest.h +++ b/common/rateest.h @@ -31,12 +31,15 @@ public: private: Result srate; usec_t last; + long reference; long samples; unsigned count; public: - RateEst(const long srate=0) { init(srate); } - void init(long srate); + RateEst(long srate = 0) { init(srate); } + RateEst(long srate, long reference) { init(srate, reference); } + void init(long srate) { init(srate, srate); } + void init(long srate, long reference); void feed(long samples); const Result& result() const { return srate; } }; diff --git a/gambatte_qt/src/audioengines/alsaengine.cpp b/gambatte_qt/src/audioengines/alsaengine.cpp index a5a9113..0485213 100644 --- a/gambatte_qt/src/audioengines/alsaengine.cpp +++ b/gambatte_qt/src/audioengines/alsaengine.cpp @@ -150,7 +150,7 @@ int AlsaEngine::write(void *const buffer, const unsigned samples) { } if (underrun) - est.init(std::min(est.result().est + (est.result().est >> 10), (long) rate() + (rate() >> 4))); + est.init(est.result().est + (est.result().est >> 10), rate()); return 0; } diff --git a/gambatte_qt/src/audioengines/ossengine.cpp b/gambatte_qt/src/audioengines/ossengine.cpp index b44e0e1..c162d7a 100644 --- a/gambatte_qt/src/audioengines/ossengine.cpp +++ b/gambatte_qt/src/audioengines/ossengine.cpp @@ -124,7 +124,7 @@ int OssEngine::write(void *const buffer, const unsigned samples) { if (bstate.fromUnderrun) est.feed(prevfur - bstate.fromUnderrun); else - est.init(std::min(est.result().est + (est.result().est >> 10), (long) rate() + (rate() >> 4))); + est.init(est.result().est + (est.result().est >> 10), rate()); } prevfur = bstate.fromUnderrun + samples; diff --git a/gambatte_qt/src/blitterwidget.cpp b/gambatte_qt/src/blitterwidget.cpp index 3ddf1d1..60fe535 100644 --- a/gambatte_qt/src/blitterwidget.cpp +++ b/gambatte_qt/src/blitterwidget.cpp @@ -36,7 +36,7 @@ void FtEst::update(const usec_t t) { if (--count == 0) { count = COUNT; long oldFtAvg = ftAvg; - ftAvg = (ftAvg * 15 + ft + 8) >> 4; + ftAvg = (ftAvg * 31 + ft + 16) >> 5; if (ftAvg > ((frameTime + (frameTime >> 5)) << COUNT_LOG2)) ftAvg = (frameTime + (frameTime >> 5)) << COUNT_LOG2; diff --git a/gambatte_qt/src/blitterwidget.h b/gambatte_qt/src/blitterwidget.h index b3717bd..e8b477e 100644 --- a/gambatte_qt/src/blitterwidget.h +++ b/gambatte_qt/src/blitterwidget.h @@ -28,7 +28,7 @@ class QHBoxLayout; class FtEst { - enum { COUNT_LOG2 = 4 }; + enum { COUNT_LOG2 = 5 }; enum { COUNT = 1 << COUNT_LOG2 }; long frameTime;