// Attempt to connect to the Jack server static PyObject* attach(PyObject* self, PyObject* args) { char* cname; if (! PyArg_ParseTuple(args, "s", &cname)) return NULL; pyjack_client_t * client = self_or_global_client(self); if(client->pjc != NULL) { PyErr_SetString(JackUsageError, "A connection is already established."); return NULL; } jack_status_t status; client->pjc = jack_client_open(cname, JackNoStartServer, &status); if(client->pjc == NULL) { //TODO check status PyErr_SetString(JackNotConnectedError, "Failed to connect to Jack audio server."); return NULL; } jack_on_shutdown(client->pjc, pyjack_shutdown, client); signal(SIGHUP, pyjack_hangup); // TODO: This just works with global clients if(jack_set_process_callback(client->pjc, pyjack_process, client) != 0) { PyErr_SetString(JackError, "Failed to set jack process callback."); return NULL; } if(jack_set_buffer_size_callback(client->pjc, pyjack_buffer_size_changed, client) != 0) { PyErr_SetString(JackError, "Failed to set jack buffer size callback."); return NULL; } if(jack_set_sample_rate_callback(client->pjc, pyjack_sample_rate_changed, client) != 0) { PyErr_SetString(JackError, "Failed to set jack sample rate callback."); return NULL; } if(jack_set_port_registration_callback(client->pjc, pyjack_port_registration, client) != 0) { PyErr_SetString(JackError, "Failed to set jack port registration callback."); return NULL; } if(jack_set_graph_order_callback(client->pjc, pyjack_graph_order, client) != 0) { PyErr_SetString(JackError, "Failed to set jack graph order callback."); return NULL; } if(jack_set_xrun_callback(client->pjc, pyjack_xrun, client) != 0) { PyErr_SetString(JackError, "Failed to set jack xrun callback."); return NULL; } // Get buffer size client->buffer_size = jack_get_buffer_size(client->pjc); // Success! Py_INCREF(Py_None); return Py_None; }
void gojack_generic_callback_sync_destroy(struct gojack_generic_callback_sync *sync) { jack_set_freewheel_callback(sync->client, NULL, NULL); jack_set_buffer_size_callback(sync->client, NULL, NULL); jack_set_sample_rate_callback(sync->client, NULL, NULL); jack_set_client_registration_callback(sync->client, NULL, NULL); jack_set_port_registration_callback(sync->client, NULL, NULL); jack_set_port_connect_callback(sync->client, NULL, NULL); jack_set_port_rename_callback(sync->client, NULL, NULL); jack_set_graph_order_callback(sync->client, NULL, NULL); jack_set_xrun_callback(sync->client, NULL, NULL); jack_set_latency_callback(sync->client, NULL, NULL); cgo_callback_sync_destroy(sync->base); pthread_mutex_destroy(&sync->lock); free(sync); }
bool SC_JackDriver::DriverSetup(int* outNumSamples, double* outSampleRate) { char* clientName = 0; char* serverName = 0; if (mWorld->hw->mInDeviceName && (strlen(mWorld->hw->mInDeviceName) > 0)) { // parse string <serverName>:<clientName> SC_StringParser sp(mWorld->hw->mInDeviceName, ':'); if (!sp.AtEnd()) serverName = strdup(sp.NextToken()); if (!sp.AtEnd()) clientName = strdup(sp.NextToken()); if (clientName == 0) { // no semicolon found clientName = serverName; serverName = 0; } else if (strlen(clientName) == 0) { free(clientName); clientName = 0; } } mClient = jack_client_open( clientName ? clientName : kJackDefaultClientName, serverName ? JackServerName : JackNullOption, NULL, serverName); if (serverName) free(serverName); if (clientName) free(clientName); if (mClient == 0) return false; scprintf("%s: client name is '%s'\n", kJackDriverIdent, jack_get_client_name(mClient)); // create jack I/O ports mInputList = new SC_JackPortList(mClient, mWorld->mNumInputs, JackPortIsInput); mOutputList = new SC_JackPortList(mClient, mWorld->mNumOutputs, JackPortIsOutput); // register callbacks jack_set_process_callback(mClient, sc_jack_process_cb, this); jack_set_buffer_size_callback(mClient, sc_jack_bufsize_cb, this); jack_set_sample_rate_callback(mClient, sc_jack_srate_cb, this); jack_set_graph_order_callback(mClient, sc_jack_graph_order_cb, this); jack_set_xrun_callback(mClient, sc_jack_xrun_cb, this); jack_on_shutdown(mClient, sc_jack_shutdown_cb, mWorld); *outNumSamples = (int)jack_get_buffer_size(mClient); *outSampleRate = (double)jack_get_sample_rate(mClient); return true; }
int main (int argc, char *argv[]) { jack_client_t *client; jack_options_t options = JackNullOption; jack_status_t status; if ((client = jack_client_open ("event-monitor", options, &status, NULL)) == 0) { fprintf (stderr, "jack_client_open() failed, " "status = 0x%2.0x\n", status); if (status & JackServerFailed) { fprintf (stderr, "Unable to connect to JACK server\n"); } return 1; } if (jack_set_port_registration_callback (client, port_callback, NULL)) { fprintf (stderr, "cannot set port registration callback\n"); return 1; } if (jack_set_port_connect_callback (client, connect_callback, NULL)) { fprintf (stderr, "cannot set port connect callback\n"); return 1; } if (jack_set_client_registration_callback (client, client_callback, NULL)) { fprintf (stderr, "cannot set client registration callback\n"); return 1; } if (jack_set_graph_order_callback (client, graph_callback, NULL)) { fprintf (stderr, "cannot set graph order registration callback\n"); return 1; } if (jack_set_property_change_callback (client, (JackPropertyChangeCallback) propchange, 0)) { fprintf (stderr, "cannot set property change callback\n"); return 1; } if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); return 1; } sleep (-1); exit (0); }
struct gojack_generic_callback_sync * gojack_generic_callback_sync_create(jack_client_t *client) { struct gojack_generic_callback_sync *sync = (struct gojack_generic_callback_sync *) malloc(sizeof(struct gojack_generic_callback_sync)); void *arg = (void *) sync; sync->base = cgo_callback_sync_create(); cgo_callback_sync_set_log_callback(sync->base, &handle_log, NULL); pthread_mutex_init(&sync->lock, NULL); sync->client = client; jack_set_freewheel_callback(client, &handle_freewheel, arg); jack_set_buffer_size_callback(client, &handle_buffer_size, arg); //jack_set_sample_rate_callback(client, &handle_sample_rate, arg); jack_set_client_registration_callback(client, &handle_client_registration, arg); jack_set_port_registration_callback(client, &handle_port_registration, arg); jack_set_port_connect_callback(client, &handle_port_connect, arg); jack_set_port_rename_callback(client, &handle_port_rename, arg); jack_set_graph_order_callback(client, &handle_graph_order, arg); jack_set_xrun_callback(client, &handle_xrun, arg); //jack_set_latency_callback(client, &handle_latency, arg); return sync; }
/***************************************************************************** * Open: create a JACK client *****************************************************************************/ static int Open( vlc_object_t *p_this ) { char psz_name[32]; audio_output_t *p_aout = (audio_output_t *)p_this; struct aout_sys_t *p_sys = NULL; int status = VLC_SUCCESS; unsigned int i; int i_error; /* Allocate structure */ p_sys = calloc( 1, sizeof( aout_sys_t ) ); if( p_sys == NULL ) { status = VLC_ENOMEM; goto error_out; } p_aout->sys = p_sys; p_sys->latency = 0; /* Connect to the JACK server */ snprintf( psz_name, sizeof(psz_name), "vlc_%d", getpid()); psz_name[sizeof(psz_name) - 1] = '\0'; p_sys->p_jack_client = jack_client_open( psz_name, JackNullOption | JackNoStartServer, NULL ); if( p_sys->p_jack_client == NULL ) { msg_Err( p_aout, "failed to connect to JACK server" ); status = VLC_EGENERIC; goto error_out; } /* Set the process callback */ jack_set_process_callback( p_sys->p_jack_client, Process, p_aout ); jack_set_graph_order_callback ( p_sys->p_jack_client, GraphChange, p_aout ); p_aout->pf_play = aout_PacketPlay; p_aout->pf_pause = aout_PacketPause; p_aout->pf_flush = aout_PacketFlush; aout_PacketInit( p_aout, &p_sys->packet, jack_get_buffer_size( p_sys->p_jack_client ) ); aout_VolumeSoftInit( p_aout ); /* JACK only supports fl32 format */ p_aout->format.i_format = VLC_CODEC_FL32; // TODO add buffer size callback p_aout->format.i_rate = jack_get_sample_rate( p_sys->p_jack_client ); p_sys->i_channels = aout_FormatNbChannels( &p_aout->format ); p_sys->p_jack_ports = malloc( p_sys->i_channels * sizeof(jack_port_t *) ); if( p_sys->p_jack_ports == NULL ) { status = VLC_ENOMEM; goto error_out; } p_sys->p_jack_buffers = malloc( p_sys->i_channels * sizeof(jack_sample_t *) ); if( p_sys->p_jack_buffers == NULL ) { status = VLC_ENOMEM; goto error_out; } /* Create the output ports */ for( i = 0; i < p_sys->i_channels; i++ ) { snprintf( psz_name, sizeof(psz_name), "out_%d", i + 1); psz_name[sizeof(psz_name) - 1] = '\0'; p_sys->p_jack_ports[i] = jack_port_register( p_sys->p_jack_client, psz_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); if( p_sys->p_jack_ports[i] == NULL ) { msg_Err( p_aout, "failed to register a JACK port" ); status = VLC_EGENERIC; goto error_out; } } /* Tell the JACK server we are ready */ i_error = jack_activate( p_sys->p_jack_client ); if( i_error ) { msg_Err( p_aout, "failed to activate JACK client (error %d)", i_error ); status = VLC_EGENERIC; goto error_out; } /* Auto connect ports if we were asked to */ if( var_InheritBool( p_aout, AUTO_CONNECT_OPTION ) ) { unsigned int i_in_ports; char *psz_regex = var_InheritString( p_aout, CONNECT_REGEX_OPTION ); const char **pp_in_ports = jack_get_ports( p_sys->p_jack_client, psz_regex, NULL, JackPortIsInput ); free( psz_regex ); /* Count the number of returned ports */ i_in_ports = 0; while( pp_in_ports && pp_in_ports[i_in_ports] ) { i_in_ports++; } /* Tie the output ports to JACK input ports */ for( i = 0; i_in_ports > 0 && i < p_sys->i_channels; i++ ) { const char* psz_in = pp_in_ports[i % i_in_ports]; const char* psz_out = jack_port_name( p_sys->p_jack_ports[i] ); i_error = jack_connect( p_sys->p_jack_client, psz_out, psz_in ); if( i_error ) { msg_Err( p_aout, "failed to connect port %s to port %s (error %d)", psz_out, psz_in, i_error ); } else { msg_Dbg( p_aout, "connecting port %s to port %s", psz_out, psz_in ); } } free( pp_in_ports ); } msg_Dbg( p_aout, "JACK audio output initialized (%d channels, rate=%d)", p_sys->i_channels, p_aout->format.i_rate ); error_out: /* Clean up, if an error occurred */ if( status != VLC_SUCCESS && p_sys != NULL) { if( p_sys->p_jack_client ) { jack_deactivate( p_sys->p_jack_client ); jack_client_close( p_sys->p_jack_client ); aout_PacketDestroy( p_aout ); } free( p_sys->p_jack_ports ); free( p_sys->p_jack_buffers ); free( p_sys ); } return status; }
mfp_context * mfp_jack_startup(char * client_name, int num_inputs, int num_outputs) { mfp_context * ctxt; jack_status_t status; jack_port_t * port; int i; char namebuf[16]; ctxt = mfp_context_new(CTYPE_JACK); if ((ctxt->info.jack->client = jack_client_open(client_name, JackNullOption, &status, NULL)) == 0) { fprintf (stderr, "jack_client_open() failed."); return NULL; } /* callbacks */ jack_set_process_callback(ctxt->info.jack->client, process_cb, ctxt); jack_set_graph_order_callback(ctxt->info.jack->client, reorder_cb, ctxt); /* no info logging to console */ jack_set_info_function(info_cb); jack_set_error_function(info_cb); /* create application input and output ports */ if (num_inputs > 0) { ctxt->info.jack->input_ports = g_array_new(TRUE, TRUE, sizeof(jack_port_t *)); for(i=0; i<num_inputs; i++) { snprintf(namebuf, 16, "in_%d", i); port = jack_port_register (ctxt->info.jack->client, namebuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, i); g_array_append_val(ctxt->info.jack->input_ports, port); } } if (num_outputs > 0) { ctxt->info.jack->output_ports = g_array_new(TRUE, TRUE, sizeof(jack_port_t *)); for(i=0; i<num_outputs; i++) { snprintf(namebuf, 16, "out_%d", i); port = jack_port_register (ctxt->info.jack->client, namebuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, i); g_array_append_val(ctxt->info.jack->output_ports, port); } } /* find out sample rate */ ctxt->samplerate = jack_get_sample_rate(ctxt->info.jack->client); ctxt->blocksize = jack_get_buffer_size(ctxt->info.jack->client); mfp_in_latency = 3000.0 * ctxt->blocksize / ctxt->samplerate; mfp_out_latency = 3000.0 * ctxt->blocksize / ctxt->samplerate; printf("jack_startup: samplerate=%d, blocksize=%d, in_latency=%.1f, out_latency = %.1f\n", ctxt->samplerate, ctxt->blocksize, mfp_in_latency, mfp_out_latency); /* tell the JACK server that we are ready to roll */ if (jack_activate (ctxt->info.jack->client)) { fprintf (stderr, "cannot activate client"); return NULL; } else { ctxt->activated = 1; } return ctxt; }