git-svn-id: svn+ssh://jackaudio.org/trunk/jack@1032 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.109.0
@@ -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) | |||
@@ -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, | |||
@@ -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 | |||
@@ -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; | |||
} |
@@ -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++) { | |||
@@ -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__ */ |
@@ -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) | |||
@@ -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. | |||
@@ -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; | |||
@@ -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]; | |||
} | |||
} | |||
@@ -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; | |||
@@ -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) | |||