Browse Source

No exception updates for Jack API.

noexceptions
Gary Scavone 5 years ago
parent
commit
f2244e394d
2 changed files with 57 additions and 43 deletions
  1. +54
    -40
      RtAudio.cpp
  2. +3
    -3
      RtAudio.h

+ 54
- 40
RtAudio.cpp View File

@@ -1949,9 +1949,9 @@ bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
if ( handle->id[0] == handle->id[1] ) // same device, only one callback if ( handle->id[0] == handle->id[1] ) // same device, only one callback
RtApi::tickStreamTime(); RtApi::tickStreamTime();
else if ( deviceId == handle->id[0] ) else if ( deviceId == handle->id[0] )
RtApi::tickStreamTime(); // only tick on the output callback
RtApi::tickStreamTime(); // two devices, only tick on the output callback
} else } else
RtApi::tickStreamTime();
RtApi::tickStreamTime(); // input or output stream only
return SUCCESS; return SUCCESS;
} }
@@ -2004,9 +2004,10 @@ const char* RtApiCore :: getErrorCode( OSStatus code )
#if defined(__UNIX_JACK__) #if defined(__UNIX_JACK__)


// JACK is a low-latency audio server, originally written for the // JACK is a low-latency audio server, originally written for the
// GNU/Linux operating system and now also ported to OS-X. It can
// connect a number of different applications to an audio device, as
// well as allowing them to share audio between themselves.
// GNU/Linux operating system and now also ported to OS-X and
// Windows. It can connect a number of different applications to an
// audio device, as well as allowing them to share audio between
// themselves.
// //
// When using JACK with RtAudio, "devices" refer to JACK clients that // When using JACK with RtAudio, "devices" refer to JACK clients that
// have ports connected to the server. The JACK server is typically // have ports connected to the server. The JACK server is typically
@@ -2141,7 +2142,7 @@ RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device )
if ( device >= nDevices ) { if ( device >= nDevices ) {
jack_client_close( client ); jack_client_close( client );
errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!"; errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!";
error( RtAudioError::INVALID_USE );
error( RTAUDIO_INVALID_USE );
return info; return info;
} }


@@ -2173,7 +2174,7 @@ RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device )
if ( info.outputChannels == 0 && info.inputChannels == 0 ) { if ( info.outputChannels == 0 && info.inputChannels == 0 ) {
jack_client_close(client); jack_client_close(client);
errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!"; errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!";
error( RtAudioError::WARNING );
error( RTAUDIO_WARNING );
return info; return info;
} }


@@ -2214,10 +2215,11 @@ static void *jackCloseStream( void *ptr )
CallbackInfo *info = (CallbackInfo *) ptr; CallbackInfo *info = (CallbackInfo *) ptr;
RtApiJack *object = (RtApiJack *) info->object; RtApiJack *object = (RtApiJack *) info->object;


info->deviceDisconnected = true;
object->closeStream(); object->closeStream();

pthread_exit( NULL ); pthread_exit( NULL );
} }

static void jackShutdown( void *infoPointer ) static void jackShutdown( void *infoPointer )
{ {
CallbackInfo *info = (CallbackInfo *) infoPointer; CallbackInfo *info = (CallbackInfo *) infoPointer;
@@ -2232,7 +2234,6 @@ static void jackShutdown( void *infoPointer )


ThreadHandle threadId; ThreadHandle threadId;
pthread_create( &threadId, NULL, jackCloseStream, info ); pthread_create( &threadId, NULL, jackCloseStream, info );
std::cerr << "\nRtApiJack: the Jack server is shutting down this client ... stream stopped and closed!!\n" << std::endl;
} }


static int jackXrun( void *infoPointer ) static int jackXrun( void *infoPointer )
@@ -2263,7 +2264,7 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
client = jack_client_open( "RtApiJack", jackoptions, status ); client = jack_client_open( "RtApiJack", jackoptions, status );
if ( client == 0 ) { if ( client == 0 ) {
errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!"; errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!";
error( RtAudioError::WARNING );
error( RTAUDIO_WARNING );
return FAILURE; return FAILURE;
} }
} }
@@ -2504,13 +2505,12 @@ void RtApiJack :: closeStream( void )
{ {
if ( stream_.state == STREAM_CLOSED ) { if ( stream_.state == STREAM_CLOSED ) {
errorText_ = "RtApiJack::closeStream(): no open stream to close!"; errorText_ = "RtApiJack::closeStream(): no open stream to close!";
error( RtAudioError::WARNING );
error( RTAUDIO_WARNING );
return; return;
} }


JackHandle *handle = (JackHandle *) stream_.apiHandle; JackHandle *handle = (JackHandle *) stream_.apiHandle;
if ( handle ) { if ( handle ) {

if ( stream_.state == STREAM_RUNNING ) if ( stream_.state == STREAM_RUNNING )
jack_deactivate( handle->client ); jack_deactivate( handle->client );


@@ -2525,6 +2525,12 @@ void RtApiJack :: closeStream( void )
stream_.apiHandle = 0; stream_.apiHandle = 0;
} }


CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
if ( info->deviceDisconnected ) {
errorText_ = "RtApiJack: the Jack server is shutting down this client ... stream stopped and closed!";
error( RTAUDIO_DEVICE_DISCONNECT );
}

for ( int i=0; i<2; i++ ) { for ( int i=0; i<2; i++ ) {
if ( stream_.userBuffer[i] ) { if ( stream_.userBuffer[i] ) {
free( stream_.userBuffer[i] ); free( stream_.userBuffer[i] );
@@ -2537,22 +2543,26 @@ void RtApiJack :: closeStream( void )
stream_.deviceBuffer = 0; stream_.deviceBuffer = 0;
} }


stream_.mode = UNINITIALIZED;
stream_.state = STREAM_CLOSED;
clearStreamInfo();
//stream_.mode = UNINITIALIZED;
//stream_.state = STREAM_CLOSED;
} }


void RtApiJack :: startStream( void )
RtAudioErrorType RtApiJack :: startStream( void )
{ {
verifyStream();
if ( stream_.state == STREAM_RUNNING ) {
errorText_ = "RtApiJack::startStream(): the stream is already running!";
error( RtAudioError::WARNING );
return;
if ( stream_.state != STREAM_STOPPED ) {
if ( stream_.state == STREAM_RUNNING )
errorText_ = "RtApiJack::startStream(): the stream is already running!";
else if ( stream_.state == STREAM_STOPPING || stream_.state == STREAM_CLOSED )
errorText_ = "RtApiJack::startStream(): the stream is stopping or closed!";
return error( RTAUDIO_WARNING );
} }


/*
#if defined( HAVE_GETTIMEOFDAY ) #if defined( HAVE_GETTIMEOFDAY )
gettimeofday( &stream_.lastTickTimestamp, NULL ); gettimeofday( &stream_.lastTickTimestamp, NULL );
#endif #endif
*/


JackHandle *handle = (JackHandle *) stream_.apiHandle; JackHandle *handle = (JackHandle *) stream_.apiHandle;
int result = jack_activate( handle->client ); int result = jack_activate( handle->client );
@@ -2615,17 +2625,18 @@ void RtApiJack :: startStream( void )
stream_.state = STREAM_RUNNING; stream_.state = STREAM_RUNNING;


unlock: unlock:
if ( result == 0 ) return;
error( RtAudioError::RTAUDIO_SYSTEM_ERROR );
if ( result == 0 ) return RTAUDIO_NO_ERROR;
return error( RTAUDIO_SYSTEM_ERROR );
} }


void RtApiJack :: stopStream( void )
RtAudioErrorType RtApiJack :: stopStream( void )
{ {
verifyStream();
if ( stream_.state == STREAM_STOPPED ) {
errorText_ = "RtApiJack::stopStream(): the stream is already stopped!";
error( RtAudioError::WARNING );
return;
if ( stream_.state != STREAM_RUNNING && stream_.state != STREAM_STOPPING ) {
if ( stream_.state == STREAM_STOPPED )
errorText_ = "RtApiJack::stopStream(): the stream is already stopped!";
else if ( stream_.state == STREAM_CLOSED )
errorText_ = "RtApiJack::stopStream(): the stream is closed!";
return error( RTAUDIO_WARNING );
} }


JackHandle *handle = (JackHandle *) stream_.apiHandle; JackHandle *handle = (JackHandle *) stream_.apiHandle;
@@ -2639,21 +2650,23 @@ void RtApiJack :: stopStream( void )


jack_deactivate( handle->client ); jack_deactivate( handle->client );
stream_.state = STREAM_STOPPED; stream_.state = STREAM_STOPPED;
return RTAUDIO_NO_ERROR;
} }


void RtApiJack :: abortStream( void )
RtAudioErrorType RtApiJack :: abortStream( void )
{ {
verifyStream();
if ( stream_.state == STREAM_STOPPED ) {
errorText_ = "RtApiJack::abortStream(): the stream is already stopped!";
error( RtAudioError::WARNING );
return;
if ( stream_.state != STREAM_RUNNING ) {
if ( stream_.state == STREAM_STOPPED )
errorText_ = "RtApiJack::abortStream(): the stream is already stopped!";
else if ( stream_.state == STREAM_STOPPING || stream_.state == STREAM_CLOSED )
errorText_ = "RtApiJack::abortStream(): the stream is stopping or closed!";
return error( RTAUDIO_WARNING );
} }


JackHandle *handle = (JackHandle *) stream_.apiHandle; JackHandle *handle = (JackHandle *) stream_.apiHandle;
handle->drainCounter = 2; handle->drainCounter = 2;


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
@@ -2674,13 +2687,13 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
{ {
if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS; if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
if ( stream_.state == STREAM_CLOSED ) { if ( stream_.state == STREAM_CLOSED ) {
errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!";
error( RtAudioError::WARNING );
errorText_ = "RtApiJack::callbackEvent(): the stream is closed ... this shouldn't happen!";
error( RTAUDIO_WARNING );
return FAILURE; return FAILURE;
} }
if ( stream_.bufferSize != nframes ) { if ( stream_.bufferSize != nframes ) {
errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size has changed ... cannot process!";
error( RtAudioError::WARNING );
errorText_ = "RtApiJack::callbackEvent(): the JACK buffer size has changed ... cannot process!";
error( RTAUDIO_WARNING );
return FAILURE; return FAILURE;
} }


@@ -2694,7 +2707,7 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
stream_.state = STREAM_STOPPING; stream_.state = STREAM_STOPPING;
if ( handle->internalDrain == true ) if ( handle->internalDrain == true )
pthread_create( &threadId, NULL, jackStopStream, info ); pthread_create( &threadId, NULL, jackStopStream, info );
else
else // external call to stopStream()
pthread_cond_signal( &handle->condition ); pthread_cond_signal( &handle->condition );
return SUCCESS; return SUCCESS;
} }
@@ -10021,6 +10034,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.deviceDisconnected = false;
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;


+ 3
- 3
RtAudio.h View File

@@ -912,9 +912,9 @@ public:
unsigned int getDeviceCount( void ); unsigned int getDeviceCount( void );
RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
void closeStream( void ); void closeStream( void );
void startStream( void );
void stopStream( void );
void abortStream( void );
RtAudioErrorType startStream( void );
RtAudioErrorType stopStream( void );
RtAudioErrorType 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,


Loading…
Cancel
Save