static int create_loopback_handle(struct loopback_handle **_handle,
const char *device,
+ const char *ctldev,
const char *id)
{
char idbuf[1024];
if (device == NULL)
device = "hw:0,0";
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);
idbuf[sizeof(idbuf)-1] = '\0';
handle->id = strdup(idbuf);
"-d,--daemonize daemonize the main process and use syslog for errors\n"
"-P,--pdevice playback 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"
"-t,--tlatency requested latency in usec (1/1000000sec)\n"
"-f,--format sample format\n"
{"daemonize", 0, NULL, 'd'},
{"pdevice", 1, NULL, 'P'},
{"cdevice", 1, NULL, 'C'},
+ {"pctl", 1, NULL, 'X'},
+ {"cctl", 1, NULL, 'Y'},
{"latency", 1, NULL, 'l'},
{"tlatency", 1, NULL, 't'},
{"format", 1, NULL, 'f'},
char *arg_config = NULL;
char *arg_pdevice = NULL;
char *arg_cdevice = NULL;
+ char *arg_pctl = NULL;
+ char *arg_cctl = NULL;
unsigned int arg_latency_req = 0;
unsigned int arg_latency_reqtime = 10000;
snd_pcm_format_t arg_format = SND_PCM_FORMAT_S16_LE;
while (1) {
int c;
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)
break;
switch (c) {
case 'C':
arg_cdevice = strdup(optarg);
break;
+ case 'X':
+ arg_pctl = strdup(optarg);
+ break;
+ case 'Y':
+ arg_cctl = strdup(optarg);
+ break;
case 'l':
err = atoi(optarg);
arg_latency_req = err >= 4 ? err : 4;
if (arg_config == NULL) {
struct loopback_handle *play;
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) {
logit(LOG_CRIT, "Unable to create playback handle.\n");
exit(EXIT_FAILURE);
}
- err = create_loopback_handle(&capt, arg_cdevice, "capture");
+ err = create_loopback_handle(&capt, arg_cdevice, arg_cctl, "capture");
if (err < 0) {
logit(LOG_CRIT, "Unable to create capture handle.\n");
exit(EXIT_FAILURE);
snd_pcm_info_free(info);
lhandle->card_number = card;
lhandle->ctl = NULL;
- if (card >= 0) {
- char name[16];
- sprintf(name, "hw:%i", card);
+ if (card >= 0 || lhandle->ctldev) {
+ char name[16], *dev = lhandle->ctldev;
+ if (dev == NULL) {
+ sprintf(name, "hw:%i", card);
+ dev = name;
+ }
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();
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;
}
if (lhandle->ctl)