Browse Source

change -I client-spec syntax and adjust -A syntax similarly; update jackd man page

tags/0.124.0^0
Paul Davis 12 years ago
parent
commit
b4066eca13
2 changed files with 136 additions and 61 deletions
  1. +37
    -3
      jackd/jackd.1.in
  2. +99
    -58
      jackd/jackd.c

+ 37
- 3
jackd/jackd.1.in View File

@@ -30,7 +30,6 @@ Select the audio interface backend. The current list of supported
backends is: \fBalsa\fR, \fBcoreaudio\fR, \fBdummy\fR, \fBfreebob\fR,
\fBoss\fR \fBsun\fR and \fBportaudio\fR. They are not all available
on all platforms. All \fIbackend\-parameters\fR are optional.

.TP
\fB\-h, \-\-help\fR
.br
@@ -42,6 +41,41 @@ show how to list them.
\fB\-m, \-\-no\-mlock\fR
Do not attempt to lock memory, even if \fB\-\-realtime\fR.
.TP
\fB\-A \fIdevice\fR, \fB\-A \fIdevice%p\fR, \fB\-A \fIdevice%c\fR
.br
(Linux-only) A simplified way to add additional audio I/O hardware to an instance
of JACK. This argument is actually just a wrapper around the -I
(internal client) version, requiring only the name of the ALSA "card"
to be used. The name should \fBNOT\fR include any ALSA device access
prefix (e.g. "hw:" or "plughw:") but can include a
subdevice. If %p is added to the device name, it will be made
available for playback only. If %c is added to the device name, it
will be made available for capture (recording) only. If neither %p nor
%c is added, it will be made available (if possible) for both capture
and playback. Although device names may be visible in various places
on your system, the file /proc/asound/cards shows them inside square
braces.
.br
Examples:
.br
-A SB (adds playback and capture for the "SB" device)
.br
-A Codec,1%c (adds capture (recording) for the 2nd subdevice of the "Codec" device)
.br
-A MT1a2%p (adds playback the 1st subdevice of the "MT1a2" device)
.br
The use of -A CARD is actually equivalent to -I foo:zalsa_in/-dhw:CARD
\fIand\fR -I CARD:zalsa_out/-dhw:CARD.
.br
The use of -A CARD%p is actually equivalent to -I CARD:zalsa_out/-dhw:CARD.
.br
The use of -A CARD%c is actually equivalent to -I CARD:zalsa_in/-dhw:CARD
.br
.br
Note that this option (like -I) can be used regardless of the backend
used, so even if you do not use the ALSA backend, you can still add
ALSA-supported devices to an instance of JACK.
.TP
\fB\-I, \-\-internal-client \fIclient-spec\fR
.br
Load \fIclient-name\fR as an internal client. May be used multiple
@@ -49,9 +83,9 @@ times. The form of \fIclient-spec\fR can be any of the following:
.br
client-path
.br
client-name/client-path
client-name:client-path
.br
client-name/client-path/init-string
client-name:client-path/init-string
.br
client-path/init-string
.br


+ 99
- 58
jackd/jackd.c View File

@@ -100,72 +100,112 @@ jack_load_internal_clients (JSList* load_list)

char* str = (char*) node->data;
jack_request_t req;
char* colon = strchr (str, ':');
char* slash = strchr (str, '/');
char* sslash;
char* client_name;
char* path;
char* client_name = NULL;
char* path = NULL;
char* args = NULL;
char* rest = NULL;
int free_path = 0;
int free_name = 0;
size_t len;

/* parse each argument/load_list member for the form foo,arg-list
and split it apart if the slash is there.
*/
/* possible argument forms:

if (slash == NULL) {
/* path (also client name) */
client_name = str;
path = client_name;
} else {
/* we want to copy the text up to the slash, not
including the slash.
*/
size_t len = slash - str;
/* add 1 to leave space for a NULL */
client_name = (char*) malloc (len + 1);
memcpy (client_name, str, len);
client_name[len] = '\0';
client-name:client-type/args
client-type/args
client-name:client-type
client-type

/* is there another slash ? */
client-name is the desired JACK client name.
client-type is basically the name of the DLL/DSO without any suffix.
args is a string whose contents will be passed to the client as
it is instantiated
*/

sslash = strchr (slash+1, '/');
if ((slash == NULL && colon == NULL) || (slash && colon && colon > slash)) {

if (sslash) {
/* client-type */

/* client-name/path/args */
len = sslash - (slash+1);

if (len) {
/* add 1 to leave space for a NULL */
path = (char*) malloc (len + 1);
memcpy (path, slash + 1, len);
path[len] = '\0';
} else {
path = client_name;
}
client_name = str;
path = client_name;

} else if (slash && colon) {

/* client-name:client-type/args */

rest = sslash + 1;
len = colon - str;
if (len) {
/* add 1 to leave space for a NULL */
client_name = (char*) malloc (len + 1);
free_name = 1;
memcpy (client_name, str, len);
client_name[len] = '\0';
}

len = slash - (colon+1);
if (len) {
/* add 1 to leave space for a NULL */
path = (char*) malloc (len + 1);
free_path = 1;
memcpy (path, colon + 1, len);
path[len] = '\0';
} else {
/* client-name/path */
path = slash + 1;
path = client_name;
}
rest = slash + 1;
len = strlen (rest);
if (len) {
/* add 1 to leave space for a NULL */
args = (char*) malloc (len + 1);
memcpy (args, rest, len);
args[len] = '\0';
}
} else if (slash && colon == NULL) {

/* we want to skip the text before the slash (len)
* plus the slash itself
*/
/* client-type/args */

if (rest) {
len = slash - str;

len = strlen (rest);
if (len) {
/* add 1 to leave space for a NULL */
path = (char *) malloc (len + 1);
free_path = 1;
memcpy (path, str, len);
path[len] = '\0';
}

rest = slash + 1;
len = strlen (rest);
if (len) {
/* add 1 to leave space for a NULL */
args = (char*) malloc (len + 1);
memcpy (args, rest, len);
args[len] = '\0';
}
if (len) {
/* add 1 to leave space for a NULL */
args = (char*) malloc (len + 1);
memcpy (args, rest, len);
args[len] = '\0';
}
} else {
/* client-name:client-type */

len = colon - str;

if (len) {
/* add 1 to leave space for a NULL */
client_name = (char *) malloc (len + 1);
free_name = 1;
memcpy (client_name, str, len);
client_name[len] = '\0';
path = colon + 1;
}
}

if (client_name == NULL || path == NULL) {
fprintf (stderr, "incorrect format for internal client specification (%s)\n", str);
exit (1);
}

memset (&req, 0, sizeof (req));
@@ -184,17 +224,18 @@ jack_load_internal_clients (JSList* load_list)
jack_intclient_load_request (engine, &req);
pthread_mutex_unlock (&engine->request_lock);
if (slash) {
if (free_name) {
free (client_name);
if (args) {
free (args);
}
}
if (free_path) {
free (path);
}
if (args) {
free (args);
}
}
}



static int
jack_main (jack_driver_desc_t * driver_desc, JSList * driver_params, JSList * slave_names, JSList * load_list)
{
@@ -721,24 +762,24 @@ main (int argc, char *argv[])
assume capture (common case: USB mics etc.)
*/
if ((dirstr = strstr (optarg, "%p")) != NULL && dirstr == (optarg + strlen(optarg) - 2)) {
snprintf (alsa_add_args, sizeof (alsa_add_args), "%.*s_play/%s/-dhw:%.*s",
snprintf (alsa_add_args, sizeof (alsa_add_args), "%.*s_play:%s/-dhw:%.*s",
(int) strlen (optarg) - 2, optarg,
alsa_add_client_name_playback,
(int) strlen (optarg) - 2, optarg);
load_list = jack_slist_append(load_list, strdup (alsa_add_args));
} else if ((dirstr = strstr (optarg, "%c")) != NULL && dirstr == (optarg + strlen(optarg) - 2)) {
snprintf (alsa_add_args, sizeof (alsa_add_args), "%.*s_rec/%s/-dhw:%.*s",
snprintf (alsa_add_args, sizeof (alsa_add_args), "%.*s_rec:%s/-dhw:%.*s",
(int) strlen (optarg) - 2, optarg,
alsa_add_client_name_capture,
(int) strlen (optarg) - 2, optarg);
load_list = jack_slist_append(load_list, strdup (alsa_add_args));
} else {
snprintf (alsa_add_args, sizeof (alsa_add_args), "%s_play/%s/-dhw:%s",
snprintf (alsa_add_args, sizeof (alsa_add_args), "%s_play:%s/-dhw:%s",
optarg,
alsa_add_client_name_playback,
optarg);
load_list = jack_slist_append(load_list, strdup (alsa_add_args));
snprintf (alsa_add_args, sizeof (alsa_add_args), "%s_rec/%s/-dhw:%s",
snprintf (alsa_add_args, sizeof (alsa_add_args), "%s_rec:%s/-dhw:%s",
optarg,
alsa_add_client_name_capture,
optarg);


Loading…
Cancel
Save