mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-09 17:45:41 +01:00
alsaloop: Fix command-line parsing and pollfd initialization
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
147a1cc75c
commit
e77983d3c5
4 changed files with 54 additions and 20 deletions
|
@ -47,6 +47,8 @@ int daemonize = 0;
|
|||
int use_syslog = 0;
|
||||
struct loopback **loopbacks = NULL;
|
||||
int loopbacks_count = 0;
|
||||
char **my_argv = NULL;
|
||||
int my_argc = 0;
|
||||
|
||||
static void my_exit(struct loopback_thread *thread, int exitcode)
|
||||
{
|
||||
|
@ -575,9 +577,6 @@ static int parse_config_file(const char *file, snd_output_t *output)
|
|||
int argc, c, err = 0;
|
||||
char **argv;
|
||||
|
||||
argv = malloc(sizeof(char *) * MAX_ARGS);
|
||||
if (argv == NULL)
|
||||
return -ENOMEM;
|
||||
fp = fopen(file, "r");
|
||||
if (fp == NULL) {
|
||||
logit(LOG_CRIT, "Unable to open file '%s': %s\n", file, strerror(errno));
|
||||
|
@ -587,8 +586,13 @@ static int parse_config_file(const char *file, snd_output_t *output)
|
|||
if (fgets(line, sizeof(line)-1, fp) == NULL)
|
||||
break;
|
||||
line[sizeof(line)-1] = '\0';
|
||||
my_argv = realloc(my_argv, my_argc + MAX_ARGS * sizeof(char *));
|
||||
if (my_argv == NULL)
|
||||
return -ENOMEM;
|
||||
argv = my_argv + my_argc;
|
||||
argc = 0;
|
||||
argv[argc++] = strdup("<prog>");
|
||||
my_argc++;
|
||||
str = line;
|
||||
while (*str) {
|
||||
ptr = word;
|
||||
|
@ -607,25 +611,30 @@ static int parse_config_file(const char *file, snd_output_t *output)
|
|||
*ptr++ = *str++;
|
||||
}
|
||||
if (ptr != word) {
|
||||
if (*(ptr-1) == '\n')
|
||||
ptr--;
|
||||
*ptr = '\0';
|
||||
if (argc >= MAX_ARGS) {
|
||||
logit(LOG_CRIT, "Too many arguments.");
|
||||
goto __error;
|
||||
}
|
||||
argv[argc++] = strdup(word);
|
||||
my_argc++;
|
||||
}
|
||||
}
|
||||
/* erase runtime variables for getopt */
|
||||
optarg = NULL;
|
||||
optind = opterr = 1;
|
||||
optopt = 63;
|
||||
optopt = '?';
|
||||
|
||||
err = parse_config(argc, argv, output);
|
||||
__next:
|
||||
while (argc > 0)
|
||||
free(argv[--argc]);
|
||||
if (err < 0)
|
||||
break;
|
||||
err = 0;
|
||||
}
|
||||
__error:
|
||||
fclose(fp);
|
||||
free(argv);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -656,7 +665,7 @@ static void thread_job1(void *_data)
|
|||
pfds_count += thread->loopbacks[i]->pollfd_count;
|
||||
}
|
||||
pfds = calloc(pfds_count, sizeof(struct pollfd));
|
||||
if (pfds == NULL) {
|
||||
if (pfds == NULL || pfds_count <= 0) {
|
||||
logit(LOG_CRIT, "Poll FDs allocation failed.\n");
|
||||
my_exit(thread, EXIT_FAILURE);
|
||||
}
|
||||
|
@ -723,6 +732,9 @@ int main(int argc, char *argv[])
|
|||
logit(LOG_CRIT, "Unable to parse arguments or configuration...\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
while (my_argc > 0)
|
||||
free(my_argv[--my_argc]);
|
||||
free(my_argv);
|
||||
|
||||
if (loopbacks_count <= 0) {
|
||||
logit(LOG_CRIT, "No loopback defined...\n");
|
||||
|
|
|
@ -164,6 +164,10 @@ static int control_init1(struct loopback_handle *lhandle,
|
|||
|
||||
snd_ctl_elem_info_set_id(ctl->info, ctl->id);
|
||||
snd_ctl_elem_value_set_id(ctl->value, ctl->id);
|
||||
if (lhandle->ctl == NULL) {
|
||||
logit(LOG_WARNING, "Unable to read control info for '%s'\n", id_str(ctl->id));
|
||||
return -EIO;
|
||||
}
|
||||
err = snd_ctl_elem_info(lhandle->ctl, ctl->info);
|
||||
if (err < 0) {
|
||||
logit(LOG_WARNING, "Unable to read control info '%s': %s\n", id_str(ctl->id), snd_strerror(err));
|
||||
|
|
|
@ -1195,6 +1195,16 @@ int pcmjob_start(struct loopback *loop)
|
|||
snd_pcm_uframes_t count;
|
||||
int err;
|
||||
|
||||
loop->pollfd_count = loop->play->ctl_pollfd_count +
|
||||
loop->capt->ctl_pollfd_count;
|
||||
if ((err = snd_pcm_poll_descriptors_count(loop->play->handle)) < 0)
|
||||
goto __error;
|
||||
loop->play->pollfd_count = err;
|
||||
loop->pollfd_count += err;
|
||||
if ((err = snd_pcm_poll_descriptors_count(loop->capt->handle)) < 0)
|
||||
goto __error;
|
||||
loop->capt->pollfd_count = err;
|
||||
loop->pollfd_count += err;
|
||||
if (loop->slave == SLAVE_TYPE_ON) {
|
||||
err = get_active(loop->capt);
|
||||
if (err < 0)
|
||||
|
@ -1214,8 +1224,6 @@ int pcmjob_start(struct loopback *loop)
|
|||
goto __error;
|
||||
loop->play->channels = loop->capt->channels = err;
|
||||
}
|
||||
loop->pollfd_count = loop->play->ctl_pollfd_count +
|
||||
loop->capt->ctl_pollfd_count;
|
||||
loop->reinit = 0;
|
||||
loop->use_samplerate = 0;
|
||||
loop->latency = loop->latency_req;
|
||||
|
@ -1258,14 +1266,6 @@ int pcmjob_start(struct loopback *loop)
|
|||
if (loop->capt->rate_req != loop->capt->rate)
|
||||
loop->use_samplerate = 1;
|
||||
}
|
||||
if ((err = snd_pcm_poll_descriptors_count(loop->play->handle)) < 0)
|
||||
goto __error;
|
||||
loop->play->pollfd_count = err;
|
||||
loop->pollfd_count += err;
|
||||
if ((err = snd_pcm_poll_descriptors_count(loop->capt->handle)) < 0)
|
||||
goto __error;
|
||||
loop->capt->pollfd_count = err;
|
||||
loop->pollfd_count += err;
|
||||
#ifdef USE_SAMPLERATE
|
||||
if (loop->sync == SYNC_TYPE_SAMPLERATE)
|
||||
loop->use_samplerate = 1;
|
||||
|
@ -1463,9 +1463,11 @@ static int handle_ctl_events(struct loopback_handle *lhandle,
|
|||
if (lhandle == lhandle->loopback->play)
|
||||
goto __ctl_check;
|
||||
if (verbose > 6)
|
||||
snd_output_printf(lhandle->loopback->output, "ctl event!!!! %s\n", snd_ctl_event_elem_get_name(ev));
|
||||
snd_output_printf(lhandle->loopback->output, "%s: ctl event!!!! %s\n", lhandle->id, snd_ctl_event_elem_get_name(ev));
|
||||
if (ctl_event_check(lhandle->ctl_active, ev)) {
|
||||
err = get_active(lhandle);
|
||||
if (verbose > 7)
|
||||
snd_output_printf(lhandle->loopback->output, "%s: ctl event active %i\n", lhandle->id, err);
|
||||
if (err != lhandle->loopback->running)
|
||||
goto __restart;
|
||||
} else if (ctl_event_check(lhandle->ctl_format, ev)) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#DBG="gdb --args "
|
||||
#DBG="strace"
|
||||
#DBG="valgrind --leak-check=full"
|
||||
CFGFILE="/tmp/alsaloop.test.cfg"
|
||||
|
||||
test1() {
|
||||
|
@ -35,7 +36,8 @@ cat > $CFGFILE <<EOF
|
|||
-C hw:1,0,0 -P plug:dmix:0 --tlatency 50000 --thread 0 \
|
||||
--mixer "name='Master Playback Volume'@name='Master Playback Volume'" \
|
||||
--mixer "name='Master Playback Switch'@name='Master Playback Switch'" \
|
||||
--mixer "name='PCM Playback Volume'"
|
||||
--mixer "name='PCM Playback Volume'" \
|
||||
--ossmixer "name=Master@VOLUME"
|
||||
-C hw:1,0,1 -P plug:dmix:0 --tlatency 50000 --thread 1
|
||||
-C hw:1,0,2 -P plug:dmix:0 --tlatency 50000 --thread 2
|
||||
-C hw:1,0,3 -P plug:dmix:0 --tlatency 50000 --thread 3
|
||||
|
@ -56,10 +58,24 @@ test4() {
|
|||
--mixer "name='PCM Playback Volume'"
|
||||
}
|
||||
|
||||
test5() {
|
||||
echo "TEST5"
|
||||
cat > $CFGFILE <<EOF
|
||||
-C hw:1,0,0 -P plughw:0,0 --tlatency 50000 --thread 1 \
|
||||
--mixer "name='Master Playback Volume'@name='Master Playback Volume'" \
|
||||
--mixer "name='Master Playback Switch'@name='Master Playback Switch'" \
|
||||
--mixer "name='PCM Playback Volume'" \
|
||||
--ossmixer "name=Master@VOLUME"
|
||||
-C hw:1,0,1 -P plughw:0,1 --tlatency 50000 --thread 2
|
||||
EOF
|
||||
$DBG ./alsaloop --config $CFGFILE
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
test1) test1 ;;
|
||||
test2) test2 ;;
|
||||
test3) test3 ;;
|
||||
test4) test4 ;;
|
||||
test5) test5 ;;
|
||||
*) test1 ;;
|
||||
esac
|
||||
|
|
Loading…
Reference in a new issue