diff options
| author | Gary Scavone <gary@music.mcgill.ca> | 2019-08-27 16:13:49 -0400 |
|---|---|---|
| committer | Gary Scavone <gary@music.mcgill.ca> | 2019-08-27 16:13:49 -0400 |
| commit | f2244e394dc2873abc4de1864d215ccab2b15e08 (patch) | |
| tree | 4ab8c9dacd7e7df1df48917265d385a83eb66798 /RtAudio.cpp | |
| parent | 10977977730415518802eb37c570af4ac18138de (diff) | |
No exception updates for Jack API.
Diffstat (limited to 'RtAudio.cpp')
| -rw-r--r-- | RtAudio.cpp | 94 |
1 files changed, 54 insertions, 40 deletions
diff --git a/RtAudio.cpp b/RtAudio.cpp index d01c4e2..9b2a972 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -1949,9 +1949,9 @@ bool RtApiCore :: callbackEvent( AudioDeviceID deviceId, if ( handle->id[0] == handle->id[1] ) // same device, only one callback RtApi::tickStreamTime(); 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 - RtApi::tickStreamTime(); + RtApi::tickStreamTime(); // input or output stream only return SUCCESS; } @@ -2004,9 +2004,10 @@ const char* RtApiCore :: getErrorCode( OSStatus code ) #if defined(__UNIX_JACK__) // 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 // 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 ) { jack_client_close( client ); errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!"; - error( RtAudioError::INVALID_USE ); + error( RTAUDIO_INVALID_USE ); return info; } @@ -2173,7 +2174,7 @@ RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device ) if ( info.outputChannels == 0 && info.inputChannels == 0 ) { jack_client_close(client); errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!"; - error( RtAudioError::WARNING ); + error( RTAUDIO_WARNING ); return info; } @@ -2214,10 +2215,11 @@ static void *jackCloseStream( void *ptr ) CallbackInfo *info = (CallbackInfo *) ptr; RtApiJack *object = (RtApiJack *) info->object; + info->deviceDisconnected = true; object->closeStream(); - pthread_exit( NULL ); } + static void jackShutdown( void *infoPointer ) { CallbackInfo *info = (CallbackInfo *) infoPointer; @@ -2232,7 +2234,6 @@ static void jackShutdown( void *infoPointer ) ThreadHandle threadId; 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 ) @@ -2263,7 +2264,7 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne client = jack_client_open( "RtApiJack", jackoptions, status ); if ( client == 0 ) { errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!"; - error( RtAudioError::WARNING ); + error( RTAUDIO_WARNING ); return FAILURE; } } @@ -2504,13 +2505,12 @@ void RtApiJack :: closeStream( void ) { if ( stream_.state == STREAM_CLOSED ) { errorText_ = "RtApiJack::closeStream(): no open stream to close!"; - error( RtAudioError::WARNING ); + error( RTAUDIO_WARNING ); return; } JackHandle *handle = (JackHandle *) stream_.apiHandle; if ( handle ) { - if ( stream_.state == STREAM_RUNNING ) jack_deactivate( handle->client ); @@ -2525,6 +2525,12 @@ void RtApiJack :: closeStream( void ) 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++ ) { if ( stream_.userBuffer[i] ) { free( stream_.userBuffer[i] ); @@ -2537,22 +2543,26 @@ void RtApiJack :: closeStream( void ) 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 ) gettimeofday( &stream_.lastTickTimestamp, NULL ); #endif + */ JackHandle *handle = (JackHandle *) stream_.apiHandle; int result = jack_activate( handle->client ); @@ -2615,17 +2625,18 @@ void RtApiJack :: startStream( void ) stream_.state = STREAM_RUNNING; 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; @@ -2639,21 +2650,23 @@ void RtApiJack :: stopStream( void ) jack_deactivate( handle->client ); 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; handle->drainCounter = 2; - stopStream(); + return stopStream(); } // 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_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; } 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; } @@ -2694,7 +2707,7 @@ bool RtApiJack :: callbackEvent( unsigned long nframes ) stream_.state = STREAM_STOPPING; if ( handle->internalDrain == true ) pthread_create( &threadId, NULL, jackStopStream, info ); - else + else // external call to stopStream() pthread_cond_signal( &handle->condition ); return SUCCESS; } @@ -10021,6 +10034,7 @@ void RtApi :: clearStreamInfo() stream_.callbackInfo.callback = 0; stream_.callbackInfo.userData = 0; stream_.callbackInfo.isRunning = false; + stream_.callbackInfo.deviceDisconnected = false; for ( int i=0; i<2; i++ ) { stream_.device[i] = 11111; stream_.doConvertBuffer[i] = false; |
