static int process_info_connect_jack (process_info_t * procinfo, ui_t * ui) { _update_status ( _("Connecting to JACK server with client name '%s'"), jack_client_name ); #if HAVE_JACK_SESSION if (strlen (session_uuid->str)) procinfo->jack_client = jack_client_open (jack_client_name, JackSessionID, NULL, session_uuid->str); else #endif procinfo->jack_client = jack_client_open (jack_client_name, JackNullOption, NULL); if (!procinfo->jack_client) return -1; _update_status ( _status_cb_data, _("Connected to JACK server") ); jack_set_process_callback (procinfo->jack_client, process, procinfo); jack_on_shutdown (procinfo->jack_client, jack_shutdown_cb, ui); /* FIXME: need a generic callback for this, too */ #if HAVE_JACK_SESSION if( jack_set_session_callback ) jack_set_session_callback (procinfo->jack_client, jack_session_cb_aux, ui); #endif return 0; }
void open_jack(void ) { if (jack_client) { fprintf (stderr, "xjadeo is alredy connected to jack.\n"); return; } int i = 0; do { snprintf(jackid,16,"xjadeo-%i",i); #ifdef JACK_SESSION if (jack_uuid) jack_client = jack_client_open (jackid, JackUseExactName|JackSessionID, NULL, jack_uuid); else #endif jack_client = jack_client_open (jackid, JackUseExactName, NULL); } while (jack_client == 0 && i++<16); if (!jack_client) { fprintf(stderr, "could not connect to jack server.\n"); } else { #ifdef JACK_SESSION jack_set_session_callback (jack_client, jack_session_cb, NULL); #endif #ifndef HAVE_WINDOWS jack_on_shutdown (jack_client, jack_shutdown, 0); jack_activate(jack_client); #endif if (!want_quiet) fprintf(stdout, "connected as jack client '%s'\n",jackid); #ifdef HAVE_LASH lash_jack_client_name(lash_client, jackid); #endif } }
process_info_t * process_info_new (ui_t* ui, unsigned long rack_channels) { process_info_t* procinfo; int err; procinfo = g_malloc (sizeof (process_info_t)); procinfo->chain = NULL; procinfo->chain_end = NULL; procinfo->jack_client = NULL; procinfo->port_count = 0; procinfo->jack_input_ports = NULL; procinfo->jack_output_ports = NULL; procinfo->channels = rack_channels; procinfo->time_runs = time_runs; /* sort out the client name */ jack_client_name = g_strdup ( client_name->str ); sanitize_client_name ( jack_client_name ); err = process_info_connect_jack (procinfo, ui); if (err == -1) { g_free (jack_client_name); g_free (procinfo); return NULL; } err = process_info_set_port_count (procinfo, ui, rack_channels); if (err) return NULL; sample_rate = jack_get_sample_rate (procinfo->jack_client); buffer_size = jack_get_sample_rate (procinfo->jack_client); jack_set_process_callback (procinfo->jack_client, process, procinfo); jack_on_shutdown (procinfo->jack_client, jack_shutdown_cb, ui); #if HAVE_JACK_SESSION if( jack_set_session_callback ) jack_set_session_callback (procinfo->jack_client, jack_session_cb_aux, ui); #endif procinfo->ui_to_process = ui->ui_to_process; procinfo->process_to_ui = ui->process_to_ui; jack_activate (procinfo->jack_client); #ifdef HAVE_LASH /* sort out LASH stuff */ lash_jack_client_name (global_lash_client, jack_client_name); #endif return procinfo; }
static int _jack_init(prog_t *handle, const char *id) { jack_options_t opts = JackNullOption | JackNoStartServer; if(handle->server_name) opts |= JackServerName; if(handle->session_id) opts |= JackSessionID; jack_status_t status; if(!(handle->client = jack_client_open(id, opts, &status, handle->server_name ? handle->server_name : handle->session_id, handle->server_name ? handle->session_id : NULL))) { return -1; } //TODO check status // set client pretty name #if defined(JACK_HAS_METADATA_API) jack_uuid_t uuid; const char *client_name = jack_get_client_name(handle->client); const char *uuid_str = jack_get_uuid_for_client_name(handle->client, client_name); if(uuid_str) jack_uuid_parse(uuid_str, &uuid); else jack_uuid_clear(&uuid); if(!jack_uuid_empty(uuid)) { jack_set_property(handle->client, uuid, JACK_METADATA_PRETTY_NAME, "Synthpod", "text/plain"); } #endif // set client process callback if(jack_set_process_callback(handle->client, _process, handle)) return -1; if(jack_set_session_callback(handle->client, _session, handle)) return -1; if(jack_set_sample_rate_callback(handle->client, _sample_rate, handle)) return -1; if(jack_set_buffer_size_callback(handle->client, _buffer_size, handle)) return -1; jack_on_shutdown(handle->client, _shutdown, handle); jack_set_xrun_callback(handle->client, _xrun, handle); return 0; }
int JackOutput::init( unsigned /*nBufferSize*/ ) { Preferences* pref = Preferences::get_instance(); output_port_name_1 = pref->m_sJackPortName1; output_port_name_2 = pref->m_sJackPortName2; QString sClientName = "Hydrogen"; #ifdef H2CORE_HAVE_NSMSESSION QString nsmClientId = pref->getNsmClientId(); if(!nsmClientId.isEmpty()){ sClientName = nsmClientId; } #endif jack_status_t status; int tries = 2; // Sometimes jackd doesn't stop and start fast enough. while ( tries > 0 ) { --tries; #ifdef H2CORE_HAVE_JACKSESSION if (pref->getJackSessionUUID().isEmpty()){ client = jack_client_open( sClientName.toLocal8Bit(), JackNullOption, &status); } else { const QByteArray uuid = pref->getJackSessionUUID().toLocal8Bit(); client = jack_client_open( sClientName.toLocal8Bit(), JackSessionID, &status, uuid.constData()); } #else client = jack_client_open( sClientName.toLocal8Bit(), JackNullOption, &status); #endif switch(status) { case JackFailure: CLIENT_FAILURE("unknown error"); break; case JackInvalidOption: CLIENT_FAILURE("invalid option"); break; case JackNameNotUnique: if (client) { sClientName = jack_get_client_name(client); CLIENT_SUCCESS(QString("Jack assigned the client name '%1'").arg(sClientName)); } else { CLIENT_FAILURE("name not unique"); } break; case JackServerStarted: CLIENT_SUCCESS("JACK Server started for Hydrogen."); break; case JackServerFailed: CLIENT_FAILURE("unable to connect"); break; case JackServerError: CLIENT_FAILURE("communication error"); break; case JackNoSuchClient: CLIENT_FAILURE("unknown client type"); break; case JackLoadFailure: CLIENT_FAILURE("can't load internal client"); break; case JackInitFailure: CLIENT_FAILURE("can't initialize client"); break; case JackShmFailure: CLIENT_FAILURE("unable to access shared memory"); break; case JackVersionError: CLIENT_FAILURE("client/server protocol version mismatch"); default: if (status) { ERRORLOG("Unknown status with JACK server."); if (client) { CLIENT_SUCCESS("Client pointer is *not* null..." " assuming we're OK"); } } else { CLIENT_SUCCESS("Connected to JACK server"); } } } if (client == 0) return -1; // Here, client should either be valid, or NULL. jack_server_sampleRate = jack_get_sample_rate ( client ); jack_server_bufferSize = jack_get_buffer_size ( client ); pref->m_nSampleRate = jack_server_sampleRate; pref->m_nBufferSize = jack_server_bufferSize; /* tell the JACK server to call `process()' whenever there is work to be done. */ jack_set_process_callback ( client, this->processCallback, 0 ); /* tell the JACK server to call `srate()' whenever the sample rate of the system changes. */ jack_set_sample_rate_callback ( client, jackDriverSampleRate, this ); /* tell JACK server to update us if the buffer size (frames per process cycle) changes. */ jack_set_buffer_size_callback ( client, jackDriverBufferSize, 0 ); /* tell the JACK server to call `jack_shutdown()' if it ever shuts down, either entirely, or if it just decides to stop calling us. */ jack_on_shutdown ( client, jackDriverShutdown, 0 ); /* create two ports */ output_port_1 = jack_port_register ( client, "out_L", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); output_port_2 = jack_port_register ( client, "out_R", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); Hydrogen *H = Hydrogen::get_instance(); if ( ( output_port_1 == NULL ) || ( output_port_2 == NULL ) ) { H->raiseError( Hydrogen::JACK_ERROR_IN_PORT_REGISTER ); return 4; } // clear buffers // jack_default_audio_sample_t *out_L = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port_1, jack_server_bufferSize); // jack_default_audio_sample_t *out_R = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port_2, jack_server_bufferSize); // memset( out_L, 0, nBufferSize * sizeof( float ) ); // memset( out_R, 0, nBufferSize * sizeof( float ) ); #ifdef H2CORE_HAVE_LASH if ( pref->useLash() ){ LashClient* lashClient = LashClient::get_instance(); if (lashClient->isConnected()) { lashClient->setJackClientName(sClientName.toLocal8Bit().constData()); } } #endif #ifdef H2CORE_HAVE_JACKSESSION jack_set_session_callback (client, jack_session_callback, (void*)this); #endif if ( pref->m_bJackMasterMode == Preferences::USE_JACK_TIME_MASTER ) initTimeMaster(); return 0; }
int JackAudioDriver::init( unsigned bufferSize ) { // Destination ports the output of Hydrogen will be connected // to. Preferences* pPref = Preferences::get_instance(); output_port_name_1 = pPref->m_sJackPortName1; output_port_name_2 = pPref->m_sJackPortName2; QString sClientName = "Hydrogen"; #ifdef H2CORE_HAVE_OSC QString sNsmClientId = pPref->getNsmClientId(); if(!sNsmClientId.isEmpty()){ sClientName = sNsmClientId; } #endif // The address of the status object will be used by JACK to // return information from the open operation. jack_status_t status; // Sometimes jackd doesn't stop and start fast enough. int nTries = 2; while ( nTries > 0 ) { --nTries; // Open an external client session with the JACK // server. The `jack_client_open' function is defined // in the jack/jack.h header. With it, clients may // choose which of several servers to connect, and // control whether and how to start the server // automatically, if it was not already running. Its // first argument _client_name_ of is at most // jack_client_name_size() characters. The name scope // is local to each server. Unless forbidden by the // JackUseExactName option, the server will modify // this name to create a unique variant, if // needed. The second argument _options_ is formed by // OR-ing together JackOptions bits. Only the // JackOpenOptions bits are allowed. _status_ (if // non-NULL) is an address for JACK to return // information from the open operation. This status // word is formed by OR-ing together the relevant // JackStatus bits. Depending on the _status_, an // optional argument _server_name_ selects from among // several possible concurrent server // instances. Server names are unique to each user. It // returns an opaque client handle if successful. If // this is NULL, the open operation failed, *status // includes JackFailure and the caller is not a JACK // client. #ifdef H2CORE_HAVE_JACKSESSION if (pPref->getJackSessionUUID().isEmpty()){ m_pClient = jack_client_open( sClientName.toLocal8Bit(), JackNullOption, &status); } else { // Unique name of the JACK server used within // the JACK session. const QByteArray uuid = pPref->getJackSessionUUID().toLocal8Bit(); // Using the JackSessionID option and the // supplied SessionID Token the sessionmanager // is able to identify the client again. m_pClient = jack_client_open( sClientName.toLocal8Bit(), JackSessionID, &status, uuid.constData()); } #else m_pClient = jack_client_open( sClientName.toLocal8Bit(), JackNullOption, &status); #endif // Check what did happen during the opening of the // client. CLIENT_SUCCESS sets the nTries variable // to 0 while CLIENT_FAILURE resets m_pClient to the // nullptr. switch(status) { case JackFailure: CLIENT_FAILURE("unknown error"); break; case JackInvalidOption: CLIENT_FAILURE("invalid option"); break; case JackNameNotUnique: if (m_pClient) { sClientName = jack_get_client_name(m_pClient); CLIENT_SUCCESS(QString("Jack assigned the client name '%1'").arg(sClientName)); } else { CLIENT_FAILURE("name not unique"); } break; case JackServerStarted: CLIENT_SUCCESS("JACK Server started for Hydrogen."); break; case JackServerFailed: CLIENT_FAILURE("unable to connect"); break; case JackServerError: CLIENT_FAILURE("communication error"); break; case JackNoSuchClient: CLIENT_FAILURE("unknown client type"); break; case JackLoadFailure: CLIENT_FAILURE("can't load internal client"); break; case JackInitFailure: CLIENT_FAILURE("can't initialize client"); break; case JackShmFailure: CLIENT_FAILURE("unable to access shared memory"); break; case JackVersionError: CLIENT_FAILURE("client/server protocol version mismatch"); break; default: if (status) { ERRORLOG("Unknown status with JACK server."); if (m_pClient) { CLIENT_SUCCESS("Client pointer is *not* null..." " assuming we're OK"); } } else { CLIENT_SUCCESS("Connected to JACK server"); } } } if (m_pClient == 0) return -1; // Here, client should either be valid, or NULL. jack_server_sampleRate = jack_get_sample_rate( m_pClient ); jack_server_bufferSize = jack_get_buffer_size( m_pClient ); pPref->m_nSampleRate = jack_server_sampleRate; pPref->m_nBufferSize = jack_server_bufferSize; /* tell the JACK server to call `process()' whenever there is work to be done. */ jack_set_process_callback( m_pClient, this->processCallback, 0 ); /* tell the JACK server to call `srate()' whenever the sample rate of the system changes. */ jack_set_sample_rate_callback( m_pClient, jackDriverSampleRate, this ); /* tell JACK server to update us if the buffer size (frames per process cycle) changes. */ jack_set_buffer_size_callback( m_pClient, jackDriverBufferSize, 0 ); /* tell the JACK server to call `jack_shutdown()' if it ever shuts down, either entirely, or if it just decides to stop calling us. */ jack_on_shutdown( m_pClient, jackDriverShutdown, 0 ); // Create two new ports for Hydrogen's client. These are // objects used for moving data of any type in or out of the // client. Ports may be connected in various ways. The // function `jack_port_register' (jack/jack.h) is called like // jack_port_register( jack_client_t *client, // const char *port_name, // const char *port_type, // unsigned long flags, // unsigned long buffer_size) // // All ports have a type, which may be any non-NULL and non-zero // length string, passed as an argument. Some port types are built // into the JACK API, currently only JACK_DEFAULT_AUDIO_TYPE. // It returns a _jack_port_t_ pointer on success, otherwise NULL. output_port_1 = jack_port_register( m_pClient, "out_L", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); output_port_2 = jack_port_register( m_pClient, "out_R", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); Hydrogen *pEngine = Hydrogen::get_instance(); if ( ( output_port_1 == NULL ) || ( output_port_2 == NULL ) ) { pEngine->raiseError( Hydrogen::JACK_ERROR_IN_PORT_REGISTER ); return 4; } #ifdef H2CORE_HAVE_LASH if ( pPref->useLash() ){ LashClient* lashClient = LashClient::get_instance(); if (lashClient->isConnected()) { lashClient->setJackClientName(sClientName.toLocal8Bit().constData()); } } #endif #ifdef H2CORE_HAVE_JACKSESSION jack_set_session_callback(m_pClient, jack_session_callback, (void*)this); #endif if ( pPref->m_bJackMasterMode == Preferences::USE_JACK_TIME_MASTER ){ // Make Hydrogen the timebase master, regardless if there // is already a timebase master present. m_nJackConditionalTakeOver = 0; // Make Hydrogen the JACK timebase master. initTimeMaster(); } return 0; }
int main ( int argc, char *argv[] ) { int i; const char **ports; const char *client_name; const char *server_name = NULL; jack_status_t status; #ifdef JACK_SESSION /* * Extra code for JS */ int c; char *uuid = "13"; while ((c = getopt (argc, argv, "u:")) != -1) switch (c) { case 'u': uuid = optarg; break; } printf("UUID is %s\n", uuid); #endif client_name = strrchr ( argv[0], '/' ); if ( client_name == 0 ) { client_name = argv[0]; } else { client_name++; } /* open a client connection to the JACK server */ /* Changed args for JS */ #ifdef JACK_SESSION client = jack_client_open ( client_name, JackSessionID, &status, uuid); #else client = jack_client_open ( client_name, JackNullOption, &status); #endif if ( client == NULL ) { fprintf ( stderr, "jack_client_open() failed, " "status = 0x%2.0x\n", status ); if ( status & JackServerFailed ) { fprintf ( stderr, "Unable to connect to JACK server\n" ); } exit ( 1 ); } if ( status & JackServerStarted ) { fprintf ( stderr, "JACK server started\n" ); } if ( status & JackNameNotUnique ) { client_name = jack_get_client_name ( client ); fprintf ( stderr, "unique name `%s' assigned\n", client_name ); } #ifdef JACK_SESSION /* Set callback function for JS */ jack_set_session_callback(client, session_callback, NULL); #endif /* tell the JACK server to call `process()' whenever there is work to be done. */ jack_set_process_callback ( client, process, 0 ); /* tell the JACK server to call `jack_shutdown()' if it ever shuts down, either entirely, or if it just decides to stop calling us. */ jack_on_shutdown ( client, jack_shutdown, 0 ); /* create two ports pairs*/ input_ports = ( jack_port_t** ) calloc ( 2, sizeof ( jack_port_t* ) ); output_ports = ( jack_port_t** ) calloc ( 2, sizeof ( jack_port_t* ) ); char port_name[16]; for ( i = 0; i < 2; i++ ) { sprintf ( port_name, "input_%d", i + 1 ); input_ports[i] = jack_port_register ( client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ); sprintf ( port_name, "output_%d", i + 1 ); output_ports[i] = jack_port_register ( client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); if ( ( input_ports[i] == NULL ) || ( output_ports[i] == NULL ) ) { fprintf ( stderr, "no more JACK ports available\n" ); exit ( 1 ); } } bzero(buffer, SIZE * sizeof ( jack_default_audio_sample_t )); delay_idx = 0; idx = DELAY; /* Tell the JACK server that we are ready to roll. Our * process() callback will start running now. */ if ( jack_activate ( client ) ) { fprintf ( stderr, "cannot activate client" ); exit ( 1 ); } /* Connect the ports. You can't do this before the client is * activated, because we can't make connections to clients * that aren't running. Note the confusing (but necessary) * orientation of the driver backend ports: playback ports are * "input" to the backend, and capture ports are "output" from * it. */ ports = jack_get_ports ( client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput ); if ( ports == NULL ) { fprintf ( stderr, "no physical capture ports\n" ); exit ( 1 ); } for ( i = 0; i < 2; i++ ) if ( jack_connect ( client, ports[i], jack_port_name ( input_ports[i] ) ) ) fprintf ( stderr, "cannot connect input ports\n" ); free ( ports ); ports = jack_get_ports ( client, NULL, NULL, JackPortIsPhysical|JackPortIsInput ); if ( ports == NULL ) { fprintf ( stderr, "no physical playback ports\n" ); exit ( 1 ); } for ( i = 0; i < 2; i++ ) if ( jack_connect ( client, jack_port_name ( output_ports[i] ), ports[i] ) ) fprintf ( stderr, "cannot connect input ports\n" ); free ( ports ); /* install a signal handler to properly quits jack client */ #ifdef WIN32 signal ( SIGINT, signal_handler ); signal ( SIGABRT, signal_handler ); signal ( SIGTERM, signal_handler ); #else signal ( SIGQUIT, signal_handler ); signal ( SIGTERM, signal_handler ); signal ( SIGHUP, signal_handler ); signal ( SIGINT, signal_handler ); #endif /* keep running until the transport stops */ while (1) { #ifdef WIN32 Sleep ( 1000 ); #else sleep ( 1 ); #endif } jack_client_close ( client ); exit ( 0 ); }