diff --git a/src/server.cpp b/src/server.cpp index 1cd30e17..f4b97c7f 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -26,67 +26,7 @@ // CHighPrecisionTimer implementation ****************************************** -#if defined ( __APPLE__ ) || defined ( __MACOSX ) -#include -#include -#include - -CHighPrecisionTimer::CHighPrecisionTimer() : - bRun ( false ) -{ - // calculate delay in mach absolute time - const uint64_t iNsDelay = - ( (uint64_t) SYSTEM_FRAME_SIZE_SAMPLES * 1000000000 ) / - (uint64_t) SYSTEM_SAMPLE_RATE_HZ; // in ns - - struct mach_timebase_info timeBaseInfo; - mach_timebase_info ( &timeBaseInfo ); - - iMachDelay = ( iNsDelay * (uint64_t) timeBaseInfo.denom ) / - (uint64_t) timeBaseInfo.numer; -} - -void CHighPrecisionTimer::Start() -{ - // only start if not already running - if ( !bRun ) - { - // set run flag - bRun = true; - - // set initial end time - iNextEnd = mach_absolute_time() + iMachDelay; - - // start thread - QThread::start(); - } -} - -void CHighPrecisionTimer::Stop() -{ - // set flag so that thread can leave the main loop - bRun = false; - - // give thread some time to terminate - wait ( 5000 ); -} - -void CHighPrecisionTimer::run() -{ - // loop until the thread shall be terminated - while ( bRun ) - { - // call processing routine by fireing signal - emit timeout(); - - // now wait until the next buffer shall be processed (we - // use the "increment method" to make sure we do not introduce - // a timing drift) - mach_wait_until(iNextEnd); - iNextEnd += iMachDelay; - } -} -#else +#ifdef _WIN32 CHighPrecisionTimer::CHighPrecisionTimer() { // add some error checking, the high precision timer implementation only @@ -94,7 +34,7 @@ CHighPrecisionTimer::CHighPrecisionTimer() #if ( SYSTEM_FRAME_SIZE_SAMPLES != 128 ) # error "Only system frame size of 128 samples is supported by this module" #endif -#if SYSTEM_SAMPLE_RATE_HZ != 48000 +#if ( SYSTEM_SAMPLE_RATE_HZ != 48000 ) # error "Only a system sample rate of 48 kHz is supported by this module" #endif @@ -160,6 +100,82 @@ void CHighPrecisionTimer::OnTimer() iIntervalCounter++; } } +#else // Mac and Linux +CHighPrecisionTimer::CHighPrecisionTimer() : + bRun ( false ) +{ + // calculate delay in ns + const uint64_t iNsDelay = + ( (uint64_t) SYSTEM_FRAME_SIZE_SAMPLES * 1000000000 ) / + (uint64_t) SYSTEM_SAMPLE_RATE_HZ; // in ns + +#if defined ( __APPLE__ ) || defined ( __MACOSX ) + // calculate delay in mach absolute time + struct mach_timebase_info timeBaseInfo; + mach_timebase_info ( &timeBaseInfo ); + + Delay = ( iNsDelay * (uint64_t) timeBaseInfo.denom ) / + (uint64_t) timeBaseInfo.numer; +#else + // set delay + Delay.tv_sec = 0; + Delay.tv_nsec = iNsDelay; +#endif +} + +void CHighPrecisionTimer::Start() +{ + // only start if not already running + if ( !bRun ) + { + // set run flag + bRun = true; + + // set initial end time +#if defined ( __APPLE__ ) || defined ( __MACOSX ) + NextEnd = mach_absolute_time(); +#else + clock_gettime ( CLOCK_MONOTONIC, NextEnd ); +#endif + NextEnd += Delay; + + // start thread + QThread::start(); + } +} + +void CHighPrecisionTimer::Stop() +{ + // set flag so that thread can leave the main loop + bRun = false; + + // give thread some time to terminate + wait ( 5000 ); +} + +void CHighPrecisionTimer::run() +{ + // loop until the thread shall be terminated + while ( bRun ) + { + // call processing routine by fireing signal + emit timeout(); + + // now wait until the next buffer shall be processed (we + // use the "increment method" to make sure we do not introduce + // a timing drift) +#if defined ( __APPLE__ ) || defined ( __MACOSX ) + mach_wait_until ( NextEnd ); +#else + clock_nanosleep ( CLOCK_MONOTONIC, + TIMER_ABSTIME, + NextEnd, + NULL ); +#endif + + NextEnd += Delay; + } +} #endif diff --git a/src/server.h b/src/server.h index 9f28aefa..6033cdc0 100755 --- a/src/server.h +++ b/src/server.h @@ -43,36 +43,10 @@ // no valid channel number #define INVALID_CHANNEL_ID ( MAX_NUM_CHANNELS + 1 ) -// minimum timer precision -#define MIN_TIMER_RESOLUTION_MS 1 // ms - /* Classes ********************************************************************/ -#if defined ( __APPLE__ ) || defined ( __MACOSX ) -// using mach timers for Mac -class CHighPrecisionTimer : public QThread -{ - Q_OBJECT - -public: - CHighPrecisionTimer(); - - void Start(); - void Stop(); - bool isActive() { return bRun; } - -protected: - virtual void run(); - - bool bRun; - uint64_t iMachDelay; - uint64_t iNextEnd; - -signals: - void timeout(); -}; -#else -// using QTimer for Windows and Linux +#if ( defined ( WIN32 ) || defined ( _WIN32 ) ) +// using QTimer for Windows class CHighPrecisionTimer : public QObject { Q_OBJECT @@ -93,6 +67,43 @@ protected: public slots: void OnTimer(); +signals: + void timeout(); +}; +#else +// using mach timers for Mac and nanosleep for Linux +#if defined ( __APPLE__ ) || defined ( __MACOSX ) +# include +# include +# include +#else +# include +#endif + +class CHighPrecisionTimer : public QThread +{ + Q_OBJECT + +public: + CHighPrecisionTimer(); + + void Start(); + void Stop(); + bool isActive() { return bRun; } + +protected: + virtual void run(); + + bool bRun; + +#if defined ( __APPLE__ ) || defined ( __MACOSX ) + uint64_t Delay; + uint64_t NextEnd; +#else + timespec Delay; + timespec NextEnd; +#endif + signals: void timeout(); };