int main (int argc, char* argv[]) { jack_client_t* client; char const default_name[] = "connector"; // this is moderately retarded aliases[0] = (char *) malloc (jack_port_name_size()); aliases[1] = (char *) malloc (jack_port_name_size()); client = jack_client_open(default_name, JackNullOption, NULL); while (1) { const char **portnames; const char **orig; orig = portnames = jack_get_ports(client, "", "", 0); desired_connection *desired = desired_connections; while (desired->from_port) { ensure_connected(client, orig, desired); desired++; } printf("\n"); sleep(5); jack_free(orig); } }
static void rtJack_CopyDevParams(RtJackGlobals *p, char **devName, const csRtAudioParams *parm, int isOutput) { CSOUND *csound; char *s; size_t nBytes; csound = p->csound; *devName = (char*) NULL; if (parm->devNum != 1024) { jack_client_t *client_; int useTmpClient = 0; /* FIXME: a temporary JACK client is created if there is no */ /* connection yet; this is a somewhat hackish solution... */ if (p->client == (jack_client_t*) NULL) { useTmpClient = 1; client_ = jack_client_open(&(p->clientName[0]), JackNoStartServer, NULL); } else client_ = p->client; if (client_ != (jack_client_t*) NULL) { rtJack_ListPorts(csound, client_, &(p->clientName[0]), isOutput); if (useTmpClient) jack_client_close(client_); } rtJack_Error(csound, -1, Str("must specify a device name, not a number")); } if (parm->devName != NULL && parm->devName[0] != (char) 0) { /* NOTE: this assumes max. 999 channels (the current limit is 255) */ nBytes = strlen(parm->devName) + 4; if (UNLIKELY(nBytes > (size_t) jack_port_name_size())) rtJack_Error(csound, -1, Str("device name is too long")); s = (char*) malloc(nBytes+1); if (UNLIKELY(s == NULL)) rtJack_Error(csound, CSOUND_MEMORY, Str("memory allocation failure")); strcpy(s, parm->devName); *devName = s; } if (isOutput && p->inputEnabled) { /* full duplex audio I/O: check consistency of parameters */ if (UNLIKELY(p->nChannels != parm->nChannels || (unsigned int)p->bufSize != parm->bufSamp_SW)) rtJack_Error(csound, -1, Str("input and output parameters are not consistent")); if (UNLIKELY((unsigned int)((parm->bufSamp_SW / csound->GetKsmps(csound)) * csound->GetKsmps(csound)) != parm->bufSamp_SW)) rtJack_Error(csound, -1, Str("period size (-b) must be an integer multiple of ksmps")); } p->sampleRate = (int) parm->sampleRate; if (UNLIKELY((float) p->sampleRate != parm->sampleRate)) rtJack_Error(csound, -1, Str("sample rate must be an integer")); p->nChannels = parm->nChannels; p->bufSize = parm->bufSamp_SW; p->nBuffers = (parm->bufSamp_HW + parm->bufSamp_SW - 1) / parm->bufSamp_SW; }
static int _port_name_size(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj* const *objv) { _t *dp = (_t *)clientData; if (argc != 2) return fw_error_str(interp, "jack-client port-name-size"); Tcl_SetObjResult(interp, Tcl_NewIntObj(jack_port_name_size())); return TCL_OK; }
int Port::max_name ( void ) { return jack_port_name_size() - jack_client_name_size() - 6; }
int main(int argc, char **argv) { int jitter_plot[101]; int latency_plot[101]; int long_index = 0; struct option long_options[] = { {"help", 0, NULL, 'h'}, {"message-size", 1, NULL, 'm'}, {"samples", 1, NULL, 's'}, {"timeout", 1, NULL, 't'} }; size_t name_arg_count; size_t name_size; char *option_string = "hm:s:t:"; int show_usage = 0; connections_established = 0; error_message = NULL; message_size = 3; program_name = argv[0]; remote_in_port = 0; remote_out_port = 0; samples = 1024; timeout = 5; for (;;) { signed char c = getopt_long(argc, argv, option_string, long_options, &long_index); switch (c) { case 'h': show_usage = 1; break; case 'm': message_size = parse_positive_number_arg(optarg, "message-size"); break; case 's': samples = parse_positive_number_arg(optarg, "samples"); break; case 't': timeout = parse_positive_number_arg(optarg, "timeout"); break; default: { char *s = "'- '"; s[2] = c; die(s, "invalid switch"); } case -1: if (show_usage) { output_usage(); exit(EXIT_SUCCESS); } goto parse_port_names; case 1: /* end of switch :) */ ; } } parse_port_names: name_arg_count = argc - optind; switch (name_arg_count) { case 2: target_in_port_name = argv[optind + 1]; target_out_port_name = argv[optind]; break; case 0: target_in_port_name = 0; target_out_port_name = 0; break; default: output_usage(); return EXIT_FAILURE; } name_size = jack_port_name_size(); alias1 = malloc(name_size * sizeof(char)); if (alias1 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto show_error; } alias2 = malloc(name_size * sizeof(char)); if (alias2 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_alias1; } latency_values = malloc(sizeof(jack_nframes_t) * samples); if (latency_values == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_alias2; } latency_time_values = malloc(sizeof(jack_time_t) * samples); if (latency_time_values == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_latency_values; } message_1 = malloc(message_size * sizeof(jack_midi_data_t)); if (message_1 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_latency_time_values; } message_2 = malloc(message_size * sizeof(jack_midi_data_t)); if (message_2 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_message_1; } switch (message_size) { case 1: message_1[0] = 0xf6; message_2[0] = 0xfe; break; case 2: message_1[0] = 0xc0; message_1[1] = 0x00; message_2[0] = 0xd0; message_2[1] = 0x7f; break; case 3: message_1[0] = 0x80; message_1[1] = 0x00; message_1[2] = 0x00; message_2[0] = 0x90; message_2[1] = 0x7f; message_2[2] = 0x7f; break; default: message_1[0] = 0xf0; memset(message_1 + 1, 0, (message_size - 2) * sizeof(jack_midi_data_t)); message_1[message_size - 1] = 0xf7; message_2[0] = 0xf0; memset(message_2 + 1, 0x7f, (message_size - 2) * sizeof(jack_midi_data_t)); message_2[message_size - 1] = 0xf7; } client = jack_client_open(program_name, JackNullOption, NULL); if (client == NULL) { error_message = "failed to open JACK client"; error_source = "jack_client_open"; goto free_message_2; } in_port = jack_port_register(client, "in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); if (in_port == NULL) { error_message = "failed to register MIDI-in port"; error_source = "jack_port_register"; goto close_client; } out_port = jack_port_register(client, "out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); if (out_port == NULL) { error_message = "failed to register MIDI-out port"; error_source = "jack_port_register"; goto unregister_in_port; } if (jack_set_process_callback(client, handle_process, NULL)) { error_message = "failed to set process callback"; error_source = "jack_set_process_callback"; goto unregister_out_port; } if (jack_set_xrun_callback(client, handle_xrun, NULL)) { error_message = "failed to set xrun callback"; error_source = "jack_set_xrun_callback"; goto unregister_out_port; } if (jack_set_port_connect_callback(client, handle_port_connection_change, NULL)) { error_message = "failed to set port connection callback"; error_source = "jack_set_port_connect_callback"; goto unregister_out_port; } jack_on_shutdown(client, handle_shutdown, NULL); jack_set_info_function(handle_info); process_state = 0; connect_semaphore = create_semaphore(0); if (connect_semaphore == NULL) { error_message = get_semaphore_error(); error_source = "create_semaphore"; goto unregister_out_port; } init_semaphore = create_semaphore(1); if (init_semaphore == NULL) { error_message = get_semaphore_error(); error_source = "create_semaphore"; goto destroy_connect_semaphore;; } process_semaphore = create_semaphore(2); if (process_semaphore == NULL) { error_message = get_semaphore_error(); error_source = "create_semaphore"; goto destroy_init_semaphore; } if (jack_activate(client)) { error_message = "could not activate client"; error_source = "jack_activate"; goto destroy_process_semaphore; } if (name_arg_count) { if (jack_connect(client, jack_port_name(out_port), target_out_port_name)) { error_message = "could not connect MIDI out port"; error_source = "jack_connect"; goto deactivate_client; } if (jack_connect(client, target_in_port_name, jack_port_name(in_port))) { error_message = "could not connect MIDI in port"; error_source = "jack_connect"; goto deactivate_client; } } if (! register_signal_handler(handle_signal)) { error_message = strerror(errno); error_source = "register_signal_handler"; goto deactivate_client; } printf("Waiting for connections ...\n"); if (wait_semaphore(connect_semaphore, 1) == -1) { error_message = get_semaphore_error(); error_source = "wait_semaphore"; goto deactivate_client; } if (connections_established) { printf("Waiting for test completion ...\n\n"); if (wait_semaphore(process_semaphore, 1) == -1) { error_message = get_semaphore_error(); error_source = "wait_semaphore"; goto deactivate_client; } } if (! register_signal_handler(SIG_DFL)) { error_message = strerror(errno); error_source = "register_signal_handler"; goto deactivate_client; } if (process_state == 2) { double average_latency = ((double) total_latency) / samples; double average_latency_time = total_latency_time / samples; size_t i; double latency_plot_offset = floor(((double) lowest_latency_time) / 100.0) / 10.0; double sample_rate = (double) jack_get_sample_rate(client); jack_nframes_t total_jitter = 0; jack_time_t total_jitter_time = 0; for (i = 0; i <= 100; i++) { jitter_plot[i] = 0; latency_plot[i] = 0; } for (i = 0; i < samples; i++) { double latency_time_value = (double) latency_time_values[i]; double latency_plot_time = (latency_time_value / 1000.0) - latency_plot_offset; double jitter_time = ABS(average_latency_time - latency_time_value); if (latency_plot_time >= 10.0) { (latency_plot[100])++; } else { (latency_plot[(int) (latency_plot_time * 10.0)])++; } if (jitter_time >= 10000.0) { (jitter_plot[100])++; } else { (jitter_plot[(int) (jitter_time / 100.0)])++; } total_jitter += ABS(average_latency - ((double) latency_values[i])); total_jitter_time += jitter_time; } printf("Reported out-port latency: %.2f-%.2f ms (%u-%u frames)\n" "Reported in-port latency: %.2f-%.2f ms (%u-%u frames)\n" "Average latency: %.2f ms (%.2f frames)\n" "Lowest latency: %.2f ms (%u frames)\n" "Highest latency: %.2f ms (%u frames)\n" "Peak MIDI jitter: %.2f ms (%u frames)\n" "Average MIDI jitter: %.2f ms (%.2f frames)\n", (out_latency_range.min / sample_rate) * 1000.0, (out_latency_range.max / sample_rate) * 1000.0, out_latency_range.min, out_latency_range.max, (in_latency_range.min / sample_rate) * 1000.0, (in_latency_range.max / sample_rate) * 1000.0, in_latency_range.min, in_latency_range.max, average_latency_time / 1000.0, average_latency, lowest_latency_time / 1000.0, lowest_latency, highest_latency_time / 1000.0, highest_latency, (highest_latency_time - lowest_latency_time) / 1000.0, highest_latency - lowest_latency, (total_jitter_time / 1000.0) / samples, ((double) total_jitter) / samples); printf("\nJitter Plot:\n"); for (i = 0; i < 100; i++) { if (jitter_plot[i]) { printf("%.1f - %.1f ms: %d\n", ((float) i) / 10.0, ((float) (i + 1)) / 10.0, jitter_plot[i]); } } if (jitter_plot[100]) { printf(" > 10 ms: %d\n", jitter_plot[100]); } printf("\nLatency Plot:\n"); for (i = 0; i < 100; i++) { if (latency_plot[i]) { printf("%.1f - %.1f ms: %d\n", latency_plot_offset + (((float) i) / 10.0), latency_plot_offset + (((float) (i + 1)) / 10.0), latency_plot[i]); } } if (latency_plot[100]) { printf(" > %.1f ms: %d\n", latency_plot_offset + 10.0, latency_plot[100]); } } deactivate_client: jack_deactivate(client); printf("\nMessages sent: %d\nMessages received: %d\n", messages_sent, messages_received); if (unexpected_messages) { printf("Unexpected messages received: %d\n", unexpected_messages); } if (xrun_count) { printf("Xruns: %d\n", xrun_count); } destroy_process_semaphore: destroy_semaphore(process_semaphore, 2); destroy_init_semaphore: destroy_semaphore(init_semaphore, 1); destroy_connect_semaphore: destroy_semaphore(connect_semaphore, 0); unregister_out_port: jack_port_unregister(client, out_port); unregister_in_port: jack_port_unregister(client, in_port); close_client: jack_client_close(client); free_message_2: free(message_2); free_message_1: free(message_1); free_latency_time_values: free(latency_time_values); free_latency_values: free(latency_values); free_alias2: free(alias2); free_alias1: free(alias1); if (error_message != NULL) { show_error: output_error(error_source, error_message); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }
static CS_NOINLINE int rtJack_ListPorts(CSOUND *csound, jack_client_t *jackClient, const char *clientName, int isOutput) { char **portNames = (char**) NULL; char clientNameBuf[MAX_NAME_LEN + 2]; char *prvPortName = (char*) NULL, *curPortName = (char*) NULL; unsigned long portFlags; int i, nChn, maxChn, len, nPorts, retval = -1; portFlags = (isOutput ? (unsigned long) JackPortIsInput : (unsigned long) JackPortIsOutput); len = jack_port_name_size(); prvPortName = (char*) malloc((size_t) len); if (UNLIKELY(prvPortName == (char*) NULL)) goto err_return; curPortName = (char*) malloc((size_t) len); if (UNLIKELY(curPortName == (char*) NULL)) goto err_return; portNames = (char**) jack_get_ports(jackClient, (char*) NULL, JACK_DEFAULT_AUDIO_TYPE, portFlags); if (UNLIKELY(portNames == (char**) NULL)) goto err_return; retval = 0; csound->Message(csound, Str("The available JACK %s devices are:\n"), (isOutput ? Str("output") : Str("input"))); /* count the number of ports, and sort port names in alphabetical order */ for (nPorts = 0; portNames[nPorts] != NULL; nPorts++) ; qsort((void*) portNames, (size_t) nPorts, sizeof(char*), portname_cmp_func); snprintf(&(clientNameBuf[0]), MAX_NAME_LEN + 2, "%s:", clientName); len = strlen(&(clientNameBuf[0])); prvPortName[0] = (char) 0; maxChn = nChn = 0; for (i = 0; portNames[i] != NULL; i++) { int n, chn_; /* skip ports owned by this client */ if (strncmp(portNames[i], &(clientNameBuf[0]), (size_t) len) == 0) goto nextPortName; n = (int) strlen(portNames[i]); do { n--; } while (n > 0 && isdigit(portNames[i][n])); n++; if (n < 2 || n == (int) strlen(portNames[i])) goto nextPortName; chn_ = (int) atoi(&(portNames[i][n])); if (chn_ == 0) goto nextPortName; strncpy(curPortName, portNames[i], (size_t) n); curPortName[n] = (char) 0; if (strcmp(curPortName, prvPortName) != 0) { if (nChn == maxChn) rtJack_PrintPortName(csound, prvPortName, nChn); strcpy(prvPortName, curPortName); nChn = 1; maxChn = chn_; } else { nChn++; if (chn_ > maxChn) maxChn = chn_; } continue; nextPortName: if (nChn == maxChn) rtJack_PrintPortName(csound, prvPortName, nChn); prvPortName[0] = (char) 0; maxChn = nChn = 0; } if (nChn == maxChn) rtJack_PrintPortName(csound, prvPortName, nChn); err_return: if (portNames != (char**) NULL) free((void*) portNames); if (curPortName != (char*) NULL) free((void*) curPortName); if (prvPortName != (char*) NULL) free((void*) prvPortName); return retval; }
PUBLIC int csoundModuleCreate(CSOUND *csound) { RtJackGlobals *p; int i, j; OPARMS oparms; csound->GetOParms(csound, &oparms); /* allocate and initialise globals */ if (oparms.msglevel & 0x400) csound->Message(csound, Str("JACK real-time audio module for Csound " "by Istvan Varga\n")); if (csound->CreateGlobalVariable(csound, "_rtjackGlobals", sizeof(RtJackGlobals)) != 0) { csound->ErrorMsg(csound, Str(" *** rtjack: error allocating globals")); return -1; } p = (RtJackGlobals*) csound->QueryGlobalVariableNoCheck(csound, "_rtjackGlobals"); p->csound = csound; p->jackState = -1; strcpy(&(p->clientName[0]), "csound6"); strcpy(&(p->inputPortName[0]), "input"); strcpy(&(p->outputPortName[0]), "output"); p->sleepTime = 1000; /* this is not actually used */ p->inDevName = (char*) NULL; p->outDevName = (char*) NULL; p->client = (jack_client_t*) NULL; p->inPorts = (jack_port_t**) NULL; p->inPortBufs = (jack_default_audio_sample_t**) NULL; p->outPorts = (jack_port_t**) NULL; p->outPortBufs = (jack_default_audio_sample_t**) NULL; p->bufs = (RtJackBuffer**) NULL; /* register options: */ /* client name */ i = jack_client_name_size(); if (i > (MAX_NAME_LEN + 1)) i = (MAX_NAME_LEN + 1); csound->CreateConfigurationVariable(csound, "jack_client", (void*) &(p->clientName[0]), CSOUNDCFG_STRING, 0, NULL, &i, Str("JACK client name (default: csound6)"), NULL); /* input port name */ i = jack_port_name_size() - 3; if (i > (MAX_NAME_LEN + 1)) i = (MAX_NAME_LEN + 1); csound->CreateConfigurationVariable(csound, "jack_inportname", (void*) &(p->inputPortName[0]), CSOUNDCFG_STRING, 0, NULL, &i, Str("JACK input port name prefix " "(default: input)"), NULL); /* output port name */ i = jack_port_name_size() - 3; if (i > (MAX_NAME_LEN + 1)) i = (MAX_NAME_LEN + 1); csound->CreateConfigurationVariable(csound, "jack_outportname", (void*) &(p->outputPortName[0]), CSOUNDCFG_STRING, 0, NULL, &i, Str("JACK output port name prefix" " (default: output)"), NULL); /* sleep time */ i = 250; j = 25000; /* min/max value */ csound->CreateConfigurationVariable(csound, "jack_sleep_time", (void*) &(p->sleepTime), CSOUNDCFG_INTEGER, 0, &i, &j, Str("Deprecated"), NULL); /* done */ p->listclient = NULL; return 0; }
int main (int argc, char *argv[]) { jack_client_t *client; jack_status_t status; jack_options_t options = JackNoStartServer; const char **ports, **connections; unsigned int i, j, k; int skip_port; int show_aliases = 0; int show_con = 0; int show_port_latency = 0; int show_total_latency = 0; int show_properties = 0; int show_type = 0; int c; int option_index; char* aliases[2]; char *server_name = NULL; jack_port_t *port; struct option long_options[] = { { "server", 1, 0, 's' }, { "aliases", 0, 0, 'A' }, { "connections", 0, 0, 'c' }, { "port-latency", 0, 0, 'l' }, { "total-latency", 0, 0, 'L' }, { "properties", 0, 0, 'p' }, { "type", 0, 0, 't' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { 0, 0, 0, 0 } }; my_name = strrchr(argv[0], '/'); if (my_name == 0) { my_name = argv[0]; } else { my_name ++; } while ((c = getopt_long (argc, argv, "s:AclLphvt", long_options, &option_index)) >= 0) { switch (c) { case 's': server_name = (char *) malloc (sizeof (char) * strlen(optarg)); strcpy (server_name, optarg); options |= JackServerName; break; case 'A': aliases[0] = (char *) malloc (jack_port_name_size()); aliases[1] = (char *) malloc (jack_port_name_size()); show_aliases = 1; break; case 'c': show_con = 1; break; case 'l': show_port_latency = 1; break; case 'L': show_total_latency = 1; break; case 'p': show_properties = 1; break; case 't': show_type = 1; break; case 'h': show_usage (); return 1; break; case 'v': show_version (); return 1; break; default: show_usage (); return 1; break; } } /* Open a client connection to the JACK server. Starting a * new server only to list its ports seems pointless, so we * specify JackNoStartServer. */ //JOQ: need a new server name option client = jack_client_open ("lsp", options, &status, server_name); if (client == NULL) { if (status & JackServerFailed) { fprintf (stderr, "JACK server not running\n"); } else { fprintf (stderr, "jack_client_open() failed, " "status = 0x%2.0x\n", status); } return 1; } ports = jack_get_ports (client, NULL, NULL, 0); if (!ports) goto error; for (i = 0; ports && ports[i]; ++i) { // skip over any that don't match ALL of the strings presented at command line skip_port = 0; for(k = optind; k < argc; k++){ if(strstr(ports[i], argv[k]) == NULL ){ skip_port = 1; } } if (skip_port) continue; printf ("%s\n", ports[i]); port = jack_port_by_name (client, ports[i]); if (show_aliases) { int cnt; int i; cnt = jack_port_get_aliases (port, aliases); for (i = 0; i < cnt; ++i) { printf (" %s\n", aliases[i]); } } if (show_con) { if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) { for (j = 0; connections[j]; j++) { printf (" %s\n", connections[j]); } free (connections); } } if (show_port_latency) { if (port) { jack_latency_range_t range; printf (" port latency = %" PRIu32 " frames\n", jack_port_get_latency (port)); jack_port_get_latency_range (port, JackPlaybackLatency, &range); printf (" port playback latency = [ %" PRIu32 " %" PRIu32 " ] frames\n", range.min, range.max); jack_port_get_latency_range (port, JackCaptureLatency, &range); printf (" port capture latency = [ %" PRIu32 " %" PRIu32 " ] frames\n", range.min, range.max); } } if (show_total_latency) { if (port) { printf (" total latency = %d frames\n", jack_port_get_total_latency (client, port)); } } if (show_properties) { if (port) { int flags = jack_port_flags (port); printf (" properties: "); if (flags & JackPortIsInput) { fputs ("input,", stdout); } if (flags & JackPortIsOutput) { fputs ("output,", stdout); } if (flags & JackPortCanMonitor) { fputs ("can-monitor,", stdout); } if (flags & JackPortIsPhysical) { fputs ("physical,", stdout); } if (flags & JackPortIsTerminal) { fputs ("terminal,", stdout); } putc ('\n', stdout); } } if (show_type) { if (port) { putc ('\t', stdout); fputs (jack_port_type (port), stdout); putc ('\n', stdout); } } } error: if (show_aliases) { free(aliases[0]); free(aliases[1]); } if (ports) jack_free (ports); jack_client_close (client); exit (0); }