diff --git a/source/modules/rtaudio/RtAudio.cpp b/source/modules/rtaudio/RtAudio.cpp index f846b4315..ce08f80c8 100644 --- a/source/modules/rtaudio/RtAudio.cpp +++ b/source/modules/rtaudio/RtAudio.cpp @@ -1936,7 +1936,6 @@ const char* RtApiCore :: getErrorCode( OSStatus code ) struct JackHandle { jack_client_t *client; jack_port_t **ports[2]; - std::string deviceName[2]; bool xrun[2]; pthread_cond_t condition; int drainCounter; // Tracks callback counts when draining @@ -1958,128 +1957,30 @@ RtApiJack :: ~RtApiJack() unsigned int RtApiJack :: getDeviceCount( void ) { - // See if we can become a jack client. - jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption; - jack_status_t *status = NULL; - jack_client_t *client = jackbridge_client_open( "CarlaJackCount", options, status ); - if ( client == 0 ) return 0; - - const char **ports; - std::string port, previousPort; - unsigned int nChannels = 0, nDevices = 0; - ports = jackbridge_get_ports( client, NULL, NULL, 0 ); - if ( ports ) { - // Parse the port names up to the first colon (:). - size_t iColon = 0; - do { - port = (char *) ports[ nChannels ]; - iColon = port.find(":"); - if ( iColon != std::string::npos ) { - port = port.substr( 0, iColon + 1 ); - if ( port != previousPort ) { - nDevices++; - previousPort = port; - } - } - } while ( ports[++nChannels] ); - jackbridge_free( ports ); - } - - jackbridge_client_close( client ); - return nDevices; + return 2; } RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device ) { - RtAudio::DeviceInfo info; - info.probed = false; - - jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption - jack_status_t *status = NULL; - jack_client_t *client = jackbridge_client_open( "CarlaJackInfo", options, status ); - if ( client == 0 ) { - errorText_ = "RtApiJack::getDeviceInfo: Jack server not found or connection error!"; - error( RtAudioError::WARNING ); - return info; - } + static RtAudio::DeviceInfo devInfo[3]; - const char **ports; - std::string port, previousPort; - unsigned int nPorts = 0, nDevices = 0; - ports = jackbridge_get_ports( client, NULL, NULL, 0 ); - if ( ports ) { - // Parse the port names up to the first colon (:). - size_t iColon = 0; - do { - port = (char *) ports[ nPorts ]; - iColon = port.find(":"); - if ( iColon != std::string::npos ) { - port = port.substr( 0, iColon ); - if ( port != previousPort ) { - if ( nDevices == device ) info.name = port; - nDevices++; - previousPort = port; - } - } - } while ( ports[++nPorts] ); - jackbridge_free( ports ); - } - - if ( device >= nDevices ) { - jackbridge_client_close( client ); - errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!"; - error( RtAudioError::INVALID_USE ); - return info; - } - - // Get the current jack server sample rate. - info.sampleRates.clear(); - - info.preferredSampleRate = jackbridge_get_sample_rate( client ); - info.sampleRates.push_back( info.preferredSampleRate ); - - // Count the available ports containing the client name as device - // channels. Jack "input ports" equal RtAudio output channels. - unsigned int nChannels = 0; - ports = jackbridge_get_ports( client, info.name.c_str(), NULL, JackPortIsInput ); - if ( ports ) { - while ( ports[ nChannels ] ) nChannels++; - jackbridge_free( ports ); - info.outputChannels = nChannels; - } - - // Jack "output ports" equal RtAudio input channels. - nChannels = 0; - ports = jackbridge_get_ports( client, info.name.c_str(), NULL, JackPortIsOutput ); - if ( ports ) { - while ( ports[ nChannels ] ) nChannels++; - jackbridge_free( ports ); - info.inputChannels = nChannels; - } - - if ( info.outputChannels == 0 && info.inputChannels == 0 ) { - jackbridge_client_close(client); - errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!"; - error( RtAudioError::WARNING ); - return info; + if (! devInfo[0].probed) + { + devInfo[0].probed = devInfo[1].probed = true; + devInfo[0].outputChannels = devInfo[1].outputChannels = 2; + devInfo[0].inputChannels = devInfo[1].inputChannels = 2; + devInfo[0].duplexChannels = devInfo[1].duplexChannels = 2; + devInfo[0].isDefaultOutput = devInfo[1].isDefaultOutput = true; + devInfo[0].isDefaultInput = devInfo[1].isDefaultInput = true; + devInfo[0].nativeFormats = devInfo[1].nativeFormats = RTAUDIO_FLOAT32; + devInfo[0].name = "Auto-connect ON"; + devInfo[1].name = "Auto-connect OFF"; } - // If device opens for both playback and capture, we determine the channels. - if ( info.outputChannels > 0 && info.inputChannels > 0 ) - info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; - - // Jack always uses 32-bit floats. - info.nativeFormats = RTAUDIO_FLOAT32; - - // Jack doesn't provide default devices so we'll use the first available one. - if ( device == 0 && info.outputChannels > 0 ) - info.isDefaultOutput = true; - if ( device == 0 && info.inputChannels > 0 ) - info.isDefaultInput = true; + if (device > 2) + device = 2; - jackbridge_client_close(client); - info.probed = true; - return info; + return devInfo[device]; } static int jackCallbackHandler( jack_nframes_t nframes, void *infoPointer ) @@ -2149,7 +2050,7 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne if ( options && !options->streamName.empty() ) client = jackbridge_client_open( options->streamName.c_str(), jackoptions, status ); else - client = jackbridge_client_open( "CarlaJack", jackoptions, status ); + client = jackbridge_client_open( "Carla", jackoptions, status ); if ( client == 0 ) { errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!"; error( RtAudioError::WARNING ); @@ -2161,51 +2062,6 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne client = handle->client; } - const char **ports; - std::string port, previousPort, deviceName; - unsigned int nPorts = 0, nDevices = 0; - ports = jackbridge_get_ports( client, NULL, NULL, 0 ); - if ( ports ) { - // Parse the port names up to the first colon (:). - size_t iColon = 0; - do { - port = (char *) ports[ nPorts ]; - iColon = port.find(":"); - if ( iColon != std::string::npos ) { - port = port.substr( 0, iColon ); - if ( port != previousPort ) { - if ( nDevices == device ) deviceName = port; - nDevices++; - previousPort = port; - } - } - } while ( ports[++nPorts] ); - jackbridge_free( ports ); - } - - if ( device >= nDevices ) { - errorText_ = "RtApiJack::probeDeviceOpen: device ID is invalid!"; - return FAILURE; - } - - // Count the available ports containing the client name as device - // channels. Jack "input ports" equal RtAudio output channels. - unsigned int nChannels = 0; - unsigned long flag = JackPortIsInput; - if ( mode == INPUT ) flag = JackPortIsOutput; - ports = jackbridge_get_ports( client, deviceName.c_str(), NULL, flag ); - if ( ports ) { - while ( ports[ nChannels ] ) nChannels++; - jackbridge_free( ports ); - } - - // Compare the jack ports for specified client to the requested number of channels. - if ( nChannels < (channels + firstChannel) ) { - errorStream_ << "RtApiJack::probeDeviceOpen: requested number of channels (" << channels << ") + offset (" << firstChannel << ") not found for specified device (" << device << ":" << deviceName << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } - // Check the jack server sample rate. unsigned int jackRate = jackbridge_get_sample_rate( client ); if ( sampleRate != jackRate ) { @@ -2214,7 +2070,8 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne stream_.sampleRate = jackRate; // Get the latency of the JACK port. - ports = jackbridge_get_ports( client, deviceName.c_str(), NULL, flag ); + const char **ports; + ports = jackbridge_get_ports( client, "system:", NULL, JackPortIsInput ); if ( ports[ firstChannel ] ) { // Added by Ge Wang jack_latency_callback_mode_t cbmode = (mode == INPUT ? JackCaptureLatency : JackPlaybackLatency); @@ -2274,7 +2131,6 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne stream_.apiHandle = (void *) handle; handle->client = client; } - handle->deviceName[mode] = deviceName; // Allocate necessary internal buffers. unsigned long bufferBytes; @@ -2348,6 +2204,9 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne } } + // auto-connect "device" is #1 + shouldAutoconnect_ = device == 0; + // Setup the buffer conversion information structure. We don't use // buffers to do channel offsets, so we override that parameter // here. @@ -2446,7 +2305,7 @@ void RtApiJack :: startStream( void ) // Get the list of available ports. if ( shouldAutoconnect_ && (stream_.mode == OUTPUT || stream_.mode == DUPLEX) ) { result = false; - ports = jackbridge_get_ports( handle->client, handle->deviceName[0].c_str(), NULL, JackPortIsInput); + ports = jackbridge_get_ports( handle->client, "system:", NULL, JackPortIsInput); if ( ports == NULL) { errorText_ = "RtApiJack::startStream(): error determining available JACK input ports!"; goto unlock; @@ -2470,7 +2329,7 @@ void RtApiJack :: startStream( void ) if ( shouldAutoconnect_ && (stream_.mode == INPUT || stream_.mode == DUPLEX) ) { result = false; - ports = jackbridge_get_ports( handle->client, handle->deviceName[1].c_str(), NULL, JackPortIsOutput ); + ports = jackbridge_get_ports( handle->client, "system:", NULL, JackPortIsOutput ); if ( ports == NULL) { errorText_ = "RtApiJack::startStream(): error determining available JACK output ports!"; goto unlock;