Added errorCallback function argument to RtAudio constructor. Updated documentation...
authorGary Scavone <gary@music.mcgill.ca>
Thu, 22 Aug 2019 16:30:50 +0000 (12:30 -0400)
committerGary Scavone <gary@music.mcgill.ca>
Thu, 22 Aug 2019 16:30:50 +0000 (12:30 -0400)
RtAudio.cpp
RtAudio.h
tests/playsaw.cpp

index 5d1b5b8a4baa3d0dcba94f554ce943e58a86bc6e..d0827fd606f86b777e707f757e9509bfe1aab484 100644 (file)
@@ -236,18 +236,27 @@ void RtAudio :: openRtApi( RtAudio::Api api )
 #endif
 }
 
-RtAudio :: RtAudio( RtAudio::Api api )
+RtAudio :: RtAudio( RtAudio::Api api, RtAudioErrorCallback errorCallback )
 {
   rtapi_ = 0;
-  
+
+  std::string errorMessage;
   if ( api != UNSPECIFIED ) {
     // Attempt to open the specified API.
     openRtApi( api );
-    if ( rtapi_ ) return;
 
-    // No compiled support for specified API value.  Issue a debug
-    // warning and continue as if no API was specified.
-    std::cerr << "\nRtAudio: no compiled support for specified API argument!\n" << std::endl;
+    if ( rtapi_ ) {
+      if ( errorCallback ) rtapi_->setErrorCallback( errorCallback );
+      return;
+    }
+
+    // No compiled support for specified API value.  Issue a warning
+    // and continue as if no API was specified.
+    errorMessage = "RtAudio: no compiled support for specified API argument!";
+    if ( errorCallback )
+      errorCallback( RTAUDIO_INVALID_USE, errorMessage );
+    else
+      std::cerr << '\n' << errorMessage << '\n' << std::endl;
   }
 
   // Iterate through the compiled APIs and return as soon as we find
@@ -259,13 +268,20 @@ RtAudio :: RtAudio( RtAudio::Api api )
     if ( rtapi_ && rtapi_->getDeviceCount() ) break;
   }
 
-  if ( rtapi_ ) return;
+  if ( rtapi_ ) {
+    if ( errorCallback ) rtapi_->setErrorCallback( errorCallback );
+    return;
+  }
 
   // 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, issue an error message and abort.
-  std::cerr << "\nRtAudio: no compiled API support found ... critical error!\n" << std::endl;
+  errorMessage = "RtAudio: no compiled API support found ... critical error!";
+  if ( errorCallback )
+    errorCallback( RTAUDIO_INVALID_USE, errorMessage );
+  else
+    std::cerr << '\n' << errorMessage << '\n' << std::endl;
   abort();
 }
 
@@ -276,11 +292,11 @@ RtAudio :: ~RtAudio()
 }
 
 RtAudioErrorType RtAudio :: openStream( RtAudio::StreamParameters *outputParameters,
-                                          RtAudio::StreamParameters *inputParameters,
-                                          RtAudioFormat format, unsigned int sampleRate,
-                                          unsigned int *bufferFrames,
-                                          RtAudioCallback callback, void *userData,
-                                          RtAudio::StreamOptions *options )
+                                        RtAudio::StreamParameters *inputParameters,
+                                        RtAudioFormat format, unsigned int sampleRate,
+                                        unsigned int *bufferFrames,
+                                        RtAudioCallback callback, void *userData,
+                                        RtAudio::StreamOptions *options )
 {
   return rtapi_->openStream( outputParameters, inputParameters, format,
                              sampleRate, bufferFrames, callback,
@@ -308,11 +324,11 @@ RtApi :: ~RtApi()
 }
 
 RtAudioErrorType RtApi :: openStream( RtAudio::StreamParameters *oParams,
-                                        RtAudio::StreamParameters *iParams,
-                                        RtAudioFormat format, unsigned int sampleRate,
-                                        unsigned int *bufferFrames,
-                                        RtAudioCallback callback, void *userData,
-                                        RtAudio::StreamOptions *options )
+                                      RtAudio::StreamParameters *iParams,
+                                      RtAudioFormat format, unsigned int sampleRate,
+                                      unsigned int *bufferFrames,
+                                      RtAudioCallback callback, void *userData,
+                                      RtAudio::StreamOptions *options )
 {
   if ( stream_.state != STREAM_CLOSED ) {
     errorText_ = "RtApi::openStream: a stream is already open!";
index ca08bc480fd4ea3275717dce3479dae250ca6e2c..92db59bed3de1c1cda6ef7f8b58ff2e2da0474ef 100644 (file)
--- a/RtAudio.h
+++ b/RtAudio.h
@@ -64,7 +64,6 @@
 
 #include <string>
 #include <vector>
-//#include <stdexcept>
 #include <iostream>
 
 /*! \typedef typedef unsigned long RtAudioFormat;
@@ -206,54 +205,6 @@ typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer,
                                 RtAudioStreamStatus status,
                                 void *userData );
 
-/************************************************************************/
-/*! \class RtAudioError
-    \brief Error handling class for RtAudio.
-
-    The RtAudioError class is quite simple but it does allow errors to be
-    identified by RtAudioError::Type.
-*/
-/************************************************************************/
-
-/* class RTAUDIO_DLL_PUBLIC RtAudioError : public std::runtime_error */
-/* { */
-/*  public: */
-/*   //! Defined RtAudioError types. */
-/*   enum Type { */
-/*     NO_ERROR,          /\*!< No error. *\/ */
-/*     WARNING,           /\*!< A non-critical error. *\/ */
-/*     UNSPECIFIED,       /\*!< The default, unspecified error type. *\/ */
-/*     NO_DEVICES_FOUND,  /\*!< No devices found on system. *\/ */
-/*     INVALID_DEVICE,    /\*!< An invalid device ID was specified. *\/ */
-/*     DEVICE_DISCONNECT, /\*!< A device in use was disconnected. *\/ */
-/*     MEMORY_ERROR,      /\*!< An error occured during memory allocation. *\/ */
-/*     INVALID_PARAMETER, /\*!< An invalid parameter was specified to a function. *\/ */
-/*     INVALID_USE,       /\*!< The function was called incorrectly. *\/ */
-/*     DRIVER_ERROR,      /\*!< A system driver error occured. *\/ */
-/*     SYSTEM_ERROR,      /\*!< A system error occured. *\/ */
-/*     THREAD_ERROR       /\*!< A thread error occured. *\/ */
-/*   }; */
-
-/*   //! The constructor. */
-/*   RtAudioError( const std::string& message, */
-/*                 Type type = RtAudioError::UNSPECIFIED ) */
-/*     : std::runtime_error(message), type_(type) {} */
-
-/*   //! Prints error message to stderr. */
-/*   virtual void printMessage( void ) const */
-/*     { std::cerr << '\n' << what() << "\n\n"; } */
-
-/*   //! Returns the error message type. */
-/*   virtual const Type& getType(void) const { return type_; } */
-
-/*   //! Returns the error message string. */
-/*   virtual const std::string getMessage(void) const */
-/*     { return std::string(what()); } */
-
-/*  protected: */
-/*   Type type_; */
-/* }; */
-
 enum RtAudioErrorType {
   RTAUDIO_NO_ERROR,          /*!< No error. */
   RTAUDIO_WARNING,           /*!< A non-critical error. */
@@ -445,14 +396,21 @@ class RTAUDIO_DLL_PUBLIC RtAudio
 
   //! The class constructor.
   /*!
-    The constructor performs minor initialization tasks.  An exception
-    can be thrown if no API support is compiled.
-
-    If no API argument is specified and multiple API support has been
-    compiled, the default order of use is JACK, ALSA, OSS (Linux
-    systems) and ASIO, DS (Windows systems).
+    The constructor attempts to create an RtApi instance.
+
+    If an API argument is specified but that API has not been
+    compiled, a warning is issued and an instance of an available API
+    is created. If no compiled API is found, the routine will abort
+    (though this should be impossible because RtDummy is the default
+    if no API-specific preprocessor definition is provided to the
+    compiler). If no API argument is specified and multiple API
+    support has been compiled, the default order of use is JACK, ALSA,
+    OSS (Linux systems) and ASIO, DS (Windows systems).
+
+    An optional errorCallback function can be specified to
+    subsequently receive warning and error messages.
   */
-  RtAudio( RtAudio::Api api=UNSPECIFIED );
+  RtAudio( RtAudio::Api api=UNSPECIFIED, RtAudioErrorCallback errorCallback=0 );
 
   //! The destructor.
   /*!
@@ -546,40 +504,40 @@ class RTAUDIO_DLL_PUBLIC RtAudio
            returned via the structure argument.  The parameter is API dependent.
   */
   RtAudioErrorType openStream( RtAudio::StreamParameters *outputParameters,
-                                 RtAudio::StreamParameters *inputParameters,
-                                 RtAudioFormat format, unsigned int sampleRate,
-                                 unsigned int *bufferFrames, RtAudioCallback callback,
-                                 void *userData = NULL, RtAudio::StreamOptions *options = NULL );
+                               RtAudio::StreamParameters *inputParameters,
+                               RtAudioFormat format, unsigned int sampleRate,
+                               unsigned int *bufferFrames, RtAudioCallback callback,
+                               void *userData = NULL, RtAudio::StreamOptions *options = NULL );
 
   //! A function that closes a stream and frees any associated stream memory.
   /*!
-    If a stream is not open, an RTAUDIO_WARNING will be
-    passed to the user-provided errorCallback function (or otherwise
-    printed to stderr).
+    If a stream is not open, an RTAUDIO_WARNING will be passed to the
+    user-provided errorCallback function (or otherwise printed to
+    stderr).
   */
   void closeStream( void );
 
   //! A function that starts a stream.
   /*!
-    An RTAUDIO_SYSTEM_ERROR is returned if an error occurs
-    during processing. An RTAUDIO_WARNING is returned if a
-    stream is not open or is already running.
+    An RTAUDIO_SYSTEM_ERROR is returned if an error occurs during
+    processing. An RTAUDIO_WARNING is returned if a stream is not open
+    or is already running.
   */
   RtAudioErrorType startStream( void );
 
   //! Stop a stream, allowing any samples remaining in the output queue to be played.
   /*!
-    An RTAUDIO_SYSTEM_ERROR is returned if an error occurs
-    during processing.  An RTAUDIO_WARNING is returned if a
-    stream is not open or is already stopped.
+    An RTAUDIO_SYSTEM_ERROR is returned if an error occurs during
+    processing.  An RTAUDIO_WARNING is returned if a stream is not
+    open or is already stopped.
   */
   RtAudioErrorType stopStream( void );
 
   //! Stop a stream, discarding any samples remaining in the input/output queue.
   /*!
-    An RTAUDIO_SYSTEM_ERROR is returned if an error occurs
-    during processing.  An RTAUDIO_WARNING is returned if a
-    stream is not open or is already stopped.
+    An RTAUDIO_SYSTEM_ERROR is returned if an error occurs during
+    processing.  An RTAUDIO_WARNING is returned if a stream is not
+    open or is already stopped.
   */
   RtAudioErrorType abortStream( void );
 
@@ -589,9 +547,13 @@ class RTAUDIO_DLL_PUBLIC RtAudio
   //! Returns true if the stream is running and false if it is stopped or not open.
   bool isStreamRunning( void ) const;
 
-  //! Returns the number of elapsed seconds since the stream was started.
+  //! Returns the number of seconds of processed data since the stream was started.
   /*!
-    If a stream is not open, the returned value may not be valid.
+    The stream time is calculated from the number of sample frames
+    processed by the underlying audio system, which will increment by
+    units of the audio buffer size. It is not an absolute running
+    time. If a stream is not open, the returned value may not be
+    valid.
   */
   double getStreamTime( void );
 
@@ -854,12 +816,6 @@ protected:
   //! Protected common method to clear an RtApiStream structure.
   void clearStreamInfo();
 
-  /*!
-    Protected common method that throws an RtAudioError (type =
-    INVALID_USE) if a stream is not open.
-  */
-  //void verifyStream( void );
-
   //! Protected common error method to allow global control over error handling.
   RtAudioErrorType error( RtAudioErrorType type );
 
@@ -891,10 +847,7 @@ 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 RtAudioErrorType RtAudio :: startStream( void ) { return rtapi_->startStream(); }
-//inline void RtAudio :: stopStream( void )  { return rtapi_->stopStream(); }
-//inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
 inline RtAudioErrorType RtAudio :: stopStream( void )  { return rtapi_->stopStream(); }
 inline RtAudioErrorType RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
 inline bool RtAudio :: isStreamOpen( void ) const { return rtapi_->isStreamOpen(); }
index 56e693f810ad0ffa47087139e4422d4f8dba544d..f678d1ef25ca3acd10d2256eea6b69b7a51a2a47 100644 (file)
@@ -153,7 +153,9 @@ int main( int argc, char *argv[] )
   // minimal command-line checking
   if (argc < 3 || argc > 6 ) usage();
 
-  RtAudio dac;
+  // Specify our own error callback function.
+  RtAudio dac( RtAudio::UNSPECIFIED, &errorCallback );
+  
   if ( dac.getDeviceCount() < 1 ) {
     std::cout << "\nNo audio devices found!\n";
     exit( 1 );
@@ -171,9 +173,8 @@ int main( int argc, char *argv[] )
 
   double *data = (double *) calloc( channels, sizeof( double ) );
 
-  // Specify our own error callback function and tell RtAudio to
-  // output all messages, even warnings.
-  dac.setErrorCallback( &errorCallback );
+  // Tell RtAudio to output all messages, even warnings.
+  //dac.setErrorCallback( &errorCallback ); // could use if not set via constructor
   dac.showWarnings( true );
 
   // Set our stream parameters for output only.