Author: bonefish Date: 2009-12-16 21:04:58 +0100 (Wed, 16 Dec 2009) New Revision: 34682 Changeset: http://dev.haiku-os.org/changeset/34682/haiku Added: haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/TimeComputer.cpp haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/TimeComputer.h Modified: haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/Jamfile Log: Added support class TimeComputer to compute smoother performance times. Modified: haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/Jamfile =================================================================== --- haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/Jamfile 2009-12-16 12:51:26 UTC (rev 34681) +++ haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/Jamfile 2009-12-16 20:04:58 UTC (rev 34682) @@ -13,6 +13,7 @@ MultiAudioDevice.cpp MultiAudioNode.cpp MultiAudioUtility.cpp + TimeComputer.cpp : be media $(TARGET_LIBSUPC++) ; Added: haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/TimeComputer.cpp =================================================================== --- haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/TimeComputer.cpp (rev 0) +++ haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/TimeComputer.cpp 2009-12-16 20:04:58 UTC (rev 34682) @@ -0,0 +1,94 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * 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; +} Added: haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/TimeComputer.h =================================================================== --- haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/TimeComputer.h (rev 0) +++ haiku/trunk/src/add-ons/media/media-add-ons/multi_audio/TimeComputer.h 2009-12-16 20:04:58 UTC (rev 34682) @@ -0,0 +1,52 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * 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