Fix erroneous getStreamTime() results in some cases.
authorCarl Hetherington <cth@carlh.net>
Sat, 19 Mar 2016 21:15:20 +0000 (21:15 +0000)
committerCarl Hetherington <cth@carlh.net>
Sat, 19 Mar 2016 21:15:20 +0000 (21:15 +0000)
Without this, if HAVE_GETTIMEOFDAY is defined getStreamTime() can return
a wrong value in the following case:

- start stream
- stop stream
- start stream
- call getStreamTime() immediately

In this case tickStreamTime() will not have been called since the
stream was restarted, hence lastTickTimestamp will refer to the
previous run of the stream.  getStreamTime() will therefore extrapolate
wrongly from stream._streamTime.  This patch only uses lastTickTimestamp
when it is valid.

RtAudio.cpp
RtAudio.h

index 5284bdb329b145fca84af16dc16f74c7417bf89d..f2c871f3309577f2d8ba15181b40f871d8fdec96 100644 (file)
@@ -408,7 +408,9 @@ double RtApi :: getStreamTime( void )
   struct timeval then;\r
   struct timeval now;\r
 \r
-  if ( stream_.state != STREAM_RUNNING || stream_.streamTime == 0.0 )\r
+  // If lastTickTimestamp is 0 it means we haven't had a "last tick" since\r
+  // we started the stream.\r
+  if ( stream_.state != STREAM_RUNNING || (stream_.lastTickTimestamp.tv_sec == 0 && stream_.lastTickTimestamp.tv_usec == 0) )\r
     return stream_.streamTime;\r
 \r
   gettimeofday( &now, NULL );\r
@@ -436,6 +438,14 @@ unsigned int RtApi :: getStreamSampleRate( void )
  return stream_.sampleRate;\r
 }\r
 \r
+void RtApi :: startStream( void )\r
+{\r
+#if defined( HAVE_GETTIMEOFDAY )\r
+  stream_.lastTickTimestamp.tv_sec = 0;\r
+  stream_.lastTickTimestamp.tv_usec = 0;\r
+#endif\r
+}\r
+\r
 \r
 // *************************************************** //\r
 //\r
@@ -1475,6 +1485,7 @@ void RtApiCore :: closeStream( void )
 void RtApiCore :: startStream( void )\r
 {\r
   verifyStream();\r
+  RtApi::startStream();\r
   if ( stream_.state == STREAM_RUNNING ) {\r
     errorText_ = "RtApiCore::startStream(): the stream is already running!";\r
     error( RtAudioError::WARNING );\r
@@ -2427,6 +2438,7 @@ void RtApiJack :: closeStream( void )
 void RtApiJack :: startStream( void )\r
 {\r
   verifyStream();\r
+  RtApi::startStream();\r
   if ( stream_.state == STREAM_RUNNING ) {\r
     errorText_ = "RtApiJack::startStream(): the stream is already running!";\r
     error( RtAudioError::WARNING );\r
@@ -3306,6 +3318,7 @@ bool stopThreadCalled = false;
 void RtApiAsio :: startStream()\r
 {\r
   verifyStream();\r
+  RtApi::startStream();\r
   if ( stream_.state == STREAM_RUNNING ) {\r
     errorText_ = "RtApiAsio::startStream(): the stream is already running!";\r
     error( RtAudioError::WARNING );\r
@@ -4317,7 +4330,8 @@ void RtApiWasapi::closeStream( void )
 void RtApiWasapi::startStream( void )\r
 {\r
   verifyStream();\r
-\r
+  RtApi::startStream();\r
+  \r
   if ( stream_.state == STREAM_RUNNING ) {\r
     errorText_ = "RtApiWasapi::startStream: The stream is already running.";\r
     error( RtAudioError::WARNING );\r
@@ -6066,6 +6080,8 @@ void RtApiDs :: closeStream()
 void RtApiDs :: startStream()\r
 {\r
   verifyStream();\r
+  RtApi::startStream();\r
+  \r
   if ( stream_.state == STREAM_RUNNING ) {\r
     errorText_ = "RtApiDs::startStream(): the stream is already running!";\r
     error( RtAudioError::WARNING );\r
@@ -7743,6 +7759,7 @@ void RtApiAlsa :: startStream()
   // This method calls snd_pcm_prepare if the device isn't already in that state.\r
 \r
   verifyStream();\r
+  RtApi::startStream();\r
   if ( stream_.state == STREAM_RUNNING ) {\r
     errorText_ = "RtApiAlsa::startStream(): the stream is already running!";\r
     error( RtAudioError::WARNING );\r
@@ -8299,6 +8316,8 @@ void RtApiPulse::callbackEvent( void )
 \r
 void RtApiPulse::startStream( void )\r
 {\r
+  RtApi::startStream();\r
+  \r
   PulseAudioHandle *pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );\r
 \r
   if ( stream_.state == STREAM_CLOSED ) {\r
@@ -9237,6 +9256,7 @@ void RtApiOss :: closeStream()
 void RtApiOss :: startStream()\r
 {\r
   verifyStream();\r
+  RtApi::startStream();\r
   if ( stream_.state == STREAM_RUNNING ) {\r
     errorText_ = "RtApiOss::startStream(): the stream is already running!";\r
     error( RtAudioError::WARNING );\r
index 11345cc6d8a72f2ea35f6d5abf44c02e266d150a..78fca0c779700bc34d83bba2c23fdcc2e72274ae 100644 (file)
--- a/RtAudio.h
+++ b/RtAudio.h
@@ -756,6 +756,9 @@ protected:
     double streamTime;         // Number of elapsed seconds since the stream started.
 
 #if defined(HAVE_GETTIMEOFDAY)
+    // The gettimeofday() when tickStreamTime was last called, or both
+    // fields at 0 if tickStreamTime has not been called since the last
+    // startStream().
     struct timeval lastTickTimestamp;
 #endif