Added support class TimeComputer to compute smoother performance times.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34682 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-12-16 20:04:58 +00:00
parent 7d592ec4d2
commit cb00754227
3 changed files with 147 additions and 0 deletions

View File

@ -13,6 +13,7 @@ Addon hmulti_audio.media_addon :
MultiAudioDevice.cpp
MultiAudioNode.cpp
MultiAudioUtility.cpp
TimeComputer.cpp
: be media $(TARGET_LIBSUPC++)
;

View File

@ -0,0 +1,94 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "TimeComputer.h"
TimeComputer::TimeComputer()
:
fRealTime(0),
fPerformanceTime(0),
fDrift(1),
fFrameRate(1000000),
fUsecsPerFrame(1),
fPerformanceTimeBase(0),
fFrameBase(0),
fResetTimeBase(true),
fFirstEntry(0),
fLastEntry(0)
{
}
void
TimeComputer::Init(float frameRate, bigtime_t realBaseTime)
{
fRealTime = realBaseTime;
fPerformanceTime = 0;
fDrift = 1;
SetFrameRate(frameRate);
}
void
TimeComputer::SetFrameRate(float frameRate)
{
if (frameRate == fFrameRate)
return;
fFrameRate = frameRate;
fUsecsPerFrame = (double)1000000 / fFrameRate;
fResetTimeBase = true;
fFirstEntry = 0;
fLastEntry = 0;
}
void
TimeComputer::AddTimeStamp(bigtime_t realTime, uint64 frames)
{
bigtime_t estimatedPerformanceTime = fPerformanceTime
+ bigtime_t((realTime - fRealTime) * fDrift);
fRealTime = realTime;
if (fResetTimeBase) {
// use the extrapolated performance time at the given real time
fPerformanceTime = estimatedPerformanceTime;
fPerformanceTimeBase = estimatedPerformanceTime;
fFrameBase = frames;
fResetTimeBase = false;
_AddEntry(fRealTime, fPerformanceTime);
return;
}
// add entry
bigtime_t performanceTime = fPerformanceTimeBase
+ bigtime_t((frames - fFrameBase) * fUsecsPerFrame);
_AddEntry(realTime, performanceTime);
// Update performance time and drift. We don't use the given
// performance time directly, but average it with the estimated
// performance time.
fPerformanceTime = (performanceTime + estimatedPerformanceTime) / 2;
Entry& entry = fEntries[fFirstEntry];
fDrift = double(fPerformanceTime - entry.performanceTime)
/ double(fRealTime - entry.realTime);
}
void
TimeComputer::_AddEntry(bigtime_t realTime, bigtime_t performanceTime)
{
fLastEntry = (fLastEntry + 1) % kEntryCount;
Entry& entry = fEntries[fLastEntry];
entry.realTime = realTime;
entry.performanceTime = performanceTime;
if (fLastEntry == fFirstEntry)
fFirstEntry = (fFirstEntry + 1) % kEntryCount;
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef TIME_COMPUTER_H
#define TIME_COMPUTER_H
#include <SupportDefs.h>
struct TimeComputer {
TimeComputer();
void Init(float frameRate, bigtime_t realBaseTime);
void SetFrameRate(float frameRate);
void AddTimeStamp(bigtime_t realTime, uint64 frames);
bigtime_t RealTime() const { return fRealTime; }
bigtime_t PerformanceTime() const
{ return fPerformanceTime; }
double Drift() const { return fDrift; }
private:
static const int32 kEntryCount = 32;
struct Entry {
bigtime_t realTime;
bigtime_t performanceTime;
};
private:
void _AddEntry(bigtime_t realTime,
bigtime_t performanceTime);
private:
bigtime_t fRealTime;
bigtime_t fPerformanceTime;
double fDrift;
float fFrameRate;
double fUsecsPerFrame;
bigtime_t fPerformanceTimeBase;
uint64 fFrameBase;
bool fResetTimeBase;
Entry fEntries[kEntryCount];
int32 fFirstEntry;
int32 fLastEntry;
};
#endif // TIME_COMPUTER_H