@@ -264,7 +264,7 @@ RtAudio :: RtAudio( RtAudio::Api api ) | |||||
// It should not be possible to get here because the preprocessor | // It should not be possible to get here because the preprocessor | ||||
// definition __RTAUDIO_DUMMY__ is automatically defined in RtAudio.h | // definition __RTAUDIO_DUMMY__ is automatically defined in RtAudio.h | ||||
// if no API-specific definitions are passed to the compiler. But just | // 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"; | std::string errorText = "\nRtAudio: no compiled API support found ... critical error!!\n\n"; | ||||
throw( RtAudioError( errorText, RtAudioError::UNSPECIFIED ) ); | throw( RtAudioError( errorText, RtAudioError::UNSPECIFIED ) ); | ||||
} | } | ||||
@@ -275,17 +275,17 @@ RtAudio :: ~RtAudio() | |||||
delete rtapi_; | 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, | return rtapi_->openStream( outputParameters, inputParameters, format, | ||||
sampleRate, bufferFrames, callback, | sampleRate, bufferFrames, callback, | ||||
userData, options, errorCallback ); | |||||
userData, options ); //, errorCallback ); | |||||
} | } | ||||
// *************************************************** // | // *************************************************** // | ||||
@@ -299,8 +299,9 @@ RtApi :: RtApi() | |||||
{ | { | ||||
clearStreamInfo(); | clearStreamInfo(); | ||||
MUTEX_INITIALIZE( &stream_.mutex ); | MUTEX_INITIALIZE( &stream_.mutex ); | ||||
errorCallback_ = 0; | |||||
showWarnings_ = true; | showWarnings_ = true; | ||||
firstErrorOccurred_ = false; | |||||
//firstErrorOccurred_ = false; | |||||
} | } | ||||
RtApi :: ~RtApi() | RtApi :: ~RtApi() | ||||
@@ -308,18 +309,19 @@ RtApi :: ~RtApi() | |||||
MUTEX_DESTROY( &stream_.mutex ); | 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 ) { | if ( stream_.state != STREAM_CLOSED ) { | ||||
//type = RtAudioError::INVALID_USE; | |||||
errorText_ = "RtApi::openStream: a stream is already open!"; | 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. | // 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 ) { | if ( oParams && oParams->nChannels < 1 ) { | ||||
errorText_ = "RtApi::openStream: a non-NULL output StreamParameters structure cannot have an nChannels value less than one."; | 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 ) { | if ( iParams && iParams->nChannels < 1 ) { | ||||
errorText_ = "RtApi::openStream: a non-NULL input StreamParameters structure cannot have an nChannels value less than one."; | 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 ) { | if ( oParams == NULL && iParams == NULL ) { | ||||
errorText_ = "RtApi::openStream: input and output StreamParameters structures are both 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 ) { | if ( formatBytes(format) == 0 ) { | ||||
errorText_ = "RtApi::openStream: 'format' parameter value is undefined."; | errorText_ = "RtApi::openStream: 'format' parameter value is undefined."; | ||||
error( RtAudioError::INVALID_USE ); | |||||
return; | |||||
return error( RtAudioError::INVALID_USE ); | |||||
//return; | |||||
} | } | ||||
unsigned int nDevices = getDeviceCount(); | unsigned int nDevices = getDeviceCount(); | ||||
@@ -355,8 +357,8 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams, | |||||
oChannels = oParams->nChannels; | oChannels = oParams->nChannels; | ||||
if ( oParams->deviceId >= nDevices ) { | if ( oParams->deviceId >= nDevices ) { | ||||
errorText_ = "RtApi::openStream: output device parameter value is invalid."; | 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; | iChannels = iParams->nChannels; | ||||
if ( iParams->deviceId >= nDevices ) { | if ( iParams->deviceId >= nDevices ) { | ||||
errorText_ = "RtApi::openStream: input device parameter value is invalid."; | 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, | result = probeDeviceOpen( oParams->deviceId, OUTPUT, oChannels, oParams->firstChannel, | ||||
sampleRate, format, bufferFrames, options ); | sampleRate, format, bufferFrames, options ); | ||||
if ( result == false ) { | 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 ); | sampleRate, format, bufferFrames, options ); | ||||
if ( result == false ) { | if ( result == false ) { | ||||
if ( oChannels > 0 ) closeStream(); | if ( oChannels > 0 ) closeStream(); | ||||
error( RtAudioError::SYSTEM_ERROR ); | |||||
return; | |||||
return error( RtAudioError::SYSTEM_ERROR ); | |||||
//return; | |||||
} | } | ||||
} | } | ||||
stream_.callbackInfo.callback = (void *) callback; | stream_.callbackInfo.callback = (void *) callback; | ||||
stream_.callbackInfo.userData = userData; | stream_.callbackInfo.userData = userData; | ||||
stream_.callbackInfo.errorCallback = (void *) errorCallback; | |||||
//stream_.callbackInfo.errorCallback = (void *) errorCallback; | |||||
if ( options ) options->numberOfBuffers = stream_.nBuffers; | if ( options ) options->numberOfBuffers = stream_.nBuffers; | ||||
stream_.state = STREAM_STOPPED; | stream_.state = STREAM_STOPPED; | ||||
return RtAudioError::NO_ERROR; | |||||
} | } | ||||
unsigned int RtApi :: getDefaultInputDevice( void ) | unsigned int RtApi :: getDefaultInputDevice( void ) | ||||
@@ -490,14 +493,12 @@ void RtApi :: setStreamTime( double time ) | |||||
*/ | */ | ||||
} | } | ||||
/* | |||||
unsigned int RtApi :: getStreamSampleRate( void ) | 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; | //stream_.state = STREAM_CLOSED; | ||||
} | } | ||||
void RtApiCore :: startStream( void ) | |||||
//void RtApiCore :: startStream( void ) | |||||
RtAudioError::Type RtApiCore :: startStream( void ) | |||||
{ | { | ||||
//verifyStream(); | //verifyStream(); | ||||
if ( stream_.state != STREAM_STOPPED ) { | if ( stream_.state != STREAM_STOPPED ) { | ||||
@@ -1572,8 +1574,8 @@ void RtApiCore :: startStream( void ) | |||||
errorText_ = "RtApiCore::startStream(): the stream is already running!"; | errorText_ = "RtApiCore::startStream(): the stream is already running!"; | ||||
else if ( stream_.state == STREAM_STOPPING || stream_.state == STREAM_CLOSED ) | else if ( stream_.state == STREAM_STOPPING || stream_.state == STREAM_CLOSED ) | ||||
errorText_ = "RtApiCore::startStream(): the stream is stopping or 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; | stream_.state = STREAM_RUNNING; | ||||
unlock: | 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(); | //verifyStream(); | ||||
if ( stream_.state != STREAM_RUNNING && stream_.state != STREAM_STOPPING ) { | 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!"; | errorText_ = "RtApiCore::stopStream(): the stream is already stopped!"; | ||||
else if ( stream_.state == STREAM_CLOSED ) | else if ( stream_.state == STREAM_CLOSED ) | ||||
errorText_ = "RtApiCore::stopStream(): the stream is closed!"; | errorText_ = "RtApiCore::stopStream(): the stream is closed!"; | ||||
error( RtAudioError::WARNING ); | |||||
return; | |||||
return error( RtAudioError::WARNING ); | |||||
//return; | |||||
} | } | ||||
OSStatus result = noErr; | OSStatus result = noErr; | ||||
@@ -1662,11 +1665,12 @@ void RtApiCore :: stopStream( void ) | |||||
stream_.state = STREAM_STOPPED; | stream_.state = STREAM_STOPPED; | ||||
unlock: | 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(); | //verifyStream(); | ||||
if ( stream_.state != STREAM_RUNNING ) { | if ( stream_.state != STREAM_RUNNING ) { | ||||
@@ -1674,15 +1678,15 @@ void RtApiCore :: abortStream( void ) | |||||
errorText_ = "RtApiCore::abortStream(): the stream is already stopped!"; | errorText_ = "RtApiCore::abortStream(): the stream is already stopped!"; | ||||
else if ( stream_.state == STREAM_STOPPING || stream_.state == STREAM_CLOSED ) | else if ( stream_.state == STREAM_STOPPING || stream_.state == STREAM_CLOSED ) | ||||
errorText_ = "RtApiCore::abortStream(): the stream is stopping or closed!"; | errorText_ = "RtApiCore::abortStream(): the stream is stopping or closed!"; | ||||
error( RtAudioError::WARNING ); | |||||
return; | |||||
return error( RtAudioError::WARNING ); | |||||
//return; | |||||
} | } | ||||
CoreHandle *handle = (CoreHandle *) stream_.apiHandle; | CoreHandle *handle = (CoreHandle *) stream_.apiHandle; | ||||
handle->drainCounter = 2; | handle->drainCounter = 2; | ||||
stream_.state = STREAM_STOPPING; | stream_.state = STREAM_STOPPING; | ||||
stopStream(); | |||||
return stopStream(); | |||||
} | } | ||||
// This function will be called by a spawned thread when the user | // 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 | // This method can be modified to control the behavior of error | ||||
// message printing. | // 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_; | 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.callback = 0; | ||||
stream_.callbackInfo.userData = 0; | stream_.callbackInfo.userData = 0; | ||||
stream_.callbackInfo.isRunning = false; | stream_.callbackInfo.isRunning = false; | ||||
stream_.callbackInfo.errorCallback = 0; | |||||
//stream_.callbackInfo.errorCallback = 0; | |||||
for ( int i=0; i<2; i++ ) { | for ( int i=0; i<2; i++ ) { | ||||
stream_.device[i] = 11111; | stream_.device[i] = 11111; | ||||
stream_.doConvertBuffer[i] = false; | stream_.doConvertBuffer[i] = false; | ||||
@@ -221,8 +221,8 @@ class RTAUDIO_DLL_PUBLIC RtAudioError : public std::runtime_error | |||||
public: | public: | ||||
//! Defined RtAudioError types. | //! Defined RtAudioError types. | ||||
enum Type { | enum Type { | ||||
NO_ERROR, /*!< No error. */ | |||||
WARNING, /*!< A non-critical error. */ | WARNING, /*!< A non-critical error. */ | ||||
DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */ | |||||
UNSPECIFIED, /*!< The default, unspecified error type. */ | UNSPECIFIED, /*!< The default, unspecified error type. */ | ||||
NO_DEVICES_FOUND, /*!< No devices found on system. */ | NO_DEVICES_FOUND, /*!< No devices found on system. */ | ||||
INVALID_DEVICE, /*!< An invalid device ID was specified. */ | 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 | \param errorCallback A client-defined function that will be invoked | ||||
when an error has occured. | 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 closes a stream and frees any associated stream memory. | ||||
/*! | /*! | ||||
@@ -546,30 +547,30 @@ class RTAUDIO_DLL_PUBLIC RtAudio | |||||
//! A function that starts a stream. | //! 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. | //! 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. | //! 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. | //! Returns true if a stream is open and false if not. | ||||
bool isStreamOpen( void ) const; | bool isStreamOpen( void ) const; | ||||
@@ -600,15 +601,23 @@ class RTAUDIO_DLL_PUBLIC RtAudio | |||||
*/ | */ | ||||
long getStreamLatency( void ); | 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 ); | 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 ); | void showWarnings( bool value = true ); | ||||
protected: | protected: | ||||
@@ -653,7 +662,7 @@ struct CallbackInfo { | |||||
ThreadHandle thread; | ThreadHandle thread; | ||||
void *callback; | void *callback; | ||||
void *userData; | void *userData; | ||||
void *errorCallback; | |||||
// void *errorCallback; | |||||
void *apiInfo; // void pointer for API specific callback information | void *apiInfo; // void pointer for API specific callback information | ||||
bool isRunning; | bool isRunning; | ||||
bool doRealtime; | bool doRealtime; | ||||
@@ -662,7 +671,7 @@ struct CallbackInfo { | |||||
// Default constructor. | // Default constructor. | ||||
CallbackInfo() | 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 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0; | ||||
virtual unsigned int getDefaultInputDevice( void ); | virtual unsigned int getDefaultInputDevice( void ); | ||||
virtual unsigned int getDefaultOutputDevice( 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 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 ); | 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 double getStreamTime( void ) const { return stream_.streamTime; } | ||||
virtual void setStreamTime( double time ); | virtual void setStreamTime( double time ); | ||||
bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; } | bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; } | ||||
bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; } | bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; } | ||||
void setErrorCallback( RtAudioErrorCallback errorCallback ) { errorCallback_ = errorCallback; } | |||||
void showWarnings( bool value ) { showWarnings_ = value; } | void showWarnings( bool value ) { showWarnings_ = value; } | ||||
@@ -816,9 +829,10 @@ protected: | |||||
std::ostringstream errorStream_; | std::ostringstream errorStream_; | ||||
std::string errorText_; | std::string errorText_; | ||||
RtAudioErrorCallback errorCallback_; | |||||
bool showWarnings_; | bool showWarnings_; | ||||
RtApiStream stream_; | RtApiStream stream_; | ||||
bool firstErrorOccurred_; | |||||
//bool firstErrorOccurred_; | |||||
/*! | /*! | ||||
Protected, api-specific method that attempts to open a device | Protected, api-specific method that attempts to open a device | ||||
@@ -845,7 +859,8 @@ protected: | |||||
void verifyStream( void ); | void verifyStream( void ); | ||||
//! Protected common error method to allow global control over error handling. | //! 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 | 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 :: getDefaultInputDevice( void ) { return rtapi_->getDefaultInputDevice(); } | ||||
inline unsigned int RtAudio :: getDefaultOutputDevice( void ) { return rtapi_->getDefaultOutputDevice(); } | inline unsigned int RtAudio :: getDefaultOutputDevice( void ) { return rtapi_->getDefaultOutputDevice(); } | ||||
inline void RtAudio :: closeStream( void ) { return rtapi_->closeStream(); } | 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 :: isStreamOpen( void ) const { return rtapi_->isStreamOpen(); } | ||||
inline bool RtAudio :: isStreamRunning( void ) const { return rtapi_->isStreamRunning(); } | inline bool RtAudio :: isStreamRunning( void ) const { return rtapi_->isStreamRunning(); } | ||||
inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); } | inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); } | ||||
inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); } | inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); } | ||||
inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); } | inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); } | ||||
inline void RtAudio :: setStreamTime( double time ) { return rtapi_->setStreamTime( time ); } | 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 ); } | inline void RtAudio :: showWarnings( bool value ) { rtapi_->showWarnings( value ); } | ||||
// RtApi Subclass prototypes. | // RtApi Subclass prototypes. | ||||
@@ -904,9 +923,12 @@ public: | |||||
unsigned int getDefaultOutputDevice( void ); | unsigned int getDefaultOutputDevice( void ); | ||||
unsigned int getDefaultInputDevice( void ); | unsigned int getDefaultInputDevice( void ); | ||||
void closeStream( 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 | // This function is intended for internal use only. It must be | ||||
// public because it is called by the internal callback handler, | // public because it is called by the internal callback handler, | ||||
@@ -161,8 +161,7 @@ int rtaudio_open_stream(rtaudio_t audio, | |||||
audio->cb = cb; | audio->cb = cb; | ||||
audio->userdata = userdata; | audio->userdata = userdata; | ||||
audio->audio->openStream(out, in, (RtAudioFormat)format, sample_rate, | 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; | return 0; | ||||
} catch (RtAudioError &err) { | } catch (RtAudioError &err) { | ||||
audio->has_error = 1; | audio->has_error = 1; | ||||
@@ -66,8 +66,7 @@ void usage( void ) { | |||||
void errorCallback( RtAudioError::Type /*type*/, const std::string &errorText ) | 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"; | std::cerr << "\nerrorCallback: " << errorText << "\n\n"; | ||||
} | } | ||||
@@ -172,7 +171,9 @@ int main( int argc, char *argv[] ) | |||||
double *data = (double *) calloc( channels, sizeof( double ) ); | 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 ); | dac.showWarnings( true ); | ||||
// Set our stream parameters for output only. | // Set our stream parameters for output only. | ||||
@@ -191,11 +192,15 @@ int main( int argc, char *argv[] ) | |||||
options.flags |= RTAUDIO_NONINTERLEAVED; | options.flags |= RTAUDIO_NONINTERLEAVED; | ||||
#endif | #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; | if ( dac.isStreamOpen() == false ) goto cleanup; | ||||
// Stream is open ... now start it. | // Stream is open ... now start it. | ||||
dac.startStream(); | |||||
if ( dac.startStream() ) goto cleanup; | |||||
if ( checkCount ) { | if ( checkCount ) { | ||||
while ( dac.isStreamRunning() == true ) SLEEP( 100 ); | while ( dac.isStreamRunning() == true ) SLEEP( 100 ); | ||||