Various updates and fixes before 4.0.5 release (GS).
authorGary Scavone <gary@music.mcgill.ca>
Thu, 29 Jan 2009 19:00:08 +0000 (19:00 +0000)
committerStephen Sinclair <sinclair@music.mcgill.ca>
Thu, 10 Oct 2013 23:38:24 +0000 (01:38 +0200)
12 files changed:
RtAudio.cpp
doc/doxygen/compiling.txt
doc/doxygen/duplex.txt
doc/doxygen/playback.txt
doc/doxygen/recording.txt
doc/doxygen/tutorial.txt
doc/release.txt
tests/duplex.cpp
tests/playraw.cpp
tests/playsaw.cpp
tests/record.cpp
tests/testall.cpp

index f86ea126525e453baf6f36b530e4afe26f8473e6..b66734ed7434b7811c8ccc3d374c9ed712d9a52c 100644 (file)
@@ -42,6 +42,9 @@
 
 #include "RtAudio.h"
 #include <iostream>
+#include <cstdlib>
+#include <cstring>
+#include <limits.h>
 
 // Static variable definitions.
 const unsigned int RtApi::MAX_SAMPLE_RATES = 14;
@@ -1731,9 +1734,15 @@ struct JackHandle {
     :client(0), drainCounter(0), internalDrain(false) { ports[0] = 0; ports[1] = 0; xrun[0] = false; xrun[1] = false; }
 };
 
+void jackSilentError( const char * ) {};
+
 RtApiJack :: RtApiJack()
 {
   // Nothing to do here.
+#if !defined(__RTAUDIO_DEBUG__)
+  // Turn off Jack's internal error reporting.
+  jack_set_error_function( &jackSilentError );
+#endif
 }
 
 RtApiJack :: ~RtApiJack()
@@ -2306,6 +2315,21 @@ void RtApiJack :: abortStream( void )
   stopStream();
 }
 
+// This function will be called by a spawned thread when the user
+// callback function signals that the stream should be stopped or
+// aborted.  It is necessary to handle it this way because the
+// callbackEvent() function must return before the jack_deactivate()
+// function will return.
+extern "C" void *jackStopStream( void *ptr )
+{
+  CallbackInfo *info = (CallbackInfo *) ptr;
+  RtApiJack *object = (RtApiJack *) info->object;
+
+  object->stopStream();
+
+  pthread_exit( NULL );
+}
+
 bool RtApiJack :: callbackEvent( unsigned long nframes )
 {
   if ( stream_.state == STREAM_STOPPED ) return SUCCESS;
@@ -2325,10 +2349,12 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
 
   // Check if we were draining the stream and signal is finished.
   if ( handle->drainCounter > 3 ) {
-    if ( handle->internalDrain == false )
-      pthread_cond_signal( &handle->condition );
+    if ( handle->internalDrain == true ) {
+      ThreadHandle id;
+      pthread_create( &id, NULL, jackStopStream, info );
+    }
     else
-      stopStream();
+      pthread_cond_signal( &handle->condition );
     return SUCCESS;
   }
 
@@ -2357,7 +2383,8 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
                                      stream_.bufferSize, streamTime, status, info->userData );
     if ( handle->drainCounter == 2 ) {
       MUTEX_UNLOCK( &stream_.mutex );
-      abortStream();
+      ThreadHandle id;
+      pthread_create( &id, NULL, jackStopStream, info );
       return SUCCESS;
     }
     else if ( handle->drainCounter == 1 )
@@ -3857,7 +3884,7 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
       bufferBytes *= 2;
 
     // Set cooperative level to DSSCL_EXCLUSIVE ... sound stops when window focus changes.
-    //result = output->SetCooperativeLevel( hWnd, DSSCL_EXCLUSIVE );
+    // result = output->SetCooperativeLevel( hWnd, DSSCL_EXCLUSIVE );
     // Set cooperative level to DSSCL_PRIORITY ... sound remains when window focus changes.
     result = output->SetCooperativeLevel( hWnd, DSSCL_PRIORITY );
     if ( FAILED( result ) ) {
@@ -4023,6 +4050,11 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
     // Update wave format structure and buffer information.
     waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
     waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
+    dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels;
+
+    // If the user wants an even bigger buffer, increase the device buffer size accordingly.
+    while ( dsPointerLeadTime * 2U > (DWORD) bufferBytes )
+      bufferBytes *= 2;
 
     // Setup the secondary DS buffer description.
     dsBufferSize = bufferBytes;
@@ -4044,6 +4076,20 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
       return FAILURE;
     }
 
+    // Get the buffer size ... might be different from what we specified.
+    DSCBCAPS dscbcaps;
+    dscbcaps.dwSize = sizeof( DSCBCAPS );
+    result = buffer->GetCaps( &dscbcaps );
+    if ( FAILED( result ) ) {
+      input->Release();
+      buffer->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting buffer settings (" << dsinfo.name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    bufferBytes = dscbcaps.dwBufferBytes;
+
     // Lock the capture buffer
     LPVOID audioPtr;
     DWORD dataLen;
@@ -4483,7 +4529,7 @@ void RtApiDs :: callbackEvent()
   // The state might change while waiting on a mutex.
   if ( stream_.state == STREAM_STOPPED ) {
     MUTEX_UNLOCK( &stream_.mutex );
-    return SUCCESS;
+    return;
   }
 
   // Invoke user callback to get fresh output data UNLESS we are
@@ -4530,7 +4576,7 @@ void RtApiDs :: callbackEvent()
   long bufferBytes;
 
   if ( stream_.mode == DUPLEX && !buffersRolling ) {
-    assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
+    //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
 
     // It takes a while for the devices to get rolling. As a result,
     // there's no guarantee that the capture and write device pointers
@@ -4581,7 +4627,7 @@ void RtApiDs :: callbackEvent()
       Sleep( 1 );
     }
 
-    assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
+    //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
 
     buffersRolling = true;
     handle->bufferPointer[0] = ( safeWritePos + handle->dsPointerLeadTime[0] );
index d7b9a2976198b10d3910e4226354c74b4ab9e479..79cb31482ed2aa913690daad5f3bd000a19a81cb 100644 (file)
@@ -2,7 +2,7 @@
 
 \section debug Debugging
 
-If you are having problems getting RtAudio to run on your system, make sure to pass a value of \e true to the RtAudio::showWarnings() function (this is the default setting).  A variety of warning messages will be displayed which may help in determining the problem.  Also, try using the programs included in the <tt>tests</tt> directory.  The program <tt>audioprobe</tt> displays the queried capabilities of all hardware devices found for all APIs compiled.  When using the ALSA API, further information can be displayed by defining the preprocessor definition __RTAUDIO_DEBUG__.
+If you are having problems getting RtAudio to run on your system, make sure to pass a value of \e true to the RtAudio::showWarnings() function (this is the default setting).  A variety of warning messages will be displayed which may help in determining the problem.  Also, try using the programs included in the <tt>tests</tt> directory.  The program <tt>audioprobe</tt> displays the queried capabilities of all hardware devices found for all APIs compiled.  When using the ALSA and JACK APIs, further information can be displayed by defining the preprocessor definition __RTAUDIO_DEBUG__.
 
 \section compile Compiling
 
index f060602f36d8586544b8451afc52a61543e211a6..c76ae73d1d9f52fde621b54d4a92a4a573c47e63 100644 (file)
@@ -5,6 +5,8 @@ Finally, it is easy to use RtAudio for simultaneous audio input/output, or duple
 \code
 #include "RtAudio.h"
 #include <iostream>
+#include <cstdlib>
+#include <cstring>
 
 // Pass-through function.
 int inout( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
index 4d5a793be4e50b8755427f133ab8f30fd862e804..c291f5ae18af548a56f1b2d5eba852274e001a09 100644 (file)
@@ -5,6 +5,7 @@ In this example, we provide a complete program that demonstrates the use of RtAu
 \code
 #include "RtAudio.h"
 #include <iostream>
+#include <cstdlib>
 
 // Two-channel sawtooth wave generator.
 int saw( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
index 6316a5c9adc3db7b0de0dc27d04933e76cd7a5a0..9b624386a1de4cc5c6d7d8bf44a44b399c37d531 100644 (file)
@@ -6,6 +6,8 @@ Using RtAudio for audio input is almost identical to the way it is used for play
 \code
 #include "RtAudio.h"
 #include <iostream>
+#include <cstdlib>
+#include <cstring>
 
 int record( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
          double streamTime, RtAudioStreamStatus status, void *userData )
index b42a945a7f728b3f4232545542f8603c82bbac33..02e3bcb50bbec902dbc4fef26c64e45cd45d87fc 100644 (file)
@@ -32,7 +32,7 @@ Devices are now re-enumerated every time the RtAudio::getDeviceCount(), RtAudio:
 
 \section download Download
 
-Latest Release (?? January 2009): <A href="http://www.music.mcgill.ca/~gary/rtaudio/release/rtaudio-4.0.5.tar.gz">Version 4.0.5</A>
+Latest Release (29 January 2009): <A href="http://www.music.mcgill.ca/~gary/rtaudio/release/rtaudio-4.0.5.tar.gz">Version 4.0.5</A>
 
 \section documentation Documentation Links
 
index 70f82c732a2adf701812e781be8cfbaef7f0ece5..42a3fa98c88302011c361cb0491df11e8401cd3f 100644 (file)
@@ -2,11 +2,12 @@ RtAudio - a set of C++ classes that provide a common API for realtime audio inpu
 
 By Gary P. Scavone, 2001-2009.
 
-v4.0.5: (?? January 2009)
+v4.0.5: (29 January 2009)
 - added support in CoreAudio for arbitrary stream channel configurations
 - added getStreamSampleRate() function because the actual sample rate can sometimes vary slightly from the specified one (thanks to Theo Veenker)
 - added new StreamOptions flag "RTAUDIO_SCHEDULE_REALTIME" and attribute "priority" to StreamOptions (thanks to Theo Veenker)
 - replaced usleep(50000) in callbackEvent() by a wait on condition variable which gets signaled in startStream() (thanks to Theo Veenker)
+- fix for Jack API when user callback function signals stop or abort calls
 - fix to way stream state is changed to avoid infinite loop problem
 - fix to int<->float conversion in convertBuffer() (thanks to Theo Veenker)
 - bug fix in byteSwapBuffer() (thanks to Stefan Muller Arisona and Theo Veenker)
index f416bad993f268ad9fba52d8f1f5bcf5d266d8ea..125b56e2d12c827a0b04e3bbb0ee931254319ec7 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "RtAudio.h"
 #include <iostream>
+#include <cstdlib>
+#include <cstring>
 
 /*
 typedef signed long  MY_TYPE;
index 13e8b4909869c6e1bb3c38cfe39d6b35d71ba0f7..1ab16007bb8e2c8c8d4dc02256ef512a2bc0851f 100644 (file)
@@ -11,6 +11,8 @@
 
 #include "RtAudio.h"
 #include <iostream>
+#include <cstdlib>
+#include <cstring>
 
 /*
 typedef char  MY_TYPE;
index d477297c08804d8d8c44e9bff58f08776d4a9172..019963b953cfcc7ca136278b0dc69b52d5aa70f6 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "RtAudio.h"
 #include <iostream>
+#include <cstdlib>
 
 /*
 typedef signed long  MY_TYPE;
index 22bcaac560d3ec76a90761ebf39f34f9072025be..a56f3514b8ba3dc371938070b918fc09d2907071 100644 (file)
@@ -11,6 +11,8 @@
 
 #include "RtAudio.h"
 #include <iostream>
+#include <cstdlib>
+#include <cstring>
 
 /*
 typedef char  MY_TYPE;
index 1f3ea264939735080682284267f588f493305040..bd9ca7466dab584cf995a2ad7538fa685928ef66 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "RtAudio.h"
 #include <iostream>
+#include <cstdlib>
+#include <cstring>
 
 #define BASE_RATE 0.005
 #define TIME   1.0