// 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 ) );
}
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 );
}
// *************************************************** //
{
clearStreamInfo();
MUTEX_INITIALIZE( &stream_.mutex );
+ errorCallback_ = 0;
showWarnings_ = true;
- firstErrorOccurred_ = false;
+ //firstErrorOccurred_ = false;
}
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.
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();
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;
}
}
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;
}
}
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;
}
}
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 )
*/
}
-/*
unsigned int RtApi :: getStreamSampleRate( void )
{
- verifyStream();
-
- return stream_.sampleRate;
+ //verifyStream();
+ if ( isStreamOpen() ) return stream_.sampleRate;
+ else return 0;
}
-*/
// *************************************************** //
//stream_.state = STREAM_CLOSED;
}
-void RtApiCore :: startStream( void )
+//void RtApiCore :: startStream( void )
+RtAudioError::Type RtApiCore :: startStream( void )
{
//verifyStream();
if ( stream_.state != STREAM_STOPPED ) {
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;
}
/*
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 ) {
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;
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 ) {
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
// 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;
}
/*
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;
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. */
\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.
/*!
//! 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;
*/
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:
ThreadHandle thread;
void *callback;
void *userData;
- void *errorCallback;
+ // void *errorCallback;
void *apiInfo; // void pointer for API specific callback information
bool isRunning;
bool doRealtime;
// 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),
};
// **************************************************************** //
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; }
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
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
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.
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,
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;
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";
}
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.
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 );