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

}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
 int
 Port::max_name ( void )
 {
     return jack_port_name_size() - jack_client_name_size() - 6;
 }
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
Archivo: lsp.c Proyecto: Andux/jack2
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);
}