/*============================================================================= CAHostTimeBase.h $Log: CAHostTimeBase.h,v $ Revision 1.12 2004/10/09 02:38:17 jcm10 when tracking the time, print out stuff as 64 bit ints Revision 1.11 2004/08/26 23:35:42 jcm10 more windows cleanup Revision 1.10 2004/08/25 23:06:04 dwyatt bring back GetCurrentTime on Mac so we don't break tons of code that doesn't need to go to Windows Revision 1.9 2004/08/23 06:23:25 jcm10 make it build on Windows Revision 1.8 2003/11/20 22:56:53 dwyatt __COREAUDIO_USE_FLAT_INCLUDES__ Revision 1.7 2003/08/29 04:13:15 jcm10 disable the Asserts so that it can be used in the debug macros themselves Revision 1.6 2003/03/27 02:46:16 jcm10 no need to initialize things on X when getting the current time Revision 1.5 2002/07/11 01:24:18 jcm10 add HostDeltaToNanos() Revision 1.4 2002/06/13 06:10:50 dwyatt back out changes - causes conflicts Revision 1.3 2002/06/13 02:57:36 dwyatt make those new constants long long Revision 1.2 2002/06/13 01:22:13 dwyatt add convenience constants for nano/micro/milli/second conversions Revision 1.1 2002/05/18 01:06:09 bills moved files to public utils Revision 1.10 2002/04/18 02:19:52 jcm10 clean up the header inclusion Revision 1.9 2002/03/29 03:27:16 jcm10 make sure things are initialized before doling out info Revision 1.8 2002/03/04 23:50:48 jcm10 make GetCurrentTime be inlined too Revision 1.7 2002/03/04 20:57:41 bills fixes for platform, inlining and lazy init Revision 1.6 2002/03/02 20:44:39 bills add DeltaHostToMics conversion and do initialization at load:) Revision 1.5 2001/03/14 23:48:38 jcm10 Lots of changes to support the new driver API Revision 1.4 2001/03/01 03:07:37 jcm10 make the code fully cross-platform and use the mach routines for getting the timebase on X Revision 1.3 2001/01/08 23:51:04 jcm10 remove #pragma once, since gcc claims it to be obsolete and issues an annoying warning to that effect when all warnings are enabled Revision 1.2 2000/10/04 19:58:55 jcm10 Add conversion routines to CAHostTimeBase Revision 1.1 2000/09/24 01:11:57 jcm10 first checked in Revision 0.0 2000/01/01 12:34:56 jcm10 created $NoKeywords: $ =============================================================================*/ #if !defined(__CAHostTimeBase_h__) #define __CAHostTimeBase_h__ //============================================================================= // Includes //============================================================================= #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) #include #else #include #endif #if TARGET_OS_MAC #include #elif TARGET_OS_WIN32 #include #else #error Unsupported operating system #endif #include "CADebugMacros.h" //============================================================================= // CAHostTimeBase // // This class provides platform independent access to the host's time base. //============================================================================= #if CoreAudio_Debug // #define Log_Host_Time_Base_Parameters 1 // #define Track_Host_TimeBase 1 #endif class CAHostTimeBase { public: static UInt64 ConvertToNanos(UInt64 inHostTime); static UInt64 ConvertFromNanos(UInt64 inNanos); static UInt64 GetTheCurrentTime(); #if TARGET_OS_MAC static UInt64 GetCurrentTime() { return GetTheCurrentTime(); } #endif static UInt64 GetCurrentTimeInNanos(); static Float64 GetFrequency() { if(!sIsInited) { Initialize(); } return sFrequency; } static UInt32 GetMinimumDelta() { if(!sIsInited) { Initialize(); } return sMinDelta; } static UInt64 AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime); static SInt64 HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime); private: static void Initialize(); static bool sIsInited; static Float64 sFrequency; static UInt32 sMinDelta; static UInt32 sToNanosNumerator; static UInt32 sToNanosDenominator; static UInt32 sFromNanosNumerator; static UInt32 sFromNanosDenominator; static bool sUseMicroseconds; #if Track_Host_TimeBase static UInt64 sLastTime; #endif }; inline UInt64 CAHostTimeBase::GetTheCurrentTime() { UInt64 theTime = 0; #if TARGET_OS_MAC theTime = mach_absolute_time(); #elif TARGET_OS_WIN32 LARGE_INTEGER theValue; QueryPerformanceCounter(&theValue); theTime = *((UInt64*)&theValue); #endif #if Track_Host_TimeBase if(sLastTime != 0) { if(theTime <= sLastTime) { DebugMessageN2("CAHostTimeBase::GetTheCurrentTime: the current time is earlier than the last time, now: %qd, then: %qd", theTime, sLastTime); } sLastTime = theTime; } else { sLastTime = theTime; } #endif return theTime; } inline UInt64 CAHostTimeBase::ConvertToNanos(UInt64 inHostTime) { if(!sIsInited) { Initialize(); } Float64 theNumerator = static_cast(sToNanosNumerator); Float64 theDenominator = static_cast(sToNanosDenominator); Float64 theHostTime = static_cast(inHostTime); Float64 thePartialAnswer = theHostTime / theDenominator; Float64 theFloatAnswer = thePartialAnswer * theNumerator; UInt64 theAnswer = static_cast(theFloatAnswer); //Assert(!((theNumerator > theDenominator) && (theAnswer < inHostTime)), "CAHostTimeBase::ConvertToNanos: The conversion wrapped"); //Assert(!((theDenominator > theNumerator) && (theAnswer > inHostTime)), "CAHostTimeBase::ConvertToNanos: The conversion wrapped"); return theAnswer; } inline UInt64 CAHostTimeBase::ConvertFromNanos(UInt64 inNanos) { if(!sIsInited) { Initialize(); } Float64 theNumerator = static_cast(sToNanosNumerator); Float64 theDenominator = static_cast(sToNanosDenominator); Float64 theNanos = static_cast(inNanos); Float64 thePartialAnswer = theNanos / theNumerator; Float64 theFloatAnswer = thePartialAnswer * theDenominator; UInt64 theAnswer = static_cast(theFloatAnswer); //Assert(!((theDenominator > theNumerator) && (theAnswer < inNanos)), "CAHostTimeBase::ConvertToNanos: The conversion wrapped"); //Assert(!((theNumerator > theDenominator) && (theAnswer > inNanos)), "CAHostTimeBase::ConvertToNanos: The conversion wrapped"); return theAnswer; } inline UInt64 CAHostTimeBase::GetCurrentTimeInNanos() { return ConvertToNanos(GetTheCurrentTime()); } inline UInt64 CAHostTimeBase::AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime) { UInt64 theAnswer; if(inStartTime <= inEndTime) { theAnswer = inEndTime - inStartTime; } else { theAnswer = inStartTime - inEndTime; } return ConvertToNanos(theAnswer); } inline SInt64 CAHostTimeBase::HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime) { SInt64 theAnswer; SInt64 theSign = 1; if(inStartTime <= inEndTime) { theAnswer = inEndTime - inStartTime; } else { theAnswer = inStartTime - inEndTime; theSign = -1; } return theSign * ConvertToNanos(theAnswer); } #endif