alsaloop: add --pctl and --cctl options

In some cases it might be usefull to specify another CTL device names.
Add -X/--pctl and -Y/--cctl options.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2010-10-11 11:53:50 +02:00
parent bee994f509
commit 38c2ef96b7
3 changed files with 34 additions and 8 deletions

View file

@ -66,6 +66,7 @@ static void my_exit(struct loopback_thread *thread, int exitcode)
static int create_loopback_handle(struct loopback_handle **_handle, static int create_loopback_handle(struct loopback_handle **_handle,
const char *device, const char *device,
const char *ctldev,
const char *id) const char *id)
{ {
char idbuf[1024]; char idbuf[1024];
@ -77,6 +78,15 @@ static int create_loopback_handle(struct loopback_handle **_handle,
if (device == NULL) if (device == NULL)
device = "hw:0,0"; device = "hw:0,0";
handle->device = strdup(device); handle->device = strdup(device);
if (handle->device == NULL)
return -ENOMEM;
if (ctldev) {
handle->ctldev = strdup(ctldev);
if (handle->ctldev == NULL)
return -ENOMEM;
} else {
handle->ctldev = NULL;
}
snprintf(idbuf, sizeof(idbuf)-1, "%s %s", id, device); snprintf(idbuf, sizeof(idbuf)-1, "%s %s", id, device);
idbuf[sizeof(idbuf)-1] = '\0'; idbuf[sizeof(idbuf)-1] = '\0';
handle->id = strdup(idbuf); handle->id = strdup(idbuf);
@ -150,6 +160,8 @@ void help(void)
"-d,--daemonize daemonize the main process and use syslog for errors\n" "-d,--daemonize daemonize the main process and use syslog for errors\n"
"-P,--pdevice playback device\n" "-P,--pdevice playback device\n"
"-C,--cdevice capture device\n" "-C,--cdevice capture device\n"
"-X,--pctl playback ctl device\n"
"-Y,--cctl capture ctl device\n"
"-l,--latency requested latency in frames\n" "-l,--latency requested latency in frames\n"
"-t,--tlatency requested latency in usec (1/1000000sec)\n" "-t,--tlatency requested latency in usec (1/1000000sec)\n"
"-f,--format sample format\n" "-f,--format sample format\n"
@ -323,6 +335,8 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
{"daemonize", 0, NULL, 'd'}, {"daemonize", 0, NULL, 'd'},
{"pdevice", 1, NULL, 'P'}, {"pdevice", 1, NULL, 'P'},
{"cdevice", 1, NULL, 'C'}, {"cdevice", 1, NULL, 'C'},
{"pctl", 1, NULL, 'X'},
{"cctl", 1, NULL, 'Y'},
{"latency", 1, NULL, 'l'}, {"latency", 1, NULL, 'l'},
{"tlatency", 1, NULL, 't'}, {"tlatency", 1, NULL, 't'},
{"format", 1, NULL, 'f'}, {"format", 1, NULL, 'f'},
@ -348,6 +362,8 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
char *arg_config = NULL; char *arg_config = NULL;
char *arg_pdevice = NULL; char *arg_pdevice = NULL;
char *arg_cdevice = NULL; char *arg_cdevice = NULL;
char *arg_pctl = NULL;
char *arg_cctl = NULL;
unsigned int arg_latency_req = 0; unsigned int arg_latency_req = 0;
unsigned int arg_latency_reqtime = 10000; unsigned int arg_latency_reqtime = 10000;
snd_pcm_format_t arg_format = SND_PCM_FORMAT_S16_LE; snd_pcm_format_t arg_format = SND_PCM_FORMAT_S16_LE;
@ -373,7 +389,7 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
while (1) { while (1) {
int c; int c;
if ((c = getopt_long(argc, argv, if ((c = getopt_long(argc, argv,
"hdg:P:C:l:t:F:f:c:r:s:benvA:S:a:m:T:O:w:", "hdg:P:C:X:Y:l:t:F:f:c:r:s:benvA:S:a:m:T:O:w:",
long_option, NULL)) < 0) long_option, NULL)) < 0)
break; break;
switch (c) { switch (c) {
@ -394,6 +410,12 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
case 'C': case 'C':
arg_cdevice = strdup(optarg); arg_cdevice = strdup(optarg);
break; break;
case 'X':
arg_pctl = strdup(optarg);
break;
case 'Y':
arg_cctl = strdup(optarg);
break;
case 'l': case 'l':
err = atoi(optarg); err = atoi(optarg);
arg_latency_req = err >= 4 ? err : 4; arg_latency_req = err >= 4 ? err : 4;
@ -521,12 +543,12 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
if (arg_config == NULL) { if (arg_config == NULL) {
struct loopback_handle *play; struct loopback_handle *play;
struct loopback_handle *capt; struct loopback_handle *capt;
err = create_loopback_handle(&play, arg_pdevice, "playback"); err = create_loopback_handle(&play, arg_pdevice, arg_pctl, "playback");
if (err < 0) { if (err < 0) {
logit(LOG_CRIT, "Unable to create playback handle.\n"); logit(LOG_CRIT, "Unable to create playback handle.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
err = create_loopback_handle(&capt, arg_cdevice, "capture"); err = create_loopback_handle(&capt, arg_cdevice, arg_cctl, "capture");
if (err < 0) { if (err < 0) {
logit(LOG_CRIT, "Unable to create capture handle.\n"); logit(LOG_CRIT, "Unable to create capture handle.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View file

@ -84,6 +84,7 @@ struct loopback_ossmixer {
struct loopback_handle { struct loopback_handle {
struct loopback *loopback; struct loopback *loopback;
char *device; char *device;
char *ctldev;
char *id; char *id;
int card_number; int card_number;
snd_pcm_t *handle; snd_pcm_t *handle;

View file

@ -1063,14 +1063,17 @@ static int openit(struct loopback_handle *lhandle)
snd_pcm_info_free(info); snd_pcm_info_free(info);
lhandle->card_number = card; lhandle->card_number = card;
lhandle->ctl = NULL; lhandle->ctl = NULL;
if (card >= 0) { if (card >= 0 || lhandle->ctldev) {
char name[16]; char name[16], *dev = lhandle->ctldev;
sprintf(name, "hw:%i", card); if (dev == NULL) {
sprintf(name, "hw:%i", card);
dev = name;
}
pcm_open_lock(); pcm_open_lock();
err = snd_ctl_open(&lhandle->ctl, name, SND_CTL_NONBLOCK); err = snd_ctl_open(&lhandle->ctl, dev, SND_CTL_NONBLOCK);
pcm_open_unlock(); pcm_open_unlock();
if (err < 0) { if (err < 0) {
logit(LOG_CRIT, "%s [%s] ctl open error: %s\n", lhandle->id, name, snd_strerror(err)); logit(LOG_CRIT, "%s [%s] ctl open error: %s\n", lhandle->id, dev, snd_strerror(err));
lhandle->ctl = NULL; lhandle->ctl = NULL;
} }
if (lhandle->ctl) if (lhandle->ctl)