mirror of
https://github.com/libretro/gambatte-libretro.git
synced 2024-11-26 17:30:23 +00:00
Substantially improved rate estimation averaging.
git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@204 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
This commit is contained in:
parent
cbf173e0a8
commit
c69e48ac80
@ -36,26 +36,27 @@ void RateEst::init(long srate, long reference) {
|
||||
this->srate.var = srate >> 12;
|
||||
last = 0;
|
||||
this->reference = reference;
|
||||
samples = 0;
|
||||
count = 1;
|
||||
samples = ((this->srate.est >> UPSHIFT) * 12) << 5;
|
||||
usecs = 12000000 << 5;
|
||||
}
|
||||
|
||||
void RateEst::feed(const long samplesIn) {
|
||||
samples += samplesIn;
|
||||
|
||||
if (--count == 0) {
|
||||
count = 32;
|
||||
|
||||
const usec_t now = getusecs();
|
||||
|
||||
if (last) {
|
||||
long est = samples * (1000000.0f * UP) / (now - last) + 0.5f;
|
||||
est = limit((srate.est * 31 + est + 16) >> 5, reference);
|
||||
srate.var = (srate.var * 15 + std::abs(est - srate.est) + 8) >> 4;
|
||||
srate.est = est;
|
||||
const usec_t now = getusecs();
|
||||
|
||||
if (last) {
|
||||
samples += samplesIn << 5;
|
||||
usecs += (now - last) << 5;
|
||||
|
||||
long est = samples * (1000000.0f * UP) / usecs + 0.5f;
|
||||
est = limit((srate.est * 31 + est + 16) >> 5, reference);
|
||||
srate.var = (srate.var * 15 + std::abs(est - srate.est) + 8) >> 4;
|
||||
srate.est = est;
|
||||
|
||||
if (usecs > 16000000 << 5) {
|
||||
samples = (samples * 3 + 2) >> 2;
|
||||
usecs = (usecs * 3 + 2) >> 2;
|
||||
}
|
||||
|
||||
last = now;
|
||||
samples = 0;
|
||||
}
|
||||
|
||||
last = now;
|
||||
}
|
||||
|
@ -34,16 +34,16 @@ private:
|
||||
|
||||
Result srate;
|
||||
usec_t last;
|
||||
usec_t usecs;
|
||||
long reference;
|
||||
long samples;
|
||||
unsigned count;
|
||||
|
||||
public:
|
||||
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 reset() { count = 1; last = 0; }
|
||||
void reset() { last = 0; }
|
||||
void feed(long samples);
|
||||
const Result result() const { const Result res = { (srate.est + UP / 2) >> UPSHIFT, (srate.var + UP / 2) >> UPSHIFT }; return res; }
|
||||
};
|
||||
|
@ -20,31 +20,37 @@
|
||||
#include <adaptivesleep.h>
|
||||
#include <cstdlib>
|
||||
|
||||
static long limit(long est, const long ref) {
|
||||
if (est > ref + (ref >> 5))
|
||||
est = ref + (ref >> 5);
|
||||
else if (est < ref - (ref >> 5))
|
||||
est = ref - (ref >> 5);
|
||||
|
||||
return est;
|
||||
}
|
||||
|
||||
void FtEst::init(const long frameTime) {
|
||||
this->frameTime = frameTime;
|
||||
ft = 0;
|
||||
ftAvg = frameTime << COUNT_LOG2;
|
||||
ft = 4500000 << 6;
|
||||
ftAvg = frameTime << UPSHIFT;
|
||||
ftVar = ftAvg >> 12;
|
||||
last = 0;
|
||||
count = COUNT;
|
||||
count = (ft + (frameTime >> 1)) / (frameTime ? frameTime : 1);
|
||||
}
|
||||
|
||||
void FtEst::update(const usec_t t) {
|
||||
if (t - last < static_cast<unsigned long>(frameTime + (frameTime >> 3))) {
|
||||
ft += t - last;
|
||||
|
||||
if (--count == 0) {
|
||||
count = COUNT;
|
||||
long oldFtAvg = ftAvg;
|
||||
ftAvg = (ftAvg * 15 + ft + 8) >> 4;
|
||||
|
||||
if (ftAvg > ((frameTime + (frameTime >> 5)) << COUNT_LOG2))
|
||||
ftAvg = (frameTime + (frameTime >> 5)) << COUNT_LOG2;
|
||||
else if (ftAvg < ((frameTime - (frameTime >> 5)) << COUNT_LOG2))
|
||||
ftAvg = (frameTime - (frameTime >> 5)) << COUNT_LOG2;
|
||||
|
||||
ftVar = (ftVar * 15 + std::abs(ftAvg - oldFtAvg) + 8) >> 4;
|
||||
ft = 0;
|
||||
ft += (t - last) << 6;
|
||||
count += 1 << 6;
|
||||
|
||||
long ftAvgNew = static_cast<long>(static_cast<float>(ft) * UP / count + 0.5f);
|
||||
ftAvgNew = limit((ftAvg * 31 + ftAvgNew + 16) >> 5, frameTime << UPSHIFT);
|
||||
ftVar = (ftVar * 15 + std::abs(ftAvgNew - ftAvg) + 8) >> 4;
|
||||
ftAvg = ftAvgNew;
|
||||
|
||||
if (ft > (6000000 << 6)) {
|
||||
ft = (ft * 3 + 2) >> 2;
|
||||
count = (count * 3 + 2) >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,8 @@
|
||||
class QHBoxLayout;
|
||||
|
||||
class FtEst {
|
||||
enum { COUNT_LOG2 = 4 };
|
||||
enum { COUNT = 1 << COUNT_LOG2 };
|
||||
enum { UPSHIFT= 5 };
|
||||
enum { UP = 1 << UPSHIFT };
|
||||
|
||||
long frameTime;
|
||||
long ft;
|
||||
@ -42,8 +42,8 @@ public:
|
||||
FtEst(long frameTime = 0) { init(frameTime); }
|
||||
void init(long frameTime);
|
||||
void update(usec_t t);
|
||||
long est() const { return (ftAvg + COUNT / 2) >> COUNT_LOG2; }
|
||||
long var() const { return (ftVar + COUNT / 2) >> COUNT_LOG2; }
|
||||
long est() const { return (ftAvg + UP / 2) >> UPSHIFT; }
|
||||
long var() const { return (ftVar + UP / 2) >> UPSHIFT; }
|
||||
};
|
||||
|
||||
class BlitterWidget : public QWidget {
|
||||
|
@ -552,7 +552,7 @@ void MainWindow::timerEvent(QTimerEvent */*event*/) {
|
||||
|
||||
if (estft.est) {
|
||||
float est = static_cast<float>(rsrate.est) * estft.est;
|
||||
const float var = static_cast<float>(rsrate.est + rsrate.var) * (estft.est + estft.var) - est;
|
||||
const float var = static_cast<float>(rsrate.est + (rsrate.var ? rsrate.var : 1)) * (estft.est + (estft.var ? estft.var : 1)) - est;
|
||||
est += var;
|
||||
|
||||
if (std::fabs(est - resampler->outRate() * static_cast<float>(usecft - (usecft >> 11))) > var * 2)
|
||||
|
Loading…
Reference in New Issue
Block a user