RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/\r
\r
RtAudio: realtime audio i/o C++ classes\r
- Copyright (c) 2001-2014 Gary P. Scavone\r
+ Copyright (c) 2001-2016 Gary P. Scavone\r
\r
Permission is hereby granted, free of charge, to any person\r
obtaining a copy of this software and associated documentation files\r
*/\r
/************************************************************************/\r
\r
-// RtAudio: Version 4.1.1\r
+// RtAudio: Version 4.1.2\r
\r
#include "RtAudio.h"\r
#include <iostream>\r
#include <cstring>\r
#include <climits>\r
#include <algorithm>\r
+#include <cmath>\r
\r
// Static variable definitions.\r
const unsigned int RtApi::MAX_SAMPLE_RATES = 14;\r
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
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
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
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
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
#include <audioclient.h>\r
#include <avrt.h>\r
#include <mmdeviceapi.h>\r
-#include <functiondiscoverykeys_devpkey.h>\r
+#include <FunctionDiscoveryKeys_devpkey.h>\r
\r
//=============================================================================\r
\r
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
// if the callback buffer was pushed renderBuffer reset callbackPulled flag\r
if ( callbackPushed ) {\r
callbackPulled = false;\r
+ // tick stream time\r
+ RtApi::tickStreamTime();\r
}\r
\r
- // tick stream time\r
- RtApi::tickStreamTime();\r
}\r
\r
Exit:\r
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
if ( FAILED( result ) ) {\r
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";\r
errorText_ = errorStream_.str();\r
+ MUTEX_UNLOCK( &stream_.mutex );\r
error( RtAudioError::SYSTEM_ERROR );\r
return;\r
}\r
// 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
bool *isRunning = &info->isRunning;\r
\r
#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread)\r
- if ( &info->doRealtime ) {\r
+ if ( info->doRealtime ) {\r
pthread_t tID = pthread_self(); // ID of this thread\r
sched_param prio = { info->priority }; // scheduling priority of thread\r
pthread_setschedparam( tID, SCHED_RR, &prio );\r
MUTEX_UNLOCK( &stream_.mutex );\r
RtApi::tickStreamTime();\r
\r
+ if (pah->s_play) {\r
+ int e = 0;\r
+ pa_usec_t const lat = pa_simple_get_latency(pah->s_play, &e);\r
+ if (e == 0) {\r
+ stream_.latency[0] = lat * stream_.sampleRate / 1000000;\r
+ }\r
+ }\r
+\r
if ( doStopStream == 1 )\r
stopStream();\r
}\r
\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
}\r
\r
stream_.state = STREAM_STOPPED;\r
+ pah->runnable = false;\r
MUTEX_LOCK( &stream_.mutex );\r
\r
if ( pah && pah->s_play ) {\r
}\r
\r
stream_.state = STREAM_STOPPED;\r
+ pah->runnable = false;\r
MUTEX_LOCK( &stream_.mutex );\r
\r
if ( pah && pah->s_play ) {\r
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
\r
void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format )\r
{\r
- register char val;\r
- register char *ptr;\r
+ char val;\r
+ char *ptr;\r
\r
ptr = buffer;\r
if ( format == RTAUDIO_SINT16 ) {\r