Remove OSS configuration from pyrtaudio.
[rtaudio-cdist.git] / RtAudio.cpp
old mode 100755 (executable)
new mode 100644 (file)
index 3875761..f4bff00
@@ -1,4 +1,4 @@
-/************************************************************************/\r
+/************************************************************************/\r
 /*! \class RtAudio\r
     \brief Realtime audio i/o C++ classes.\r
 \r
@@ -10,7 +10,7 @@
     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
@@ -38,7 +38,7 @@
 */\r
 /************************************************************************/\r
 \r
-// RtAudio: Version 4.1.1\r
+// RtAudio: Version 4.1.2\r
 \r
 #include "RtAudio.h"\r
 #include <iostream>\r
@@ -3859,8 +3859,7 @@ private:
 // In order to satisfy WASAPI's buffer requirements, we need a means of converting sample rate\r
 // between HW and the user. The convertBufferWasapi function is used to perform this conversion\r
 // between HwIn->UserIn and UserOut->HwOut during the stream callback loop.\r
-// This sample rate converter favors speed over quality, and works best with conversions between\r
-// one rate and its multiple.\r
+// This sample rate converter works best with conversions between one rate and its multiple.\r
 void convertBufferWasapi( char* outBuffer,\r
                           const char* inBuffer,\r
                           const unsigned int& channelCount,\r
@@ -3872,40 +3871,129 @@ void convertBufferWasapi( char* outBuffer,
 {\r
   // calculate the new outSampleCount and relative sampleStep\r
   float sampleRatio = ( float ) outSampleRate / inSampleRate;\r
+  float sampleRatioInv = ( float ) 1 / sampleRatio;\r
   float sampleStep = 1.0f / sampleRatio;\r
   float inSampleFraction = 0.0f;\r
 \r
   outSampleCount = ( unsigned int ) roundf( inSampleCount * sampleRatio );\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
+  // 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
   {\r
-    unsigned int inSample = ( unsigned int ) inSampleFraction;\r
-\r
-    switch ( format )\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
-      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
+      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
+      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
+      // jump to next in sample\r
+      inSampleFraction += sampleStep;\r
+    }\r
   }\r
 }\r
 \r
@@ -5158,10 +5246,10 @@ void RtApiWasapi::wasapiThread()
     // 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
@@ -6438,6 +6526,7 @@ void RtApiDs :: callbackEvent()
       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