Merge pull request #68 from jpcima/master
[rtaudio-cdist.git] / RtAudio.cpp
index cdb98d760b91bfd00480d6d08d6f82c8d4d679c1..0b952f02ec8812c169d3eb17d1ca5c94ae151070 100644 (file)
@@ -45,6 +45,7 @@
 #include <cstdlib>\r
 #include <cstring>\r
 #include <climits>\r
+#include <cmath>\r
 #include <algorithm>\r
 \r
 // Static variable definitions.\r
@@ -92,12 +93,12 @@ const unsigned int RtApi::SAMPLE_RATES[] = {
 //\r
 // *************************************************** //\r
 \r
-std::string RtAudio :: getVersion( void ) throw()\r
+std::string RtAudio :: getVersion( void )\r
 {\r
   return RTAUDIO_VERSION;\r
 }\r
 \r
-void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis ) throw()\r
+void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis )\r
 {\r
   apis.clear();\r
 \r
@@ -209,7 +210,7 @@ RtAudio :: RtAudio( RtAudio::Api api )
   throw( RtAudioError( errorText, RtAudioError::UNSPECIFIED ) );\r
 }\r
 \r
-RtAudio :: ~RtAudio() throw()\r
+RtAudio :: ~RtAudio()\r
 {\r
   if ( rtapi_ )\r
     delete rtapi_;\r
@@ -427,6 +428,9 @@ void RtApi :: setStreamTime( double time )
 \r
   if ( time >= 0.0 )\r
     stream_.streamTime = time;\r
+#if defined( HAVE_GETTIMEOFDAY )\r
+  gettimeofday( &stream_.lastTickTimestamp, NULL );\r
+#endif\r
 }\r
 \r
 unsigned int RtApi :: getStreamSampleRate( void )\r
@@ -1943,7 +1947,7 @@ struct JackHandle {
 static void jackSilentError( const char * ) {};\r
 \r
 RtApiJack :: RtApiJack()\r
-{\r
+    :shouldAutoconnect_(true) {\r
   // Nothing to do here.\r
 #if !defined(__RTAUDIO_DEBUG__)\r
   // Turn off Jack's internal error reporting.\r
@@ -2354,6 +2358,8 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
   // here.\r
   if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, 0 );\r
 \r
+  if ( options && options->flags & RTAUDIO_JACK_DONT_CONNECT ) shouldAutoconnect_ = false;\r
+\r
   return SUCCESS;\r
 \r
  error:\r
@@ -2443,7 +2449,7 @@ void RtApiJack :: startStream( void )
   const char **ports;\r
 \r
   // Get the list of available ports.\r
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {\r
+  if ( shouldAutoconnect_ && (stream_.mode == OUTPUT || stream_.mode == DUPLEX) ) {\r
     result = 1;\r
     ports = jack_get_ports( handle->client, handle->deviceName[0].c_str(), NULL, JackPortIsInput);\r
     if ( ports == NULL) {\r
@@ -2467,7 +2473,7 @@ void RtApiJack :: startStream( void )
     free(ports);\r
   }\r
 \r
-  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {\r
+  if ( shouldAutoconnect_ && (stream_.mode == INPUT || stream_.mode == DUPLEX) ) {\r
     result = 1;\r
     ports = jack_get_ports( handle->client, handle->deviceName[1].c_str(), NULL, JackPortIsOutput );\r
     if ( ports == NULL) {\r
@@ -3875,122 +3881,125 @@ void convertBufferWasapi( char* outBuffer,
   float sampleStep = 1.0f / sampleRatio;\r
   float inSampleFraction = 0.0f;\r
 \r
-  outSampleCount = ( unsigned int ) roundf( inSampleCount * sampleRatio );\r
+  outSampleCount = ( unsigned int ) std::roundf( inSampleCount * sampleRatio );\r
 \r
   // if inSampleRate is a multiple of outSampleRate (or vice versa) there's no need to interpolate\r
-  if (floor(sampleRatio) == sampleRatio || floor(sampleRatioInv) == sampleRatioInv)\r
+  if ( floor( sampleRatio ) == sampleRatio || floor( sampleRatioInv ) == sampleRatioInv )\r
   {\r
-         // frame-by-frame, copy each relative input sample into it's corresponding output sample\r
-         for (unsigned int outSample = 0; outSample < outSampleCount; outSample++)\r
-         {\r
-                 unsigned int inSample = (unsigned int)inSampleFraction;\r
-\r
-                 switch (format)\r
-                 {\r
-                 case RTAUDIO_SINT8:\r
-                         memcpy(&((char*)outBuffer)[outSample * channelCount], &((char*)inBuffer)[inSample * channelCount], channelCount * sizeof(char));\r
-                         break;\r
-                 case RTAUDIO_SINT16:\r
-                         memcpy(&((short*)outBuffer)[outSample * channelCount], &((short*)inBuffer)[inSample * channelCount], channelCount * sizeof(short));\r
-                         break;\r
-                 case RTAUDIO_SINT24:\r
-                         memcpy(&((S24*)outBuffer)[outSample * channelCount], &((S24*)inBuffer)[inSample * channelCount], channelCount * sizeof(S24));\r
-                         break;\r
-                 case RTAUDIO_SINT32:\r
-                         memcpy(&((int*)outBuffer)[outSample * channelCount], &((int*)inBuffer)[inSample * channelCount], channelCount * sizeof(int));\r
-                         break;\r
-                 case RTAUDIO_FLOAT32:\r
-                         memcpy(&((float*)outBuffer)[outSample * channelCount], &((float*)inBuffer)[inSample * channelCount], channelCount * sizeof(float));\r
-                         break;\r
-                 case RTAUDIO_FLOAT64:\r
-                         memcpy(&((double*)outBuffer)[outSample * channelCount], &((double*)inBuffer)[inSample * channelCount], channelCount * sizeof(double));\r
-                         break;\r
-                 }\r
-\r
-                 // jump to next in sample\r
-                 inSampleFraction += sampleStep;\r
-         }\r
+    // frame-by-frame, copy each relative input sample into it's corresponding output sample\r
+    for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ )\r
+    {\r
+      unsigned int inSample = ( unsigned int ) inSampleFraction;\r
+\r
+      switch ( format )\r
+      {\r
+        case RTAUDIO_SINT8:\r
+          memcpy( &( ( char* ) outBuffer )[ outSample * channelCount ], &( ( char* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( char ) );\r
+          break;\r
+        case RTAUDIO_SINT16:\r
+          memcpy( &( ( short* ) outBuffer )[ outSample * channelCount ], &( ( short* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( short ) );\r
+          break;\r
+        case RTAUDIO_SINT24:\r
+          memcpy( &( ( S24* ) outBuffer )[ outSample * channelCount ], &( ( S24* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( S24 ) );\r
+          break;\r
+        case RTAUDIO_SINT32:\r
+          memcpy( &( ( int* ) outBuffer )[ outSample * channelCount ], &( ( int* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( int ) );\r
+          break;\r
+        case RTAUDIO_FLOAT32:\r
+          memcpy( &( ( float* ) outBuffer )[ outSample * channelCount ], &( ( float* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( float ) );\r
+          break;\r
+        case RTAUDIO_FLOAT64:\r
+          memcpy( &( ( double* ) outBuffer )[ outSample * channelCount ], &( ( double* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( double ) );\r
+          break;\r
+      }\r
+\r
+      // jump to next in sample\r
+      inSampleFraction += sampleStep;\r
+    }\r
   }\r
   else // else interpolate\r
   {\r
-         // frame-by-frame, copy each relative input sample into it's corresponding output sample\r
-         for (unsigned int outSample = 0; outSample < outSampleCount; outSample++)\r
-         {\r
-                 unsigned int inSample = (unsigned int)inSampleFraction;\r
-\r
-                 switch (format)\r
-                 {\r
-                 case RTAUDIO_SINT8:\r
-                 {\r
-                         for (unsigned int channel = 0; channel < channelCount; channel++)\r
-                         {\r
-                                 char fromSample = ((char*)inBuffer)[(inSample * channelCount) + channel];\r
-                                 char toSample = ((char*)inBuffer)[((inSample + 1) * channelCount) + channel];\r
-                                 float sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction));\r
-                                 ((char*)outBuffer)[(outSample * channelCount) + channel] = fromSample + (char)sampleDiff;\r
-                         }\r
-                         break;\r
-                 }\r
-                 case RTAUDIO_SINT16:\r
-                 {\r
-                         for (unsigned int channel = 0; channel < channelCount; channel++)\r
-                         {\r
-                                 short fromSample = ((short*)inBuffer)[(inSample * channelCount) + channel];\r
-                                 short toSample = ((short*)inBuffer)[((inSample + 1) * channelCount) + channel];\r
-                                 float sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction));\r
-                                 ((short*)outBuffer)[(outSample * channelCount) + channel] = fromSample + (short)sampleDiff;\r
-                         }\r
-                         break;\r
-                 }\r
-                 case RTAUDIO_SINT24:\r
-                 {\r
-                         for (unsigned int channel = 0; channel < channelCount; channel++)\r
-                         {\r
-                                 int fromSample = ((S24*)inBuffer)[(inSample * channelCount) + channel].asInt();\r
-                                 int toSample = ((S24*)inBuffer)[((inSample + 1) * channelCount) + channel].asInt();\r
-                                 float sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction));\r
-                                 ((S24*)outBuffer)[(outSample * channelCount) + channel] = fromSample + (int)sampleDiff;\r
-                         }\r
-                         break;\r
-                 }\r
-                 case RTAUDIO_SINT32:\r
-                 {\r
-                         for (unsigned int channel = 0; channel < channelCount; channel++)\r
-                         {\r
-                                 int fromSample = ((int*)inBuffer)[(inSample * channelCount) + channel];\r
-                                 int toSample = ((int*)inBuffer)[((inSample + 1) * channelCount) + channel];\r
-                                 float sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction));\r
-                                 ((int*)outBuffer)[(outSample * channelCount) + channel] = fromSample + (int)sampleDiff;\r
-                         }\r
-                         break;\r
-                 }\r
-                 case RTAUDIO_FLOAT32:\r
-                 {\r
-                         for (unsigned int channel = 0; channel < channelCount; channel++)\r
-                         {\r
-                                 float fromSample = ((float*)inBuffer)[(inSample * channelCount) + channel];\r
-                                 float toSample = ((float*)inBuffer)[((inSample + 1) * channelCount) + channel];\r
-                                 float sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction));\r
-                                 ((float*)outBuffer)[(outSample * channelCount) + channel] = fromSample + sampleDiff;\r
-                         }\r
-                         break;\r
-                 }\r
-                 case RTAUDIO_FLOAT64:\r
-                 {\r
-                         for (unsigned int channel = 0; channel < channelCount; channel++)\r
-                         {\r
-                                 double fromSample = ((double*)inBuffer)[(inSample * channelCount) + channel];\r
-                                 double toSample = ((double*)inBuffer)[((inSample + 1) * channelCount) + channel];\r
-                                 double sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction));\r
-                                 ((double*)outBuffer)[(outSample * channelCount) + channel] = fromSample + sampleDiff;\r
-                         }\r
-                         break;\r
-                 }\r
-                 }\r
-\r
-                 // jump to next in sample\r
-                 inSampleFraction += sampleStep;\r
-         }\r
+    // frame-by-frame, copy each relative input sample into it's corresponding output sample\r
+    for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ )\r
+    {\r
+      unsigned int inSample = ( unsigned int ) inSampleFraction;\r
+      float inSampleDec = inSampleFraction - inSample;\r
+      unsigned int frameInSample = inSample * channelCount;\r
+      unsigned int frameOutSample = outSample * channelCount;\r
+\r
+      switch ( format )\r
+      {\r
+        case RTAUDIO_SINT8:\r
+        {\r
+          for ( unsigned int channel = 0; channel < channelCount; channel++ )\r
+          {\r
+            char fromSample = ( ( char* ) inBuffer )[ frameInSample + channel ];\r
+            char toSample = ( ( char* ) inBuffer )[ frameInSample + channelCount + channel ];\r
+            char sampleDiff = ( char ) ( ( toSample - fromSample ) * inSampleDec );\r
+            ( ( char* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff;\r
+          }\r
+          break;\r
+        }\r
+        case RTAUDIO_SINT16:\r
+        {\r
+          for ( unsigned int channel = 0; channel < channelCount; channel++ )\r
+          {\r
+            short fromSample = ( ( short* ) inBuffer )[ frameInSample + channel ];\r
+            short toSample = ( ( short* ) inBuffer )[ frameInSample + channelCount + channel ];\r
+            short sampleDiff = ( short ) ( ( toSample - fromSample ) * inSampleDec );\r
+            ( ( short* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff;\r
+          }\r
+          break;\r
+        }\r
+        case RTAUDIO_SINT24:\r
+        {\r
+          for ( unsigned int channel = 0; channel < channelCount; channel++ )\r
+          {\r
+            int fromSample = ( ( S24* ) inBuffer )[ frameInSample + channel ].asInt();\r
+            int toSample = ( ( S24* ) inBuffer )[ frameInSample + channelCount + channel ].asInt();\r
+            int sampleDiff = ( int ) ( ( toSample - fromSample ) * inSampleDec );\r
+            ( ( S24* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff;\r
+          }\r
+          break;\r
+        }\r
+        case RTAUDIO_SINT32:\r
+        {\r
+          for ( unsigned int channel = 0; channel < channelCount; channel++ )\r
+          {\r
+            int fromSample = ( ( int* ) inBuffer )[ frameInSample + channel ];\r
+            int toSample = ( ( int* ) inBuffer )[ frameInSample + channelCount + channel ];\r
+            int sampleDiff = ( int ) ( ( toSample - fromSample ) * inSampleDec );\r
+            ( ( int* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff;\r
+          }\r
+          break;\r
+        }\r
+        case RTAUDIO_FLOAT32:\r
+        {\r
+          for ( unsigned int channel = 0; channel < channelCount; channel++ )\r
+          {\r
+            float fromSample = ( ( float* ) inBuffer )[ frameInSample + channel ];\r
+            float toSample = ( ( float* ) inBuffer )[ frameInSample + channelCount + channel ];\r
+            float sampleDiff = ( toSample - fromSample ) * inSampleDec;\r
+            ( ( float* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff;\r
+          }\r
+          break;\r
+        }\r
+        case RTAUDIO_FLOAT64:\r
+        {\r
+          for ( unsigned int channel = 0; channel < channelCount; channel++ )\r
+          {\r
+            double fromSample = ( ( double* ) inBuffer )[ frameInSample + channel ];\r
+            double toSample = ( ( double* ) inBuffer )[ frameInSample + channelCount + channel ];\r
+            double sampleDiff = ( toSample - fromSample ) * inSampleDec;\r
+            ( ( double* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff;\r
+          }\r
+          break;\r
+        }\r
+      }\r
+\r
+      // jump to next in sample\r
+      inSampleFraction += sampleStep;\r
+    }\r
   }\r
 }\r
 \r
@@ -5280,6 +5289,8 @@ Exit:
 // Various revisions for RtAudio 4.0 by Gary Scavone, April 2007\r
 // Changed device query structure for RtAudio 4.0.7, January 2010\r
 \r
+#include <mmsystem.h>\r
+#include <mmreg.h>\r
 #include <dsound.h>\r
 #include <assert.h>\r
 #include <algorithm>\r
@@ -5360,8 +5371,8 @@ RtApiDs :: RtApiDs()
 \r
 RtApiDs :: ~RtApiDs()\r
 {\r
-  if ( coInitialized_ ) CoUninitialize(); // balanced call.\r
   if ( stream_.state != STREAM_CLOSED ) closeStream();\r
+  if ( coInitialized_ ) CoUninitialize(); // balanced call.\r
 }\r
 \r
 // The DirectSound default output is always the first device.\r
@@ -8780,8 +8791,10 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device )
     info.nativeFormats |= RTAUDIO_SINT8;\r
   if ( mask & AFMT_S32_LE || mask & AFMT_S32_BE )\r
     info.nativeFormats |= RTAUDIO_SINT32;\r
+#ifdef AFMT_FLOAT\r
   if ( mask & AFMT_FLOAT )\r
     info.nativeFormats |= RTAUDIO_FLOAT32;\r
+#endif\r
   if ( mask & AFMT_S24_LE || mask & AFMT_S24_BE )\r
     info.nativeFormats |= RTAUDIO_SINT24;\r
 \r
@@ -9108,7 +9121,7 @@ bool RtApiOss :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
   }\r
 \r
   // Verify the sample rate setup worked.\r
-  if ( abs( srate - sampleRate ) > 100 ) {\r
+  if ( abs( srate - (int)sampleRate ) > 100 ) {\r
     close( fd );\r
     errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support sample rate (" << sampleRate << ").";\r
     errorText_ = errorStream_.str();\r