+#include <stdbool.h>
#include <alsa/asoundlib.h>
extern int debugflag;
extern char *statefile;
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 error_(const char *fcn, long line, const char *fmt, ...);
void cerror_(const char *fcn, long line, int cond, const char *fmt, ...);
#define FLAG_UCM_BOOT (1<<2)
#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 init(const char *file, int flags, const char *cardname);
int init_ucm(int flags, int cardno);
int clean(const char *cardname, char *const *extra_args)
{
+ struct snd_card_iterator iter;
int err;
- if (!cardname) {
- int card, first = 1;
-
- 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;
- } 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;
- }
+ err = snd_card_iterator_sinit(&iter, cardname);
+ if (err < 0)
+ return err;
+ while (snd_card_iterator_next(&iter)) {
+ if ((err = clean_controls(iter.card, extra_args)))
+ return err;
}
-out:
- return err;
+ return snd_card_iterator_error(&iter);
}
int init(const char *filename, int flags, const char *cardname)
{
struct space *space;
- int err = 0, lasterr = 0, card, first;
+ struct snd_card_iterator iter;
+ int err = 0, lasterr = 0;
sysfs_init();
- if (!cardname) {
- first = 1;
- card = -1;
- 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)
- continue;
- err = init_space(&space, card);
- if (err == 0) {
- space->rootdir = new_root_dir(filename);
- if (space->rootdir != NULL)
- err = parse(space, filename);
- if (err <= -99) { /* non-fatal errors */
- if (lasterr == 0)
- lasterr = err;
- err = 0;
- }
- free_space(space);
- }
- if (err < 0)
- break;
- }
- err = lasterr;
- } else {
- card = snd_card_get_index(cardname);
- if (card < 0) {
- error("Cannot find soundcard '%s'...", cardname);
- goto error;
- }
- err = init_ucm(flags, card);
+ err = snd_card_iterator_sinit(&iter, cardname);
+ while (snd_card_iterator_next(&iter)) {
+ err = init_ucm(flags, iter.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);
+ continue;
+ err = init_space(&space, iter.card);
+ if (err != 0)
+ continue;
+ space->rootdir = new_root_dir(filename);
+ if (space->rootdir != NULL) {
+ err = parse(space, filename);
+ if (!cardname && err <= -99) { /* non-fatal errors */
+ if (lasterr == 0)
+ lasterr = err;
+ err = 0;
+ }
}
+ free_space(space);
+ if (err < 0)
+ goto out;
}
- error:
+ err = lasterr ? lasterr : snd_card_iterator_error(&iter);
+out:
sysfs_cleanup();
return err;
}
#include <time.h>
#include <signal.h>
#include <sys/signalfd.h>
-#include <alsa/asoundlib.h>
#include <stddef.h>
#include "list.h"
+#include "alsactl.h"
+
struct src_entry {
snd_ctl_t *handle;
char *name;
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)
{
list_del(&entry->list);
struct snd_card_iterator iter;
const char *cardname;
- snd_card_iterator_init(&iter);
+ snd_card_iterator_init(&iter, -1);
while ((cardname = snd_card_iterator_next(&iter))) {
if (seek_entry_by_name(srcs, cardname))
continue;
int stdio;
char *nfile = NULL;
int lock_fd = -EINVAL;
+ struct snd_card_iterator iter;
err = snd_config_top(&config);
if (err < 0) {
#endif
}
- if (!cardname) {
- int card, first = 1;
-
- 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;
- } else {
- error("No soundcards found...");
- err = -ENODEV;
- goto out;
- }
- }
- break;
- }
- first = 0;
- if ((err = get_controls(card, config)))
- 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))) {
+ err = snd_card_iterator_sinit(&iter, cardname);
+ if (err < 0)
+ goto out;
+ while (snd_card_iterator_next(&iter)) {
+ if ((err = get_controls(iter.card, config)))
goto out;
- }
}
-
+ if (iter.first) {
+ err = snd_card_iterator_error(&iter);
+ goto out;
+ }
+
if (stdio) {
err = snd_output_stdio_attach(&out, stdout, 0);
} else {
const char *cardname, int do_init)
{
int err, finalerr = 0, open_failed;
+ struct snd_card_iterator iter;
snd_config_t *config;
+ const char *cardname1;
err = load_configuration(file, &config, &open_failed);
if (err < 0 && !open_failed)
return err;
if (open_failed) {
- int card, first = 1;
- char cardname1[16];
-
error("Cannot open %s for reading: %s", file, snd_strerror(err));
finalerr = err;
- if (cardname) {
- card = snd_card_get_index(cardname);
- if (card < 0) {
- error("Cannot find soundcard '%s'...", cardname);
- err = -ENODEV;
- 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;
+
+ err = snd_card_iterator_sinit(&iter, cardname);
+ if (err < 0)
+ return err;
+ while ((cardname1 = snd_card_iterator_next(&iter)) != NULL) {
if (!do_init)
break;
- sprintf(cardname1, "%i", card);
err = init(initfile, initflags | FLAG_UCM_FBOOT | FLAG_UCM_BOOT, cardname1);
if (err < 0) {
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;
+ if (iter.first)
+ err = 0; /* no cards, no error code */
goto out;
}
- if (!cardname) {
- int card, first = 1;
- 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;
- } else {
- error("No soundcards found...");
- err = -ENODEV;
- goto out;
- }
- }
- break;
- }
- first = 0;
- /* error is ignored */
- init_ucm(initflags | FLAG_UCM_FBOOT, card);
- /* do a check if controls matches state file */
- if (do_init && set_controls(card, config, 0)) {
- sprintf(cardname1, "%i", card);
- err = init(initfile, initflags | FLAG_UCM_BOOT, cardname1);
- if (err < 0) {
- initfailed(card, "init", err);
- finalerr = err;
- }
- }
- if ((err = set_controls(card, config, 1))) {
- if (!force_restore)
- finalerr = err;
- initfailed(card, "restore", err);
- }
- }
- } else {
- int cardno;
-
- cardno = snd_card_get_index(cardname);
- if (cardno < 0) {
- error("Cannot find soundcard '%s'...", cardname);
- err = -ENODEV;
- goto out;
- }
+ err = snd_card_iterator_sinit(&iter, cardname);
+ if (err < 0)
+ goto out;
+ while ((cardname1 = snd_card_iterator_next(&iter)) != NULL) {
/* error is ignored */
- init_ucm(initflags | FLAG_UCM_FBOOT, cardno);
+ init_ucm(initflags | FLAG_UCM_FBOOT, iter.card);
/* 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 (do_init && set_controls(iter.card, config, 0)) {
+ err = init(initfile, initflags | FLAG_UCM_BOOT, cardname1);
if (err < 0) {
- initfailed(cardno, "init", err);
+ initfailed(iter.card, "init", err);
finalerr = err;
}
}
- if ((err = set_controls(cardno, config, 1))) {
- initfailed(cardno, "restore", err);
+ if ((err = set_controls(iter.card, config, 1))) {
if (!force_restore)
- goto out;
+ finalerr = err;
+ initfailed(iter.card, "restore", err);
}
}
- err = finalerr;
+ err = finalerr ? finalerr : snd_card_iterator_error(&iter);
out:
snd_config_delete(config);
snd_config_update_free_global();
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;
+}