Added new setErrorCallback() function and removed errorCallback argument in openStrea...
authorGary Scavone <gary@music.mcgill.ca>
Tue, 30 Jul 2019 16:26:44 +0000 (12:26 -0400)
committerGary Scavone <gary@music.mcgill.ca>
Tue, 30 Jul 2019 16:26:44 +0000 (12:26 -0400)
RtAudio.cpp
RtAudio.h
rtaudio_c.cpp
tests/playsaw.cpp

index a14f954f604492a8282d6ac09166e7dc7b0d14cf..e147b368dada7bdb1e46015758d1a7747e53342e 100644 (file)
@@ -264,7 +264,7 @@ RtAudio :: RtAudio( RtAudio::Api api )
   // It should not be possible to get here because the preprocessor
   // definition __RTAUDIO_DUMMY__ is automatically defined in RtAudio.h
   // if no API-specific definitions are passed to the compiler. But just
-  // in case something weird happens, we'll thow an error.
+  // in case something weird happens, we'll throw an error.
   std::string errorText = "\nRtAudio: no compiled API support found ... critical error!!\n\n";
   throw( RtAudioError( errorText, RtAudioError::UNSPECIFIED ) );
 }
@@ -275,17 +275,17 @@ RtAudio :: ~RtAudio()
     delete rtapi_;
 }
 
-void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters,
-                            RtAudio::StreamParameters *inputParameters,
-                            RtAudioFormat format, unsigned int sampleRate,
-                            unsigned int *bufferFrames,
-                            RtAudioCallback callback, void *userData,
-                            RtAudio::StreamOptions *options,
-                            RtAudioErrorCallback errorCallback )
+//void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters,
+RtAudioError::Type RtAudio :: openStream( RtAudio::StreamParameters *outputParameters,
+                                          RtAudio::StreamParameters *inputParameters,
+                                          RtAudioFormat format, unsigned int sampleRate,
+                                          unsigned int *bufferFrames,
+                                          RtAudioCallback callback, void *userData,
+                                          RtAudio::StreamOptions *options ) //, RtAudioErrorCallback errorCallback )
 {
   return rtapi_->openStream( outputParameters, inputParameters, format,
                              sampleRate, bufferFrames, callback,
-                             userData, options, errorCallback );
+                             userData, options ); //, errorCallback );
 }
 
 // *************************************************** //
@@ -299,8 +299,9 @@ RtApi :: RtApi()
 {
   clearStreamInfo();
   MUTEX_INITIALIZE( &stream_.mutex );
+  errorCallback_ = 0;
   showWarnings_ = true;
-  firstErrorOccurred_ = false;
+  //firstErrorOccurred_ = false;
 }
 
 RtApi :: ~RtApi()
@@ -308,18 +309,19 @@ RtApi :: ~RtApi()
   MUTEX_DESTROY( &stream_.mutex );
 }
 
-void RtApi :: openStream( RtAudio::StreamParameters *oParams,
-                          RtAudio::StreamParameters *iParams,
-                          RtAudioFormat format, unsigned int sampleRate,
-                          unsigned int *bufferFrames,
-                          RtAudioCallback callback, void *userData,
-                          RtAudio::StreamOptions *options,
-                          RtAudioErrorCallback errorCallback )
+//void RtApi :: openStream( RtAudio::StreamParameters *oParams,
+RtAudioError::Type RtApi :: openStream( RtAudio::StreamParameters *oParams,
+                                        RtAudio::StreamParameters *iParams,
+                                        RtAudioFormat format, unsigned int sampleRate,
+                                        unsigned int *bufferFrames,
+                                        RtAudioCallback callback, void *userData,
+                                        RtAudio::StreamOptions *options ) //, RtAudioErrorCallback errorCallback )
 {
+  //RtAudioError::Type type = RtAudioError::NO_ERROR;
   if ( stream_.state != STREAM_CLOSED ) {
+    //type = RtAudioError::INVALID_USE;
     errorText_ = "RtApi::openStream: a stream is already open!";
-    error( RtAudioError::INVALID_USE );
-    return;
+    return error( RtAudioError::INVALID_USE );
   }
 
   // Clear stream information potentially left from a previously open stream.
@@ -327,26 +329,26 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams,
 
   if ( oParams && oParams->nChannels < 1 ) {
     errorText_ = "RtApi::openStream: a non-NULL output StreamParameters structure cannot have an nChannels value less than one.";
-    error( RtAudioError::INVALID_USE );
-    return;
+    return error( RtAudioError::INVALID_USE );
+    //return;
   }
 
   if ( iParams && iParams->nChannels < 1 ) {
     errorText_ = "RtApi::openStream: a non-NULL input StreamParameters structure cannot have an nChannels value less than one.";
-    error( RtAudioError::INVALID_USE );
-    return;
+    return error( RtAudioError::INVALID_USE );
+    //return;
   }
 
   if ( oParams == NULL && iParams == NULL ) {
     errorText_ = "RtApi::openStream: input and output StreamParameters structures are both NULL!";
-    error( RtAudioError::INVALID_USE );
-    return;
+    return error( RtAudioError::INVALID_USE );
+    //return;
   }
 
   if ( formatBytes(format) == 0 ) {
     errorText_ = "RtApi::openStream: 'format' parameter value is undefined.";
-    error( RtAudioError::INVALID_USE );
-    return;
+    return error( RtAudioError::INVALID_USE );
+    //return;
   }
 
   unsigned int nDevices = getDeviceCount();
@@ -355,8 +357,8 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams,
     oChannels = oParams->nChannels;
     if ( oParams->deviceId >= nDevices ) {
       errorText_ = "RtApi::openStream: output device parameter value is invalid.";
-      error( RtAudioError::INVALID_USE );
-      return;
+      return error( RtAudioError::INVALID_USE );
+      //return;
     }
   }
 
@@ -365,8 +367,8 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams,
     iChannels = iParams->nChannels;
     if ( iParams->deviceId >= nDevices ) {
       errorText_ = "RtApi::openStream: input device parameter value is invalid.";
-      error( RtAudioError::INVALID_USE );
-      return;
+      return error( RtAudioError::INVALID_USE );
+      //return;
     }
   }
 
@@ -377,8 +379,8 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams,
     result = probeDeviceOpen( oParams->deviceId, OUTPUT, oChannels, oParams->firstChannel,
                               sampleRate, format, bufferFrames, options );
     if ( result == false ) {
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
+      return error( RtAudioError::SYSTEM_ERROR );
+      //return;
     }
   }
 
@@ -388,17 +390,18 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams,
                               sampleRate, format, bufferFrames, options );
     if ( result == false ) {
       if ( oChannels > 0 ) closeStream();
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
+      return error( RtAudioError::SYSTEM_ERROR );
+      //return;
     }
   }
 
   stream_.callbackInfo.callback = (void *) callback;
   stream_.callbackInfo.userData = userData;
-  stream_.callbackInfo.errorCallback = (void *) errorCallback;
+  //stream_.callbackInfo.errorCallback = (void *) errorCallback;
 
   if ( options ) options->numberOfBuffers = stream_.nBuffers;
   stream_.state = STREAM_STOPPED;
+  return RtAudioError::NO_ERROR;
 }
 
 unsigned int RtApi :: getDefaultInputDevice( void )
@@ -490,14 +493,12 @@ void RtApi :: setStreamTime( double time )
   */
 }
 
-/*
 unsigned int RtApi :: getStreamSampleRate( void )
 {
-  verifyStream();
-
return stream_.sampleRate;
+  //verifyStream();
+  if ( isStreamOpen() ) return stream_.sampleRate;
 else return 0;
 }
-*/
 
 
 // *************************************************** //
@@ -1564,7 +1565,8 @@ void RtApiCore :: closeStream( void )
   //stream_.state = STREAM_CLOSED;
 }
 
-void RtApiCore :: startStream( void )
+//void RtApiCore :: startStream( void )
+RtAudioError::Type RtApiCore :: startStream( void )
 {
   //verifyStream();
   if ( stream_.state != STREAM_STOPPED ) {
@@ -1572,8 +1574,8 @@ void RtApiCore :: startStream( void )
       errorText_ = "RtApiCore::startStream(): the stream is already running!";
     else if ( stream_.state == STREAM_STOPPING || stream_.state == STREAM_CLOSED )
       errorText_ = "RtApiCore::startStream(): the stream is stopping or closed!";
-    error( RtAudioError::WARNING );
-    return;
+    return error( RtAudioError::WARNING );
+    //return;
   }
 
   /*
@@ -1616,11 +1618,12 @@ void RtApiCore :: startStream( void )
   stream_.state = STREAM_RUNNING;
 
  unlock:
-  if ( result == noErr ) return;
-  error( RtAudioError::SYSTEM_ERROR );
+  if ( result == noErr ) return RtAudioError::NO_ERROR;
+  return error( RtAudioError::SYSTEM_ERROR );
 }
 
-void RtApiCore :: stopStream( void )
+//void RtApiCore :: stopStream( void )
+RtAudioError::Type RtApiCore :: stopStream( void )
 {
   //verifyStream();
   if ( stream_.state != STREAM_RUNNING && stream_.state != STREAM_STOPPING ) {
@@ -1628,8 +1631,8 @@ void RtApiCore :: stopStream( void )
       errorText_ = "RtApiCore::stopStream(): the stream is already stopped!";
     else if ( stream_.state == STREAM_CLOSED )
       errorText_ = "RtApiCore::stopStream(): the stream is closed!";
-    error( RtAudioError::WARNING );
-    return;
+    return error( RtAudioError::WARNING );
+    //return;
   }
 
   OSStatus result = noErr;
@@ -1662,11 +1665,12 @@ void RtApiCore :: stopStream( void )
   stream_.state = STREAM_STOPPED;
 
  unlock:
-  if ( result == noErr ) return;
-  error( RtAudioError::SYSTEM_ERROR );
+  if ( result == noErr ) return RtAudioError::NO_ERROR;
+  return error( RtAudioError::SYSTEM_ERROR );
 }
 
-void RtApiCore :: abortStream( void )
+//void RtApiCore :: abortStream( void )
+RtAudioError::Type RtApiCore :: abortStream( void )
 {
   //verifyStream();
   if ( stream_.state != STREAM_RUNNING ) {
@@ -1674,15 +1678,15 @@ void RtApiCore :: abortStream( void )
       errorText_ = "RtApiCore::abortStream(): the stream is already stopped!";
     else if ( stream_.state == STREAM_STOPPING || stream_.state == STREAM_CLOSED )
       errorText_ = "RtApiCore::abortStream(): the stream is stopping or closed!";
-    error( RtAudioError::WARNING );
-    return;
+    return error( RtAudioError::WARNING );
+    //return;
   }
 
   CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
   handle->drainCounter = 2;
 
   stream_.state = STREAM_STOPPING;
-  stopStream();
+  return stopStream();
 }
 
 // This function will be called by a spawned thread when the user
@@ -9983,19 +9987,21 @@ static void *ossCallbackHandler( void *ptr )
 
 // This method can be modified to control the behavior of error
 // message printing.
-void RtApi :: error( RtAudioError::Type type )
+//void RtApi :: error( RtAudioError::Type type )
+RtAudioError::Type RtApi :: error( RtAudioError::Type type )
 {
-  errorStream_.str(""); // clear the ostringstream
+  errorStream_.str(""); // clear the ostringstream to avoid repeated messages
 
-  RtAudioErrorCallback errorCallback = (RtAudioErrorCallback) stream_.callbackInfo.errorCallback;
-  if ( errorCallback ) {
+  // Don't output warnings if showWarnings_ is false
+  if ( type == RtAudioError::WARNING && showWarnings_ == false ) return type;
+  
+  if ( errorCallback_ ) {
     const std::string errorMessage = errorText_;
-    errorCallback( type, errorMessage );
-  }
-  else {
-    if ( showWarnings_ == true )
-      std::cerr << '\n' << errorText_ << "\n\n";
+    errorCallback_( type, errorMessage );
   }
+  else
+    std::cerr << '\n' << errorText_ << "\n\n";
+  return type;
 }
 
 /*
@@ -10023,7 +10029,7 @@ void RtApi :: clearStreamInfo()
   stream_.callbackInfo.callback = 0;
   stream_.callbackInfo.userData = 0;
   stream_.callbackInfo.isRunning = false;
-  stream_.callbackInfo.errorCallback = 0;
+  //stream_.callbackInfo.errorCallback = 0;
   for ( int i=0; i<2; i++ ) {
     stream_.device[i] = 11111;
     stream_.doConvertBuffer[i] = false;
index 347478e43d005183da5438437dfd3dfbaf29b18c..9e02ed68d331a1cbaca86528749ec1cd5741c761 100644 (file)
--- a/RtAudio.h
+++ b/RtAudio.h
@@ -221,8 +221,8 @@ class RTAUDIO_DLL_PUBLIC RtAudioError : public std::runtime_error
  public:
   //! Defined RtAudioError types.
   enum Type {
+    NO_ERROR,          /*!< No error. */
     WARNING,           /*!< A non-critical error. */
-    DEBUG_WARNING,     /*!< A non-critical error which might be useful for debugging. */
     UNSPECIFIED,       /*!< The default, unspecified error type. */
     NO_DEVICES_FOUND,  /*!< No devices found on system. */
     INVALID_DEVICE,    /*!< An invalid device ID was specified. */
@@ -531,11 +531,12 @@ class RTAUDIO_DLL_PUBLIC RtAudio
     \param errorCallback A client-defined function that will be invoked
            when an error has occured.
   */
-  void openStream( RtAudio::StreamParameters *outputParameters,
-                   RtAudio::StreamParameters *inputParameters,
-                   RtAudioFormat format, unsigned int sampleRate,
-                   unsigned int *bufferFrames, RtAudioCallback callback,
-                   void *userData = NULL, RtAudio::StreamOptions *options = NULL, RtAudioErrorCallback errorCallback = NULL );
+  //void openStream( RtAudio::StreamParameters *outputParameters,
+  RtAudioError::Type openStream( RtAudio::StreamParameters *outputParameters,
+                                 RtAudio::StreamParameters *inputParameters,
+                                 RtAudioFormat format, unsigned int sampleRate,
+                                 unsigned int *bufferFrames, RtAudioCallback callback,
+                                 void *userData = NULL, RtAudio::StreamOptions *options = NULL ); //, RtAudioErrorCallback errorCallback = NULL );
 
   //! A function that closes a stream and frees any associated stream memory.
   /*!
@@ -546,30 +547,30 @@ class RTAUDIO_DLL_PUBLIC RtAudio
 
   //! A function that starts a stream.
   /*!
-    An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
-    during processing.  An RtAudioError (type = INVALID_USE) is thrown if a
-    stream is not open.  A warning is issued if the stream is already
-    running.
+    An RtAudioError::SYSTEM_ERROR is returned if an error occurs
+    during processing. An RtAudioError:WARNING is returned if a
+    stream is not open or is already running.
   */
-  void startStream( void );
+  //void startStream( void );
+  RtAudioError::Type startStream( void );
 
   //! Stop a stream, allowing any samples remaining in the output queue to be played.
   /*!
-    An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
-    during processing.  An RtAudioError (type = INVALID_USE) is thrown if a
-    stream is not open.  A warning is issued if the stream is already
-    stopped.
+    An RtAudioError::SYSTEM_ERROR is returned if an error occurs
+    during processing.  An RtAudioError::WARNING is returned if a
+    stream is not open or is already stopped.
   */
-  void stopStream( void );
+  //void stopStream( void );
+  RtAudioError::Type stopStream( void );
 
   //! Stop a stream, discarding any samples remaining in the input/output queue.
   /*!
-    An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
-    during processing.  An RtAudioError (type = INVALID_USE) is thrown if a
-    stream is not open.  A warning is issued if the stream is already
-    stopped.
+    An RtAudioError::SYSTEM_ERROR is returned if an error occurs
+    during processing.  An RtAudioError::WARNING is returned if a
+    stream is not open or is already stopped.
   */
-  void abortStream( void );
+  //void abortStream( void );
+  RtAudioError::Type abortStream( void );
 
   //! Returns true if a stream is open and false if not.
   bool isStreamOpen( void ) const;
@@ -600,15 +601,23 @@ class RTAUDIO_DLL_PUBLIC RtAudio
   */
   long getStreamLatency( void );
 
//! Returns actual sample rate in use by the stream.
- /*!
-   On some systems, the sample rate used may be slightly different
-   than that specified in the stream parameters.  If a stream is not
-   open, an RtAudioError (type = INVALID_USE) will be thrown.
- */
 //! Returns actual sample rate in use by the (open) stream.
 /*!
+    On some systems, the sample rate used may be slightly different
+    than that specified in the stream parameters.  If a stream is not
+    open, a value of zero is returned.
 */
   unsigned int getStreamSampleRate( void );
 
-  //! Specify whether warning messages should be printed to stderr.
+  //! Set a client-defined function that will be invoked when an error or warning occurs.
+  void setErrorCallback( RtAudioErrorCallback errorCallback );
+
+  //! Specify whether warning messages should be output or not.
+  /*!
+    The default behaviour is for warning messages to be output,
+    either to a client-defined error callback function (if specified)
+    or to stderr.
+  */
   void showWarnings( bool value = true );
 
  protected:
@@ -653,7 +662,7 @@ struct CallbackInfo {
   ThreadHandle thread;
   void *callback;
   void *userData;
-  void *errorCallback;
+  //  void *errorCallback;
   void *apiInfo;   // void pointer for API specific callback information
   bool isRunning;
   bool doRealtime;
@@ -662,7 +671,7 @@ struct CallbackInfo {
 
   // Default constructor.
   CallbackInfo()
-  :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false), priority(0), deviceDisconnected(false) {}
+  :object(0), callback(0), userData(0), apiInfo(0), isRunning(false), doRealtime(false), priority(0), deviceDisconnected(false) {} // errorCallback(0), 
 };
 
 // **************************************************************** //
@@ -725,22 +734,26 @@ public:
   virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0;
   virtual unsigned int getDefaultInputDevice( void );
   virtual unsigned int getDefaultOutputDevice( void );
-  void openStream( RtAudio::StreamParameters *outputParameters,
-                   RtAudio::StreamParameters *inputParameters,
-                   RtAudioFormat format, unsigned int sampleRate,
-                   unsigned int *bufferFrames, RtAudioCallback callback,
-                   void *userData, RtAudio::StreamOptions *options,
-                   RtAudioErrorCallback errorCallback );
+  //void openStream( RtAudio::StreamParameters *outputParameters,
+  RtAudioError::Type openStream( RtAudio::StreamParameters *outputParameters,
+                                 RtAudio::StreamParameters *inputParameters,
+                                 RtAudioFormat format, unsigned int sampleRate,
+                                 unsigned int *bufferFrames, RtAudioCallback callback,
+                                 void *userData, RtAudio::StreamOptions *options ); //, RtAudioErrorCallback errorCallback );
   virtual void closeStream( void );
-  virtual void startStream( void ) = 0;
-  virtual void stopStream( void ) = 0;
-  virtual void abortStream( void ) = 0;
+  //virtual void startStream( void ) = 0;
+  virtual RtAudioError::Type startStream( void ) = 0;
+  //virtual void stopStream( void ) = 0;
+  //virtual void abortStream( void ) = 0;
+  virtual RtAudioError::Type stopStream( void ) = 0;
+  virtual RtAudioError::Type abortStream( void ) = 0;
   long getStreamLatency( void );
-  unsigned int getStreamSampleRate( void ) const { return stream_.sampleRate; }
+  unsigned int getStreamSampleRate( void ); // const { return stream_.sampleRate; }
   virtual double getStreamTime( void ) const { return stream_.streamTime; }
   virtual void setStreamTime( double time );
   bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; }
   bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; }
+  void setErrorCallback( RtAudioErrorCallback errorCallback ) { errorCallback_ = errorCallback; }
   void showWarnings( bool value ) { showWarnings_ = value; }
 
 
@@ -816,9 +829,10 @@ protected:
 
   std::ostringstream errorStream_;
   std::string errorText_;
+  RtAudioErrorCallback errorCallback_;
   bool showWarnings_;
   RtApiStream stream_;
-  bool firstErrorOccurred_;
+  //bool firstErrorOccurred_;
 
   /*!
     Protected, api-specific method that attempts to open a device
@@ -845,7 +859,8 @@ protected:
   void verifyStream( void );
 
   //! Protected common error method to allow global control over error handling.
-  void error( RtAudioError::Type type );
+  //void error( RtAudioError::Type type );
+  RtAudioError::Type error( RtAudioError::Type type );
 
   /*!
     Protected method used to perform format, channel number, and/or interleaving
@@ -875,15 +890,19 @@ inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { ret
 inline unsigned int RtAudio :: getDefaultInputDevice( void ) { return rtapi_->getDefaultInputDevice(); }
 inline unsigned int RtAudio :: getDefaultOutputDevice( void ) { return rtapi_->getDefaultOutputDevice(); }
 inline void RtAudio :: closeStream( void ) { return rtapi_->closeStream(); }
-inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); }
-inline void RtAudio :: stopStream( void )  { return rtapi_->stopStream(); }
-inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
+//inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); }
+inline RtAudioError::Type RtAudio :: startStream( void ) { return rtapi_->startStream(); }
+//inline void RtAudio :: stopStream( void )  { return rtapi_->stopStream(); }
+//inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
+inline RtAudioError::Type RtAudio :: stopStream( void )  { return rtapi_->stopStream(); }
+inline RtAudioError::Type RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
 inline bool RtAudio :: isStreamOpen( void ) const { return rtapi_->isStreamOpen(); }
 inline bool RtAudio :: isStreamRunning( void ) const { return rtapi_->isStreamRunning(); }
 inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); }
 inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); }
 inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); }
 inline void RtAudio :: setStreamTime( double time ) { return rtapi_->setStreamTime( time ); }
+inline void RtAudio :: setErrorCallback( RtAudioErrorCallback errorCallback ) { rtapi_->setErrorCallback( errorCallback ); }
 inline void RtAudio :: showWarnings( bool value ) { rtapi_->showWarnings( value ); }
 
 // RtApi Subclass prototypes.
@@ -904,9 +923,12 @@ public:
   unsigned int getDefaultOutputDevice( void );
   unsigned int getDefaultInputDevice( void );
   void closeStream( void );
-  void startStream( void );
-  void stopStream( void );
-  void abortStream( void );
+  //void startStream( void );
+  RtAudioError::Type startStream( void );
+  //void stopStream( void ;)
+  RtAudioError::Type stopStream( void );
+  //void abortStream( void );
+  RtAudioError::Type abortStream( void );
 
   // This function is intended for internal use only.  It must be
   // public because it is called by the internal callback handler,
index ad91babb5c68d8495f798cbd247e914915c388dd..bcb6930b6811090aeeeb4bbfe5c00044d7967d5f 100644 (file)
@@ -161,8 +161,7 @@ int rtaudio_open_stream(rtaudio_t audio,
     audio->cb = cb;
     audio->userdata = userdata;
     audio->audio->openStream(out, in, (RtAudioFormat)format, sample_rate,
-                             buffer_frames, proxy_cb_func, (void *)audio, opts,
-                             NULL);
+                             buffer_frames, proxy_cb_func, (void *)audio, opts); //,  NULL);
     return 0;
   } catch (RtAudioError &err) {
     audio->has_error = 1;
index beaf714a4c220ef16fe89ceca9e956d2dc48361e..e875313a752c96d7beb2c556d4aae67ffa2bad7e 100644 (file)
@@ -66,8 +66,7 @@ void usage( void ) {
 
 void errorCallback( RtAudioError::Type /*type*/, const std::string &errorText )
 {
-  // This example error handling function does exactly the same thing
-  // as the embedded RtAudio::error() function.
+  // This example error handling function simply outputs the error message to stderr.
   std::cerr << "\nerrorCallback: " << errorText << "\n\n";
 }
 
@@ -172,7 +171,9 @@ int main( int argc, char *argv[] )
 
   double *data = (double *) calloc( channels, sizeof( double ) );
 
-  // Let RtAudio print messages to stderr.
+  // Specify our own error callback function and tell RtAudio to
+  // output all messages, even warnings.
+  dac.setErrorCallback( &errorCallback );
   dac.showWarnings( true );
 
   // Set our stream parameters for output only.
@@ -191,11 +192,15 @@ int main( int argc, char *argv[] )
   options.flags |= RTAUDIO_NONINTERLEAVED;
 #endif
 
-  dac.openStream( &oParams, NULL, FORMAT, fs, &bufferFrames, &saw, (void *)data, &options, &errorCallback );
+  // An error in the openStream() function can be detected either by
+  // checking for a non-zero return value OR by a subsequent call to
+  // isStreamOpen().
+  if ( dac.openStream( &oParams, NULL, FORMAT, fs, &bufferFrames, &saw, (void *)data, &options ) )
+    goto cleanup;
   if ( dac.isStreamOpen() == false ) goto cleanup;
 
   // Stream is open ... now start it.
-  dac.startStream();
+  if ( dac.startStream() ) goto cleanup;
 
   if ( checkCount ) {
     while ( dac.isStreamRunning() == true ) SLEEP( 100 );