diff --git a/0001-alsactl-use-snd_config_imake-functions.patch b/0001-alsactl-use-snd_config_imake-functions.patch new file mode 100644 index 0000000..d775da8 --- /dev/null +++ b/0001-alsactl-use-snd_config_imake-functions.patch @@ -0,0 +1,332 @@ +From e509df69a5100df28921980362488f6947df0aae Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +Date: Wed, 26 May 2010 10:07:47 +0200 +Subject: [PATCH 01/13] alsactl: use snd_config_imake* functions + +To save a call to snd_config_set_xxx, replace the calls to +snd_config_make_xxx with snd_config_imake_xxx. + +Signed-off-by: Clemens Ladisch +--- + alsactl/alsactl.h | 10 ++++---- + alsactl/state.c | 43 ++++++++++++---------------------------- + alsactl/utils.c | 6 +---- + configure.in | 2 +- + seq/aconnect/aconnect.c | 49 ++++++++++++++++++++++++++++++++-------------- + 5 files changed, 54 insertions(+), 56 deletions(-) + +diff --git a/alsactl/alsactl.h b/alsactl/alsactl.h +index be90efb..89ad295 100644 +--- a/alsactl/alsactl.h ++++ b/alsactl/alsactl.h +@@ -34,16 +34,16 @@ extern char *statefile; + + #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) + #define cerror(cond, ...) do {\ +- if (cond || debugflag) { \ +- fprintf(stderr, "%s%s: %s:%d: ", debugflag ? "WARNING: " : "", command, __FUNCTION__, __LINE__); \ ++ if (cond) { \ ++ fprintf(stderr, "%s: %s:%d: ", command, __FUNCTION__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + putc('\n', stderr); \ + } \ + } while (0) + #else + #define cerror(cond, args...) do {\ +- if (cond || debugflag) { \ +- fprintf(stderr, "%s%s: %s:%d: ", debugflag ? "WARNING: " : "", command, __FUNCTION__, __LINE__); \ ++ if (cond) { \ ++ fprintf(stderr, "%s: %s:%d: ", command, __FUNCTION__, __LINE__); \ + fprintf(stderr, ##args); \ + putc('\n', stderr); \ + } \ +@@ -78,7 +78,7 @@ int generate_names(const char *cfgfile); + int file_map(const char *filename, char **buf, size_t *bufsize); + void file_unmap(void *buf, size_t bufsize); + size_t line_width(const char *buf, size_t bufsize, size_t pos); +-void initfailed(int cardnumber, const char *reason, int exitcode); ++void initfailed(int cardnumber, const char *reason); + + static inline int hextodigit(int c) + { +diff --git a/alsactl/state.c b/alsactl/state.c +index e70c6f9..a9ffeea 100644 +--- a/alsactl/state.c ++++ b/alsactl/state.c +@@ -58,7 +58,7 @@ static int snd_config_integer_add(snd_config_t *father, char *id, long integer) + { + int err; + snd_config_t *leaf; +- err = snd_config_make_integer(&leaf, id); ++ err = snd_config_imake_integer(&leaf, id, integer); + if (err < 0) + return err; + err = snd_config_add(father, leaf); +@@ -66,11 +66,6 @@ static int snd_config_integer_add(snd_config_t *father, char *id, long integer) + snd_config_delete(leaf); + return err; + } +- err = snd_config_set_integer(leaf, integer); +- if (err < 0) { +- snd_config_delete(leaf); +- return err; +- } + return 0; + } + +@@ -78,7 +73,7 @@ static int snd_config_integer64_add(snd_config_t *father, char *id, long long in + { + int err; + snd_config_t *leaf; +- err = snd_config_make_integer64(&leaf, id); ++ err = snd_config_imake_integer64(&leaf, id, integer); + if (err < 0) + return err; + err = snd_config_add(father, leaf); +@@ -86,11 +81,6 @@ static int snd_config_integer64_add(snd_config_t *father, char *id, long long in + snd_config_delete(leaf); + return err; + } +- err = snd_config_set_integer64(leaf, integer); +- if (err < 0) { +- snd_config_delete(leaf); +- return err; +- } + return 0; + } + +@@ -98,7 +88,7 @@ static int snd_config_string_add(snd_config_t *father, const char *id, const cha + { + int err; + snd_config_t *leaf; +- err = snd_config_make_string(&leaf, id); ++ err = snd_config_imake_string(&leaf, id, string); + if (err < 0) + return err; + err = snd_config_add(father, leaf); +@@ -106,11 +96,6 @@ static int snd_config_string_add(snd_config_t *father, const char *id, const cha + snd_config_delete(leaf); + return err; + } +- err = snd_config_set_string(leaf, string); +- if (err < 0) { +- snd_config_delete(leaf); +- return err; +- } + return 0; + } + +@@ -1117,6 +1102,7 @@ static int restore_config_value2(snd_ctl_t *handle, snd_ctl_elem_info_t *info, + } + snd_ctl_elem_value_set_byte(ctl, idx, val); + return 1; ++ break; + default: + break; + } +@@ -1403,7 +1389,6 @@ static int set_controls(int card, snd_config_t *top, int doit) + snd_ctl_card_info_alloca(&info); + + sprintf(name, "hw:%d", card); +- dbg("device='%s', doit=%i", name, doit); + err = snd_ctl_open(&handle, name, 0); + if (err < 0) { + error("snd_ctl_open error: %s", snd_strerror(err)); +@@ -1415,7 +1400,6 @@ static int set_controls(int card, snd_config_t *top, int doit) + goto _close; + } + id = snd_ctl_card_info_get_id(info); +- dbg("card-info-id: '%s'", id); + err = snd_config_searchv(top, &control, "state", id, "control", 0); + if (err < 0) { + if (force_restore) { +@@ -1441,25 +1425,24 @@ static int set_controls(int card, snd_config_t *top, int doit) + goto _close; + } + +- dbg("maxnumid=%i", maxnumid); + /* check if we have additional controls in driver */ + /* in this case we should go through init procedure */ + if (!doit && maxnumid >= 0) { ++ snd_ctl_elem_id_t *id; + snd_ctl_elem_info_t *info; ++ snd_ctl_elem_id_alloca(&id); + snd_ctl_elem_info_alloca(&info); + snd_ctl_elem_info_set_numid(info, maxnumid+1); + if (snd_ctl_elem_info(handle, info) == 0) { + /* not very informative */ + /* but value is used for check only */ + err = -EAGAIN; +- dbg("more controls than maxnumid?"); + goto _close; + } + } + + _close: + snd_ctl_close(handle); +- dbg("result code: %i", err); + return err; + } + +@@ -1584,9 +1567,9 @@ int load_state(const char *file, const char *initfile, const char *cardname, + err = init(initfile, cardname1); + if (err < 0) { + finalerr = err; +- initfailed(card, "init", err); ++ initfailed(card, "init"); + } +- initfailed(card, "restore", -ENOENT); ++ initfailed(card, "restore"); + } + if (first) + finalerr = 0; /* no cards, no error code */ +@@ -1619,14 +1602,14 @@ int load_state(const char *file, const char *initfile, const char *cardname, + sprintf(cardname1, "%i", card); + err = init(initfile, cardname1); + if (err < 0) { +- initfailed(card, "init", err); ++ initfailed(card, "init"); + finalerr = err; + } + } + if ((err = set_controls(card, config, 1))) { + if (!force_restore) + finalerr = err; +- initfailed(card, "restore", err); ++ initfailed(card, "restore"); + } + } + } else { +@@ -1641,12 +1624,12 @@ int load_state(const char *file, const char *initfile, const char *cardname, + if (do_init && set_controls(cardno, config, 0)) { + err = init(initfile, cardname); + if (err < 0) { +- initfailed(cardno, "init", err); +- finalerr = err; ++ initfailed(cardno, "init"); ++ return err; + } + } + if ((err = set_controls(cardno, config, 1))) { +- initfailed(cardno, "restore", err); ++ initfailed(cardno, "restore"); + if (!force_restore) + return err; + } +diff --git a/alsactl/utils.c b/alsactl/utils.c +index a27eb6e..ab4dbd4 100644 +--- a/alsactl/utils.c ++++ b/alsactl/utils.c +@@ -79,23 +79,19 @@ size_t line_width(const char *buf, size_t bufsize, size_t pos) + return count - pos; + } + +-void initfailed(int cardnumber, const char *reason, int exitcode) ++void initfailed(int cardnumber, const char *reason) + { + int fp; + char *str; +- char sexitcode[16]; + + if (statefile == NULL) + return; + if (snd_card_get_name(cardnumber, &str) < 0) + return; +- sprintf(sexitcode, "%i", exitcode); + fp = open(statefile, O_WRONLY|O_CREAT|O_APPEND, 0644); + write(fp, str, strlen(str)); + write(fp, ":", 1); + write(fp, reason, strlen(reason)); +- write(fp, ":", 1); +- write(fp, sexitcode, strlen(sexitcode)); + write(fp, "\n", 1); + close(fp); + free(str); +diff --git a/configure.in b/configure.in +index 8bae007..66b785f 100644 +--- a/configure.in ++++ b/configure.in +@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. + AC_PREREQ(2.59) + AC_INIT(aplay/aplay.c) + AC_PREFIX_DEFAULT(/usr) +-AM_INIT_AUTOMAKE(alsa-utils, 1.0.23) ++AM_INIT_AUTOMAKE(alsa-utils, 1.0.22) + + AM_GNU_GETTEXT([external]) + AM_GNU_GETTEXT_VERSION([0.15]) +diff --git a/seq/aconnect/aconnect.c b/seq/aconnect/aconnect.c +index 8c66cfd..1a50666 100644 +--- a/seq/aconnect/aconnect.c ++++ b/seq/aconnect/aconnect.c +@@ -192,33 +192,52 @@ static void remove_connection(snd_seq_t *seq, snd_seq_client_info_t *cinfo, + snd_seq_port_info_t *pinfo, int count) + { + snd_seq_query_subscribe_t *query; +- snd_seq_port_info_t *port; +- snd_seq_port_subscribe_t *subs; + + snd_seq_query_subscribe_alloca(&query); + snd_seq_query_subscribe_set_root(query, snd_seq_port_info_get_addr(pinfo)); ++ + snd_seq_query_subscribe_set_type(query, SND_SEQ_QUERY_SUBS_READ); + snd_seq_query_subscribe_set_index(query, 0); +- +- snd_seq_port_info_alloca(&port); +- snd_seq_port_subscribe_alloca(&subs); +- +- while (snd_seq_query_port_subscribers(seq, query) >= 0) { ++ for (; snd_seq_query_port_subscribers(seq, query) >= 0; ++ snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1)) { ++ snd_seq_port_info_t *port; ++ snd_seq_port_subscribe_t *subs; + const snd_seq_addr_t *sender = snd_seq_query_subscribe_get_root(query); + const snd_seq_addr_t *dest = snd_seq_query_subscribe_get_addr(query); ++ snd_seq_port_info_alloca(&port); ++ if (snd_seq_get_any_port_info(seq, dest->client, dest->port, port) < 0) ++ continue; ++ if (!(snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_SUBS_WRITE)) ++ continue; ++ if (snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_NO_EXPORT) ++ continue; ++ snd_seq_port_subscribe_alloca(&subs); ++ snd_seq_port_subscribe_set_queue(subs, snd_seq_query_subscribe_get_queue(query)); ++ snd_seq_port_subscribe_set_sender(subs, sender); ++ snd_seq_port_subscribe_set_dest(subs, dest); ++ snd_seq_unsubscribe_port(seq, subs); ++ } + +- if (snd_seq_get_any_port_info(seq, dest->client, dest->port, port) < 0 || +- !(snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_SUBS_WRITE) || +- (snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_NO_EXPORT)) { +- snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1); ++ snd_seq_query_subscribe_set_type(query, SND_SEQ_QUERY_SUBS_WRITE); ++ snd_seq_query_subscribe_set_index(query, 0); ++ for (; snd_seq_query_port_subscribers(seq, query) >= 0; ++ snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1)) { ++ snd_seq_port_info_t *port; ++ snd_seq_port_subscribe_t *subs; ++ const snd_seq_addr_t *dest = snd_seq_query_subscribe_get_root(query); ++ const snd_seq_addr_t *sender = snd_seq_query_subscribe_get_addr(query); ++ snd_seq_port_info_alloca(&port); ++ if (snd_seq_get_any_port_info(seq, sender->client, sender->port, port) < 0) + continue; +- } ++ if (!(snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_SUBS_READ)) ++ continue; ++ if (snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_NO_EXPORT) ++ continue; ++ snd_seq_port_subscribe_alloca(&subs); + snd_seq_port_subscribe_set_queue(subs, snd_seq_query_subscribe_get_queue(query)); + snd_seq_port_subscribe_set_sender(subs, sender); + snd_seq_port_subscribe_set_dest(subs, dest); +- if (snd_seq_unsubscribe_port(seq, subs) < 0) { +- snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1); +- } ++ snd_seq_unsubscribe_port(seq, subs); + } + } + +-- +1.7.2.1 + diff --git a/0002-alsactl-move-alloca-out-of-loop.patch b/0002-alsactl-move-alloca-out-of-loop.patch new file mode 100644 index 0000000..12d69bf --- /dev/null +++ b/0002-alsactl-move-alloca-out-of-loop.patch @@ -0,0 +1,50 @@ +From ad47784b01b9dd532ba2c2249547ce55505bbf08 Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +Date: Wed, 26 May 2010 10:18:43 +0200 +Subject: [PATCH 02/13] alsactl: move alloca out of loop + +Reserving new space from the stack in every loop iteration is not +necessary, so move the call to snd_ctl_elem_id_alloca outside where it +is executed only once. + +Signed-off-by: Clemens Ladisch +--- + alsactl/state.c | 8 ++++---- + 1 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/alsactl/state.c b/alsactl/state.c +index a9ffeea..86f7748 100644 +--- a/alsactl/state.c ++++ b/alsactl/state.c +@@ -523,6 +523,7 @@ static int get_controls(int cardno, snd_config_t *top) + snd_ctl_card_info_t *info; + snd_config_t *state, *card, *control; + snd_ctl_elem_list_t *list; ++ snd_ctl_elem_id_t *elem_id; + unsigned int idx; + int err; + char name[32]; +@@ -530,6 +531,7 @@ static int get_controls(int cardno, snd_config_t *top) + const char *id; + snd_ctl_card_info_alloca(&info); + snd_ctl_elem_list_alloca(&list); ++ snd_ctl_elem_id_alloca(&elem_id); + + sprintf(name, "hw:%d", cardno); + err = snd_ctl_open(&handle, name, SND_CTL_READONLY); +@@ -604,10 +606,8 @@ static int get_controls(int cardno, snd_config_t *top) + goto _free; + } + for (idx = 0; idx < count; ++idx) { +- snd_ctl_elem_id_t *id; +- snd_ctl_elem_id_alloca(&id); +- snd_ctl_elem_list_get_id(list, idx, id); +- err = get_control(handle, id, control); ++ snd_ctl_elem_list_get_id(list, idx, elem_id); ++ err = get_control(handle, elem_id, control); + if (err < 0) + goto _free; + } +-- +1.7.2.1 + diff --git a/0003-alsactl-remove-open-coded-search.patch b/0003-alsactl-remove-open-coded-search.patch new file mode 100644 index 0000000..8d8830d --- /dev/null +++ b/0003-alsactl-remove-open-coded-search.patch @@ -0,0 +1,79 @@ +From 224c12238e484ec795ace29bf5ff712dbae21633 Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +Date: Wed, 26 May 2010 10:19:17 +0200 +Subject: [PATCH 03/13] alsactl: remove open-coded search + +Remove search_comment_item since it does the same as snd_config_search. + +Signed-off-by: Clemens Ladisch +--- + alsactl/state.c | 30 +++++------------------------- + 1 files changed, 5 insertions(+), 25 deletions(-) + +diff --git a/alsactl/state.c b/alsactl/state.c +index 86f7748..815345a 100644 +--- a/alsactl/state.c ++++ b/alsactl/state.c +@@ -900,31 +900,14 @@ static int add_user_control(snd_ctl_t *handle, snd_ctl_elem_info_t *info, snd_co + } + + /* +- * 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"); ++ snd_config_t *n; + int ctype; + +- if (!n) ++ if (snd_config_search(conf, "type", &n) < 0) + return 0; /* not defined */ + ctype = get_comment_type(n); + if (ctype == type) +@@ -980,8 +963,7 @@ static int check_comment_range(snd_ctl_t *handle, snd_config_t *conf, + long ndbmin, ndbmax; + snd_ctl_elem_id_t *id; + +- n = search_comment_item(conf, "range"); +- if (!n) ++ if (snd_config_search(conf, "range", &n) < 0) + return 0; + if (get_comment_range(n, SND_CTL_ELEM_TYPE_INTEGER, + &omin, &omax, &ostep) < 0) +@@ -996,13 +978,11 @@ static int check_comment_range(snd_ctl_t *handle, snd_config_t *conf, + if (omin >= omax || nmin >= nmax) + return 0; /* invalid values */ + +- n = search_comment_item(conf, "dbmin"); +- if (!n) ++ if (snd_config_search(conf, "dbmin", &n) < 0) + return 0; + if (config_integer(n, &odbmin, doit) < 0) + return 0; +- n = search_comment_item(conf, "dbmax"); +- if (!n) ++ if (snd_config_search(conf, "dbmax", &n) < 0) + return 0; + if (config_integer(n, &odbmax, doit) < 0) + return 0; +-- +1.7.2.1 + diff --git a/0004-alsactl-correctly-restore-dB-values-of-controls-with.patch b/0004-alsactl-correctly-restore-dB-values-of-controls-with.patch new file mode 100644 index 0000000..df02e62 --- /dev/null +++ b/0004-alsactl-correctly-restore-dB-values-of-controls-with.patch @@ -0,0 +1,168 @@ +From 4f29877d54f9132219261218c2357e2b6e8910f4 Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +Date: Wed, 26 May 2010 10:27:25 +0200 +Subject: [PATCH 04/13] alsactl: correctly restore dB values of controls with changed range + +When the range of a control has changed between driver versions, it is a +good idea to restore the same dB value of the control. However, +computing the dB value by interpolating betweem the min/max dB values +duplicates alsa-lib's TLV functions and does not even work for controls +with a linear dB range. + +A simple conversion to dB and back can be done if we add the dB value(s) +to the saved state. + +Signed-off-by: Clemens Ladisch +--- + alsactl/state.c | 85 +++++++++++++++++++++++++++++++++++++++++------------- + 1 files changed, 64 insertions(+), 21 deletions(-) + +diff --git a/alsactl/state.c b/alsactl/state.c +index 815345a..538fa82 100644 +--- a/alsactl/state.c ++++ b/alsactl/state.c +@@ -164,14 +164,18 @@ static unsigned int *str_to_tlv(const char *s) + } + + /* +- * add the TLV string and dB ranges to comment fields ++ * add the TLV string, dB ranges, and dB values 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) ++ snd_ctl_elem_info_t *info, snd_ctl_elem_value_t *ctl, ++ snd_config_t *comment) + { + unsigned int tlv[MAX_USER_TLV_SIZE]; + unsigned int *db; +- long dbmin, dbmax; ++ long rangemin, rangemax; ++ long dbmin, dbmax, dbgain; ++ snd_config_t *value; ++ unsigned int i, count; + int err; + + if (snd_ctl_elem_tlv_read(handle, id, tlv, sizeof(tlv)) < 0) +@@ -193,13 +197,35 @@ static int add_tlv_comments(snd_ctl_t *handle, snd_ctl_elem_id_t *id, + 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); ++ rangemin = snd_ctl_elem_info_get_min(info); ++ rangemax = snd_ctl_elem_info_get_max(info); ++ snd_tlv_get_dB_range(db, rangemin, rangemax, &dbmin, &dbmax); + if (err < 0) + return err; + snd_config_integer_add(comment, "dbmin", dbmin); + snd_config_integer_add(comment, "dbmax", dbmax); ++ ++ if (snd_ctl_elem_info_get_type(info) == SND_CTL_ELEM_TYPE_INTEGER) { ++ err = snd_config_compound_add(comment, "dbvalue", 1, &value); ++ if (err < 0) { ++ error("snd_config_compound_add: %s", snd_strerror(err)); ++ return err; ++ } ++ count = snd_ctl_elem_info_get_count(info); ++ for (i = 0; i < count; i++) { ++ err = snd_tlv_convert_to_dB(db, rangemin, rangemax, ++ snd_ctl_elem_value_get_integer(ctl, i), &dbgain); ++ if (err < 0) { ++ error("snd_tlv_convert_to_dB: %s", snd_strerror(err)); ++ return err; ++ } ++ err = snd_config_integer_add(value, num_str(i), dbgain); ++ if (err < 0) { ++ error("snd_config_integer_add: %s", snd_strerror(err)); ++ return err; ++ } ++ } ++ } + return 0; + } + +@@ -302,7 +328,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t + return err; + } + if (snd_ctl_elem_info_is_tlv_readable(info)) { +- err = add_tlv_comments(handle, id, info, comment); ++ err = add_tlv_comments(handle, id, info, ctl, comment); + if (err < 0) + return err; + } +@@ -930,20 +956,31 @@ static int check_comment_type(snd_config_t *conf, int type) + 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, ++ snd_config_t *comment, const char *index, ++ snd_ctl_t *device, snd_ctl_elem_id_t *id, + int doit) + { +- long val; +- if (config_integer(value, &val, doit) < 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; ++ snd_config_t *db_node; ++ long db, val; ++ int err; ++ ++ if (snd_config_searchv(comment, &db_node, "dbvalue", index, NULL) < 0 || ++ snd_config_get_integer(db_node, &db) < 0) { ++ err = config_integer(value, &val, doit); ++ if (err < 0) ++ return err; ++ if (val < omin || val > omax) ++ return -EINVAL; ++ db = ((val - omin) * (odbmax - odbmin)) / (omax - omin) + odbmin; ++ } ++ ++ err = snd_ctl_convert_from_dB(device, id, db, &val, db > 0); ++ if (err < 0) ++ return err; ++ if (val < nmin) ++ val = nmin; ++ else if (val > nmax) ++ val = nmax; + return snd_config_set_integer(value, val); + } + +@@ -961,6 +998,7 @@ static int check_comment_range(snd_ctl_t *handle, snd_config_t *conf, + long nmin, nmax; + long odbmin, odbmax; + long ndbmin, ndbmax; ++ long db; + snd_ctl_elem_id_t *id; + + if (snd_config_search(conf, "range", &n) < 0) +@@ -1003,12 +1041,17 @@ static int check_comment_range(snd_ctl_t *handle, snd_config_t *conf, + snd_config_iterator_t i, next; + snd_config_for_each(i, next, value) { + snd_config_t *n = snd_config_iterator_entry(i); ++ const char *idxstr; ++ if (snd_config_get_id(n, &idxstr) < 0) ++ continue; + convert_to_new_db(n, omin, omax, nmin, nmax, +- odbmin, odbmax, ndbmin, ndbmax, doit); ++ odbmin, odbmax, conf, idxstr, ++ handle, id, doit); + } + } else + convert_to_new_db(value, omin, omax, nmin, nmax, +- odbmin, odbmax, ndbmin, ndbmax, doit); ++ odbmin, odbmax, conf, "0", ++ handle, id, doit); + return 0; + } + +-- +1.7.2.1 + diff --git a/0005-alsactl-change-format-of-comment-node-in-state-file.patch b/0005-alsactl-change-format-of-comment-node-in-state-file.patch new file mode 100644 index 0000000..cb0cafb --- /dev/null +++ b/0005-alsactl-change-format-of-comment-node-in-state-file.patch @@ -0,0 +1,88 @@ +From bd15b1e5ea23d25fcb2ccccd1cf25350c60fe527 Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +Date: Wed, 26 May 2010 10:28:11 +0200 +Subject: [PATCH 05/13] alsactl: change format of comment node in state file + +Make the comment node a separate node in the state file (join=0), and +move it after the other fields of the respective control. + +Signed-off-by: Clemens Ladisch +--- + alsactl/state.c | 20 +++++++++++++------- + 1 files changed, 13 insertions(+), 7 deletions(-) + +diff --git a/alsactl/state.c b/alsactl/state.c +index 538fa82..01b1cd6 100644 +--- a/alsactl/state.c ++++ b/alsactl/state.c +@@ -266,9 +266,9 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t + error("snd_config_compound_add: %s", snd_strerror(err)); + return err; + } +- err = snd_config_compound_add(control, "comment", 1, &comment); ++ err = snd_config_make_compound(&comment, "comment", 0); + if (err < 0) { +- error("snd_config_compound_add: %s", snd_strerror(err)); ++ error("snd_config_make_compound: %s", snd_strerror(err)); + return err; + } + +@@ -432,7 +432,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t + error("snd_config_string_add: %s", snd_strerror(err)); + return err; + } +- return 0; ++ goto finish; + } + default: + break; +@@ -446,21 +446,21 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t + error("snd_config_string_add: %s", snd_strerror(err)); + return err; + } +- return 0; ++ goto finish; + case SND_CTL_ELEM_TYPE_INTEGER: + err = snd_config_integer_add(control, "value", snd_ctl_elem_value_get_integer(ctl, 0)); + if (err < 0) { + error("snd_config_integer_add: %s", snd_strerror(err)); + return err; + } +- return 0; ++ goto finish; + case SND_CTL_ELEM_TYPE_INTEGER64: + err = snd_config_integer64_add(control, "value", snd_ctl_elem_value_get_integer64(ctl, 0)); + if (err < 0) { + error("snd_config_integer64_add: %s", snd_strerror(err)); + return err; + } +- return 0; ++ goto finish; + case SND_CTL_ELEM_TYPE_ENUMERATED: + { + unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, 0); +@@ -475,7 +475,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t + } + if (err < 0) + error("snd_config add: %s", snd_strerror(err)); +- return 0; ++ goto finish; + } + default: + error("Unknown control type: %d\n", type); +@@ -540,6 +540,12 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t + return -EINVAL; + } + ++finish: ++ err = snd_config_add(control, comment); ++ if (err < 0) { ++ error("snd_config_add: %s", snd_strerror(err)); ++ return err; ++ } + return 0; + } + +-- +1.7.2.1 + diff --git a/0006-Revert-wrong-parts-of-alsactl-use-snd_config_imake-f.patch b/0006-Revert-wrong-parts-of-alsactl-use-snd_config_imake-f.patch new file mode 100644 index 0000000..d057740 --- /dev/null +++ b/0006-Revert-wrong-parts-of-alsactl-use-snd_config_imake-f.patch @@ -0,0 +1,269 @@ +From b4ff58b685fe9da25901cd3e395dd2f2d64532df Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +Date: Wed, 26 May 2010 10:37:58 +0200 +Subject: [PATCH 06/13] Revert wrong parts of "alsactl: use snd_config_imake* functions" + +This reverts the parts of commit e509df69a5100df28921980362488f6947df0aae +that accidentally reverted a bunch of earlier commits. + +Signed-off-by: Clemens Ladisch +--- + alsactl/alsactl.h | 10 ++++---- + alsactl/state.c | 22 +++++++++++--------- + alsactl/utils.c | 6 ++++- + configure.in | 2 +- + seq/aconnect/aconnect.c | 49 ++++++++++++++-------------------------------- + 5 files changed, 38 insertions(+), 51 deletions(-) + +diff --git a/alsactl/alsactl.h b/alsactl/alsactl.h +index 89ad295..be90efb 100644 +--- a/alsactl/alsactl.h ++++ b/alsactl/alsactl.h +@@ -34,16 +34,16 @@ extern char *statefile; + + #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) + #define cerror(cond, ...) do {\ +- if (cond) { \ +- fprintf(stderr, "%s: %s:%d: ", command, __FUNCTION__, __LINE__); \ ++ if (cond || debugflag) { \ ++ fprintf(stderr, "%s%s: %s:%d: ", debugflag ? "WARNING: " : "", command, __FUNCTION__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + putc('\n', stderr); \ + } \ + } while (0) + #else + #define cerror(cond, args...) do {\ +- if (cond) { \ +- fprintf(stderr, "%s: %s:%d: ", command, __FUNCTION__, __LINE__); \ ++ if (cond || debugflag) { \ ++ fprintf(stderr, "%s%s: %s:%d: ", debugflag ? "WARNING: " : "", command, __FUNCTION__, __LINE__); \ + fprintf(stderr, ##args); \ + putc('\n', stderr); \ + } \ +@@ -78,7 +78,7 @@ int generate_names(const char *cfgfile); + int file_map(const char *filename, char **buf, size_t *bufsize); + void file_unmap(void *buf, size_t bufsize); + size_t line_width(const char *buf, size_t bufsize, size_t pos); +-void initfailed(int cardnumber, const char *reason); ++void initfailed(int cardnumber, const char *reason, int exitcode); + + static inline int hextodigit(int c) + { +diff --git a/alsactl/state.c b/alsactl/state.c +index 01b1cd6..7eb107f 100644 +--- a/alsactl/state.c ++++ b/alsactl/state.c +@@ -1131,7 +1131,6 @@ static int restore_config_value2(snd_ctl_t *handle, snd_ctl_elem_info_t *info, + } + snd_ctl_elem_value_set_byte(ctl, idx, val); + return 1; +- break; + default: + break; + } +@@ -1418,6 +1417,7 @@ static int set_controls(int card, snd_config_t *top, int doit) + snd_ctl_card_info_alloca(&info); + + sprintf(name, "hw:%d", card); ++ dbg("device='%s', doit=%i", name, doit); + err = snd_ctl_open(&handle, name, 0); + if (err < 0) { + error("snd_ctl_open error: %s", snd_strerror(err)); +@@ -1429,6 +1429,7 @@ static int set_controls(int card, snd_config_t *top, int doit) + goto _close; + } + id = snd_ctl_card_info_get_id(info); ++ dbg("card-info-id: '%s'", id); + err = snd_config_searchv(top, &control, "state", id, "control", 0); + if (err < 0) { + if (force_restore) { +@@ -1454,24 +1455,25 @@ static int set_controls(int card, snd_config_t *top, int doit) + goto _close; + } + ++ dbg("maxnumid=%i", maxnumid); + /* check if we have additional controls in driver */ + /* in this case we should go through init procedure */ + if (!doit && maxnumid >= 0) { +- snd_ctl_elem_id_t *id; + snd_ctl_elem_info_t *info; +- snd_ctl_elem_id_alloca(&id); + snd_ctl_elem_info_alloca(&info); + snd_ctl_elem_info_set_numid(info, maxnumid+1); + if (snd_ctl_elem_info(handle, info) == 0) { + /* not very informative */ + /* but value is used for check only */ + err = -EAGAIN; ++ dbg("more controls than maxnumid?"); + goto _close; + } + } + + _close: + snd_ctl_close(handle); ++ dbg("result code: %i", err); + return err; + } + +@@ -1596,9 +1598,9 @@ int load_state(const char *file, const char *initfile, const char *cardname, + err = init(initfile, cardname1); + if (err < 0) { + finalerr = err; +- initfailed(card, "init"); ++ initfailed(card, "init", err); + } +- initfailed(card, "restore"); ++ initfailed(card, "restore", -ENOENT); + } + if (first) + finalerr = 0; /* no cards, no error code */ +@@ -1631,14 +1633,14 @@ int load_state(const char *file, const char *initfile, const char *cardname, + sprintf(cardname1, "%i", card); + err = init(initfile, cardname1); + if (err < 0) { +- initfailed(card, "init"); ++ initfailed(card, "init", err); + finalerr = err; + } + } + if ((err = set_controls(card, config, 1))) { + if (!force_restore) + finalerr = err; +- initfailed(card, "restore"); ++ initfailed(card, "restore", err); + } + } + } else { +@@ -1653,12 +1655,12 @@ int load_state(const char *file, const char *initfile, const char *cardname, + if (do_init && set_controls(cardno, config, 0)) { + err = init(initfile, cardname); + if (err < 0) { +- initfailed(cardno, "init"); +- return err; ++ initfailed(cardno, "init", err); ++ finalerr = err; + } + } + if ((err = set_controls(cardno, config, 1))) { +- initfailed(cardno, "restore"); ++ initfailed(cardno, "restore", err); + if (!force_restore) + return err; + } +diff --git a/alsactl/utils.c b/alsactl/utils.c +index ab4dbd4..a27eb6e 100644 +--- a/alsactl/utils.c ++++ b/alsactl/utils.c +@@ -79,19 +79,23 @@ size_t line_width(const char *buf, size_t bufsize, size_t pos) + return count - pos; + } + +-void initfailed(int cardnumber, const char *reason) ++void initfailed(int cardnumber, const char *reason, int exitcode) + { + int fp; + char *str; ++ char sexitcode[16]; + + if (statefile == NULL) + return; + if (snd_card_get_name(cardnumber, &str) < 0) + return; ++ sprintf(sexitcode, "%i", exitcode); + fp = open(statefile, O_WRONLY|O_CREAT|O_APPEND, 0644); + write(fp, str, strlen(str)); + write(fp, ":", 1); + write(fp, reason, strlen(reason)); ++ write(fp, ":", 1); ++ write(fp, sexitcode, strlen(sexitcode)); + write(fp, "\n", 1); + close(fp); + free(str); +diff --git a/configure.in b/configure.in +index 66b785f..8bae007 100644 +--- a/configure.in ++++ b/configure.in +@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. + AC_PREREQ(2.59) + AC_INIT(aplay/aplay.c) + AC_PREFIX_DEFAULT(/usr) +-AM_INIT_AUTOMAKE(alsa-utils, 1.0.22) ++AM_INIT_AUTOMAKE(alsa-utils, 1.0.23) + + AM_GNU_GETTEXT([external]) + AM_GNU_GETTEXT_VERSION([0.15]) +diff --git a/seq/aconnect/aconnect.c b/seq/aconnect/aconnect.c +index 1a50666..8c66cfd 100644 +--- a/seq/aconnect/aconnect.c ++++ b/seq/aconnect/aconnect.c +@@ -192,52 +192,33 @@ static void remove_connection(snd_seq_t *seq, snd_seq_client_info_t *cinfo, + snd_seq_port_info_t *pinfo, int count) + { + snd_seq_query_subscribe_t *query; ++ snd_seq_port_info_t *port; ++ snd_seq_port_subscribe_t *subs; + + snd_seq_query_subscribe_alloca(&query); + snd_seq_query_subscribe_set_root(query, snd_seq_port_info_get_addr(pinfo)); +- + snd_seq_query_subscribe_set_type(query, SND_SEQ_QUERY_SUBS_READ); + snd_seq_query_subscribe_set_index(query, 0); +- for (; snd_seq_query_port_subscribers(seq, query) >= 0; +- snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1)) { +- snd_seq_port_info_t *port; +- snd_seq_port_subscribe_t *subs; ++ ++ snd_seq_port_info_alloca(&port); ++ snd_seq_port_subscribe_alloca(&subs); ++ ++ while (snd_seq_query_port_subscribers(seq, query) >= 0) { + const snd_seq_addr_t *sender = snd_seq_query_subscribe_get_root(query); + const snd_seq_addr_t *dest = snd_seq_query_subscribe_get_addr(query); +- snd_seq_port_info_alloca(&port); +- if (snd_seq_get_any_port_info(seq, dest->client, dest->port, port) < 0) +- continue; +- if (!(snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_SUBS_WRITE)) +- continue; +- if (snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_NO_EXPORT) +- continue; +- snd_seq_port_subscribe_alloca(&subs); +- snd_seq_port_subscribe_set_queue(subs, snd_seq_query_subscribe_get_queue(query)); +- snd_seq_port_subscribe_set_sender(subs, sender); +- snd_seq_port_subscribe_set_dest(subs, dest); +- snd_seq_unsubscribe_port(seq, subs); +- } + +- snd_seq_query_subscribe_set_type(query, SND_SEQ_QUERY_SUBS_WRITE); +- snd_seq_query_subscribe_set_index(query, 0); +- for (; snd_seq_query_port_subscribers(seq, query) >= 0; +- snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1)) { +- snd_seq_port_info_t *port; +- snd_seq_port_subscribe_t *subs; +- const snd_seq_addr_t *dest = snd_seq_query_subscribe_get_root(query); +- const snd_seq_addr_t *sender = snd_seq_query_subscribe_get_addr(query); +- snd_seq_port_info_alloca(&port); +- if (snd_seq_get_any_port_info(seq, sender->client, sender->port, port) < 0) +- continue; +- if (!(snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_SUBS_READ)) ++ if (snd_seq_get_any_port_info(seq, dest->client, dest->port, port) < 0 || ++ !(snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_SUBS_WRITE) || ++ (snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_NO_EXPORT)) { ++ snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1); + continue; +- if (snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_NO_EXPORT) +- continue; +- snd_seq_port_subscribe_alloca(&subs); ++ } + snd_seq_port_subscribe_set_queue(subs, snd_seq_query_subscribe_get_queue(query)); + snd_seq_port_subscribe_set_sender(subs, sender); + snd_seq_port_subscribe_set_dest(subs, dest); +- snd_seq_unsubscribe_port(seq, subs); ++ if (snd_seq_unsubscribe_port(seq, subs) < 0) { ++ snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1); ++ } + } + } + +-- +1.7.2.1 + diff --git a/0007-aplay-arecord-Added-hardware-pause-support-press-SPA.patch b/0007-aplay-arecord-Added-hardware-pause-support-press-SPA.patch new file mode 100644 index 0000000..7397b2c --- /dev/null +++ b/0007-aplay-arecord-Added-hardware-pause-support-press-SPA.patch @@ -0,0 +1,192 @@ +From 3bd65336222a4d00cefc4db5e74a7a96c07ab567 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Thu, 15 Jul 2010 10:40:21 +0200 +Subject: [PATCH 07/13] aplay/arecord: Added hardware pause support (press SPACE or Enter) + +Signed-off-by: Jaroslav Kysela +--- + aplay/aplay.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 files changed, 73 insertions(+), 5 deletions(-) + +diff --git a/aplay/aplay.c b/aplay/aplay.c +index e1d8e6a..b5203a7 100644 +--- a/aplay/aplay.c ++++ b/aplay/aplay.c +@@ -41,6 +41,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -102,6 +103,7 @@ static int avail_min = -1; + static int start_delay = 0; + static int stop_delay = 0; + static int monotonic = 0; ++static int can_pause = 0; + static int verbose = 0; + static int vumeter = VUMETER_NONE; + static int buffer_pos = 0; +@@ -1111,6 +1113,7 @@ static void set_params(void) + } + assert(err >= 0); + monotonic = snd_pcm_hw_params_is_monotonic(params); ++ can_pause = snd_pcm_hw_params_can_pause(params); + err = snd_pcm_hw_params(handle, params); + if (err < 0) { + error(_("Unable to install hw params:")); +@@ -1182,7 +1185,7 @@ static void set_params(void) + int i; + err = snd_pcm_mmap_begin(handle, &areas, &offset, &size); + if (err < 0) { +- error("snd_pcm_mmap_begin problem: %s", snd_strerror(err)); ++ error(_("snd_pcm_mmap_begin problem: %s"), snd_strerror(err)); + prg_exit(EXIT_FAILURE); + } + for (i = 0; i < hwparams.channels; i++) +@@ -1194,6 +1197,65 @@ static void set_params(void) + buffer_frames = buffer_size; /* for position test */ + } + ++static void init_stdin(void) ++{ ++ struct termios term; ++ long flags; ++ ++ if (fd == fileno(stdin)) ++ return; ++ flags = fcntl(fileno(stdin), F_GETFL); ++ if (flags < 0 || fcntl(fileno(stdin), F_SETFL, flags|O_NONBLOCK) < 0) ++ fprintf(stderr, _("stdin O_NONBLOCK flag setup failed\n")); ++ tcgetattr(fileno(stdin), &term); ++ term.c_lflag &= ~ICANON; ++ tcsetattr(fileno(stdin), TCSANOW, &term); ++} ++ ++static void do_pause(void) ++{ ++ int err; ++ unsigned char b; ++ ++ if (!can_pause) { ++ fprintf(stderr, _("\rPAUSE command ignored (no hw support)\n")); ++ return; ++ } ++ err = snd_pcm_pause(handle, 1); ++ if (err < 0) { ++ error(_("pause push error: %s"), snd_strerror(err)); ++ return; ++ } ++ while (1) { ++ while (read(fileno(stdin), &b, 1) != 1); ++ if (b == ' ' || b == '\r') { ++ while (read(fileno(stdin), &b, 1) == 1); ++ err = snd_pcm_pause(handle, 0); ++ if (err < 0) ++ error(_("pause release error: %s"), snd_strerror(err)); ++ return; ++ } ++ } ++} ++ ++static void check_stdin(void) ++{ ++ unsigned char b; ++ ++ if (fd != fileno(stdin)) { ++ while (read(fileno(stdin), &b, 1) == 1) { ++ if (b == ' ' || b == '\r') { ++ while (read(fileno(stdin), &b, 1) == 1); ++ fprintf(stderr, _("\r=== PAUSE === ")); ++ fflush(stderr); ++ do_pause(); ++ fprintf(stderr, " \r"); ++ fflush(stderr); ++ } ++ } ++ } ++} ++ + #ifndef timersub + #define timersub(a, b, result) \ + do { \ +@@ -1589,12 +1651,13 @@ static ssize_t pcm_write(u_char *data, size_t count) + while (count > 0) { + if (test_position) + do_test_position(); ++ check_stdin(); + r = writei_func(handle, data, count); + if (test_position) + do_test_position(); + if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) { + if (!test_nowait) +- snd_pcm_wait(handle, 1000); ++ snd_pcm_wait(handle, 100); + } else if (r == -EPIPE) { + xrun(); + } else if (r == -ESTRPIPE) { +@@ -1635,12 +1698,13 @@ static ssize_t pcm_writev(u_char **data, unsigned int channels, size_t count) + bufs[channel] = data[channel] + offset * bits_per_sample / 8; + if (test_position) + do_test_position(); ++ check_stdin(); + r = writen_func(handle, bufs, count); + if (test_position) + do_test_position(); + if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) { + if (!test_nowait) +- snd_pcm_wait(handle, 1000); ++ snd_pcm_wait(handle, 100); + } else if (r == -EPIPE) { + xrun(); + } else if (r == -ESTRPIPE) { +@@ -1678,12 +1742,13 @@ static ssize_t pcm_read(u_char *data, size_t rcount) + while (count > 0) { + if (test_position) + do_test_position(); ++ check_stdin(); + r = readi_func(handle, data, count); + if (test_position) + do_test_position(); + if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) { + if (!test_nowait) +- snd_pcm_wait(handle, 1000); ++ snd_pcm_wait(handle, 100); + } else if (r == -EPIPE) { + xrun(); + } else if (r == -ESTRPIPE) { +@@ -1721,12 +1786,13 @@ static ssize_t pcm_readv(u_char **data, unsigned int channels, size_t rcount) + bufs[channel] = data[channel] + offset * bits_per_sample / 8; + if (test_position) + do_test_position(); ++ check_stdin(); + r = readn_func(handle, bufs, count); + if (test_position) + do_test_position(); + if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) { + if (!test_nowait) +- snd_pcm_wait(handle, 1000); ++ snd_pcm_wait(handle, 100); + } else if (r == -EPIPE) { + xrun(); + } else if (r == -ESTRPIPE) { +@@ -2361,6 +2427,7 @@ static void playback(char *name) + fd = fileno(stdin); + name = "stdin"; + } else { ++ init_stdin(); + if ((fd = open64(name, O_RDONLY, 0)) == -1) { + perror(name); + prg_exit(EXIT_FAILURE); +@@ -2616,6 +2683,7 @@ static void capture(char *orig_name) + if (count > fmt_rec_table[file_type].max_filesize) + count = fmt_rec_table[file_type].max_filesize; + } ++ init_stdin(); + + do { + /* open a file to write */ +-- +1.7.2.1 + diff --git a/0008-aplay-fix-termio-settings-return-back-old-c_flag-val.patch b/0008-aplay-fix-termio-settings-return-back-old-c_flag-val.patch new file mode 100644 index 0000000..d467e48 --- /dev/null +++ b/0008-aplay-fix-termio-settings-return-back-old-c_flag-val.patch @@ -0,0 +1,75 @@ +From 73c79ebf26a51a2d9b582a4cae82867873875743 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Thu, 15 Jul 2010 13:39:14 +0200 +Subject: [PATCH 08/13] aplay: fix termio settings - return back old c_flag value on exit + +- symptom - ssh client password authentication does not work with + the modified terminal settings + +Signed-off-by: Jaroslav Kysela +--- + aplay/aplay.c | 18 +++++++++++++++++- + 1 files changed, 17 insertions(+), 1 deletions(-) + +diff --git a/aplay/aplay.c b/aplay/aplay.c +index b5203a7..a92ca93 100644 +--- a/aplay/aplay.c ++++ b/aplay/aplay.c +@@ -117,6 +117,7 @@ static long long max_file_size = 0; + static int max_file_time = 0; + static int use_strftime = 0; + volatile static int recycle_capture_file = 0; ++static long term_c_lflag = 0; + + static int fd = -1; + static off64_t pbrec_count = LLONG_MAX, fdcount; +@@ -128,6 +129,8 @@ static int pidfile_written = 0; + + /* needed prototypes */ + ++static void done_stdin(void); ++ + static void playback(char *filename); + static void capture(char *filename); + static void playbackv(char **filenames, unsigned int count); +@@ -343,6 +346,7 @@ static void version(void) + */ + static void prg_exit(int code) + { ++ done_stdin(); + if (handle) + snd_pcm_close(handle); + if (pidfile_written) +@@ -1202,16 +1206,28 @@ static void init_stdin(void) + struct termios term; + long flags; + ++ tcgetattr(fileno(stdin), &term); ++ term_c_lflag = term.c_lflag; + if (fd == fileno(stdin)) + return; + flags = fcntl(fileno(stdin), F_GETFL); + if (flags < 0 || fcntl(fileno(stdin), F_SETFL, flags|O_NONBLOCK) < 0) + fprintf(stderr, _("stdin O_NONBLOCK flag setup failed\n")); +- tcgetattr(fileno(stdin), &term); + term.c_lflag &= ~ICANON; + tcsetattr(fileno(stdin), TCSANOW, &term); + } + ++static void done_stdin(void) ++{ ++ struct termios term; ++ ++ if (fd == fileno(stdin)) ++ return; ++ tcgetattr(fileno(stdin), &term); ++ term.c_lflag = term_c_lflag; ++ tcsetattr(fileno(stdin), TCSANOW, &term); ++} ++ + static void do_pause(void) + { + int err; +-- +1.7.2.1 + diff --git a/0009-speaker-test-add-test-pattern-for-PCM-layer-debuggin.patch b/0009-speaker-test-add-test-pattern-for-PCM-layer-debuggin.patch new file mode 100644 index 0000000..ce002d6 --- /dev/null +++ b/0009-speaker-test-add-test-pattern-for-PCM-layer-debuggin.patch @@ -0,0 +1,129 @@ +From 4c337275d1cc0579cc8ad45b4c138287e8658f0d Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Wed, 18 Aug 2010 08:22:23 +0200 +Subject: [PATCH 09/13] speaker-test: add test pattern for PCM layer debugging purposes + +Signed-off-by: Jaroslav Kysela +--- + speaker-test/speaker-test.c | 75 +++++++++++++++++++++++++++++++++++++++++- + 1 files changed, 73 insertions(+), 2 deletions(-) + +diff --git a/speaker-test/speaker-test.c b/speaker-test/speaker-test.c +index d8d68e2..458a8d7 100644 +--- a/speaker-test/speaker-test.c ++++ b/speaker-test/speaker-test.c +@@ -63,7 +63,8 @@ + enum { + TEST_PINK_NOISE = 1, + TEST_SINE, +- TEST_WAV ++ TEST_WAV, ++ TEST_PATTERN, + }; + + #define MAX_CHANNELS 16 +@@ -303,6 +304,71 @@ static void generate_pink_noise( uint8_t *frames, int channel, int count) { + } + } + ++/* ++ * useful for tests ++ */ ++static void generate_pattern(uint8_t *frames, int channel, int count, int *_pattern) { ++ int pattern = *_pattern; ++ int chn; ++ int8_t *samp8 = (int8_t*) frames; ++ int16_t *samp16 = (int16_t*) frames; ++ int32_t *samp32 = (int32_t*) frames; ++ float *samp_f = (float*) frames; ++ ++ while (count-- > 0) { ++ for(chn=0;chn TEST_WAV) { ++ if (test_type < TEST_PINK_NOISE || test_type > TEST_PATTERN) { + fprintf(stderr, _("Invalid test type %s\n"), optarg); + exit(1); + } +-- +1.7.2.1 + diff --git a/0010-aplay-arecord-term_c_lflag-variable-might-be-unitial.patch b/0010-aplay-arecord-term_c_lflag-variable-might-be-unitial.patch new file mode 100644 index 0000000..0608bf7 --- /dev/null +++ b/0010-aplay-arecord-term_c_lflag-variable-might-be-unitial.patch @@ -0,0 +1,38 @@ +From bb865dc10b6dcee9d428d3c5a17ee312e0aaf7e0 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Wed, 18 Aug 2010 08:23:09 +0200 +Subject: [PATCH 10/13] aplay/arecord: term_c_lflag variable might be unitialized in some cases + +The term_c_lflag variable might be unitialized in some cases. Add extra +check to avoid setting of wrong value. + +Signed-off-by: Jaroslav Kysela +--- + aplay/aplay.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/aplay/aplay.c b/aplay/aplay.c +index a92ca93..c09f23c 100644 +--- a/aplay/aplay.c ++++ b/aplay/aplay.c +@@ -117,7 +117,7 @@ static long long max_file_size = 0; + static int max_file_time = 0; + static int use_strftime = 0; + volatile static int recycle_capture_file = 0; +-static long term_c_lflag = 0; ++static long term_c_lflag = -1; + + static int fd = -1; + static off64_t pbrec_count = LLONG_MAX, fdcount; +@@ -1221,7 +1221,7 @@ static void done_stdin(void) + { + struct termios term; + +- if (fd == fileno(stdin)) ++ if (fd == fileno(stdin) || term_c_lflag == -1) + return; + tcgetattr(fileno(stdin), &term); + term.c_lflag = term_c_lflag; +-- +1.7.2.1 + diff --git a/0011-alsactl-init-Use-Found-hardware-instead-Unknown-hard.patch b/0011-alsactl-init-Use-Found-hardware-instead-Unknown-hard.patch new file mode 100644 index 0000000..0fbb839 --- /dev/null +++ b/0011-alsactl-init-Use-Found-hardware-instead-Unknown-hard.patch @@ -0,0 +1,29 @@ +From dcb90a779e74315596a4cdb4741983b21cba69c9 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Thu, 2 Sep 2010 15:03:23 +0200 +Subject: [PATCH 11/13] alsactl init: Use "Found hardware:" instead "Unknown hardware:" + +It seems that "Unknown hardware:" confuses users. Use "Found hardware:" +instead. + +Signed-off-by: Jaroslav Kysela +--- + alsactl/init/00main | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/alsactl/init/00main b/alsactl/init/00main +index 2d26bbf..fb7f02c 100644 +--- a/alsactl/init/00main ++++ b/alsactl/init/00main +@@ -37,7 +37,7 @@ CARDINFO{driver}=="Test", INCLUDE="test", GOTO="init_end" + LABEL="init_end" + ACCESS=="postinit", INCLUDE="postinit" + RESULT=="true", GOTO="00_mainend" +-ERROR="Unknown hardware: \"$cardinfo{driver}\" \"$cardinfo{mixername}\" \"$cardinfo{components}\" \"$attr{subsystem_vendor}\" \"$attr{subsystem_device}\"\n" ++ERROR="Found hardware: \"$cardinfo{driver}\" \"$cardinfo{mixername}\" \"$cardinfo{components}\" \"$attr{subsystem_vendor}\" \"$attr{subsystem_device}\"\n" + ERROR="Hardware is initialized using a guess method\n" + INCLUDE="default" + EXIT="99" +-- +1.7.2.1 + diff --git a/0012-alsactl-init-use-generic-method-instead-guess-method.patch b/0012-alsactl-init-use-generic-method-instead-guess-method.patch new file mode 100644 index 0000000..8d73f07 --- /dev/null +++ b/0012-alsactl-init-use-generic-method-instead-guess-method.patch @@ -0,0 +1,26 @@ +From 7f6a55e203e2bb069c35006b605e1a19cfcd88cb Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Thu, 2 Sep 2010 15:36:56 +0200 +Subject: [PATCH 12/13] alsactl init: use "generic method" instead "guess method" + +Signed-off-by: Jaroslav Kysela +--- + alsactl/init/00main | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/alsactl/init/00main b/alsactl/init/00main +index fb7f02c..660df38 100644 +--- a/alsactl/init/00main ++++ b/alsactl/init/00main +@@ -38,7 +38,7 @@ LABEL="init_end" + ACCESS=="postinit", INCLUDE="postinit" + RESULT=="true", GOTO="00_mainend" + ERROR="Found hardware: \"$cardinfo{driver}\" \"$cardinfo{mixername}\" \"$cardinfo{components}\" \"$attr{subsystem_vendor}\" \"$attr{subsystem_device}\"\n" +-ERROR="Hardware is initialized using a guess method\n" ++ERROR="Hardware is initialized using a generic method\n" + INCLUDE="default" + EXIT="99" + +-- +1.7.2.1 + diff --git a/0013-alsactl-Change-handling-of-inactive-controls.patch b/0013-alsactl-Change-handling-of-inactive-controls.patch new file mode 100644 index 0000000..3572bce --- /dev/null +++ b/0013-alsactl-Change-handling-of-inactive-controls.patch @@ -0,0 +1,76 @@ +From 0fea2452cb8bca5b5d28daedeb31df7a21284e7d Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Thu, 2 Sep 2010 15:48:43 +0200 +Subject: [PATCH 13/13] alsactl: Change handling of inactive controls + +The inactive controls are stored, but they are not restored +when they are marked inactive in the state file or in the +driver. + +Signed-off-by: Jaroslav Kysela +--- + alsactl/state.c | 13 +++++++------ + 1 files changed, 7 insertions(+), 6 deletions(-) + +diff --git a/alsactl/state.c b/alsactl/state.c +index 7eb107f..7422deb 100644 +--- a/alsactl/state.c ++++ b/alsactl/state.c +@@ -251,8 +251,7 @@ static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *t + return err; + } + +- if (snd_ctl_elem_info_is_inactive(info) || +- !snd_ctl_elem_info_is_readable(info)) ++ if (!snd_ctl_elem_info_is_readable(info)) + return 0; + snd_ctl_elem_value_set_id(ctl, id); + err = snd_ctl_elem_read(handle, ctl); +@@ -778,7 +777,7 @@ static int config_integer64(snd_config_t *n, long long *val, int doit) + return err; + } + +-static int is_user_control(snd_config_t *conf) ++static int check_comment_access(snd_config_t *conf, const char *str) + { + snd_config_iterator_t i, next; + +@@ -790,7 +789,7 @@ static int is_user_control(snd_config_t *conf) + if (strcmp(id, "access") == 0) { + if (snd_config_get_string(n, &s) < 0) + return 0; +- if (strstr(s, "user")) ++ if (strstr(s, str)) + return 1; + } + } +@@ -1004,7 +1003,6 @@ static int check_comment_range(snd_ctl_t *handle, snd_config_t *conf, + long nmin, nmax; + long odbmin, odbmax; + long ndbmin, ndbmax; +- long db; + snd_ctl_elem_id_t *id; + + if (snd_config_search(conf, "range", &n) < 0) +@@ -1256,7 +1254,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control, + snd_ctl_elem_info_set_name(info, name); + snd_ctl_elem_info_set_index(info, index); + err = snd_ctl_elem_info(handle, info); +- if (err < 0 && comment && is_user_control(comment)) { ++ if (err < 0 && comment && check_comment_access(comment, "user")) { + err = add_user_control(handle, info, comment); + if (err < 0) { + cerror(doit, "failed to add user control #%d (%s)", +@@ -1305,6 +1303,9 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control, + return -EINVAL; + } + } ++ /* inactive controls are not restored */ ++ if (comment && check_comment_access(comment, "inactive")) ++ return 0; + } + + if (snd_ctl_elem_info_is_inactive(info) || +-- +1.7.2.1 + diff --git a/alsa-utils.changes b/alsa-utils.changes index d011a93..e0142fd 100644 --- a/alsa-utils.changes +++ b/alsa-utils.changes @@ -1,3 +1,21 @@ +------------------------------------------------------------------- +Thu Sep 2 16:06:17 CEST 2010 - tiwai@suse.de + +- backported GIT patches: + * 0001-alsactl-use-snd_config_imake-functions.patch + * 0002-alsactl-move-alloca-out-of-loop.patch + * 0003-alsactl-remove-open-coded-search.patch + * 0004-alsactl-correctly-restore-dB-values-of-controls-with.patch + * 0005-alsactl-change-format-of-comment-node-in-state-file.patch + * 0006-Revert-wrong-parts-of-alsactl-use-snd_config_imake-f.patch + * 0007-aplay-arecord-Added-hardware-pause-support-press-SPA.patch + * 0008-aplay-fix-termio-settings-return-back-old-c_flag-val.patch + * 0009-speaker-test-add-test-pattern-for-PCM-layer-debuggin.patch + * 0010-aplay-arecord-term_c_lflag-variable-might-be-unitial.patch + * 0011-alsactl-init-Use-Found-hardware-instead-Unknown-hard.patch + * 0012-alsactl-init-use-generic-method-instead-guess-method.patch + * 0013-alsactl-Change-handling-of-inactive-controls.patch + ------------------------------------------------------------------- Mon Apr 19 10:39:35 CEST 2010 - tiwai@suse.de diff --git a/alsa-utils.spec b/alsa-utils.spec index 4bdac04..5320f95 100644 --- a/alsa-utils.spec +++ b/alsa-utils.spec @@ -28,11 +28,24 @@ Requires: dialog pciutils AutoReqProv: on Summary: Advanced Linux Sound Architecture Utilities Version: 1.0.23 -Release: 1 +Release: 4 Source: ftp://ftp.alsa-project.org/pub/util/alsa-utils-%{package_version}.tar.bz2 # Patch: alsa-utils-git-fixes.diff -Patch1: alsa-utils-gettext-version-removal.diff -# Patch2: alsa-utils-po-pre-patch.diff +Patch1: 0001-alsactl-use-snd_config_imake-functions.patch +Patch2: 0002-alsactl-move-alloca-out-of-loop.patch +Patch3: 0003-alsactl-remove-open-coded-search.patch +Patch4: 0004-alsactl-correctly-restore-dB-values-of-controls-with.patch +Patch5: 0005-alsactl-change-format-of-comment-node-in-state-file.patch +Patch6: 0006-Revert-wrong-parts-of-alsactl-use-snd_config_imake-f.patch +Patch7: 0007-aplay-arecord-Added-hardware-pause-support-press-SPA.patch +Patch8: 0008-aplay-fix-termio-settings-return-back-old-c_flag-val.patch +Patch9: 0009-speaker-test-add-test-pattern-for-PCM-layer-debuggin.patch +Patch10: 0010-aplay-arecord-term_c_lflag-variable-might-be-unitial.patch +Patch11: 0011-alsactl-init-Use-Found-hardware-instead-Unknown-hard.patch +Patch12: 0012-alsactl-init-use-generic-method-instead-guess-method.patch +Patch13: 0013-alsactl-Change-handling-of-inactive-controls.patch +Patch99: alsa-utils-gettext-version-removal.diff +# Patch100: alsa-utils-po-pre-patch.diff Url: http://www.alsa-project.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -52,11 +65,24 @@ Authors: # fix stupid automake's automatic action sed -i -e's/EXTRA_DIST= config.rpath /EXTRA_DIST=/' Makefile.am # fix po changes in tarball first -# %patch2 -p1 +# %patch100 -p1 # rm -f po/Makefile* po/*.gmo po/*.pot po/*.header po/stamp-* # %patch -p1 -%if %suse_version < 1020 %patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%if %suse_version < 1020 +%patch99 -p1 %endif %build