Let convertBuffer() take care of all channel count conversion, while convertBufferWas...
authorMarcus Tomlinson <themarcustomlinson@gmail.com>
Sat, 26 Apr 2014 09:01:40 +0000 (11:01 +0200)
committerMarcus Tomlinson <themarcustomlinson@gmail.com>
Sat, 26 Apr 2014 09:01:40 +0000 (11:01 +0200)
RtAudio.cpp

index 3af802974697c21dae9ef1e135d3bc4005b7be90..6ab16155bfa6c3feaa3607dc981abf3aa762bb86 100644 (file)
@@ -3585,7 +3585,7 @@ static const char* getAsioErrorString( ASIOError result )
 // - Introduces support for the Windows WASAPI API\r
 // - Aims to deliver bit streams to and from hardware at the lowest possible latency, via the absolute minimum buffer sizes required\r
 // - Provides flexible stream configuration to an otherwise strict and inflexible WASAPI interface\r
-// - Includes automatic internal conversion of sample rate, buffer size and channel count\r
+// - Includes automatic internal conversion of sample rate and buffer size between hardware and the user\r
 \r
 #ifndef INITGUID\r
   #define INITGUID\r
@@ -3767,15 +3767,14 @@ private:
 \r
 //-----------------------------------------------------------------------------\r
 \r
-// In order to satisfy WASAPI's buffer requirements, we need a means of converting sample rate and\r
-// channel counts between HW and the user. The convertBufferWasapi function is used to perform\r
-// these conversions between HwIn->UserIn and UserOut->HwOut during the stream callback loop.\r
+// 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
 void convertBufferWasapi( char* outBuffer,\r
                           const char* inBuffer,\r
-                          const unsigned int& inChannelCount,\r
-                          const unsigned int& outChannelCount,\r
+                          const unsigned int& channelCount,\r
                           const unsigned int& inSampleRate,\r
                           const unsigned int& outSampleRate,\r
                           const unsigned int& inSampleCount,\r
@@ -3786,7 +3785,6 @@ void convertBufferWasapi( char* outBuffer,
   float sampleRatio = ( float ) outSampleRate / inSampleRate;\r
   float sampleStep = 1.0f / sampleRatio;\r
   float inSampleFraction = 0.0f;\r
-  unsigned int commonChannelCount = std::min( inChannelCount, outChannelCount );\r
 \r
   outSampleCount = ( unsigned int ) ( inSampleCount * sampleRatio );\r
 \r
@@ -3798,22 +3796,22 @@ void convertBufferWasapi( char* outBuffer,
     switch ( format )\r
     {\r
       case RTAUDIO_SINT8:\r
-        memcpy( &( ( char* ) outBuffer )[ outSample * outChannelCount ], &( ( char* ) inBuffer )[ inSample * inChannelCount ], commonChannelCount * sizeof( char ) );\r
+        memcpy( &( ( char* ) outBuffer )[ outSample * channelCount ], &( ( char* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( char ) );\r
         break;\r
       case RTAUDIO_SINT16:\r
-        memcpy( &( ( short* ) outBuffer )[ outSample * outChannelCount ], &( ( short* ) inBuffer )[ inSample * inChannelCount ], commonChannelCount * sizeof( short ) );\r
+        memcpy( &( ( short* ) outBuffer )[ outSample * channelCount ], &( ( short* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( short ) );\r
         break;\r
       case RTAUDIO_SINT24:\r
-        memcpy( &( ( S24* ) outBuffer )[ outSample * outChannelCount ], &( ( S24* ) inBuffer )[ inSample * inChannelCount ], commonChannelCount * sizeof( S24 ) );\r
+        memcpy( &( ( S24* ) outBuffer )[ outSample * channelCount ], &( ( S24* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( S24 ) );\r
         break;\r
       case RTAUDIO_SINT32:\r
-        memcpy( &( ( int* ) outBuffer )[ outSample * outChannelCount ], &( ( int* ) inBuffer )[ inSample * inChannelCount ], commonChannelCount * sizeof( int ) );\r
+        memcpy( &( ( int* ) outBuffer )[ outSample * channelCount ], &( ( int* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( int ) );\r
         break;\r
       case RTAUDIO_FLOAT32:\r
-        memcpy( &( ( float* ) outBuffer )[ outSample * outChannelCount ], &( ( float* ) inBuffer )[ inSample * inChannelCount ], commonChannelCount * sizeof( float ) );\r
+        memcpy( &( ( float* ) outBuffer )[ outSample * channelCount ], &( ( float* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( float ) );\r
         break;\r
       case RTAUDIO_FLOAT64:\r
-        memcpy( &( ( double* ) outBuffer )[ outSample * outChannelCount ], &( ( double* ) inBuffer )[ inSample * inChannelCount ], commonChannelCount * sizeof( double ) );\r
+        memcpy( &( ( double* ) outBuffer )[ outSample * channelCount ], &( ( double* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( double ) );\r
         break;\r
     }\r
 \r
@@ -4511,10 +4509,11 @@ bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
 \r
   // Set flags for buffer conversion.\r
   stream_.doConvertBuffer[mode] = false;\r
-  if ( stream_.userFormat != stream_.deviceFormat[mode] )\r
+  if ( stream_.userFormat != stream_.deviceFormat[mode] ||\r
+       stream_.nUserChannels != stream_.nDeviceChannels )\r
     stream_.doConvertBuffer[mode] = true;\r
-  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&\r
-       stream_.nUserChannels[mode] > 1 )\r
+  else if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&\r
+            stream_.nUserChannels[mode] > 1 )\r
     stream_.doConvertBuffer[mode] = true;\r
 \r
   if ( stream_.doConvertBuffer[mode] )\r
@@ -4833,11 +4832,10 @@ void RtApiWasapi::wasapiThread()
                                                    stream_.deviceFormat[INPUT] );\r
 \r
         if ( callbackPulled ) {\r
-          // Convert callback buffer to user sample rate and channel count\r
+          // Convert callback buffer to user sample rate\r
           convertBufferWasapi( stream_.deviceBuffer,\r
                                convBuffer,\r
                                stream_.nDeviceChannels[INPUT],\r
-                               stream_.nUserChannels[INPUT],\r
                                captureFormat->nSamplesPerSec,\r
                                stream_.sampleRate,\r
                                ( unsigned int ) ( stream_.bufferSize * captureSrRatio ),\r
@@ -4851,7 +4849,7 @@ void RtApiWasapi::wasapiThread()
                            stream_.convertInfo[INPUT] );\r
           }\r
           else {\r
-            // no conversion, simple copy deviceBuffer to userBuffer\r
+            // no further conversion, simple copy deviceBuffer to userBuffer\r
             memcpy( stream_.userBuffer[INPUT],\r
                     stream_.deviceBuffer,\r
                     stream_.bufferSize * stream_.nUserChannels[INPUT] * formatBytes( stream_.userFormat ) );\r
@@ -4927,30 +4925,18 @@ void RtApiWasapi::wasapiThread()
                        stream_.userBuffer[OUTPUT],\r
                        stream_.convertInfo[OUTPUT] );\r
 \r
-        // Convert callback buffer to stream sample rate and channel count\r
-        convertBufferWasapi( convBuffer,\r
-                             stream_.deviceBuffer,\r
-                             stream_.nUserChannels[OUTPUT],\r
-                             stream_.nDeviceChannels[OUTPUT],\r
-                             stream_.sampleRate,\r
-                             renderFormat->nSamplesPerSec,\r
-                             stream_.bufferSize,\r
-                             convBufferSize,\r
-                             stream_.deviceFormat[OUTPUT] );\r
-      }\r
-      else {\r
-        // Convert callback buffer to stream sample rate and channel count\r
-        convertBufferWasapi( convBuffer,\r
-                             stream_.userBuffer[OUTPUT],\r
-                             stream_.nUserChannels[OUTPUT],\r
-                             stream_.nDeviceChannels[OUTPUT],\r
-                             stream_.sampleRate,\r
-                             renderFormat->nSamplesPerSec,\r
-                             stream_.bufferSize,\r
-                             convBufferSize,\r
-                             stream_.deviceFormat[OUTPUT] );\r
       }\r
 \r
+      // Convert callback buffer to stream sample rate\r
+      convertBufferWasapi( convBuffer,\r
+                           stream_.deviceBuffer,\r
+                           stream_.nDeviceChannels[OUTPUT],\r
+                           stream_.sampleRate,\r
+                           renderFormat->nSamplesPerSec,\r
+                           stream_.bufferSize,\r
+                           convBufferSize,\r
+                           stream_.deviceFormat[OUTPUT] );\r
+\r
       // Push callback buffer into outputBuffer\r
       callbackPushed = renderBuffer.pushBuffer( convBuffer,\r
                                                 convBufferSize * stream_.nDeviceChannels[OUTPUT],\r
@@ -4985,8 +4971,8 @@ void RtApiWasapi::wasapiThread()
       if ( bufferFrameCount != 0 ) {\r
         // Push capture buffer into inputBuffer\r
         if ( captureBuffer.pushBuffer( ( char* ) streamBuffer,\r
-                                      bufferFrameCount * stream_.nDeviceChannels[INPUT],\r
-                                      stream_.deviceFormat[INPUT] ) )\r
+                                       bufferFrameCount * stream_.nDeviceChannels[INPUT],\r
+                                       stream_.deviceFormat[INPUT] ) )\r
         {\r
           // Release capture buffer\r
           hr = captureClient->ReleaseBuffer( bufferFrameCount );\r
@@ -5054,8 +5040,8 @@ void RtApiWasapi::wasapiThread()
         // Pull next buffer from outputBuffer\r
         // Fill render buffer with next buffer\r
         if ( renderBuffer.pullBuffer( ( char* ) streamBuffer,\r
-                                     bufferFrameCount * stream_.nDeviceChannels[OUTPUT],\r
-                                     stream_.deviceFormat[OUTPUT] ) )\r
+                                      bufferFrameCount * stream_.nDeviceChannels[OUTPUT],\r
+                                      stream_.deviceFormat[OUTPUT] ) )\r
         {\r
           // Release render buffer\r
           hr = renderClient->ReleaseBuffer( bufferFrameCount, 0 );\r