Update to CMake file for WASAPI; documentation update for CMake; finalized date for...
[rtaudio-cdist.git] / RtAudio.cpp
index 202de261a46668af3e8b6e0fb857c4e41f2f793c..eb3eadc411236243eded55af91ee744ff31b8048 100644 (file)
@@ -5,12 +5,12 @@
     RtAudio provides a common API (Application Programming Interface)\r
     for realtime audio input/output across Linux (native ALSA, Jack,\r
     and OSS), Macintosh OS X (CoreAudio and Jack), and Windows\r
-    (DirectSound and ASIO) operating systems.\r
+    (DirectSound, ASIO and WASAPI) operating systems.\r
 \r
     RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/\r
 \r
     RtAudio: realtime audio i/o C++ classes\r
-    Copyright (c) 2001-2013 Gary P. Scavone\r
+    Copyright (c) 2001-2014 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.0.12\r
+// RtAudio: Version 4.1.0\r
 \r
 #include "RtAudio.h"\r
 #include <iostream>\r
@@ -249,6 +249,9 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams,
     return;\r
   }\r
 \r
+  // Clear stream information potentially left from a previously open stream.\r
+  clearStreamInfo();\r
+\r
   if ( oParams && oParams->nChannels < 1 ) {\r
     errorText_ = "RtApi::openStream: a non-NULL output StreamParameters structure cannot have an nChannels value less than one.";\r
     error( RtAudioError::INVALID_USE );\r
@@ -294,7 +297,6 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams,
     }\r
   }\r
 \r
-  clearStreamInfo();\r
   bool result;\r
 \r
   if ( oChannels > 0 ) {\r
@@ -3955,16 +3957,13 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
     EXIT_ON_ERROR( -1, RtAudioError::INVALID_USE, "Invalid device index" );\r
 \r
   // determine whether index falls within capture or render devices\r
-  //if ( device < captureDeviceCount ) {\r
   if ( device >= renderDeviceCount ) {\r
-    //hr = captureDevices->Item( device, &devicePtr );\r
     hr = captureDevices->Item( device - renderDeviceCount, &devicePtr );\r
     EXIT_ON_ERROR( hr, RtAudioError::DRIVER_ERROR, "Unable to retrieve capture device handle" );\r
 \r
     isCaptureDevice = true;\r
   }\r
   else {\r
-    //hr = renderDevices->Item( device - captureDeviceCount, &devicePtr );\r
     hr = renderDevices->Item( device, &devicePtr );\r
     EXIT_ON_ERROR( hr, RtAudioError::DRIVER_ERROR, "Unable to retrieve render device handle" );\r
 \r
@@ -4338,7 +4337,6 @@ bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
     EXIT_ON_ERROR( -1, RtAudioError::INVALID_USE, "Invalid device index" );\r
 \r
   // determine whether index falls within capture or render devices\r
-  //if ( device < captureDeviceCount ) {\r
   if ( device >= renderDeviceCount ) {\r
     if ( mode != INPUT )\r
       EXIT_ON_ERROR( -1, RtAudioError::INVALID_USE, "Capture device selected as output device" );\r
@@ -4346,7 +4344,6 @@ bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
     // retrieve captureAudioClient from devicePtr\r
     IAudioClient*& captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;\r
 \r
-    //hr = captureDevices->Item( device, &devicePtr );\r
     hr = captureDevices->Item( device - renderDeviceCount, &devicePtr );\r
     EXIT_ON_ERROR( hr, RtAudioError::DRIVER_ERROR, "Unable to retrieve capture device handle" );\r
 \r
@@ -4367,7 +4364,6 @@ bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
     // retrieve renderAudioClient from devicePtr\r
     IAudioClient*& renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;\r
 \r
-    //hr = renderDevices->Item( device - captureDeviceCount, &devicePtr );\r
     hr = renderDevices->Item( device, &devicePtr );\r
     EXIT_ON_ERROR( hr, RtAudioError::DRIVER_ERROR, "Unable to retrieve render device handle" );\r
 \r
@@ -4426,15 +4422,6 @@ bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
   if ( !stream_.userBuffer[mode] )\r
     EXIT_ON_ERROR( -1, RtAudioError::MEMORY_ERROR, "Error allocating user buffer memory" );\r
 \r
-  if ( stream_.doConvertBuffer[mode] && !stream_.deviceBuffer ) {\r
-    unsigned int deviceBufferSize = max( stream_.nUserChannels[INPUT] * stream_.bufferSize * formatBytes( stream_.userFormat ),\r
-                                         stream_.nUserChannels[OUTPUT] * stream_.bufferSize * formatBytes( stream_.userFormat ) );\r
-\r
-    stream_.deviceBuffer = ( char* ) calloc( deviceBufferSize, 1 );\r
-    if ( !stream_.deviceBuffer )\r
-      EXIT_ON_ERROR( -1, RtAudioError::MEMORY_ERROR, "Error allocating device buffer memory" );\r
-  }\r
-\r
   if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME )\r
     stream_.callbackInfo.priority = 15;\r
   else\r
@@ -4648,19 +4635,23 @@ void RtApiWasapi::wasapiThread()
   int callbackResult = 0;\r
 \r
   // convBuffer is used to store converted buffers between WASAPI and the user\r
-  char* convBuffer = NULL;\r
-\r
+  unsigned int deviceBufferSize = 0;\r
   if ( stream_.mode == INPUT ) {\r
-    convBuffer = ( char* ) malloc( ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ) );\r
+    deviceBufferSize = ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] );\r
   }\r
   else if ( stream_.mode == OUTPUT ) {\r
-    convBuffer = ( char* ) malloc( ( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) );\r
+    deviceBufferSize = ( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] );\r
   }\r
   else if ( stream_.mode == DUPLEX ) {\r
-    convBuffer = ( char* ) malloc( max( ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ),\r
-                                        ( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) ) );\r
+    deviceBufferSize = max( ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ),\r
+                            ( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) );\r
   }\r
 \r
+  char* convBuffer = ( char* ) malloc( deviceBufferSize );\r
+  stream_.deviceBuffer = ( char* ) malloc( deviceBufferSize );\r
+  if ( !convBuffer || !stream_.deviceBuffer )\r
+      EXIT_ON_ERROR( -1, RtAudioError::MEMORY_ERROR, "Error allocating device buffer memory" );\r
+\r
   // stream process loop\r
   while ( stream_.state != STREAM_STOPPING ) {\r
     if ( !callbackPulled ) {\r
@@ -5053,9 +5044,10 @@ unsigned int RtApiDs :: getDeviceCount( void )
   std::vector< int > indices;\r
   for ( unsigned int i=0; i<dsDevices.size(); i++ )\r
     if ( dsDevices[i].found == false ) indices.push_back( i );\r
-  unsigned int nErased = 0;\r
+  //unsigned int nErased = 0;\r
   for ( unsigned int i=0; i<indices.size(); i++ )\r
-    dsDevices.erase( dsDevices.begin()-nErased++ );\r
+    dsDevices.erase( dsDevices.begin()+indices[i] );\r
+  //dsDevices.erase( dsDevices.begin()-nErased++ );\r
 \r
   return static_cast<unsigned int>(dsDevices.size());\r
 }\r