Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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
	}
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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 );
}