Browse Source

first pass at implementing port aliases (2 port port, 1 set by jackd) plus standard backend port names using system:(playback|capture)_N

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@1032 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
paul 18 years ago
parent
commit
5e37ca65f7
12 changed files with 295 additions and 15 deletions
  1. +3
    -3
      configure.ac
  2. +1
    -1
      drivers/alsa/alsa_driver.c
  3. +5
    -0
      example-clients/Makefile.am
  4. +121
    -0
      example-clients/alias.c
  5. +22
    -3
      example-clients/lsp.c
  6. +1
    -0
      jack/engine.h
  7. +1
    -0
      jack/internal.h
  8. +32
    -0
      jack/jack.h
  9. +2
    -0
      jack/port.h
  10. +44
    -2
      jackd/engine.c
  11. +2
    -0
      jackd/jackd.c
  12. +61
    -6
      libjack/port.c

+ 3
- 3
configure.ac View File

@@ -16,7 +16,7 @@ dnl micro version = incremented when implementation-only
dnl changes are made
dnl ---
JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=103
JACK_MINOR_VERSION=104
JACK_MICRO_VERSION=0

dnl ---
@@ -27,7 +27,7 @@ dnl made to the way libjack communicates with jackd
dnl that would break applications linked with an older
dnl version of libjack.
dnl ---
JACK_PROTOCOL_VERSION=19
JACK_PROTOCOL_VERSION=20

dnl ---
dnl HOWTO: updating the libjack interface version
@@ -44,7 +44,7 @@ dnl slacker than this, and closer to those for the JACK version
dnl number.
dnl ---
JACK_API_CURRENT=0
JACK_API_REVISION=25
JACK_API_REVISION=26
JACK_API_AGE=0

AC_SUBST(JACK_MAJOR_VERSION)


+ 1
- 1
drivers/alsa/alsa_driver.c View File

@@ -1751,7 +1751,7 @@ alsa_driver_attach (alsa_driver_t *driver)

for (chn = 0; chn < driver->capture_nchannels; chn++) {

snprintf (buf, sizeof(buf) - 1, "capture_%lu", chn+1);
snprintf (buf, sizeof(buf), "capture_%lu", chn+1);

if ((port = jack_port_register (driver->client, buf,
JACK_DEFAULT_AUDIO_TYPE,


+ 5
- 0
example-clients/Makefile.am View File

@@ -37,6 +37,7 @@ bin_PROGRAMS = jack_load \
jack_lsp \
jack_freewheel \
jack_evmon \
jack_alias \
$(JACKREC) \
$(JACK_TRANSPORT) \
jack_midisine \
@@ -80,6 +81,10 @@ jack_evmon_SOURCES = evmon.c
jack_evmon_LDFLAGS = @OS_LDFLAGS@
jack_evmon_LDADD = ../libjack/libjack.la

jack_alias_SOURCES = alias.c
jack_alias_LDFLAGS = @OS_LDFLAGS@
jack_alias_LDADD = ../libjack/libjack.la

jack_lsp_SOURCES = lsp.c
jack_lsp_LDFLAGS = @OS_LDFLAGS@
jack_lsp_LDADD = ../libjack/libjack.la


+ 121
- 0
example-clients/alias.c View File

@@ -0,0 +1,121 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>

#include <config.h>

#include <jack/jack.h>

char * my_name;

void
show_version (void)
{
fprintf (stderr, "%s: JACK Audio Connection Kit version " VERSION "\n",
my_name);
}

void
show_usage (void)
{
show_version ();
fprintf (stderr, "\nUsage: %s [options] portname alias\n", my_name);
fprintf (stderr, "List active Jack ports, and optionally display extra information.\n\n");
fprintf (stderr, "Display options:\n");
fprintf (stderr, " -u, --unalias remove `alias' as an alias for `port'\n");
fprintf (stderr, " -h, --help Display this help message\n");
fprintf (stderr, " --version Output version information and exit\n\n");
fprintf (stderr, "For more information see http://jackaudio.org/\n");
}

int
main (int argc, char *argv[])
{
jack_client_t *client;
jack_status_t status;
char* portname;
char* alias;
int unset = 0;
int ret;
int c;
int option_index;
extern int optind;
jack_port_t* port;
struct option long_options[] = {
{ "unalias", 0, 0, 'u' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ 0, 0, 0, 0 }
};

if (argc < 3) {
show_usage ();
return 1;
}

my_name = strrchr(argv[0], '/');
if (my_name == 0) {
my_name = argv[0];
} else {
my_name ++;
}

while ((c = getopt_long (argc, argv, "uhv", long_options, &option_index)) >= 0) {
switch (c) {
case 'u':
unset = 1;
break;
case 'h':
show_usage ();
return 1;
break;
case 'v':
show_version ();
return 1;
break;
default:
show_usage ();
return 1;
break;
}
}

portname = argv[optind++];
alias = argv[optind];

/* 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", JackNoStartServer, &status);

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;
}

if ((port = jack_port_by_name (client, portname)) == 0) {
fprintf (stderr, "No port named \"%s\"\n", portname);
return 1;
}

if (!unset) {
ret = jack_port_set_alias (port, alias);
} else {
ret = jack_port_unset_alias (port, alias);
}

jack_client_close (client);

return ret;
}

+ 22
- 3
example-clients/lsp.c View File

@@ -24,6 +24,7 @@ show_usage (void)
fprintf (stderr, "\nUsage: %s [options]\n", my_name);
fprintf (stderr, "List active Jack ports, and optionally display extra information.\n\n");
fprintf (stderr, "Display options:\n");
fprintf (stderr, " -A, --aliases List aliases for each port\n");
fprintf (stderr, " -c, --connections List connections to/from each port\n");
fprintf (stderr, " -l, --latency Display per-port latency in frames at each port\n");
fprintf (stderr, " -L, --latency Display total latency in frames at each port\n");
@@ -32,7 +33,7 @@ show_usage (void)
fprintf (stderr, " -t, --type Display port type\n");
fprintf (stderr, " -h, --help Display this help message\n");
fprintf (stderr, " --version Output version information and exit\n\n");
fprintf (stderr, "For more information see http://jackit.sourceforge.net/\n");
fprintf (stderr, "For more information see http://jackaudio.org/\n");
}

int
@@ -42,6 +43,7 @@ main (int argc, char *argv[])
jack_status_t status;
const char **ports, **connections;
unsigned int i, j;
int show_aliases = 0;
int show_con = 0;
int show_port_latency = 0;
int show_total_latency = 0;
@@ -49,8 +51,10 @@ main (int argc, char *argv[])
int show_type = 0;
int c;
int option_index;

char* aliases[2];
struct option long_options[] = {
{ "aliases", 0, 0, 'A' },
{ "connections", 0, 0, 'c' },
{ "port-latency", 0, 0, 'l' },
{ "total-latency", 0, 0, 'L' },
@@ -68,8 +72,13 @@ main (int argc, char *argv[])
my_name ++;
}

while ((c = getopt_long (argc, argv, "clLphvt", long_options, &option_index)) >= 0) {
while ((c = getopt_long (argc, argv, "AclLphvt", long_options, &option_index)) >= 0) {
switch (c) {
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;
@@ -123,6 +132,16 @@ main (int argc, char *argv[])

jack_port_t *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++) {


+ 1
- 0
jack/engine.h View File

@@ -203,5 +203,6 @@ void jack_port_clear_connections (jack_engine_t *engine,
void jack_port_registration_notify (jack_engine_t *, jack_port_id_t, int);
void jack_port_release (jack_engine_t *engine, jack_port_internal_t *);
void jack_sort_graph (jack_engine_t *engine);
void jack_engine_munge_backend_port_names (jack_engine_t* engine);

#endif /* __jack_engine_h__ */

+ 1
- 0
jack/internal.h View File

@@ -460,6 +460,7 @@ jack_port_t *jack_port_by_id_int (const jack_client_t *client,

jack_port_t *jack_port_by_name_int (jack_client_t *client,
const char *port_name);
int jack_port_name_equals (jack_port_shared_t* port, const char* target);

#ifdef __GNUC__
# define likely(x) __builtin_expect((x),1)


+ 32
- 0
jack/jack.h View File

@@ -569,6 +569,38 @@ int jack_recompute_total_latencies (jack_client_t*);
*/
int jack_port_set_name (jack_port_t *port, const char *port_name);

/**
* Set @a alias as an alias for @a port. May be called at any time.
* If the alias is longer than jack_port_name_size(), it will be truncated.
*
* After a successful call, and until JACK exits or
* @function jack_port_unset_alias() is called, @alias may be
* used as a alternate name for the port.
*
* Ports can have up to two aliases - if both are already
* set, this function will return an error.
*
* @return 0 on success, otherwise a non-zero error code.
*/
int jack_port_set_alias (jack_port_t *port, const char *alias);

/**
* Remove @a alias as an alias for @a port. May be called at any time.
*
* After a successful call, @a alias can no longer be
* used as a alternate name for the port.
*
* @return 0 on success, otherwise a non-zero error code.
*/
int jack_port_unset_alias (jack_port_t *port, const char *alias);

/*
* Get any aliases known for @port.
*
* @return the number of aliases discovered for the port
*/
int jack_port_get_aliases (const jack_port_t *port, char* const aliases[2]);

/**
* If @ref JackPortCanMonitor is set for this @a port, turn input
* monitoring on or off. Otherwise, do nothing.


+ 2
- 0
jack/port.h View File

@@ -98,6 +98,8 @@ typedef struct _jack_port_shared {
jack_port_id_t id; /* index into engine port array */
enum JackPortFlags flags;
char name[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE];
char alias1[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE];
char alias2[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE];
jack_client_id_t client_id; /* who owns me */

volatile jack_nframes_t latency;


+ 44
- 2
jackd/engine.c View File

@@ -944,6 +944,44 @@ jack_start_watchdog (jack_engine_t *engine)
}
#endif /* !JACK_USE_MACH_THREADS */

void
jack_engine_munge_backend_port_names (jack_engine_t* engine)
{
int out_cnt = 1;
int in_cnt = 1;
int i;
char* backend_client_name = (char*) engine->driver->internal_client->control->name;
size_t len = strlen (backend_client_name);

for (i = 0; i < engine->port_max; i++) {
jack_port_shared_t* port = &engine->control->ports[i];

if (strncmp (port->name, backend_client_name, len) == 0) {

/* save the backend's own name */

char name[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE];
snprintf (name, sizeof (name), "%s", engine->control->ports[i].name);

/* replace input port names, and use backend's original as an alias */

if ((port->flags & (JackPortIsPhysical|JackPortIsInput)) == (JackPortIsPhysical|JackPortIsInput)) {
snprintf (port->name, sizeof (port->name), "system:playback_%d", out_cnt++);
strcpy (port->alias1, name);
continue;
}

/* replace output port names, and use backend's original as an alias */

if ((port->flags & (JackPortIsPhysical|JackPortIsOutput)) == (JackPortIsPhysical|JackPortIsOutput)) {
snprintf (port->name, sizeof (port->name), "system:capture_%d", in_cnt++);
strcpy (port->alias1, name);
continue;
}
}
}
}

static jack_driver_info_t *
jack_load_driver (jack_engine_t *engine, jack_driver_desc_t * driver_desc)
{
@@ -1678,6 +1716,8 @@ jack_engine_new (int realtime, int rtpriority, int do_mlock, int do_unlock,
for (i = 0; i < engine->port_max; i++) {
engine->control->ports[i].in_use = 0;
engine->control->ports[i].id = i;
engine->control->ports[i].alias1[0] = '\0';
engine->control->ports[i].alias2[0] = '\0';
}

/* allocate internal port structures so that we can keep track
@@ -3369,6 +3409,8 @@ jack_port_release (jack_engine_t *engine, jack_port_internal_t *port)
{
pthread_mutex_lock (&engine->port_lock);
port->shared->in_use = 0;
port->shared->alias1[0] = '\0';
port->shared->alias2[0] = '\0';

if (port->buffer_info) {
jack_port_buffer_list_t *blist =
@@ -3391,7 +3433,7 @@ jack_get_port_internal_by_name (jack_engine_t *engine, const char *name)
pthread_mutex_lock (&engine->port_lock);

for (id = 0; id < engine->port_max; id++) {
if (strcmp (engine->control->ports[id].name, name) == 0) {
if (jack_port_name_equals (&engine->control->ports[id], name)) {
break;
}
}
@@ -3725,7 +3767,7 @@ jack_get_port_by_name (jack_engine_t *engine, const char *name)

for (id = 0; id < engine->port_max; id++) {
if (engine->control->ports[id].in_use &&
strcmp (engine->control->ports[id].name, name) == 0) {
jack_port_name_equals (&engine->control->ports[id], name)) {
return &engine->internal_ports[id];
}
}


+ 2
- 0
jackd/jackd.c View File

@@ -158,6 +158,8 @@ jack_main (jack_driver_desc_t * driver_desc, JSList * driver_params)
goto error;
}

jack_engine_munge_backend_port_names (engine);

if (engine->driver->start (engine->driver) != 0) {
jack_error ("cannot start driver");
goto error;


+ 61
- 6
libjack/port.c View File

@@ -333,6 +333,14 @@ void jack_port_set_funcs ()

#endif /* USE_DYNSIMD */

int
jack_port_name_equals (jack_port_shared_t* port, const char* target)
{
return (strcmp (port->name, target) == 0 ||
strcmp (port->alias1, target) == 0 ||
strcmp (port->alias2, target) == 0);
}
jack_port_functions_t *
jack_get_port_functions(jack_port_type_id_t ptid)
{
@@ -372,7 +380,7 @@ jack_port_new (const jack_client_t *client, jack_port_id_t port_id,
pthread_mutex_init (&port->connection_lock, NULL);
port->connections = 0;
port->tied = NULL;
if (client->control->id == port->shared->client_id) {
/* It's our port, so initialize the pointers to port
@@ -488,7 +496,7 @@ jack_port_connected_to (const jack_port_t *port, const char *portname)
for (node = port->connections; node; node = jack_slist_next (node)) {
jack_port_t *other_port = (jack_port_t *) node->data;
if (strcmp (other_port->shared->name, portname) == 0) {
if (jack_port_name_equals (other_port->shared, portname)) {
ret = TRUE;
break;
}
@@ -521,7 +529,8 @@ jack_port_get_connections (const jack_port_t *port)
* (jack_slist_length (port->connections) + 1));
for (n = 0, node = port->connections; node;
node = jack_slist_next (node), ++n) {
ret[n] = ((jack_port_t *) node->data)->shared->name;
jack_port_t* other =(jack_port_t *) node->data;
ret[n] = other->shared->name;
}
ret[n] = NULL;
}
@@ -644,7 +653,7 @@ jack_port_by_name_int (jack_client_t *client, const char *port_name)
port = &client->engine->ports[0];
for (i = 0; i < limit; i++) {
if (port[i].in_use && strcmp (port[i].name, port_name) == 0) {
if (port[i].in_use && jack_port_name_equals (&port[i], port_name)) {
return jack_port_new (client, port[i].id,
client->engine);
}
@@ -660,7 +669,7 @@ jack_port_by_name (jack_client_t *client, const char *port_name)
jack_port_t* port;
for (node = client->ports_ext; node; node = jack_slist_next (node)) {
port = node->data;
if (strcmp (port->shared->name, port_name) == 0) {
if (jack_port_name_equals (port->shared, port_name)) {
/* Found port, return the cached structure. */
return port;
}
@@ -766,7 +775,6 @@ jack_port_tie (jack_port_t *src, jack_port_t *dst)

int
jack_port_untie (jack_port_t *port)

{
if (port->tied == NULL) {
jack_error ("port \"%s\" is not tied", port->shared->name);
@@ -868,6 +876,24 @@ jack_port_name (const jack_port_t *port)
return port->shared->name;
}

int
jack_port_get_aliases (const jack_port_t *port, char* const aliases[2])
{
int cnt = 0;
if (port->shared->alias1[0] != '\0') {
snprintf (aliases[0], JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE, "%s", port->shared->alias1);
cnt++;
}

if (port->shared->alias2[0] != '\0') {
snprintf (aliases[1], JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE, "%s", port->shared->alias2);
cnt++;
}

return cnt;
}

const char *
jack_port_short_name (const jack_port_t *port)
{
@@ -910,6 +936,35 @@ jack_port_set_name (jack_port_t *port, const char *new_name)
return 0;
}

int
jack_port_set_alias (jack_port_t *port, const char *alias)
{
if (port->shared->alias1[0] == '\0') {
snprintf (port->shared->alias1, sizeof (port->shared->alias1), "%s", alias);
} else if (port->shared->alias2[0] == '\0') {
snprintf (port->shared->alias2, sizeof (port->shared->alias2), "%s", alias);
} else {
return -1;
}

return 0;
}

int
jack_port_unset_alias (jack_port_t *port, const char *alias)
{
if (strcmp (port->shared->alias1, alias) == 0) {
port->shared->alias1[0] = '\0';
} else if (strcmp (port->shared->alias2, alias) == 0) {
port->shared->alias2[0] = '\0';
} else {
return -1;
}

return 0;
}


/* AUDIO PORT SUPPORT */

static inline float f_max(float x, float a)


Loading…
Cancel
Save