2007-12-14 16:25:23 +01:00
|
|
|
diff -r 3b8e4ee4363e alsactl/alsactl.1
|
|
|
|
--- a/alsactl/alsactl.1 Mon Oct 15 10:36:47 2007 +0200
|
|
|
|
+++ b/alsactl/alsactl.1 Fri Dec 14 15:35:34 2007 +0100
|
|
|
|
@@ -41,7 +41,12 @@ Select the configuration file to use. Th
|
|
|
|
.TP
|
|
|
|
\fI\-F, \-\-force\fP
|
|
|
|
Used with restore command. Try to restore the matching control elements
|
|
|
|
-as much as possible.
|
|
|
|
+as much as possible. This option is set as default now.
|
|
|
|
+
|
|
|
|
+.TP
|
|
|
|
+\fI\-P, \-\-pedantic\fP
|
|
|
|
+Used with restore command. Don't restore mismatching control elements.
|
|
|
|
+This option was the old default behavior.
|
|
|
|
|
|
|
|
.TP
|
|
|
|
\fI\-d, \-\-debug\fP
|
|
|
|
diff -r 3b8e4ee4363e alsactl/alsactl.c
|
|
|
|
--- a/alsactl/alsactl.c Mon Oct 15 10:36:47 2007 +0200
|
|
|
|
+++ b/alsactl/alsactl.c Fri Dec 14 15:35:34 2007 +0100
|
|
|
|
@@ -34,7 +34,7 @@
|
|
|
|
#define SYS_ASOUNDNAMES "/etc/asound.names"
|
|
|
|
|
|
|
|
int debugflag = 0;
|
|
|
|
-int force_restore = 0;
|
|
|
|
+int force_restore = 1;
|
|
|
|
char *command;
|
|
|
|
|
|
|
|
static void help(void)
|
|
|
|
@@ -44,6 +44,8 @@ static void help(void)
|
|
|
|
printf(" -h,--help this help\n");
|
|
|
|
printf(" -f,--file # configuration file (default " SYS_ASOUNDRC " or " SYS_ASOUNDNAMES ")\n");
|
|
|
|
printf(" -F,--force try to restore the matching controls as much as possible\n");
|
|
|
|
+ printf(" (default mode)\n");
|
|
|
|
+ printf(" -P,--pedantic don't restore mismatching controls (old default)\n");
|
|
|
|
printf(" -d,--debug debug mode\n");
|
|
|
|
printf(" -v,--version print version of this program\n");
|
|
|
|
printf("\nAvailable commands:\n");
|
|
|
|
@@ -62,6 +64,7 @@ int main(int argc, char *argv[])
|
|
|
|
{"help", 0, NULL, 'h'},
|
|
|
|
{"file", 1, NULL, 'f'},
|
|
|
|
{"force", 0, NULL, 'F'},
|
|
|
|
+ {"pedantic", 0, NULL, 'P'},
|
|
|
|
{"debug", 0, NULL, 'd'},
|
|
|
|
{"version", 0, NULL, 'v'},
|
|
|
|
{NULL, 0, NULL, 0},
|
|
|
|
@@ -84,6 +87,9 @@ int main(int argc, char *argv[])
|
|
|
|
break;
|
|
|
|
case 'F':
|
|
|
|
force_restore = 1;
|
|
|
|
+ break;
|
|
|
|
+ case 'P':
|
|
|
|
+ force_restore = 0;
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
debugflag = 1;
|
2007-10-29 12:26:03 +01:00
|
|
|
diff -r 3b8e4ee4363e alsactl/state.c
|
|
|
|
--- a/alsactl/state.c Mon Oct 15 10:36:47 2007 +0200
|
2007-12-14 16:25:23 +01:00
|
|
|
+++ b/alsactl/state.c Fri Dec 14 15:35:34 2007 +0100
|
2007-10-29 12:26:03 +01:00
|
|
|
@@ -188,6 +188,46 @@ static unsigned int *str_to_tlv(const ch
|
|
|
|
return tlv;
|
|
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * add the TLV string and dB ranges to comment fields
|
|
|
|
+ */
|
|
|
|
+static int add_tlv_comments(snd_ctl_t *handle, snd_ctl_elem_id_t *id,
|
|
|
|
+ snd_ctl_elem_info_t *info, snd_config_t *comment)
|
|
|
|
+{
|
|
|
|
+ unsigned int tlv[MAX_USER_TLV_SIZE];
|
|
|
|
+ unsigned int *db;
|
|
|
|
+ long dbmin, dbmax;
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ if (snd_ctl_elem_tlv_read(handle, id, tlv, sizeof(tlv)) < 0)
|
|
|
|
+ return 0; /* ignore error */
|
|
|
|
+
|
|
|
|
+ if (snd_ctl_elem_info_is_tlv_writable(info)) {
|
|
|
|
+ char *s = tlv_to_str(tlv);
|
|
|
|
+ if (s) {
|
|
|
|
+ err = snd_config_string_add(comment, "tlv", s);
|
|
|
|
+ if (err < 0) {
|
|
|
|
+ error("snd_config_string_add: %s", snd_strerror(err));
|
|
|
|
+ return err;
|
|
|
|
+ }
|
|
|
|
+ free(s);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ err = snd_tlv_parse_dB_info(tlv, sizeof(tlv), &db);
|
|
|
|
+ if (err <= 0)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ snd_tlv_get_dB_range(db, snd_ctl_elem_info_get_min(info),
|
|
|
|
+ snd_ctl_elem_info_get_max(info),
|
|
|
|
+ &dbmin, &dbmax);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ return err;
|
|
|
|
+ snd_config_integer_add(comment, "dbmin", dbmin);
|
|
|
|
+ snd_config_integer_add(comment, "dbmax", dbmax);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *top)
|
|
|
|
{
|
|
|
|
snd_ctl_elem_value_t *ctl;
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -285,23 +325,11 @@ static int get_control(snd_ctl_t *handle
|
2007-10-29 12:26:03 +01:00
|
|
|
error("snd_config_string_add: %s", snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
- if (snd_ctl_elem_info_is_tlv_readable(info) &&
|
|
|
|
- snd_ctl_elem_info_is_tlv_writable(info)) {
|
2007-12-14 16:25:23 +01:00
|
|
|
- unsigned int tlv[MAX_USER_TLV_SIZE];
|
|
|
|
- err = snd_ctl_elem_tlv_read(handle, id, tlv, sizeof(tlv));
|
|
|
|
- if (err >= 0) {
|
|
|
|
- char *s = tlv_to_str(tlv);
|
|
|
|
- if (s) {
|
|
|
|
- err = snd_config_string_add(comment, "tlv", s);
|
|
|
|
- if (err < 0) {
|
|
|
|
- error("snd_config_string_add: %s", snd_strerror(err));
|
|
|
|
- return err;
|
|
|
|
- }
|
|
|
|
- free(s);
|
|
|
|
- }
|
|
|
|
- }
|
2007-10-29 12:26:03 +01:00
|
|
|
+ if (snd_ctl_elem_info_is_tlv_readable(info)) {
|
|
|
|
+ err = add_tlv_comments(handle, id, info, comment);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ return err;
|
2007-12-14 16:25:23 +01:00
|
|
|
}
|
|
|
|
-
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SND_CTL_ELEM_TYPE_INTEGER64:
|
|
|
|
@@ -651,6 +679,7 @@ static int config_bool(snd_config_t *n)
|
2007-10-29 12:26:03 +01:00
|
|
|
const char *str;
|
|
|
|
long val;
|
|
|
|
long long lval;
|
|
|
|
+
|
|
|
|
switch (snd_config_get_type(n)) {
|
|
|
|
case SND_CONFIG_TYPE_INTEGER:
|
|
|
|
snd_config_get_integer(n, &val);
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -665,6 +694,11 @@ static int config_bool(snd_config_t *n)
|
2007-10-29 12:26:03 +01:00
|
|
|
case SND_CONFIG_TYPE_STRING:
|
|
|
|
snd_config_get_string(n, &str);
|
|
|
|
break;
|
|
|
|
+ case SND_CONFIG_TYPE_COMPOUND:
|
|
|
|
+ if (!force_restore)
|
|
|
|
+ return -1;
|
|
|
|
+ n = snd_config_iterator_entry(snd_config_iterator_first(n));
|
|
|
|
+ return config_bool(n);
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -682,6 +716,7 @@ static int config_enumerated(snd_config_
|
2007-10-29 12:26:03 +01:00
|
|
|
long val;
|
|
|
|
long long lval;
|
|
|
|
unsigned int idx, items;
|
|
|
|
+
|
|
|
|
switch (snd_config_get_type(n)) {
|
|
|
|
case SND_CONFIG_TYPE_INTEGER:
|
|
|
|
snd_config_get_integer(n, &val);
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -692,6 +727,11 @@ static int config_enumerated(snd_config_
|
2007-10-29 12:26:03 +01:00
|
|
|
case SND_CONFIG_TYPE_STRING:
|
|
|
|
snd_config_get_string(n, &str);
|
|
|
|
break;
|
|
|
|
+ case SND_CONFIG_TYPE_COMPOUND:
|
|
|
|
+ if (!force_restore)
|
|
|
|
+ return -1;
|
|
|
|
+ n = snd_config_iterator_entry(snd_config_iterator_first(n));
|
|
|
|
+ return config_enumerated(n, handle, info);
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -708,6 +748,30 @@ static int config_enumerated(snd_config_
|
2007-10-29 12:26:03 +01:00
|
|
|
return idx;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int config_integer(snd_config_t *n, long *val)
|
|
|
|
+{
|
|
|
|
+ int err = snd_config_get_integer(n, val);
|
|
|
|
+ if (err < 0 && force_restore) {
|
|
|
|
+ if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND)
|
|
|
|
+ return err;
|
|
|
|
+ n = snd_config_iterator_entry(snd_config_iterator_first(n));
|
|
|
|
+ return config_integer(n, val);
|
|
|
|
+ }
|
|
|
|
+ return err;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int config_integer64(snd_config_t *n, long long *val)
|
|
|
|
+{
|
|
|
|
+ int err = snd_config_get_integer64(n, val);
|
|
|
|
+ if (err < 0 && force_restore) {
|
|
|
|
+ if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND)
|
|
|
|
+ return err;
|
|
|
|
+ n = snd_config_iterator_entry(snd_config_iterator_first(n));
|
|
|
|
+ return config_integer64(n, val);
|
|
|
|
+ }
|
|
|
|
+ return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int is_user_control(snd_config_t *conf)
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -729,6 +793,56 @@ static int is_user_control(snd_config_t
|
2007-10-29 12:26:03 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * get the item type from the given comment config
|
|
|
|
+ */
|
|
|
|
+static int get_comment_type(snd_config_t *n)
|
|
|
|
+{
|
|
|
|
+ const char *type;
|
|
|
|
+
|
|
|
|
+ if (snd_config_get_string(n, &type) < 0)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ if (strcmp(type, "BOOLEAN") == 0)
|
|
|
|
+ return SND_CTL_ELEM_TYPE_BOOLEAN;
|
|
|
|
+ else if (strcmp(type, "INTEGER") == 0)
|
|
|
|
+ return SND_CTL_ELEM_TYPE_INTEGER;
|
|
|
|
+ else if (strcmp(type, "ENUMERATED") == 0)
|
|
|
|
+ return SND_CTL_ELEM_TYPE_ENUMERATED;
|
|
|
|
+ else if (strcmp(type, "INTEGER64") == 0)
|
|
|
|
+ return SND_CTL_ELEM_TYPE_INTEGER;
|
|
|
|
+ else if (strcmp(type, "IEC958") == 0)
|
|
|
|
+ return SND_CTL_ELEM_TYPE_IEC958;
|
|
|
|
+ else
|
|
|
|
+ return -EINVAL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * get the value range from the given comment config
|
|
|
|
+ */
|
|
|
|
+static int get_comment_range(snd_config_t *n, int ctype,
|
|
|
|
+ long *imin, long *imax, long *istep)
|
|
|
|
+{
|
|
|
|
+ const char *s;
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ if (snd_config_get_string(n, &s) < 0)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ switch (ctype) {
|
|
|
|
+ case SND_CTL_ELEM_TYPE_INTEGER:
|
|
|
|
+ err = sscanf(s, "%li - %li (step %li)", imin, imax, istep);
|
|
|
|
+ if (err != 3) {
|
|
|
|
+ istep = 0;
|
|
|
|
+ err = sscanf(s, "%li - %li", imin, imax);
|
|
|
|
+ if (err != 2)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static int add_user_control(snd_ctl_t *handle, snd_ctl_elem_info_t *info, snd_config_t *conf)
|
|
|
|
{
|
|
|
|
snd_ctl_elem_id_t *id;
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -745,39 +859,20 @@ static int add_user_control(snd_ctl_t *h
|
2007-10-29 12:26:03 +01:00
|
|
|
tlv = NULL;
|
|
|
|
snd_config_for_each(i, next, conf) {
|
|
|
|
snd_config_t *n = snd_config_iterator_entry(i);
|
|
|
|
- const char *id, *type;
|
|
|
|
+ const char *id;
|
|
|
|
if (snd_config_get_id(n, &id) < 0)
|
|
|
|
continue;
|
|
|
|
if (strcmp(id, "type") == 0) {
|
|
|
|
- if ((err = snd_config_get_string(n, &type)) < 0)
|
|
|
|
- return -EINVAL;
|
|
|
|
- if (strcmp(type, "BOOLEAN") == 0)
|
|
|
|
- ctype = SND_CTL_ELEM_TYPE_BOOLEAN;
|
|
|
|
- else if (strcmp(type, "INTEGER") == 0)
|
|
|
|
- ctype = SND_CTL_ELEM_TYPE_INTEGER;
|
|
|
|
- else if (strcmp(type, "IEC958") == 0)
|
|
|
|
- ctype = SND_CTL_ELEM_TYPE_IEC958;
|
|
|
|
- else
|
|
|
|
- return -EINVAL;
|
|
|
|
+ err = get_comment_type(n);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ return err;
|
|
|
|
+ ctype = err;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (strcmp(id, "range") == 0) {
|
|
|
|
- const char *s;
|
|
|
|
- if ((err = snd_config_get_string(n, &s)) < 0)
|
|
|
|
- return -EINVAL;
|
|
|
|
- switch (ctype) {
|
|
|
|
- case SND_CTL_ELEM_TYPE_INTEGER:
|
|
|
|
- err = sscanf(s, "%li - %li (step %li)", &imin, &imax, &istep);
|
|
|
|
- if (err != 3) {
|
|
|
|
- istep = 0;
|
|
|
|
- err = sscanf(s, "%li - %li", &imin, &imax);
|
|
|
|
- if (err != 2)
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
+ err = get_comment_range(n, ctype, &imin, &imax, &istep);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ return err;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (strcmp(id, "count") == 0) {
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -831,6 +926,213 @@ static int add_user_control(snd_ctl_t *h
|
2007-10-29 12:26:03 +01:00
|
|
|
return snd_ctl_elem_info(handle, info);
|
|
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * look for a config node with the given item name
|
|
|
|
+ */
|
|
|
|
+static snd_config_t *search_comment_item(snd_config_t *conf, const char *name)
|
|
|
|
+{
|
|
|
|
+ snd_config_iterator_t i, next;
|
|
|
|
+ snd_config_for_each(i, next, conf) {
|
|
|
|
+ snd_config_t *n = snd_config_iterator_entry(i);
|
|
|
|
+ const char *id;
|
|
|
|
+ if (snd_config_get_id(n, &id) < 0)
|
|
|
|
+ continue;
|
|
|
|
+ if (strcmp(id, name) == 0)
|
|
|
|
+ return n;
|
|
|
|
+ }
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * check whether the config item has the same of compatible type
|
|
|
|
+ */
|
|
|
|
+static int check_comment_type(snd_config_t *conf, int type)
|
|
|
|
+{
|
|
|
|
+ snd_config_t *n = search_comment_item(conf, "type");
|
|
|
|
+ int ctype;
|
|
|
|
+
|
|
|
|
+ if (!n)
|
|
|
|
+ return 0; /* not defined */
|
|
|
|
+ ctype = get_comment_type(n);
|
|
|
|
+ if (ctype == type)
|
|
|
|
+ return 0;
|
|
|
|
+ if ((ctype == SND_CTL_ELEM_TYPE_BOOLEAN ||
|
|
|
|
+ ctype == SND_CTL_ELEM_TYPE_INTEGER ||
|
|
|
|
+ ctype == SND_CTL_ELEM_TYPE_INTEGER64 ||
|
|
|
|
+ ctype == SND_CTL_ELEM_TYPE_ENUMERATED) &&
|
|
|
|
+ (type == SND_CTL_ELEM_TYPE_BOOLEAN ||
|
|
|
|
+ type == SND_CTL_ELEM_TYPE_INTEGER ||
|
|
|
|
+ type == SND_CTL_ELEM_TYPE_INTEGER64 ||
|
|
|
|
+ type == SND_CTL_ELEM_TYPE_ENUMERATED))
|
|
|
|
+ return 0; /* OK, compatible */
|
|
|
|
+ return -EINVAL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * convert from an old value to a new value with the same dB level
|
|
|
|
+ */
|
|
|
|
+static int convert_to_new_db(snd_config_t *value, long omin, long omax,
|
|
|
|
+ long nmin, long nmax,
|
|
|
|
+ long odbmin, long odbmax,
|
|
|
|
+ long ndbmin, long ndbmax)
|
|
|
|
+{
|
|
|
|
+ long val;
|
|
|
|
+ if (config_integer(value, &val) < 0)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ if (val < omin || val > omax)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ val = ((val - omin) * (odbmax - odbmin)) / (omax - omin) + odbmin;
|
|
|
|
+ if (val < ndbmin)
|
|
|
|
+ val = ndbmin;
|
|
|
|
+ else if (val > ndbmax)
|
|
|
|
+ val = ndbmax;
|
|
|
|
+ val = ((val - ndbmin) * (nmax - nmin)) / (ndbmax - ndbmin) + nmin;
|
|
|
|
+ return snd_config_set_integer(value, val);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * compare the current value range with the old range in comments.
|
|
|
|
+ * also, if dB information is available, try to compare them.
|
|
|
|
+ * if any change occurs, try to keep the same dB level.
|
|
|
|
+ */
|
|
|
|
+static int check_comment_range(snd_ctl_t *handle, snd_config_t *conf,
|
|
|
|
+ snd_ctl_elem_info_t *info, snd_config_t *value)
|
|
|
|
+{
|
|
|
|
+ snd_config_t *n;
|
|
|
|
+ long omin, omax, ostep;
|
|
|
|
+ long nmin, nmax;
|
|
|
|
+ long odbmin, odbmax;
|
|
|
|
+ long ndbmin, ndbmax;
|
|
|
|
+ snd_ctl_elem_id_t *id;
|
|
|
|
+
|
|
|
|
+ n = search_comment_item(conf, "range");
|
|
|
|
+ if (!n)
|
|
|
|
+ return 0;
|
|
|
|
+ if (get_comment_range(n, SND_CTL_ELEM_TYPE_INTEGER,
|
|
|
|
+ &omin, &omax, &ostep) < 0)
|
|
|
|
+ return 0;
|
|
|
|
+ nmin = snd_ctl_elem_info_get_min(info);
|
|
|
|
+ nmax = snd_ctl_elem_info_get_max(info);
|
|
|
|
+ if (omin != nmin && omax != nmax) {
|
|
|
|
+ /* Hey, the range mismatches */
|
|
|
|
+ if (!force_restore)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ if (omin >= omax || nmin >= nmax)
|
|
|
|
+ return 0; /* invalid values */
|
|
|
|
+
|
|
|
|
+ n = search_comment_item(conf, "dbmin");
|
|
|
|
+ if (!n)
|
|
|
|
+ return 0;
|
|
|
|
+ if (config_integer(n, &odbmin) < 0)
|
|
|
|
+ return 0;
|
|
|
|
+ n = search_comment_item(conf, "dbmax");
|
|
|
|
+ if (!n)
|
|
|
|
+ return 0;
|
|
|
|
+ if (config_integer(n, &odbmax) < 0)
|
|
|
|
+ return 0;
|
|
|
|
+ if (odbmin >= odbmax)
|
|
|
|
+ return 0; /* invalid values */
|
|
|
|
+ snd_ctl_elem_id_alloca(&id);
|
|
|
|
+ snd_ctl_elem_info_get_id(info, id);
|
|
|
|
+ if (snd_ctl_get_dB_range(handle, id, &ndbmin, &ndbmax) < 0)
|
|
|
|
+ return 0;
|
|
|
|
+ if (ndbmin >= ndbmax)
|
|
|
|
+ return 0; /* invalid values */
|
|
|
|
+ if (omin == nmin && omax == nmax &&
|
|
|
|
+ odbmin == ndbmin && odbmax == ndbmax)
|
|
|
|
+ return 0; /* OK, identical one */
|
|
|
|
+
|
|
|
|
+ /* Let's guess the current value from dB range */
|
|
|
|
+ if (snd_config_get_type(value) == SND_CONFIG_TYPE_COMPOUND) {
|
|
|
|
+ snd_config_iterator_t i, next;
|
|
|
|
+ snd_config_for_each(i, next, value) {
|
|
|
|
+ snd_config_t *n = snd_config_iterator_entry(i);
|
|
|
|
+ convert_to_new_db(n, omin, omax, nmin, nmax,
|
|
|
|
+ odbmin, odbmax, ndbmin, ndbmax);
|
|
|
|
+ }
|
|
|
|
+ } else
|
|
|
|
+ convert_to_new_db(value, omin, omax, nmin, nmax,
|
|
|
|
+ odbmin, odbmax, ndbmin, ndbmax);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int restore_config_value(snd_ctl_t *handle, snd_ctl_elem_info_t *info,
|
|
|
|
+ snd_ctl_elem_iface_t type,
|
|
|
|
+ snd_config_t *value,
|
|
|
|
+ snd_ctl_elem_value_t *ctl, int idx)
|
|
|
|
+{
|
|
|
|
+ long val;
|
|
|
|
+ long long lval;
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ switch (type) {
|
|
|
|
+ case SND_CTL_ELEM_TYPE_BOOLEAN:
|
|
|
|
+ val = config_bool(value);
|
|
|
|
+ if (val >= 0) {
|
|
|
|
+ snd_ctl_elem_value_set_boolean(ctl, idx, val);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case SND_CTL_ELEM_TYPE_INTEGER:
|
|
|
|
+ err = config_integer(value, &val);
|
|
|
|
+ if (err == 0) {
|
|
|
|
+ snd_ctl_elem_value_set_integer(ctl, idx, val);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case SND_CTL_ELEM_TYPE_INTEGER64:
|
|
|
|
+ err = config_integer64(value, &lval);
|
|
|
|
+ if (err == 0) {
|
|
|
|
+ snd_ctl_elem_value_set_integer64(ctl, idx, lval);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case SND_CTL_ELEM_TYPE_ENUMERATED:
|
|
|
|
+ val = config_enumerated(value, handle, info);
|
|
|
|
+ if (val >= 0) {
|
|
|
|
+ snd_ctl_elem_value_set_enumerated(ctl, idx, val);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case SND_CTL_ELEM_TYPE_BYTES:
|
|
|
|
+ case SND_CTL_ELEM_TYPE_IEC958:
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ error("Unknow control type: %d", type);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int restore_config_value2(snd_ctl_t *handle, snd_ctl_elem_info_t *info,
|
|
|
|
+ snd_ctl_elem_iface_t type,
|
|
|
|
+ snd_config_t *value,
|
|
|
|
+ snd_ctl_elem_value_t *ctl, int idx,
|
|
|
|
+ unsigned int numid)
|
|
|
|
+{
|
|
|
|
+ int err = restore_config_value(handle, info, type, value, ctl, idx);
|
|
|
|
+ long val;
|
|
|
|
+
|
|
|
|
+ if (err != 0)
|
|
|
|
+ return err;
|
|
|
|
+ switch (type) {
|
|
|
|
+ case SND_CTL_ELEM_TYPE_BYTES:
|
|
|
|
+ case SND_CTL_ELEM_TYPE_IEC958:
|
|
|
|
+ err = snd_config_get_integer(value, &val);
|
|
|
|
+ if (err < 0 || val < 0 || val > 255) {
|
|
|
|
+ error("bad control.%d.value.%d content", numid, idx);
|
|
|
|
+ return force_restore ? 0 : -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ snd_ctl_elem_value_set_byte(ctl, idx, val);
|
|
|
|
+ return 1;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static int set_control(snd_ctl_t *handle, snd_config_t *control)
|
|
|
|
{
|
|
|
|
snd_ctl_elem_value_t *ctl;
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -852,8 +1154,6 @@ static int set_control(snd_ctl_t *handle
|
2007-10-29 12:26:03 +01:00
|
|
|
long index = -1;
|
|
|
|
snd_config_t *value = NULL;
|
|
|
|
snd_config_t *comment = NULL;
|
|
|
|
- long val;
|
|
|
|
- long long lval;
|
|
|
|
unsigned int idx;
|
|
|
|
int err;
|
|
|
|
char *set;
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -994,56 +1294,28 @@ static int set_control(snd_ctl_t *handle
|
2007-10-29 12:26:03 +01:00
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
-#if 0
|
|
|
|
if (comment) {
|
|
|
|
- check_comment_type(comment, type);
|
|
|
|
- if (type == SND_CTL_ELEM_TYPE_INTEGER ||
|
|
|
|
- type == SND_CTL_ELEM_TYPE_INTEGER64)
|
|
|
|
- check_comment_range(comment, info);
|
|
|
|
+ if (check_comment_type(comment, type) < 0)
|
|
|
|
+ error("incompatible field type for control #%d", numid);
|
|
|
|
+ if (type == SND_CTL_ELEM_TYPE_INTEGER) {
|
|
|
|
+ if (check_comment_range(handle, comment, info, value) < 0) {
|
|
|
|
+ error("value range mismatch for control #%d",
|
|
|
|
+ numid);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
-#endif
|
|
|
|
|
|
|
|
if (!snd_ctl_elem_info_is_writable(info))
|
|
|
|
return 0;
|
|
|
|
snd_ctl_elem_value_set_numid(ctl, numid1);
|
|
|
|
|
|
|
|
if (count == 1) {
|
|
|
|
- switch (type) {
|
|
|
|
- case SND_CTL_ELEM_TYPE_BOOLEAN:
|
|
|
|
- val = config_bool(value);
|
|
|
|
- if (val >= 0) {
|
|
|
|
- snd_ctl_elem_value_set_boolean(ctl, 0, val);
|
|
|
|
- goto _ok;
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case SND_CTL_ELEM_TYPE_INTEGER:
|
|
|
|
- err = snd_config_get_integer(value, &val);
|
|
|
|
- if (err == 0) {
|
|
|
|
- snd_ctl_elem_value_set_integer(ctl, 0, val);
|
|
|
|
- goto _ok;
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case SND_CTL_ELEM_TYPE_INTEGER64:
|
|
|
|
- err = snd_config_get_integer64(value, &lval);
|
|
|
|
- if (err == 0) {
|
|
|
|
- snd_ctl_elem_value_set_integer64(ctl, 0, lval);
|
|
|
|
- goto _ok;
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case SND_CTL_ELEM_TYPE_ENUMERATED:
|
|
|
|
- val = config_enumerated(value, handle, info);
|
|
|
|
- if (val >= 0) {
|
|
|
|
- snd_ctl_elem_value_set_enumerated(ctl, 0, val);
|
|
|
|
- goto _ok;
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case SND_CTL_ELEM_TYPE_BYTES:
|
|
|
|
- case SND_CTL_ELEM_TYPE_IEC958:
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- error("Unknow control type: %d", type);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
+ err = restore_config_value(handle, info, type, value, ctl, 0);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ return err;
|
|
|
|
+ if (err > 0)
|
|
|
|
+ goto _ok;
|
|
|
|
}
|
|
|
|
switch (type) {
|
|
|
|
case SND_CTL_ELEM_TYPE_BYTES:
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -1080,8 +1352,17 @@ static int set_control(snd_ctl_t *handle
|
2007-10-29 12:26:03 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (snd_config_get_type(value) != SND_CONFIG_TYPE_COMPOUND) {
|
|
|
|
- error("bad control.%d.value type", numid);
|
|
|
|
- return -EINVAL;
|
|
|
|
+ if (!force_restore) {
|
|
|
|
+ error("bad control.%d.value type", numid);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ for (idx = 0; idx < count; ++idx) {
|
|
|
|
+ err = restore_config_value2(handle, info, type, value,
|
|
|
|
+ ctl, idx, numid);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ return err;
|
|
|
|
+ }
|
|
|
|
+ goto _ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
set = (char*) alloca(count);
|
2007-12-14 16:25:23 +01:00
|
|
|
@@ -1095,59 +1376,22 @@ static int set_control(snd_ctl_t *handle
|
2007-10-29 12:26:03 +01:00
|
|
|
if (idx < 0 || idx >= count ||
|
|
|
|
set[idx]) {
|
|
|
|
error("bad control.%d.value index", numid);
|
|
|
|
- return -EINVAL;
|
|
|
|
+ if (!force_restore)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ continue;
|
|
|
|
}
|
|
|
|
- switch (type) {
|
|
|
|
- case SND_CTL_ELEM_TYPE_BOOLEAN:
|
|
|
|
- val = config_bool(n);
|
|
|
|
- if (val < 0) {
|
|
|
|
- error("bad control.%d.value.%d content", numid, idx);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
- snd_ctl_elem_value_set_boolean(ctl, idx, val);
|
|
|
|
- break;
|
|
|
|
- case SND_CTL_ELEM_TYPE_INTEGER:
|
|
|
|
- err = snd_config_get_integer(n, &val);
|
|
|
|
- if (err < 0) {
|
|
|
|
- error("bad control.%d.value.%d content", numid, idx);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
- snd_ctl_elem_value_set_integer(ctl, idx, val);
|
|
|
|
- break;
|
|
|
|
- case SND_CTL_ELEM_TYPE_INTEGER64:
|
|
|
|
- err = snd_config_get_integer64(n, &lval);
|
|
|
|
- if (err < 0) {
|
|
|
|
- error("bad control.%d.value.%d content", numid, idx);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
- snd_ctl_elem_value_set_integer64(ctl, idx, lval);
|
|
|
|
- break;
|
|
|
|
- case SND_CTL_ELEM_TYPE_ENUMERATED:
|
|
|
|
- val = config_enumerated(n, handle, info);
|
|
|
|
- if (val < 0) {
|
|
|
|
- error("bad control.%d.value.%d content", numid, idx);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
- snd_ctl_elem_value_set_enumerated(ctl, idx, val);
|
|
|
|
- break;
|
|
|
|
- case SND_CTL_ELEM_TYPE_BYTES:
|
|
|
|
- case SND_CTL_ELEM_TYPE_IEC958:
|
|
|
|
- err = snd_config_get_integer(n, &val);
|
|
|
|
- if (err < 0 || val < 0 || val > 255) {
|
|
|
|
- error("bad control.%d.value.%d content", numid, idx);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
- snd_ctl_elem_value_set_byte(ctl, idx, val);
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- set[idx] = 1;
|
2007-12-14 16:25:23 +01:00
|
|
|
+ err = restore_config_value2(handle, info, type, n,
|
2007-10-29 12:26:03 +01:00
|
|
|
+ ctl, idx, numid);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ return err;
|
|
|
|
+ if (err > 0)
|
|
|
|
+ set[idx] = 1;
|
|
|
|
}
|
|
|
|
for (idx = 0; idx < count; ++idx) {
|
|
|
|
if (!set[idx]) {
|
|
|
|
error("control.%d.value.%d is not specified", numid, idx);
|
|
|
|
- return -EINVAL;
|
|
|
|
+ if (!force_restore)
|
|
|
|
+ return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-14 16:25:23 +01:00
|
|
|
diff -r 3b8e4ee4363e aplay/aplay.c
|
|
|
|
--- a/aplay/aplay.c Mon Oct 15 10:36:47 2007 +0200
|
|
|
|
+++ b/aplay/aplay.c Fri Dec 14 15:35:34 2007 +0100
|
|
|
|
@@ -1462,7 +1462,9 @@ static void voc_pcm_flush(void)
|
|
|
|
if (pcm_write(audiobuf, b) != (ssize_t)b)
|
|
|
|
error(_("voc_pcm_flush error"));
|
|
|
|
}
|
|
|
|
+ snd_pcm_nonblock(handle, 0);
|
|
|
|
snd_pcm_drain(handle);
|
|
|
|
+ snd_pcm_nonblock(handle, nonblock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void voc_play(int fd, int ofs, char *name)
|
|
|
|
@@ -1988,7 +1990,9 @@ void playback_go(int fd, size_t loaded,
|
|
|
|
written += r;
|
|
|
|
l = 0;
|
|
|
|
}
|
|
|
|
+ snd_pcm_nonblock(handle, 0);
|
|
|
|
snd_pcm_drain(handle);
|
|
|
|
+ snd_pcm_nonblock(handle, nonblock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -2227,7 +2231,9 @@ void playbackv_go(int* fds, unsigned int
|
|
|
|
r = r * bits_per_frame / 8;
|
|
|
|
count -= r;
|
|
|
|
}
|
|
|
|
+ snd_pcm_nonblock(handle, 0);
|
|
|
|
snd_pcm_drain(handle);
|
|
|
|
+ snd_pcm_nonblock(handle, nonblock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void capturev_go(int* fds, unsigned int channels, off64_t count, int rtype, char **names)
|
2007-10-29 12:26:03 +01:00
|
|
|
diff -r 3b8e4ee4363e configure.in
|
|
|
|
--- a/configure.in Mon Oct 15 10:36:47 2007 +0200
|
2007-12-14 16:25:23 +01:00
|
|
|
+++ b/configure.in Fri Dec 14 15:35:34 2007 +0100
|
2007-10-29 12:26:03 +01:00
|
|
|
@@ -27,7 +27,9 @@ dnl AC_PROG_CXX
|
|
|
|
dnl AC_PROG_CXX
|
|
|
|
AC_PROG_INSTALL
|
|
|
|
AC_PROG_LN_S
|
|
|
|
-AM_PATH_ALSA(1.0.12)
|
|
|
|
+AM_PATH_ALSA(1.0.15)
|
|
|
|
+AC_CHECK_FUNC(snd_tlv_get_dB_range,,
|
|
|
|
+ AC_ERROR([No TLV support code in alsa-lib]))
|
|
|
|
|
|
|
|
AC_ARG_ENABLE(alsamixer,
|
|
|
|
[ --disable-alsamixer Disable alsamixer compilation],
|
2007-12-14 16:25:23 +01:00
|
|
|
diff -r 3b8e4ee4363e iecset/iecset.c
|
|
|
|
--- a/iecset/iecset.c Mon Oct 15 10:36:47 2007 +0200
|
|
|
|
+++ b/iecset/iecset.c Fri Dec 14 15:35:34 2007 +0100
|
|
|
|
@@ -308,7 +308,7 @@ int main(int argc, char **argv)
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
i = atoi(optarg);
|
|
|
|
- if (i < 0 || i >= 7) {
|
|
|
|
+ if (i < 0 || i >= 32) {
|
|
|
|
fprintf(stderr, "invalid card index %d\n", i);
|
|
|
|
return 1;
|
|
|
|
}
|
2007-10-29 12:26:03 +01:00
|
|
|
diff -r 3b8e4ee4363e seq/aseqnet/aseqnet.c
|
|
|
|
--- a/seq/aseqnet/aseqnet.c Mon Oct 15 10:36:47 2007 +0200
|
2007-12-14 16:25:23 +01:00
|
|
|
+++ b/seq/aseqnet/aseqnet.c Fri Dec 14 15:35:34 2007 +0100
|
2007-10-29 12:26:03 +01:00
|
|
|
@@ -26,6 +26,7 @@
|
|
|
|
#include <alsa/asoundlib.h>
|
|
|
|
#include <getopt.h>
|
|
|
|
#include <signal.h>
|
|
|
|
+#include <assert.h>
|
|
|
|
#include "aconfig.h"
|
|
|
|
#include "gettext.h"
|
|
|
|
|
2007-12-14 16:25:23 +01:00
|
|
|
diff -r 3b8e4ee4363e speaker-test/speaker-test.c
|
|
|
|
--- a/speaker-test/speaker-test.c Mon Oct 15 10:36:47 2007 +0200
|
|
|
|
+++ b/speaker-test/speaker-test.c Fri Dec 14 15:35:34 2007 +0100
|
|
|
|
@@ -276,28 +276,28 @@ static int set_hwparams(snd_pcm_t *handl
|
|
|
|
/* choose all parameters */
|
|
|
|
err = snd_pcm_hw_params_any(handle, params);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Broken configuration for playback: no configurations available: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Broken configuration for playback: no configurations available: %s\n"), snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set the interleaved read/write format */
|
|
|
|
err = snd_pcm_hw_params_set_access(handle, params, access);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Access type not available for playback: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Access type not available for playback: %s\n"), snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set the sample format */
|
|
|
|
err = snd_pcm_hw_params_set_format(handle, params, format);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Sample format not available for playback: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Sample format not available for playback: %s\n"), snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set the count of channels */
|
|
|
|
err = snd_pcm_hw_params_set_channels(handle, params, channels);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Channels count (%i) not available for playbacks: %s\n"), channels, snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Channels count (%i) not available for playbacks: %s\n"), channels, snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -305,12 +305,12 @@ static int set_hwparams(snd_pcm_t *handl
|
|
|
|
rrate = rate;
|
|
|
|
err = snd_pcm_hw_params_set_rate(handle, params, rate, 0);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Rate %iHz not available for playback: %s\n"), rate, snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Rate %iHz not available for playback: %s\n"), rate, snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rrate != rate) {
|
|
|
|
- printf(_("Rate doesn't match (requested %iHz, get %iHz, err %d)\n"), rate, rrate, err);
|
|
|
|
+ fprintf(stderr, _("Rate doesn't match (requested %iHz, get %iHz, err %d)\n"), rate, rrate, err);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -326,7 +326,7 @@ static int set_hwparams(snd_pcm_t *handl
|
|
|
|
printf(_("Requested period time %u us\n"), period_time);
|
|
|
|
err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, NULL);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Unable to set period time %u us for playback: %s\n"),
|
|
|
|
+ fprintf(stderr, _("Unable to set period time %u us for playback: %s\n"),
|
|
|
|
period_time, snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
@@ -335,7 +335,7 @@ static int set_hwparams(snd_pcm_t *handl
|
|
|
|
printf(_("Requested buffer time %u us\n"), buffer_time);
|
|
|
|
err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, NULL);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Unable to set buffer time %u us for playback: %s\n"),
|
|
|
|
+ fprintf(stderr, _("Unable to set buffer time %u us for playback: %s\n"),
|
|
|
|
buffer_time, snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
@@ -347,7 +347,7 @@ static int set_hwparams(snd_pcm_t *handl
|
|
|
|
printf(_("Using max buffer size %lu\n"), buffer_size);
|
|
|
|
err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_size);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Unable to set buffer size %lu for playback: %s\n"),
|
|
|
|
+ fprintf(stderr, _("Unable to set buffer size %lu for playback: %s\n"),
|
|
|
|
buffer_size, snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
@@ -356,7 +356,7 @@ static int set_hwparams(snd_pcm_t *handl
|
|
|
|
printf(_("Periods = %u\n"), nperiods);
|
|
|
|
err = snd_pcm_hw_params_set_periods_near(handle, params, &nperiods, NULL);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Unable to set nperiods %u for playback: %s\n"),
|
|
|
|
+ fprintf(stderr, _("Unable to set nperiods %u for playback: %s\n"),
|
|
|
|
nperiods, snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
@@ -366,14 +366,14 @@ static int set_hwparams(snd_pcm_t *handl
|
|
|
|
printf(_("was set period_size = %lu\n"),period_size);
|
|
|
|
printf(_("was set buffer_size = %lu\n"),buffer_size);
|
|
|
|
if (2*period_size > buffer_size) {
|
|
|
|
- printf(_("buffer to small, could not use\n"));
|
|
|
|
- return err;
|
|
|
|
+ fprintf(stderr, _("buffer to small, could not use\n"));
|
|
|
|
+ return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* write the parameters to device */
|
|
|
|
err = snd_pcm_hw_params(handle, params);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Unable to set hw params for playback: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Unable to set hw params for playback: %s\n"), snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -386,35 +386,35 @@ static int set_swparams(snd_pcm_t *handl
|
|
|
|
/* get the current swparams */
|
|
|
|
err = snd_pcm_sw_params_current(handle, swparams);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Unable to determine current swparams for playback: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Unable to determine current swparams for playback: %s\n"), snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* start the transfer when a buffer is full */
|
|
|
|
err = snd_pcm_sw_params_set_start_threshold(handle, swparams, buffer_size);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Unable to set start threshold mode for playback: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Unable to set start threshold mode for playback: %s\n"), snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* allow the transfer when at least period_size frames can be processed */
|
|
|
|
err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_size);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Unable to set avail min for playback: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Unable to set avail min for playback: %s\n"), snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* align all transfers to 1 sample */
|
|
|
|
err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Unable to set transfer align for playback: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Unable to set transfer align for playback: %s\n"), snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* write the parameters to the playback device */
|
|
|
|
err = snd_pcm_sw_params(handle, swparams);
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Unable to set sw params for playback: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Unable to set sw params for playback: %s\n"), snd_strerror(err));
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -429,7 +429,7 @@ static int xrun_recovery(snd_pcm_t *hand
|
|
|
|
if (err == -EPIPE) { /* under-run */
|
|
|
|
err = snd_pcm_prepare(handle);
|
|
|
|
if (err < 0)
|
|
|
|
- printf(_("Can't recovery from underrun, prepare failed: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Can't recovery from underrun, prepare failed: %s\n"), snd_strerror(err));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (err == -ESTRPIPE) {
|
|
|
|
@@ -440,7 +440,7 @@ static int xrun_recovery(snd_pcm_t *hand
|
|
|
|
if (err < 0) {
|
|
|
|
err = snd_pcm_prepare(handle);
|
|
|
|
if (err < 0)
|
|
|
|
- printf(_("Can't recovery from suspend, prepare failed: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Can't recovery from suspend, prepare failed: %s\n"), snd_strerror(err));
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
@@ -648,9 +648,9 @@ static int write_buffer(snd_pcm_t *handl
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Write error: %d,%s\n"), err, snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Write error: %d,%s\n"), err, snd_strerror(err));
|
|
|
|
if (xrun_recovery(handle, err) < 0) {
|
|
|
|
- printf(_("xrun_recovery failed: %d,%s\n"), err, snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("xrun_recovery failed: %d,%s\n"), err, snd_strerror(err));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
break; /* skip one period */
|
|
|
|
@@ -683,6 +683,9 @@ static int write_loop(snd_pcm_t *handle,
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ if (periods <= 0)
|
|
|
|
+ periods = 1;
|
|
|
|
|
|
|
|
for(n = 0; n < periods; n++) {
|
|
|
|
if (test_type == TEST_PINK_NOISE)
|
|
|
|
@@ -847,7 +850,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
speaker = speaker < 1 ? 0 : speaker;
|
|
|
|
speaker = speaker > channels ? 0 : speaker;
|
|
|
|
if (speaker==0) {
|
|
|
|
- printf(_("Invalid parameter for -s option.\n"));
|
|
|
|
+ fprintf(stderr, _("Invalid parameter for -s option.\n"));
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
@@ -858,7 +861,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
wav_file_dir = optarg;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
- printf(_("Unknown option '%c'\n"), c);
|
|
|
|
+ fprintf(stderr, _("Unknown option '%c'\n"), c);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
@@ -908,7 +911,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
initialize_pink_noise(&pink, 16);
|
|
|
|
|
|
|
|
if (frames == NULL) {
|
|
|
|
- printf(_("No enough memory\n"));
|
|
|
|
+ fprintf(stderr, _("No enough memory\n"));
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
if (speaker==0) {
|
|
|
|
@@ -939,7 +942,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
err = write_loop(handle, channel, ((rate*3)/period_size), frames);
|
|
|
|
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Transfer failed: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Transfer failed: %s\n"), snd_strerror(err));
|
|
|
|
free(frames);
|
|
|
|
snd_pcm_close(handle);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
@@ -961,7 +964,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
err = write_loop(handle, speaker-1, ((rate*5)/period_size), frames);
|
|
|
|
|
|
|
|
if (err < 0) {
|
|
|
|
- printf(_("Transfer failed: %s\n"), snd_strerror(err));
|
|
|
|
+ fprintf(stderr, _("Transfer failed: %s\n"), snd_strerror(err));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|