mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-12-23 01:36:30 +01:00
alsactl: use card iterator functions for all card loops
Take the card iterator idea from the monitor code and use it for all card loops. It reduces the code duplications and makes things easy to review. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
9a2115b5cc
commit
eefc2c61cf
6 changed files with 131 additions and 237 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdbool.h>
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
extern int debugflag;
|
extern int debugflag;
|
||||||
|
@ -9,6 +10,13 @@ extern char *command;
|
||||||
extern char *statefile;
|
extern char *statefile;
|
||||||
extern char *lockfile;
|
extern char *lockfile;
|
||||||
|
|
||||||
|
struct snd_card_iterator {
|
||||||
|
int card;
|
||||||
|
char name[16];
|
||||||
|
bool single;
|
||||||
|
bool first;
|
||||||
|
};
|
||||||
|
|
||||||
void info_(const char *fcn, long line, const char *fmt, ...);
|
void info_(const char *fcn, long line, const char *fmt, ...);
|
||||||
void error_(const char *fcn, long line, const char *fmt, ...);
|
void error_(const char *fcn, long line, const char *fmt, ...);
|
||||||
void cerror_(const char *fcn, long line, int cond, const char *fmt, ...);
|
void cerror_(const char *fcn, long line, int cond, const char *fmt, ...);
|
||||||
|
@ -32,6 +40,11 @@ void error_handler(const char *file, int line, const char *function, int err, co
|
||||||
#define FLAG_UCM_BOOT (1<<2)
|
#define FLAG_UCM_BOOT (1<<2)
|
||||||
#define FLAG_UCM_DEFAULTS (1<<3)
|
#define FLAG_UCM_DEFAULTS (1<<3)
|
||||||
|
|
||||||
|
void snd_card_iterator_init(struct snd_card_iterator *iter, int cardno);
|
||||||
|
int snd_card_iterator_sinit(struct snd_card_iterator *iter, const char *cardname);
|
||||||
|
const char *snd_card_iterator_next(struct snd_card_iterator *iter);
|
||||||
|
int snd_card_iterator_error(struct snd_card_iterator *iter);
|
||||||
|
|
||||||
int load_configuration(const char *file, snd_config_t **top, int *open_failed);
|
int load_configuration(const char *file, snd_config_t **top, int *open_failed);
|
||||||
int init(const char *file, int flags, const char *cardname);
|
int init(const char *file, int flags, const char *cardname);
|
||||||
int init_ucm(int flags, int cardno);
|
int init_ucm(int flags, int cardno);
|
||||||
|
|
|
@ -182,46 +182,15 @@ fin_err:
|
||||||
|
|
||||||
int clean(const char *cardname, char *const *extra_args)
|
int clean(const char *cardname, char *const *extra_args)
|
||||||
{
|
{
|
||||||
|
struct snd_card_iterator iter;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!cardname) {
|
err = snd_card_iterator_sinit(&iter, cardname);
|
||||||
int card, first = 1;
|
if (err < 0)
|
||||||
|
return err;
|
||||||
card = -1;
|
while (snd_card_iterator_next(&iter)) {
|
||||||
/* find each installed soundcards */
|
if ((err = clean_controls(iter.card, extra_args)))
|
||||||
while (1) {
|
|
||||||
if (snd_card_next(&card) < 0)
|
|
||||||
break;
|
|
||||||
if (card < 0) {
|
|
||||||
if (first) {
|
|
||||||
if (ignore_nocards) {
|
|
||||||
err = 0;
|
|
||||||
goto out;
|
|
||||||
} else {
|
|
||||||
error("No soundcards found...");
|
|
||||||
err = -ENODEV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
first = 0;
|
|
||||||
if ((err = clean_controls(card, extra_args)))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int cardno;
|
|
||||||
|
|
||||||
cardno = snd_card_get_index(cardname);
|
|
||||||
if (cardno < 0) {
|
|
||||||
error("Cannot find soundcard '%s'...", cardname);
|
|
||||||
err = cardno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if ((err = clean_controls(cardno, extra_args))) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
return snd_card_iterator_error(&iter);
|
||||||
|
}
|
||||||
|
|
|
@ -1746,63 +1746,33 @@ static int parse(struct space *space, const char *filename)
|
||||||
int init(const char *filename, int flags, const char *cardname)
|
int init(const char *filename, int flags, const char *cardname)
|
||||||
{
|
{
|
||||||
struct space *space;
|
struct space *space;
|
||||||
int err = 0, lasterr = 0, card, first;
|
struct snd_card_iterator iter;
|
||||||
|
int err = 0, lasterr = 0;
|
||||||
|
|
||||||
sysfs_init();
|
sysfs_init();
|
||||||
if (!cardname) {
|
err = snd_card_iterator_sinit(&iter, cardname);
|
||||||
first = 1;
|
while (snd_card_iterator_next(&iter)) {
|
||||||
card = -1;
|
err = init_ucm(flags, iter.card);
|
||||||
while (1) {
|
|
||||||
if (snd_card_next(&card) < 0)
|
|
||||||
break;
|
|
||||||
if (card < 0) {
|
|
||||||
if (first) {
|
|
||||||
if (ignore_nocards)
|
|
||||||
return 0;
|
|
||||||
error("No soundcards found...");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
first = 0;
|
|
||||||
err = init_ucm(flags, card);
|
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
continue;
|
continue;
|
||||||
err = init_space(&space, card);
|
err = init_space(&space, iter.card);
|
||||||
if (err == 0) {
|
if (err != 0)
|
||||||
|
continue;
|
||||||
space->rootdir = new_root_dir(filename);
|
space->rootdir = new_root_dir(filename);
|
||||||
if (space->rootdir != NULL)
|
if (space->rootdir != NULL) {
|
||||||
err = parse(space, filename);
|
err = parse(space, filename);
|
||||||
if (err <= -99) { /* non-fatal errors */
|
if (!cardname && err <= -99) { /* non-fatal errors */
|
||||||
if (lasterr == 0)
|
if (lasterr == 0)
|
||||||
lasterr = err;
|
lasterr = err;
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
free_space(space);
|
|
||||||
}
|
}
|
||||||
|
free_space(space);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
err = lasterr;
|
err = lasterr ? lasterr : snd_card_iterator_error(&iter);
|
||||||
} else {
|
out:
|
||||||
card = snd_card_get_index(cardname);
|
|
||||||
if (card < 0) {
|
|
||||||
error("Cannot find soundcard '%s'...", cardname);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
err = init_ucm(flags, card);
|
|
||||||
if (err == 0)
|
|
||||||
return 0;
|
|
||||||
memset(&space, 0, sizeof(space));
|
|
||||||
err = init_space(&space, card);
|
|
||||||
if (err == 0) {
|
|
||||||
space->rootdir = new_root_dir(filename);
|
|
||||||
if (space->rootdir != NULL)
|
|
||||||
err = parse(space, filename);
|
|
||||||
free_space(space);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
error:
|
|
||||||
sysfs_cleanup();
|
sysfs_cleanup();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,12 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/signalfd.h>
|
#include <sys/signalfd.h>
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
|
#include "alsactl.h"
|
||||||
|
|
||||||
struct src_entry {
|
struct src_entry {
|
||||||
snd_ctl_t *handle;
|
snd_ctl_t *handle;
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -40,29 +41,6 @@ struct src_entry {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct snd_card_iterator {
|
|
||||||
int card;
|
|
||||||
char name[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
void snd_card_iterator_init(struct snd_card_iterator *iter)
|
|
||||||
{
|
|
||||||
iter->card = -1;
|
|
||||||
memset(iter->name, 0, sizeof(iter->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *snd_card_iterator_next(struct snd_card_iterator *iter)
|
|
||||||
{
|
|
||||||
if (snd_card_next(&iter->card) < 0)
|
|
||||||
return NULL;
|
|
||||||
if (iter->card < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
snprintf(iter->name, sizeof(iter->name), "hw:%d", iter->card);
|
|
||||||
|
|
||||||
return (const char *)iter->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void remove_source_entry(struct src_entry *entry)
|
static void remove_source_entry(struct src_entry *entry)
|
||||||
{
|
{
|
||||||
list_del(&entry->list);
|
list_del(&entry->list);
|
||||||
|
@ -159,7 +137,7 @@ static int prepare_source_entry(struct list_head *srcs, const char *name)
|
||||||
struct snd_card_iterator iter;
|
struct snd_card_iterator iter;
|
||||||
const char *cardname;
|
const char *cardname;
|
||||||
|
|
||||||
snd_card_iterator_init(&iter);
|
snd_card_iterator_init(&iter, -1);
|
||||||
while ((cardname = snd_card_iterator_next(&iter))) {
|
while ((cardname = snd_card_iterator_next(&iter))) {
|
||||||
if (seek_entry_by_name(srcs, cardname))
|
if (seek_entry_by_name(srcs, cardname))
|
||||||
continue;
|
continue;
|
||||||
|
|
141
alsactl/state.c
141
alsactl/state.c
|
@ -1544,6 +1544,7 @@ int save_state(const char *file, const char *cardname)
|
||||||
int stdio;
|
int stdio;
|
||||||
char *nfile = NULL;
|
char *nfile = NULL;
|
||||||
int lock_fd = -EINVAL;
|
int lock_fd = -EINVAL;
|
||||||
|
struct snd_card_iterator iter;
|
||||||
|
|
||||||
err = snd_config_top(&config);
|
err = snd_config_top(&config);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@ -1577,44 +1578,17 @@ int save_state(const char *file, const char *cardname)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cardname) {
|
err = snd_card_iterator_sinit(&iter, cardname);
|
||||||
int card, first = 1;
|
if (err < 0)
|
||||||
|
|
||||||
card = -1;
|
|
||||||
/* find each installed soundcards */
|
|
||||||
while (1) {
|
|
||||||
if (snd_card_next(&card) < 0)
|
|
||||||
break;
|
|
||||||
if (card < 0) {
|
|
||||||
if (first) {
|
|
||||||
if (ignore_nocards) {
|
|
||||||
err = 0;
|
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
while (snd_card_iterator_next(&iter)) {
|
||||||
error("No soundcards found...");
|
if ((err = get_controls(iter.card, config)))
|
||||||
err = -ENODEV;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
if (iter.first) {
|
||||||
break;
|
err = snd_card_iterator_error(&iter);
|
||||||
}
|
|
||||||
first = 0;
|
|
||||||
if ((err = get_controls(card, config)))
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
int cardno;
|
|
||||||
|
|
||||||
cardno = snd_card_get_index(cardname);
|
|
||||||
if (cardno < 0) {
|
|
||||||
error("Cannot find soundcard '%s'...", cardname);
|
|
||||||
err = cardno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if ((err = get_controls(cardno, config))) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stdio) {
|
if (stdio) {
|
||||||
err = snd_output_stdio_attach(&out, stdout, 0);
|
err = snd_output_stdio_attach(&out, stdout, 0);
|
||||||
|
@ -1648,119 +1622,58 @@ int load_state(const char *file, const char *initfile, int initflags,
|
||||||
const char *cardname, int do_init)
|
const char *cardname, int do_init)
|
||||||
{
|
{
|
||||||
int err, finalerr = 0, open_failed;
|
int err, finalerr = 0, open_failed;
|
||||||
|
struct snd_card_iterator iter;
|
||||||
snd_config_t *config;
|
snd_config_t *config;
|
||||||
|
const char *cardname1;
|
||||||
|
|
||||||
err = load_configuration(file, &config, &open_failed);
|
err = load_configuration(file, &config, &open_failed);
|
||||||
if (err < 0 && !open_failed)
|
if (err < 0 && !open_failed)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (open_failed) {
|
if (open_failed) {
|
||||||
int card, first = 1;
|
|
||||||
char cardname1[16];
|
|
||||||
|
|
||||||
error("Cannot open %s for reading: %s", file, snd_strerror(err));
|
error("Cannot open %s for reading: %s", file, snd_strerror(err));
|
||||||
finalerr = err;
|
finalerr = err;
|
||||||
if (cardname) {
|
|
||||||
card = snd_card_get_index(cardname);
|
err = snd_card_iterator_sinit(&iter, cardname);
|
||||||
if (card < 0) {
|
if (err < 0)
|
||||||
error("Cannot find soundcard '%s'...", cardname);
|
return err;
|
||||||
err = -ENODEV;
|
while ((cardname1 = snd_card_iterator_next(&iter)) != NULL) {
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
goto single;
|
|
||||||
} else {
|
|
||||||
card = -1;
|
|
||||||
}
|
|
||||||
/* find each installed soundcards */
|
|
||||||
while (!cardname) {
|
|
||||||
if (snd_card_next(&card) < 0)
|
|
||||||
break;
|
|
||||||
if (card < 0)
|
|
||||||
break;
|
|
||||||
single:
|
|
||||||
first = 0;
|
|
||||||
if (!do_init)
|
if (!do_init)
|
||||||
break;
|
break;
|
||||||
sprintf(cardname1, "%i", card);
|
|
||||||
err = init(initfile, initflags | FLAG_UCM_FBOOT | FLAG_UCM_BOOT, cardname1);
|
err = init(initfile, initflags | FLAG_UCM_FBOOT | FLAG_UCM_BOOT, cardname1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
finalerr = err;
|
finalerr = err;
|
||||||
initfailed(card, "init", err);
|
initfailed(iter.card, "init", err);
|
||||||
}
|
}
|
||||||
initfailed(card, "restore", -ENOENT);
|
initfailed(iter.card, "restore", -ENOENT);
|
||||||
}
|
}
|
||||||
if (first)
|
|
||||||
finalerr = 0; /* no cards, no error code */
|
|
||||||
err = finalerr;
|
err = finalerr;
|
||||||
|
if (iter.first)
|
||||||
|
err = 0; /* no cards, no error code */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cardname) {
|
err = snd_card_iterator_sinit(&iter, cardname);
|
||||||
int card, first = 1;
|
if (err < 0)
|
||||||
char cardname1[16];
|
|
||||||
|
|
||||||
card = -1;
|
|
||||||
/* find each installed soundcards */
|
|
||||||
while (1) {
|
|
||||||
if (snd_card_next(&card) < 0)
|
|
||||||
break;
|
|
||||||
if (card < 0) {
|
|
||||||
if (first) {
|
|
||||||
if (ignore_nocards) {
|
|
||||||
err = 0;
|
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
while ((cardname1 = snd_card_iterator_next(&iter)) != NULL) {
|
||||||
error("No soundcards found...");
|
|
||||||
err = -ENODEV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
first = 0;
|
|
||||||
/* error is ignored */
|
/* error is ignored */
|
||||||
init_ucm(initflags | FLAG_UCM_FBOOT, card);
|
init_ucm(initflags | FLAG_UCM_FBOOT, iter.card);
|
||||||
/* do a check if controls matches state file */
|
/* do a check if controls matches state file */
|
||||||
if (do_init && set_controls(card, config, 0)) {
|
if (do_init && set_controls(iter.card, config, 0)) {
|
||||||
sprintf(cardname1, "%i", card);
|
|
||||||
err = init(initfile, initflags | FLAG_UCM_BOOT, cardname1);
|
err = init(initfile, initflags | FLAG_UCM_BOOT, cardname1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
initfailed(card, "init", err);
|
initfailed(iter.card, "init", err);
|
||||||
finalerr = err;
|
finalerr = err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((err = set_controls(card, config, 1))) {
|
if ((err = set_controls(iter.card, config, 1))) {
|
||||||
if (!force_restore)
|
if (!force_restore)
|
||||||
finalerr = err;
|
finalerr = err;
|
||||||
initfailed(card, "restore", err);
|
initfailed(iter.card, "restore", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
err = finalerr ? finalerr : snd_card_iterator_error(&iter);
|
||||||
int cardno;
|
|
||||||
|
|
||||||
cardno = snd_card_get_index(cardname);
|
|
||||||
if (cardno < 0) {
|
|
||||||
error("Cannot find soundcard '%s'...", cardname);
|
|
||||||
err = -ENODEV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* error is ignored */
|
|
||||||
init_ucm(initflags | FLAG_UCM_FBOOT, cardno);
|
|
||||||
/* do a check if controls matches state file */
|
|
||||||
if (do_init && set_controls(cardno, config, 0)) {
|
|
||||||
err = init(initfile, initflags | FLAG_UCM_BOOT, cardname);
|
|
||||||
if (err < 0) {
|
|
||||||
initfailed(cardno, "init", err);
|
|
||||||
finalerr = err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((err = set_controls(cardno, config, 1))) {
|
|
||||||
initfailed(cardno, "restore", err);
|
|
||||||
if (!force_restore)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = finalerr;
|
|
||||||
out:
|
out:
|
||||||
snd_config_delete(config);
|
snd_config_delete(config);
|
||||||
snd_config_update_free_global();
|
snd_config_update_free_global();
|
||||||
|
|
|
@ -233,3 +233,54 @@ out:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void snd_card_iterator_init(struct snd_card_iterator *iter, int cardno)
|
||||||
|
{
|
||||||
|
iter->card = cardno;
|
||||||
|
iter->single = cardno >= 0;
|
||||||
|
iter->first = true;
|
||||||
|
iter->name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_card_iterator_sinit(struct snd_card_iterator *iter, const char *cardname)
|
||||||
|
{
|
||||||
|
int cardno = -1;
|
||||||
|
|
||||||
|
if (cardname) {
|
||||||
|
cardno = snd_card_get_index(cardname);
|
||||||
|
if (cardno < 0) {
|
||||||
|
error("Cannot find soundcard '%s'...", cardname);
|
||||||
|
return cardno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snd_card_iterator_init(iter, cardno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *snd_card_iterator_next(struct snd_card_iterator *iter)
|
||||||
|
{
|
||||||
|
if (iter->single) {
|
||||||
|
if (iter->first) {
|
||||||
|
iter->first = false;
|
||||||
|
goto retval;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (snd_card_next(&iter->card) < 0) {
|
||||||
|
if (!ignore_nocards && iter->first)
|
||||||
|
error("No soundcards found...");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
iter->first = false;
|
||||||
|
if (iter->card < 0)
|
||||||
|
return NULL;
|
||||||
|
retval:
|
||||||
|
snprintf(iter->name, sizeof(iter->name), "hw:%d", iter->card);
|
||||||
|
|
||||||
|
return (const char *)iter->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_card_iterator_error(struct snd_card_iterator *iter)
|
||||||
|
{
|
||||||
|
return iter->first ? (ignore_nocards ? 0 : -ENODEV) : 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue