From 4c35faad78a3c56b861d9e245133a6100a5fff55d088b2c9e226df2b374621ff Mon Sep 17 00:00:00 2001 From: OBS User autobuild Date: Thu, 22 Apr 2010 23:30:53 +0000 Subject: [PATCH 1/4] Accepting request 38518 from multimedia:libs checked in (request 38518) OBS-URL: https://build.opensuse.org/request/show/38518 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa-utils?expand=0&rev=20 --- alsa-utils-1.0.22.tar.bz2 | 3 + alsa-utils-1.0.23.tar.bz2 | 3 - alsa-utils-git-fixes.diff | 1430 +++++++++++++++++++++++++++++++++++++ alsa-utils.changes | 7 - alsa-utils.spec | 12 +- 5 files changed, 1439 insertions(+), 16 deletions(-) create mode 100644 alsa-utils-1.0.22.tar.bz2 delete mode 100644 alsa-utils-1.0.23.tar.bz2 create mode 100644 alsa-utils-git-fixes.diff diff --git a/alsa-utils-1.0.22.tar.bz2 b/alsa-utils-1.0.22.tar.bz2 new file mode 100644 index 0000000..ab7735e --- /dev/null +++ b/alsa-utils-1.0.22.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95133815d2c1c11396d75951b4db253b8c3010ea4c352cfa9fcd7d122cbd8d13 +size 1075216 diff --git a/alsa-utils-1.0.23.tar.bz2 b/alsa-utils-1.0.23.tar.bz2 deleted file mode 100644 index 75917ba..0000000 --- a/alsa-utils-1.0.23.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b7d05e915e25f8540ad151c6dd558cf0fc1e9bb0ee23052d531c983666a1f7b0 -size 1076937 diff --git a/alsa-utils-git-fixes.diff b/alsa-utils-git-fixes.diff new file mode 100644 index 0000000..53ad2ba --- /dev/null +++ b/alsa-utils-git-fixes.diff @@ -0,0 +1,1430 @@ +diff --git a/alsactl/alsactl.c b/alsactl/alsactl.c +index 02e082f..3b5dfda 100644 +--- a/alsactl/alsactl.c ++++ b/alsactl/alsactl.c +@@ -189,5 +189,5 @@ int main(int argc, char *argv[]) + } + + snd_config_update_free_global(); +- return res < 0 ? res : 0; ++ return res < 0 ? -res : 0; + } +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 635a999..e70c6f9 100644 +--- a/alsactl/state.c ++++ b/alsactl/state.c +@@ -1117,7 +1117,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; + } +@@ -1404,6 +1403,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)); +@@ -1415,6 +1415,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) { +@@ -1440,24 +1441,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; + } + +@@ -1582,9 +1584,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 */ +@@ -1617,14 +1619,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 { +@@ -1639,12 +1641,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/alsamixer/mixer_display.c b/alsamixer/mixer_display.c +index 9eadcc9..20d6d6a 100644 +--- a/alsamixer/mixer_display.c ++++ b/alsamixer/mixer_display.c +@@ -390,6 +390,15 @@ static void display_string_centered_in_control(int y, int col, const char *s, in + display_string_in_field(y, x, s, width, ALIGN_CENTER); + } + ++static long clamp(long value, long min, long max) ++{ ++ if (value < min) ++ return min; ++ if (value > max) ++ return max; ++ return value; ++} ++ + static void display_control(unsigned int control_index) + { + struct control *control; +@@ -462,6 +471,10 @@ static void display_control(unsigned int control_index) + err = snd_mixer_selem_get_capture_volume_range(control->elem, &min, &max); + if (err < 0) + return; ++ if (min >= max) ++ max = min + 1; ++ volumes[0] = clamp(volumes[0], min, max); ++ volumes[1] = clamp(volumes[1], min, max); + + if (control->flags & IS_ACTIVE) + wattrset(mixer_widget.window, 0); +diff --git a/amidi/amidi.c b/amidi/amidi.c +index 2e970ae..cedf18c 100644 +--- a/amidi/amidi.c ++++ b/amidi/amidi.c +@@ -95,122 +95,63 @@ static void *my_malloc(size_t size) + return p; + } + +-static int is_input(snd_ctl_t *ctl, int card, int device, int sub) +-{ +- snd_rawmidi_info_t *info; +- int err; +- +- snd_rawmidi_info_alloca(&info); +- snd_rawmidi_info_set_device(info, device); +- snd_rawmidi_info_set_subdevice(info, sub); +- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); +- +- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0 && err != -ENXIO) +- return err; +- else if (err == 0) +- return 1; +- +- return 0; +-} +- +-static int is_output(snd_ctl_t *ctl, int card, int device, int sub) +-{ +- snd_rawmidi_info_t *info; +- int err; +- +- snd_rawmidi_info_alloca(&info); +- snd_rawmidi_info_set_device(info, device); +- snd_rawmidi_info_set_subdevice(info, sub); +- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); +- +- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0 && err != -ENXIO) +- return err; +- else if (err == 0) +- return 1; +- +- return 0; +-} +- + static void list_device(snd_ctl_t *ctl, int card, int device) + { + snd_rawmidi_info_t *info; + const char *name; + const char *sub_name; + int subs, subs_in, subs_out; +- int sub, in, out; ++ int sub; + int err; + + snd_rawmidi_info_alloca(&info); + snd_rawmidi_info_set_device(info, device); + + snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); +- snd_ctl_rawmidi_info(ctl, info); +- subs_in = snd_rawmidi_info_get_subdevices_count(info); ++ err = snd_ctl_rawmidi_info(ctl, info); ++ if (err >= 0) ++ subs_in = snd_rawmidi_info_get_subdevices_count(info); ++ else ++ subs_in = 0; ++ + snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); +- snd_ctl_rawmidi_info(ctl, info); +- subs_out = snd_rawmidi_info_get_subdevices_count(info); +- subs = subs_in > subs_out ? subs_in : subs_out; ++ err = snd_ctl_rawmidi_info(ctl, info); ++ if (err >= 0) ++ subs_out = snd_rawmidi_info_get_subdevices_count(info); ++ else ++ subs_out = 0; + +- sub = 0; +- in = out = 0; +- if ((err = is_output(ctl, card, device, sub)) < 0) { +- error("cannot get rawmidi information %d:%d: %s", +- card, device, snd_strerror(err)); ++ subs = subs_in > subs_out ? subs_in : subs_out; ++ if (!subs) + return; +- } else if (err) +- out = 1; + +- if (err == 0) { +- if ((err = is_input(ctl, card, device, sub)) < 0) { +- error("cannot get rawmidi information %d:%d: %s", +- card, device, snd_strerror(err)); ++ for (sub = 0; sub < subs; ++sub) { ++ snd_rawmidi_info_set_stream(info, sub < subs_in ? ++ SND_RAWMIDI_STREAM_INPUT : ++ SND_RAWMIDI_STREAM_OUTPUT); ++ snd_rawmidi_info_set_subdevice(info, sub); ++ err = snd_ctl_rawmidi_info(ctl, info); ++ if (err < 0) { ++ error("cannot get rawmidi information %d:%d:%d: %s\n", ++ card, device, sub, snd_strerror(err)); + return; + } +- } else if (err) +- in = 1; +- +- if (err == 0) +- return; +- +- name = snd_rawmidi_info_get_name(info); +- sub_name = snd_rawmidi_info_get_subdevice_name(info); +- if (sub_name[0] == '\0') { +- if (subs == 1) { +- printf("%c%c hw:%d,%d %s\n", +- in ? 'I' : ' ', out ? 'O' : ' ', ++ name = snd_rawmidi_info_get_name(info); ++ sub_name = snd_rawmidi_info_get_subdevice_name(info); ++ if (sub == 0 && sub_name[0] == '\0') { ++ printf("%c%c hw:%d,%d %s", ++ sub < subs_in ? 'I' : ' ', ++ sub < subs_out ? 'O' : ' ', + card, device, name); +- } else +- printf("%c%c hw:%d,%d %s (%d subdevices)\n", +- in ? 'I' : ' ', out ? 'O' : ' ', +- card, device, name, subs); +- } else { +- sub = 0; +- for (;;) { ++ if (subs > 1) ++ printf(" (%d subdevices)", subs); ++ putchar('\n'); ++ break; ++ } else { + printf("%c%c hw:%d,%d,%d %s\n", +- in ? 'I' : ' ', out ? 'O' : ' ', ++ sub < subs_in ? 'I' : ' ', ++ sub < subs_out ? 'O' : ' ', + card, device, sub, sub_name); +- if (++sub >= subs) +- break; +- +- in = is_input(ctl, card, device, sub); +- out = is_output(ctl, card, device, sub); +- snd_rawmidi_info_set_subdevice(info, sub); +- if (out) { +- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); +- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0) { +- error("cannot get rawmidi information %d:%d:%d: %s", +- card, device, sub, snd_strerror(err)); +- break; +- } +- } else { +- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); +- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0) { +- error("cannot get rawmidi information %d:%d:%d: %s", +- card, device, sub, snd_strerror(err)); +- break; +- } +- } +- sub_name = snd_rawmidi_info_get_subdevice_name(info); + } + } + } +diff --git a/amixer/amixer.c b/amixer/amixer.c +index 9620721..c9ea572 100644 +--- a/amixer/amixer.c ++++ b/amixer/amixer.c +@@ -534,6 +534,26 @@ static void decode_tlv(unsigned int spaces, unsigned int *tlv, unsigned int tlv_ + } + break; + #endif ++#ifdef SND_CTL_TLVT_DB_MINMAX ++ case SND_CTL_TLVT_DB_MINMAX: ++ case SND_CTL_TLVT_DB_MINMAX_MUTE: ++ if (type == SND_CTL_TLVT_DB_MINMAX_MUTE) ++ printf("dBminmaxmute-"); ++ else ++ printf("dBminmax-"); ++ if (size != 2 * sizeof(unsigned int)) { ++ while (size > 0) { ++ printf("0x%08x,", tlv[idx++]); ++ size -= sizeof(unsigned int); ++ } ++ } else { ++ printf("min="); ++ print_dB(tlv[2]); ++ printf(",max="); ++ print_dB(tlv[3]); ++ } ++ break; ++#endif + default: + printf("unk-%i-", type); + while (size > 0) { +@@ -602,6 +622,8 @@ static int show_control(const char *space, snd_hctl_elem_t *elem, + break; + } + if (level & LEVEL_BASIC) { ++ if (!snd_ctl_elem_info_is_readable(info)) ++ goto __skip_read; + if ((err = snd_hctl_elem_read(elem, control)) < 0) { + error("Control %s element read error: %s\n", card, snd_strerror(err)); + return err; +@@ -638,6 +660,7 @@ static int show_control(const char *space, snd_hctl_elem_t *elem, + } + } + printf("\n"); ++ __skip_read: + if (!snd_ctl_elem_info_is_tlv_readable(info)) + goto __skip_tlv; + tlv = malloc(4096); +diff --git a/aplay/aplay.1 b/aplay/aplay.1 +index 7759347..b6caf0b 100644 +--- a/aplay/aplay.1 ++++ b/aplay/aplay.1 +@@ -1,4 +1,4 @@ +-.TH APLAY 1 "2 August 2001" ++.TH APLAY 1 "1 January 2010" + .SH NAME + arecord, aplay \- command-line sound recorder and player for ALSA + soundcard driver +@@ -46,6 +46,7 @@ If this parameter is omitted the WAVE format is used. + \fI\-c, \-\-channels=#\fP + The number of channels. + The default is one channel. ++Valid values are 1 through 32. + .TP + \fI\-f \-\-format=FORMAT\fP + Sample format +@@ -53,19 +54,23 @@ Sample format + Recognized sample formats are: S8 U8 S16_LE S16_BE U16_LE U16_BE S24_LE + S24_BE U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE FLOAT_LE FLOAT_BE + FLOAT64_LE FLOAT64_BE IEC958_SUBFRAME_LE IEC958_SUBFRAME_BE MU_LAW +-A_LAW IMA_ADPCM MPEG GSM ++A_LAW IMA_ADPCM MPEG GSM SPECIAL S24_3LE S24_3BE U24_3LE U24_3BE S20_3LE ++S20_3BE U20_3LE U20_3BE S18_3LE S18_3BE U18_3LE + .br + Some of these may not be available on selected hardware + .br +-There are also two format shortcuts available: ++The available format shortcuts are: + .nf +-\-f cd (16 bit little endian, 44100, stereo [\-f S16_LE \-c2 \-r44100] ++\-f cd (16 bit little endian, 44100, stereo) [\-f S16_LE \-c2 \-r44100] ++\-f cdr (16 bit big endian, 44100, stereo) [\-f S16_BE \-c2 \-f44100] + \-f dat (16 bit little endian, 48000, stereo) [\-f S16_LE \-c2 \-r48000] + .fi + If no format is given U8 is used. + .TP + \fI\-r, \-\-rate=#\fP + Sampling rate in Hertz. The default rate is 8000 Hertz. ++If the value specified is less than 300, it is taken as the rate in kilohertz. ++Valid values are 2000 through 192000 Hertz. + .TP + \fI\-d, \-\-duration=#\fP + Interrupt after # seconds. +@@ -120,10 +125,69 @@ The stereo VU-meter is available only for 2-channel stereo samples + with interleaved format. + .TP + \fI\-I, \-\-separate\-channels\fP +-One file for each channel ++One file for each channel. This option disables max\-file\-time ++and use\-strftime, and ignores SIGUSR1. The stereo VU meter is ++not available with separate channels. ++.TP ++\fI\-P\fP ++Playback. This is the default if the program is invoked ++by typing aplay. ++.TP ++\fI\-C\fP ++Record. This is the default if the program is invoked ++by typing arecord. ++.TP ++\fI\-\-disable\-resample\fP ++Disable automatic rate resample. ++.TP ++\fI\-\-disable\-channels\fP ++Disable automatic channel conversions. ++.TP ++\fI\-\-disable\-format\fP ++Disable automatic format conversions. ++.TP ++\fI\-\-disable\-softvol\fP ++Disable software volume control (softvol). ++.TP ++\fI\-\-test\-position\fP ++Test ring buffer position. ++.TP ++\fI\-\-test\-coef=\fP ++Test coefficient for ring buffer position; default is 8. ++Expression for validation is: coef * (buffer_size / 2). ++Minimum value is 1. ++.TP ++\fI\-\-test\-nowait\fP ++Do not wait for the ring buffer--eats the whole CPU. ++.TP ++\fI\-\-max\-file\-time\fP ++While recording, when the output file has been accumulating ++sound for this long, ++close it and open a new output file. Default is the maximum ++size supported by the file format: 2 GiB for WAV files. ++This option has no effect if \-\-separate\-channels is ++specified. ++.TP ++\fI\-\-process\-id\-file \fP ++aplay writes its process ID here, so other programs can ++send signals to it. ++.TP ++\fI\-\-use\-strftime\fP ++When recording, interpret %-codes in the file name parameter using ++the strftime facility whenever the output file is opened. The ++important strftime codes are: %Y is the year, %m month, %d day of ++the month, %H hour, %M minute and %S second. In addition, %v is ++the file number, starting at 1. When this option is specified, ++intermediate directories for the output file are created automatically. ++This option has no effect if \-\-separate\-channels is specified. + +-.SS +-Example: ++.SH SIGNALS ++When recording, SIGINT, SIGTERM and SIGABRT will close the output ++file and exit. SIGUSR1 will close the output file, open a new one, ++and continue recording. However, SIGUSR1 does not work with ++\-\-separate\-channels. ++ ++.SH EXAMPLES + + .TP + \fBaplay \-c 1 \-t raw \-r 22050 \-f mu_law foobar\fR +@@ -144,6 +208,19 @@ pcm.copy { + } + .fi + ++.TP ++\fBarecord \-t wav \-max-file_time 30 mon.wav\fP ++Record from the default audio source in monaural, 8,000 samples ++per second, 8 bits per sample. Start a new file every ++30 seconds. File names are mon-nn.wav, where nn increases ++from 01. The file after mon-99.wav is mon-100.wav. ++ ++.TP ++\fBarecord \-f cd \-t wav \-max-file-time 3600 --use-strftime %Y/%m/%d/listen-%H-%M-%v.wav\fP ++Record in stereo from the default audio source. Create a new file ++every hour. The files are placed in directories based on their start dates ++and have names which include their start times and file numbers. ++ + .SH SEE ALSO + \fB + alsamixer(1), +diff --git a/aplay/aplay.c b/aplay/aplay.c +index 22a5fe0..e1d8e6a 100644 +--- a/aplay/aplay.c ++++ b/aplay/aplay.c +@@ -111,11 +111,19 @@ static int test_position = 0; + static int test_coef = 8; + static int test_nowait = 0; + static snd_output_t *log; ++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 int fd = -1; + static off64_t pbrec_count = LLONG_MAX, fdcount; + static int vocmajor, vocminor; + ++static char *pidfile_name = NULL; ++FILE *pidf = NULL; ++static int pidfile_written = 0; ++ + /* needed prototypes */ + + static void playback(char *filename); +@@ -194,7 +202,11 @@ _("Usage: %s [OPTION]... [FILE]...\n" + " --test-position test ring buffer position\n" + " --test-coef=# test coeficient for ring buffer position (default 8)\n" + " expression for validation is: coef * (buffer_size / 2)\n" +-" --test-nowait do not wait for ring buffer - eats whole CPU\n") ++" --test-nowait do not wait for ring buffer - eats whole CPU\n" ++" --max-file-time=# start another output file when the old file has recorded\n" ++" for this many seconds\n" ++" --process-id-file write the process ID here\n" ++" --use-strftime apply the strftime facility to the output file name\n") + , command); + printf(_("Recognized sample formats are:")); + for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) { +@@ -324,6 +336,18 @@ static void version(void) + printf("%s: version " SND_UTIL_VERSION_STR " by Jaroslav Kysela \n", command); + } + ++/* ++ * Subroutine to clean up before exit. ++ */ ++static void prg_exit(int code) ++{ ++ if (handle) ++ snd_pcm_close(handle); ++ if (pidfile_written) ++ remove (pidfile_name); ++ exit(code); ++} ++ + static void signal_handler(int sig) + { + if (verbose==2) +@@ -345,7 +369,14 @@ static void signal_handler(int sig) + snd_pcm_close(handle); + handle = NULL; + } +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); ++} ++ ++/* call on SIGUSR1 signal. */ ++static void signal_handler_recycle (int sig) ++{ ++ /* flag the capture loop to start a new output file */ ++ recycle_capture_file = 1; + } + + enum { +@@ -358,7 +389,10 @@ enum { + OPT_DISABLE_SOFTVOL, + OPT_TEST_POSITION, + OPT_TEST_COEF, +- OPT_TEST_NOWAIT ++ OPT_TEST_NOWAIT, ++ OPT_MAX_FILE_TIME, ++ OPT_PROCESS_ID_FILE, ++ OPT_USE_STRFTIME + }; + + int main(int argc, char *argv[]) +@@ -399,6 +433,9 @@ int main(int argc, char *argv[]) + {"test-position", 0, 0, OPT_TEST_POSITION}, + {"test-coef", 1, 0, OPT_TEST_COEF}, + {"test-nowait", 0, 0, OPT_TEST_NOWAIT}, ++ {"max-file-time", 1, 0, OPT_MAX_FILE_TIME}, ++ {"process-id-file", 1, 0, OPT_PROCESS_ID_FILE}, ++ {"use-strftime", 0, 0, OPT_USE_STRFTIME}, + {0, 0, 0, 0} + }; + char *pcm_name = "default"; +@@ -493,7 +530,7 @@ int main(int argc, char *argv[]) + rhwparams.format = snd_pcm_format_value(optarg); + if (rhwparams.format == SND_PCM_FORMAT_UNKNOWN) { + error(_("wrong extended format '%s'"), optarg); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + break; +@@ -588,6 +625,15 @@ int main(int argc, char *argv[]) + case OPT_TEST_NOWAIT: + test_nowait = 1; + break; ++ case OPT_MAX_FILE_TIME: ++ max_file_time = strtol(optarg, NULL, 0); ++ break; ++ case OPT_PROCESS_ID_FILE: ++ pidfile_name = optarg; ++ break; ++ case OPT_USE_STRFTIME: ++ use_strftime = 1; ++ break; + default: + fprintf(stderr, _("Try `%s --help' for more information.\n"), command); + return 1; +@@ -643,10 +689,24 @@ int main(int argc, char *argv[]) + readn_func = snd_pcm_readn; + } + ++ if (pidfile_name) { ++ errno = 0; ++ pidf = fopen (pidfile_name, "w"); ++ if (pidf) { ++ (void)fprintf (pidf, "%d\n", getpid()); ++ fclose(pidf); ++ pidfile_written = 1; ++ } else { ++ error(_("Cannot create process ID file %s: %s"), ++ pidfile_name, strerror (errno)); ++ return 1; ++ } ++ } + + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGABRT, signal_handler); ++ signal(SIGUSR1, signal_handler_recycle); + if (interleaved) { + if (optind > argc - 1) { + if (stream == SND_PCM_STREAM_PLAYBACK) +@@ -670,10 +730,13 @@ int main(int argc, char *argv[]) + if (verbose==2) + putchar('\n'); + snd_pcm_close(handle); ++ handle = NULL; + free(audiobuf); + __end: + snd_output_close(log); + snd_config_update_free_global(); ++ prg_exit(EXIT_SUCCESS); ++ /* avoid warning */ + return EXIT_SUCCESS; + } + +@@ -725,7 +788,7 @@ static size_t test_wavefile_read(int fd, u_char *buffer, size_t *size, size_t re + return *size; + if ((size_t)safe_read(fd, buffer + *size, reqsize - *size) != reqsize - *size) { + error(_("read error (called from line %i)"), line); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + return *size = reqsize; + } +@@ -735,7 +798,7 @@ static size_t test_wavefile_read(int fd, u_char *buffer, size_t *size, size_t re + blimit = len; \ + if ((buffer = realloc(buffer, blimit)) == NULL) { \ + error(_("not enough memory")); \ +- exit(EXIT_FAILURE); \ ++ prg_exit(EXIT_FAILURE); \ + } \ + } + +@@ -784,7 +847,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) + if (len < sizeof(WaveFmtBody)) { + error(_("unknown length of 'fmt ' chunk (read %u, should be %u at least)"), + len, (u_int)sizeof(WaveFmtBody)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + check_wavefile_space(buffer, len, blimit); + test_wavefile_read(fd, buffer, &size, len, __LINE__); +@@ -794,22 +857,22 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) + if (len < sizeof(WaveFmtExtensibleBody)) { + error(_("unknown length of extensible 'fmt ' chunk (read %u, should be %u at least)"), + len, (u_int)sizeof(WaveFmtExtensibleBody)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (memcmp(fe->guid_tag, WAV_GUID_TAG, 14) != 0) { + error(_("wrong format tag in extensible 'fmt ' chunk")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + f->format = fe->guid_format; + } + if (LE_SHORT(f->format) != WAV_FMT_PCM && + LE_SHORT(f->format) != WAV_FMT_IEEE_FLOAT) { + error(_("can't play WAVE-file format 0x%04x which is not PCM or FLOAT encoded"), LE_SHORT(f->format)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (LE_SHORT(f->channels) < 1) { + error(_("can't play WAVE-files with %d tracks"), LE_SHORT(f->channels)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + hwparams.channels = LE_SHORT(f->channels); + switch (LE_SHORT(f->bit_p_spl)) { +@@ -842,7 +905,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) + default: + error(_(" can't play WAVE-files with sample %d bits in %d bytes wide (%d channels)"), + LE_SHORT(f->bit_p_spl), LE_SHORT(f->byte_p_spl), hwparams.channels); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + break; + case 32: +@@ -854,7 +917,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) + default: + error(_(" can't play WAVE-files with sample %d bits wide"), + LE_SHORT(f->bit_p_spl)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + hwparams.rate = LE_INT(f->sample_fq); + +@@ -936,7 +999,7 @@ static int test_au(int fd, void *buffer) + return -1; + if ((size_t)safe_read(fd, buffer + sizeof(AuHeader), BE_INT(ap->hdr_size) - sizeof(AuHeader)) != BE_INT(ap->hdr_size) - sizeof(AuHeader)) { + error(_("read error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + return 0; + } +@@ -966,7 +1029,7 @@ static void set_params(void) + err = snd_pcm_hw_params_any(handle, params); + if (err < 0) { + error(_("Broken configuration for this PCM: no configurations available")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (mmap_flag) { + snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof()); +@@ -983,18 +1046,18 @@ static void set_params(void) + SND_PCM_ACCESS_RW_NONINTERLEAVED); + if (err < 0) { + error(_("Access type not available")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + err = snd_pcm_hw_params_set_format(handle, params, hwparams.format); + if (err < 0) { + error(_("Sample format non available")); + show_available_sample_formats(params); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + err = snd_pcm_hw_params_set_channels(handle, params, hwparams.channels); + if (err < 0) { + error(_("Channels count non available")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + + #if 0 +@@ -1052,14 +1115,14 @@ static void set_params(void) + if (err < 0) { + error(_("Unable to install hw params:")); + snd_pcm_hw_params_dump(params, log); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + snd_pcm_hw_params_get_period_size(params, &chunk_size, 0); + snd_pcm_hw_params_get_buffer_size(params, &buffer_size); + if (chunk_size == buffer_size) { + error(_("Can't use period equal to buffer size (%lu == %lu)"), + chunk_size, buffer_size); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + snd_pcm_sw_params_current(handle, swparams); + if (avail_min < 0) +@@ -1090,7 +1153,7 @@ static void set_params(void) + if (snd_pcm_sw_params(handle, swparams) < 0) { + error(_("unable to install sw params:")); + snd_pcm_sw_params_dump(swparams, log); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + + if (verbose) +@@ -1102,7 +1165,7 @@ static void set_params(void) + audiobuf = realloc(audiobuf, chunk_bytes); + if (audiobuf == NULL) { + error(_("not enough memory")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + // fprintf(stderr, "real chunk_size = %i, frags = %i, total = %i\n", chunk_size, setup.buf.block.frags, setup.buf.block.frags * chunk_size); + +@@ -1120,7 +1183,7 @@ static void set_params(void) + err = snd_pcm_mmap_begin(handle, &areas, &offset, &size); + if (err < 0) { + error("snd_pcm_mmap_begin problem: %s", snd_strerror(err)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + for (i = 0; i < hwparams.channels; i++) + fprintf(stderr, "mmap_area[%i] = %p,%u,%u (%u)\n", i, areas[i].addr, areas[i].first, areas[i].step, snd_pcm_format_physical_width(hwparams.format)); +@@ -1164,7 +1227,7 @@ static void xrun(void) + snd_pcm_status_alloca(&status); + if ((res = snd_pcm_status(handle, status))<0) { + error(_("status error: %s"), snd_strerror(res)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) { + if (monotonic) { +@@ -1194,7 +1257,7 @@ static void xrun(void) + } + if ((res = snd_pcm_prepare(handle))<0) { + error(_("xrun: prepare error: %s"), snd_strerror(res)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + return; /* ok, data should be accepted again */ + } if (snd_pcm_status_get_state(status) == SND_PCM_STATE_DRAINING) { +@@ -1206,7 +1269,7 @@ static void xrun(void) + fprintf(stderr, _("capture stream format change? attempting recover...\n")); + if ((res = snd_pcm_prepare(handle))<0) { + error(_("xrun(DRAINING): prepare error: %s"), snd_strerror(res)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + return; + } +@@ -1216,7 +1279,7 @@ static void xrun(void) + snd_pcm_status_dump(status, log); + } + error(_("read/write error, state = %s"), snd_pcm_state_name(snd_pcm_status_get_state(status))); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + + /* I/O suspend handler */ +@@ -1233,7 +1296,7 @@ static void suspend(void) + fprintf(stderr, _("Failed. Restarting stream. ")); fflush(stderr); + if ((res = snd_pcm_prepare(handle)) < 0) { + error(_("suspend: prepare error: %s"), snd_strerror(res)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + if (!quiet_mode) +@@ -1538,7 +1601,7 @@ static ssize_t pcm_write(u_char *data, size_t count) + suspend(); + } else if (r < 0) { + error(_("write error: %s"), snd_strerror(r)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (r > 0) { + if (vumeter) +@@ -1584,7 +1647,7 @@ static ssize_t pcm_writev(u_char **data, unsigned int channels, size_t count) + suspend(); + } else if (r < 0) { + error(_("writev error: %s"), snd_strerror(r)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (r > 0) { + if (vumeter) { +@@ -1627,7 +1690,7 @@ static ssize_t pcm_read(u_char *data, size_t rcount) + suspend(); + } else if (r < 0) { + error(_("read error: %s"), snd_strerror(r)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (r > 0) { + if (vumeter) +@@ -1670,7 +1733,7 @@ static ssize_t pcm_readv(u_char **data, unsigned int channels, size_t rcount) + suspend(); + } else if (r < 0) { + error(_("readv error: %s"), snd_strerror(r)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (r > 0) { + if (vumeter) { +@@ -1727,7 +1790,7 @@ static void voc_write_silence(unsigned x) + l = chunk_size; + if (voc_pcm_write(buf, l) != (ssize_t)l) { + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + x -= l; + } +@@ -1769,7 +1832,7 @@ static void voc_play(int fd, int ofs, char *name) + buffer_pos = 0; + if (data == NULL) { + error(_("malloc error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (!quiet_mode) { + fprintf(stderr, _("Playing Creative Labs Channel file '%s'...\n"), name); +@@ -1778,14 +1841,14 @@ static void voc_play(int fd, int ofs, char *name) + while (ofs > (ssize_t)chunk_bytes) { + if ((size_t)safe_read(fd, buf, chunk_bytes) != chunk_bytes) { + error(_("read error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + ofs -= chunk_bytes; + } + if (ofs) { + if (safe_read(fd, buf, ofs) != ofs) { + error(_("read error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + hwparams.format = DEFAULT_FORMAT; +@@ -1809,7 +1872,7 @@ static void voc_play(int fd, int ofs, char *name) + nextblock = buf[0] = 0; + if (l == -1) { + perror(name); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + } +@@ -1953,12 +2016,12 @@ static void voc_play(int fd, int ofs, char *name) + if (output && !quiet_mode) { + if (write(2, data, l) != l) { /* to stderr */ + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } else { + if (voc_pcm_write(data, l) != l) { + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + COUNT(l); +@@ -2005,7 +2068,7 @@ static void begin_voc(int fd, size_t cnt) + + if (write(fd, &vh, sizeof(VocHeader)) != sizeof(VocHeader)) { + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (hwparams.channels > 1) { + /* write an extended block */ +@@ -2014,14 +2077,14 @@ static void begin_voc(int fd, size_t cnt) + bt.datalen_m = bt.datalen_h = 0; + if (write(fd, &bt, sizeof(VocBlockType)) != sizeof(VocBlockType)) { + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + eb.tc = LE_SHORT(65536 - 256000000L / (hwparams.rate << 1)); + eb.pack = 0; + eb.mode = 1; + if (write(fd, &eb, sizeof(VocExtBlock)) != sizeof(VocExtBlock)) { + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + bt.type = 1; +@@ -2031,13 +2094,13 @@ static void begin_voc(int fd, size_t cnt) + bt.datalen_h = (u_char) ((cnt & 0xFF0000) >> 16); + if (write(fd, &bt, sizeof(VocBlockType)) != sizeof(VocBlockType)) { + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + vd.tc = (u_char) (256 - (1000000 / hwparams.rate)); + vd.pack = 0; + if (write(fd, &vd, sizeof(VocVoiceData)) != sizeof(VocVoiceData)) { + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + +@@ -2073,7 +2136,7 @@ static void begin_wave(int fd, size_t cnt) + break; + default: + error(_("Wave doesn't support %s format..."), snd_pcm_format_name(hwparams.format)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + h.magic = WAV_RIFF; + tmp = cnt + sizeof(WaveHeader) + sizeof(WaveChunkHeader) + sizeof(WaveFmtBody) + sizeof(WaveChunkHeader) - 8; +@@ -2109,7 +2172,7 @@ static void begin_wave(int fd, size_t cnt) + write(fd, &f, sizeof(WaveFmtBody)) != sizeof(WaveFmtBody) || + write(fd, &cd, sizeof(WaveChunkHeader)) != sizeof(WaveChunkHeader)) { + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + +@@ -2133,13 +2196,13 @@ static void begin_au(int fd, size_t cnt) + break; + default: + error(_("Sparc Audio doesn't support %s format..."), snd_pcm_format_name(hwparams.format)); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + ah.sample_rate = BE_INT(hwparams.rate); + ah.channels = BE_INT(hwparams.channels); + if (write(fd, &ah, sizeof(AuHeader)) != sizeof(AuHeader)) { + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + +@@ -2153,7 +2216,7 @@ static void end_voc(int fd) + + if (write(fd, &dummy, 1) != 1) { + error(_("write error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + length_seek = sizeof(VocHeader); + if (hwparams.channels > 1) +@@ -2261,7 +2324,7 @@ static void playback_go(int fd, size_t loaded, off64_t count, int rtype, char *n + r = safe_read(fd, audiobuf + l, c); + if (r < 0) { + perror(name); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + fdcount += r; + if (r == 0) +@@ -2300,14 +2363,14 @@ static void playback(char *name) + } else { + if ((fd = open64(name, O_RDONLY, 0)) == -1) { + perror(name); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + /* read the file header */ + dta = sizeof(AuHeader); + if ((size_t)safe_read(fd, audiobuf, dta) != dta) { + error(_("read error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + if (test_au(fd, audiobuf) >= 0) { + rhwparams.format = hwparams.format; +@@ -2319,7 +2382,7 @@ static void playback(char *name) + if ((size_t)safe_read(fd, audiobuf + sizeof(AuHeader), + dta - sizeof(AuHeader)) != dta - sizeof(AuHeader)) { + error(_("read error")); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE);; + } + if ((ofs = test_vocfile(audiobuf)) >= 0) { + pbrec_count = calc_count(); +@@ -2341,13 +2404,98 @@ static void playback(char *name) + close(fd); + } + ++/** ++ * mystrftime ++ * ++ * Variant of strftime(3) that supports additional format ++ * specifiers in the format string. ++ * ++ * Parameters: ++ * ++ * s - destination string ++ * max - max number of bytes to write ++ * userformat - format string ++ * tm - time information ++ * filenumber - the number of the file, starting at 1 ++ * ++ * Returns: number of bytes written to the string s ++ */ ++size_t mystrftime(char *s, size_t max, const char *userformat, ++ const struct tm *tm, const int filenumber) ++{ ++ char formatstring[PATH_MAX] = ""; ++ char tempstring[PATH_MAX] = ""; ++ char *format, *tempstr; ++ const char *pos_userformat; ++ ++ format = formatstring; ++ ++ /* if mystrftime is called with userformat = NULL we return a zero length string */ ++ if (userformat == NULL) { ++ *s = '\0'; ++ return 0; ++ } ++ ++ for (pos_userformat = userformat; *pos_userformat; ++pos_userformat) { ++ if (*pos_userformat == '%') { ++ tempstr = tempstring; ++ tempstr[0] = '\0'; ++ switch (*++pos_userformat) { ++ ++ case '\0': // end of string ++ --pos_userformat; ++ break; ++ ++ case 'v': // file number ++ sprintf(tempstr, "%02d", filenumber); ++ break; ++ ++ default: // All other codes will be handled by strftime ++ *format++ = '%'; ++ *format++ = *pos_userformat; ++ continue; ++ } ++ ++ /* If a format specifier was found and used, copy the result. */ ++ if (tempstr[0]) { ++ while ((*format = *tempstr++) != '\0') ++ ++format; ++ continue; ++ } ++ } ++ ++ /* For any other character than % we simply copy the character */ ++ *format++ = *pos_userformat; ++ } ++ ++ *format = '\0'; ++ format = formatstring; ++ return strftime(s, max, format, tm); ++} ++ + static int new_capture_file(char *name, char *namebuf, size_t namelen, + int filecount) + { +- /* get a copy of the original filename */ + char *s; + char buf[PATH_MAX+1]; ++ time_t t; ++ struct tm *tmp; ++ ++ if (use_strftime) { ++ t = time(NULL); ++ tmp = localtime(&t); ++ if (tmp == NULL) { ++ perror("localtime"); ++ prg_exit(EXIT_FAILURE); ++ } ++ if (mystrftime(namebuf, namelen, name, tmp, filecount+1) == 0) { ++ fprintf(stderr, "mystrftime returned 0"); ++ prg_exit(EXIT_FAILURE); ++ } ++ return filecount; ++ } + ++ /* get a copy of the original filename */ + strncpy(buf, name, sizeof(buf)); + + /* separate extension from filename */ +@@ -2379,6 +2527,58 @@ static int new_capture_file(char *name, char *namebuf, size_t namelen, + return filecount; + } + ++/** ++ * create_path ++ * ++ * This function creates a file path, like mkdir -p. ++ * ++ * Parameters: ++ * ++ * path - the path to create ++ * ++ * Returns: 0 on success, -1 on failure ++ * On failure, a message has been printed to stderr. ++ */ ++int create_path(const char *path) ++{ ++ char *start; ++ mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; ++ ++ if (path[0] == '/') ++ start = strchr(path + 1, '/'); ++ else ++ start = strchr(path, '/'); ++ ++ while (start) { ++ char *buffer = strdup(path); ++ buffer[start-path] = 0x00; ++ ++ if (mkdir(buffer, mode) == -1 && errno != EEXIST) { ++ fprintf(stderr, "Problem creating directory %s", buffer); ++ perror(" "); ++ free(buffer); ++ return -1; ++ } ++ free(buffer); ++ start = strchr(start + 1, '/'); ++ } ++ return 0; ++} ++ ++static int safe_open(const char *name) ++{ ++ int fd; ++ ++ fd = open64(name, O_WRONLY | O_CREAT, 0644); ++ if (fd == -1) { ++ if (errno != ENOENT || !use_strftime) ++ return -1; ++ if (create_path(name) == 0) ++ fd = open64(name, O_WRONLY | O_CREAT, 0644); ++ } ++ return fd; ++} ++ + static void capture(char *orig_name) + { + int tostdout=0; /* boolean which describes output stream */ +@@ -2391,6 +2591,10 @@ static void capture(char *orig_name) + count = calc_count(); + if (count == 0) + count = LLONG_MAX; ++ /* compute the number of bytes per file */ ++ max_file_size = max_file_time * ++ snd_pcm_format_size(hwparams.format, ++ hwparams.rate * hwparams.channels); + /* WAVE-file should be even (I'm not sure), but wasting one byte + isn't a problem (this can only be in 8 bit mono) */ + if (count < LLONG_MAX) +@@ -2417,7 +2621,7 @@ static void capture(char *orig_name) + /* open a file to write */ + if(!tostdout) { + /* upon the second file we start the numbering scheme */ +- if (filecount) { ++ if (filecount || use_strftime) { + filecount = new_capture_file(orig_name, namebuf, + sizeof(namebuf), + filecount); +@@ -2426,9 +2630,10 @@ static void capture(char *orig_name) + + /* open a new file */ + remove(name); +- if ((fd = open64(name, O_WRONLY | O_CREAT, 0644)) == -1) { ++ fd = safe_open(name); ++ if (fd < 0) { + perror(name); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + filecount++; + } +@@ -2436,6 +2641,8 @@ static void capture(char *orig_name) + rest = count; + if (rest > fmt_rec_table[file_type].max_filesize) + rest = fmt_rec_table[file_type].max_filesize; ++ if (max_file_size && (rest > max_file_size)) ++ rest = max_file_size; + + /* setup sample header */ + if (fmt_rec_table[file_type].start) +@@ -2443,7 +2650,7 @@ static void capture(char *orig_name) + + /* capture */ + fdcount = 0; +- while (rest > 0) { ++ while (rest > 0 && recycle_capture_file == 0) { + size_t c = (rest <= (off64_t)chunk_bytes) ? + (size_t)rest : chunk_bytes; + size_t f = c * 8 / bits_per_frame; +@@ -2451,13 +2658,19 @@ static void capture(char *orig_name) + break; + if (write(fd, audiobuf, c) != c) { + perror(name); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + count -= c; + rest -= c; + fdcount += c; + } + ++ /* re-enable SIGUSR1 signal */ ++ if (recycle_capture_file) { ++ recycle_capture_file = 0; ++ signal(SIGUSR1, signal_handler_recycle); ++ } ++ + /* finish sample container */ + if (fmt_rec_table[file_type].end && !tostdout) { + fmt_rec_table[file_type].end(fd); +@@ -2498,12 +2711,12 @@ static void playbackv_go(int* fds, unsigned int channels, size_t loaded, off64_t + r = safe_read(fds[0], bufs[0], expected); + if (r < 0) { + perror(names[channel]); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + for (channel = 1; channel < channels; ++channel) { + if (safe_read(fds[channel], bufs[channel], r) != r) { + perror(names[channel]); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + if (r == 0) +@@ -2550,7 +2763,7 @@ static void capturev_go(int* fds, unsigned int channels, off64_t count, int rtyp + for (channel = 0; channel < channels; ++channel) { + if ((size_t)write(fds[channel], bufs[channel], rv) != rv) { + perror(names[channel]); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + } + r = r * bits_per_frame / 8; +@@ -2583,7 +2796,7 @@ static void playbackv(char **names, unsigned int count) + alloced = 1; + } else if (count != channels) { + error(_("You need to specify %d files"), channels); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + + for (channel = 0; channel < channels; ++channel) { +@@ -2609,7 +2822,7 @@ static void playbackv(char **names, unsigned int count) + if (alloced) + free(names); + if (ret) +- exit(ret); ++ prg_exit(ret); + } + + static void capturev(char **names, unsigned int count) +@@ -2636,7 +2849,7 @@ static void capturev(char **names, unsigned int count) + alloced = 1; + } else if (count != channels) { + error(_("You need to specify %d files"), channels); +- exit(EXIT_FAILURE); ++ prg_exit(EXIT_FAILURE); + } + + for (channel = 0; channel < channels; ++channel) { +@@ -2662,5 +2875,5 @@ static void capturev(char **names, unsigned int count) + if (alloced) + free(names); + if (ret) +- exit(ret); ++ prg_exit(ret); + } +diff --git a/speaker-test/speaker-test.c b/speaker-test/speaker-test.c +index 053ed3b..d8d68e2 100644 +--- a/speaker-test/speaker-test.c ++++ b/speaker-test/speaker-test.c +@@ -689,6 +689,7 @@ static int write_loop(snd_pcm_t *handle, int channel, int periods, uint8_t *fram + double phase = 0; + int err, n; + ++ fflush(stdout); + if (test_type == TEST_WAV) { + int bufsize = snd_pcm_frames_to_bytes(handle, period_size); + n = 0; diff --git a/alsa-utils.changes b/alsa-utils.changes index d011a93..40c062c 100644 --- a/alsa-utils.changes +++ b/alsa-utils.changes @@ -1,10 +1,3 @@ -------------------------------------------------------------------- -Mon Apr 19 10:39:35 CEST 2010 - tiwai@suse.de - -- updated to version 1.0.23: - * including previous fixes - * aconnect -x: Do not update index after removal of connection. - ------------------------------------------------------------------- Mon Mar 8 14:35:52 CET 2010 - tiwai@suse.de diff --git a/alsa-utils.spec b/alsa-utils.spec index 4bdac04..87a34da 100644 --- a/alsa-utils.spec +++ b/alsa-utils.spec @@ -1,5 +1,5 @@ # -# spec file for package alsa-utils (Version 1.0.23) +# spec file for package alsa-utils (Version 1.0.21) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -20,17 +20,17 @@ Name: alsa-utils BuildRequires: alsa-devel ncurses-devel xmlto -%define package_version 1.0.23 +%define package_version 1.0.22 License: GPLv2+ Group: Productivity/Multimedia/Sound/Players Provides: alsa-conf Requires: dialog pciutils AutoReqProv: on Summary: Advanced Linux Sound Architecture Utilities -Version: 1.0.23 -Release: 1 +Version: 1.0.21 +Release: 4 Source: ftp://ftp.alsa-project.org/pub/util/alsa-utils-%{package_version}.tar.bz2 -# Patch: alsa-utils-git-fixes.diff +Patch: alsa-utils-git-fixes.diff Patch1: alsa-utils-gettext-version-removal.diff # Patch2: alsa-utils-po-pre-patch.diff Url: http://www.alsa-project.org/ @@ -54,7 +54,7 @@ sed -i -e's/EXTRA_DIST= config.rpath /EXTRA_DIST=/' Makefile.am # fix po changes in tarball first # %patch2 -p1 # rm -f po/Makefile* po/*.gmo po/*.pot po/*.header po/stamp-* -# %patch -p1 +%patch -p1 %if %suse_version < 1020 %patch1 -p1 %endif From fe30535b09d7719c488e2ce9a1ebbf4c67b4655995aede7d02af1bbc15dcdbd3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Sep 2010 14:08:00 +0000 Subject: [PATCH 2/4] backported patches OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa-utils?expand=0&rev=21 --- ...sactl-use-snd_config_imake-functions.patch | 332 ++++ 0002-alsactl-move-alloca-out-of-loop.patch | 50 + 0003-alsactl-remove-open-coded-search.patch | 79 + ...y-restore-dB-values-of-controls-with.patch | 168 ++ ...format-of-comment-node-in-state-file.patch | 88 + ...ts-of-alsactl-use-snd_config_imake-f.patch | 269 ++++ ...ded-hardware-pause-support-press-SPA.patch | 192 +++ ...-settings-return-back-old-c_flag-val.patch | 75 + ...-test-pattern-for-PCM-layer-debuggin.patch | 129 ++ ...rm_c_lflag-variable-might-be-unitial.patch | 38 + ...-Found-hardware-instead-Unknown-hard.patch | 29 + ...-generic-method-instead-guess-method.patch | 26 + ...Change-handling-of-inactive-controls.patch | 76 + alsa-utils-1.0.22.tar.bz2 | 3 - alsa-utils-1.0.23.tar.bz2 | 3 + alsa-utils-git-fixes.diff | 1430 ----------------- alsa-utils.changes | 25 + alsa-utils.spec | 46 +- 18 files changed, 1615 insertions(+), 1443 deletions(-) create mode 100644 0001-alsactl-use-snd_config_imake-functions.patch create mode 100644 0002-alsactl-move-alloca-out-of-loop.patch create mode 100644 0003-alsactl-remove-open-coded-search.patch create mode 100644 0004-alsactl-correctly-restore-dB-values-of-controls-with.patch create mode 100644 0005-alsactl-change-format-of-comment-node-in-state-file.patch create mode 100644 0006-Revert-wrong-parts-of-alsactl-use-snd_config_imake-f.patch create mode 100644 0007-aplay-arecord-Added-hardware-pause-support-press-SPA.patch create mode 100644 0008-aplay-fix-termio-settings-return-back-old-c_flag-val.patch create mode 100644 0009-speaker-test-add-test-pattern-for-PCM-layer-debuggin.patch create mode 100644 0010-aplay-arecord-term_c_lflag-variable-might-be-unitial.patch create mode 100644 0011-alsactl-init-Use-Found-hardware-instead-Unknown-hard.patch create mode 100644 0012-alsactl-init-use-generic-method-instead-guess-method.patch create mode 100644 0013-alsactl-Change-handling-of-inactive-controls.patch delete mode 100644 alsa-utils-1.0.22.tar.bz2 create mode 100644 alsa-utils-1.0.23.tar.bz2 delete mode 100644 alsa-utils-git-fixes.diff 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-1.0.22.tar.bz2 b/alsa-utils-1.0.22.tar.bz2 deleted file mode 100644 index ab7735e..0000000 --- a/alsa-utils-1.0.22.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:95133815d2c1c11396d75951b4db253b8c3010ea4c352cfa9fcd7d122cbd8d13 -size 1075216 diff --git a/alsa-utils-1.0.23.tar.bz2 b/alsa-utils-1.0.23.tar.bz2 new file mode 100644 index 0000000..75917ba --- /dev/null +++ b/alsa-utils-1.0.23.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7d05e915e25f8540ad151c6dd558cf0fc1e9bb0ee23052d531c983666a1f7b0 +size 1076937 diff --git a/alsa-utils-git-fixes.diff b/alsa-utils-git-fixes.diff deleted file mode 100644 index 53ad2ba..0000000 --- a/alsa-utils-git-fixes.diff +++ /dev/null @@ -1,1430 +0,0 @@ -diff --git a/alsactl/alsactl.c b/alsactl/alsactl.c -index 02e082f..3b5dfda 100644 ---- a/alsactl/alsactl.c -+++ b/alsactl/alsactl.c -@@ -189,5 +189,5 @@ int main(int argc, char *argv[]) - } - - snd_config_update_free_global(); -- return res < 0 ? res : 0; -+ return res < 0 ? -res : 0; - } -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 635a999..e70c6f9 100644 ---- a/alsactl/state.c -+++ b/alsactl/state.c -@@ -1117,7 +1117,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; - } -@@ -1404,6 +1403,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)); -@@ -1415,6 +1415,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) { -@@ -1440,24 +1441,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; - } - -@@ -1582,9 +1584,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 */ -@@ -1617,14 +1619,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 { -@@ -1639,12 +1641,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/alsamixer/mixer_display.c b/alsamixer/mixer_display.c -index 9eadcc9..20d6d6a 100644 ---- a/alsamixer/mixer_display.c -+++ b/alsamixer/mixer_display.c -@@ -390,6 +390,15 @@ static void display_string_centered_in_control(int y, int col, const char *s, in - display_string_in_field(y, x, s, width, ALIGN_CENTER); - } - -+static long clamp(long value, long min, long max) -+{ -+ if (value < min) -+ return min; -+ if (value > max) -+ return max; -+ return value; -+} -+ - static void display_control(unsigned int control_index) - { - struct control *control; -@@ -462,6 +471,10 @@ static void display_control(unsigned int control_index) - err = snd_mixer_selem_get_capture_volume_range(control->elem, &min, &max); - if (err < 0) - return; -+ if (min >= max) -+ max = min + 1; -+ volumes[0] = clamp(volumes[0], min, max); -+ volumes[1] = clamp(volumes[1], min, max); - - if (control->flags & IS_ACTIVE) - wattrset(mixer_widget.window, 0); -diff --git a/amidi/amidi.c b/amidi/amidi.c -index 2e970ae..cedf18c 100644 ---- a/amidi/amidi.c -+++ b/amidi/amidi.c -@@ -95,122 +95,63 @@ static void *my_malloc(size_t size) - return p; - } - --static int is_input(snd_ctl_t *ctl, int card, int device, int sub) --{ -- snd_rawmidi_info_t *info; -- int err; -- -- snd_rawmidi_info_alloca(&info); -- snd_rawmidi_info_set_device(info, device); -- snd_rawmidi_info_set_subdevice(info, sub); -- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); -- -- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0 && err != -ENXIO) -- return err; -- else if (err == 0) -- return 1; -- -- return 0; --} -- --static int is_output(snd_ctl_t *ctl, int card, int device, int sub) --{ -- snd_rawmidi_info_t *info; -- int err; -- -- snd_rawmidi_info_alloca(&info); -- snd_rawmidi_info_set_device(info, device); -- snd_rawmidi_info_set_subdevice(info, sub); -- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); -- -- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0 && err != -ENXIO) -- return err; -- else if (err == 0) -- return 1; -- -- return 0; --} -- - static void list_device(snd_ctl_t *ctl, int card, int device) - { - snd_rawmidi_info_t *info; - const char *name; - const char *sub_name; - int subs, subs_in, subs_out; -- int sub, in, out; -+ int sub; - int err; - - snd_rawmidi_info_alloca(&info); - snd_rawmidi_info_set_device(info, device); - - snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); -- snd_ctl_rawmidi_info(ctl, info); -- subs_in = snd_rawmidi_info_get_subdevices_count(info); -+ err = snd_ctl_rawmidi_info(ctl, info); -+ if (err >= 0) -+ subs_in = snd_rawmidi_info_get_subdevices_count(info); -+ else -+ subs_in = 0; -+ - snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); -- snd_ctl_rawmidi_info(ctl, info); -- subs_out = snd_rawmidi_info_get_subdevices_count(info); -- subs = subs_in > subs_out ? subs_in : subs_out; -+ err = snd_ctl_rawmidi_info(ctl, info); -+ if (err >= 0) -+ subs_out = snd_rawmidi_info_get_subdevices_count(info); -+ else -+ subs_out = 0; - -- sub = 0; -- in = out = 0; -- if ((err = is_output(ctl, card, device, sub)) < 0) { -- error("cannot get rawmidi information %d:%d: %s", -- card, device, snd_strerror(err)); -+ subs = subs_in > subs_out ? subs_in : subs_out; -+ if (!subs) - return; -- } else if (err) -- out = 1; - -- if (err == 0) { -- if ((err = is_input(ctl, card, device, sub)) < 0) { -- error("cannot get rawmidi information %d:%d: %s", -- card, device, snd_strerror(err)); -+ for (sub = 0; sub < subs; ++sub) { -+ snd_rawmidi_info_set_stream(info, sub < subs_in ? -+ SND_RAWMIDI_STREAM_INPUT : -+ SND_RAWMIDI_STREAM_OUTPUT); -+ snd_rawmidi_info_set_subdevice(info, sub); -+ err = snd_ctl_rawmidi_info(ctl, info); -+ if (err < 0) { -+ error("cannot get rawmidi information %d:%d:%d: %s\n", -+ card, device, sub, snd_strerror(err)); - return; - } -- } else if (err) -- in = 1; -- -- if (err == 0) -- return; -- -- name = snd_rawmidi_info_get_name(info); -- sub_name = snd_rawmidi_info_get_subdevice_name(info); -- if (sub_name[0] == '\0') { -- if (subs == 1) { -- printf("%c%c hw:%d,%d %s\n", -- in ? 'I' : ' ', out ? 'O' : ' ', -+ name = snd_rawmidi_info_get_name(info); -+ sub_name = snd_rawmidi_info_get_subdevice_name(info); -+ if (sub == 0 && sub_name[0] == '\0') { -+ printf("%c%c hw:%d,%d %s", -+ sub < subs_in ? 'I' : ' ', -+ sub < subs_out ? 'O' : ' ', - card, device, name); -- } else -- printf("%c%c hw:%d,%d %s (%d subdevices)\n", -- in ? 'I' : ' ', out ? 'O' : ' ', -- card, device, name, subs); -- } else { -- sub = 0; -- for (;;) { -+ if (subs > 1) -+ printf(" (%d subdevices)", subs); -+ putchar('\n'); -+ break; -+ } else { - printf("%c%c hw:%d,%d,%d %s\n", -- in ? 'I' : ' ', out ? 'O' : ' ', -+ sub < subs_in ? 'I' : ' ', -+ sub < subs_out ? 'O' : ' ', - card, device, sub, sub_name); -- if (++sub >= subs) -- break; -- -- in = is_input(ctl, card, device, sub); -- out = is_output(ctl, card, device, sub); -- snd_rawmidi_info_set_subdevice(info, sub); -- if (out) { -- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); -- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0) { -- error("cannot get rawmidi information %d:%d:%d: %s", -- card, device, sub, snd_strerror(err)); -- break; -- } -- } else { -- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); -- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0) { -- error("cannot get rawmidi information %d:%d:%d: %s", -- card, device, sub, snd_strerror(err)); -- break; -- } -- } -- sub_name = snd_rawmidi_info_get_subdevice_name(info); - } - } - } -diff --git a/amixer/amixer.c b/amixer/amixer.c -index 9620721..c9ea572 100644 ---- a/amixer/amixer.c -+++ b/amixer/amixer.c -@@ -534,6 +534,26 @@ static void decode_tlv(unsigned int spaces, unsigned int *tlv, unsigned int tlv_ - } - break; - #endif -+#ifdef SND_CTL_TLVT_DB_MINMAX -+ case SND_CTL_TLVT_DB_MINMAX: -+ case SND_CTL_TLVT_DB_MINMAX_MUTE: -+ if (type == SND_CTL_TLVT_DB_MINMAX_MUTE) -+ printf("dBminmaxmute-"); -+ else -+ printf("dBminmax-"); -+ if (size != 2 * sizeof(unsigned int)) { -+ while (size > 0) { -+ printf("0x%08x,", tlv[idx++]); -+ size -= sizeof(unsigned int); -+ } -+ } else { -+ printf("min="); -+ print_dB(tlv[2]); -+ printf(",max="); -+ print_dB(tlv[3]); -+ } -+ break; -+#endif - default: - printf("unk-%i-", type); - while (size > 0) { -@@ -602,6 +622,8 @@ static int show_control(const char *space, snd_hctl_elem_t *elem, - break; - } - if (level & LEVEL_BASIC) { -+ if (!snd_ctl_elem_info_is_readable(info)) -+ goto __skip_read; - if ((err = snd_hctl_elem_read(elem, control)) < 0) { - error("Control %s element read error: %s\n", card, snd_strerror(err)); - return err; -@@ -638,6 +660,7 @@ static int show_control(const char *space, snd_hctl_elem_t *elem, - } - } - printf("\n"); -+ __skip_read: - if (!snd_ctl_elem_info_is_tlv_readable(info)) - goto __skip_tlv; - tlv = malloc(4096); -diff --git a/aplay/aplay.1 b/aplay/aplay.1 -index 7759347..b6caf0b 100644 ---- a/aplay/aplay.1 -+++ b/aplay/aplay.1 -@@ -1,4 +1,4 @@ --.TH APLAY 1 "2 August 2001" -+.TH APLAY 1 "1 January 2010" - .SH NAME - arecord, aplay \- command-line sound recorder and player for ALSA - soundcard driver -@@ -46,6 +46,7 @@ If this parameter is omitted the WAVE format is used. - \fI\-c, \-\-channels=#\fP - The number of channels. - The default is one channel. -+Valid values are 1 through 32. - .TP - \fI\-f \-\-format=FORMAT\fP - Sample format -@@ -53,19 +54,23 @@ Sample format - Recognized sample formats are: S8 U8 S16_LE S16_BE U16_LE U16_BE S24_LE - S24_BE U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE FLOAT_LE FLOAT_BE - FLOAT64_LE FLOAT64_BE IEC958_SUBFRAME_LE IEC958_SUBFRAME_BE MU_LAW --A_LAW IMA_ADPCM MPEG GSM -+A_LAW IMA_ADPCM MPEG GSM SPECIAL S24_3LE S24_3BE U24_3LE U24_3BE S20_3LE -+S20_3BE U20_3LE U20_3BE S18_3LE S18_3BE U18_3LE - .br - Some of these may not be available on selected hardware - .br --There are also two format shortcuts available: -+The available format shortcuts are: - .nf --\-f cd (16 bit little endian, 44100, stereo [\-f S16_LE \-c2 \-r44100] -+\-f cd (16 bit little endian, 44100, stereo) [\-f S16_LE \-c2 \-r44100] -+\-f cdr (16 bit big endian, 44100, stereo) [\-f S16_BE \-c2 \-f44100] - \-f dat (16 bit little endian, 48000, stereo) [\-f S16_LE \-c2 \-r48000] - .fi - If no format is given U8 is used. - .TP - \fI\-r, \-\-rate=#\fP - Sampling rate in Hertz. The default rate is 8000 Hertz. -+If the value specified is less than 300, it is taken as the rate in kilohertz. -+Valid values are 2000 through 192000 Hertz. - .TP - \fI\-d, \-\-duration=#\fP - Interrupt after # seconds. -@@ -120,10 +125,69 @@ The stereo VU-meter is available only for 2-channel stereo samples - with interleaved format. - .TP - \fI\-I, \-\-separate\-channels\fP --One file for each channel -+One file for each channel. This option disables max\-file\-time -+and use\-strftime, and ignores SIGUSR1. The stereo VU meter is -+not available with separate channels. -+.TP -+\fI\-P\fP -+Playback. This is the default if the program is invoked -+by typing aplay. -+.TP -+\fI\-C\fP -+Record. This is the default if the program is invoked -+by typing arecord. -+.TP -+\fI\-\-disable\-resample\fP -+Disable automatic rate resample. -+.TP -+\fI\-\-disable\-channels\fP -+Disable automatic channel conversions. -+.TP -+\fI\-\-disable\-format\fP -+Disable automatic format conversions. -+.TP -+\fI\-\-disable\-softvol\fP -+Disable software volume control (softvol). -+.TP -+\fI\-\-test\-position\fP -+Test ring buffer position. -+.TP -+\fI\-\-test\-coef=\fP -+Test coefficient for ring buffer position; default is 8. -+Expression for validation is: coef * (buffer_size / 2). -+Minimum value is 1. -+.TP -+\fI\-\-test\-nowait\fP -+Do not wait for the ring buffer--eats the whole CPU. -+.TP -+\fI\-\-max\-file\-time\fP -+While recording, when the output file has been accumulating -+sound for this long, -+close it and open a new output file. Default is the maximum -+size supported by the file format: 2 GiB for WAV files. -+This option has no effect if \-\-separate\-channels is -+specified. -+.TP -+\fI\-\-process\-id\-file \fP -+aplay writes its process ID here, so other programs can -+send signals to it. -+.TP -+\fI\-\-use\-strftime\fP -+When recording, interpret %-codes in the file name parameter using -+the strftime facility whenever the output file is opened. The -+important strftime codes are: %Y is the year, %m month, %d day of -+the month, %H hour, %M minute and %S second. In addition, %v is -+the file number, starting at 1. When this option is specified, -+intermediate directories for the output file are created automatically. -+This option has no effect if \-\-separate\-channels is specified. - --.SS --Example: -+.SH SIGNALS -+When recording, SIGINT, SIGTERM and SIGABRT will close the output -+file and exit. SIGUSR1 will close the output file, open a new one, -+and continue recording. However, SIGUSR1 does not work with -+\-\-separate\-channels. -+ -+.SH EXAMPLES - - .TP - \fBaplay \-c 1 \-t raw \-r 22050 \-f mu_law foobar\fR -@@ -144,6 +208,19 @@ pcm.copy { - } - .fi - -+.TP -+\fBarecord \-t wav \-max-file_time 30 mon.wav\fP -+Record from the default audio source in monaural, 8,000 samples -+per second, 8 bits per sample. Start a new file every -+30 seconds. File names are mon-nn.wav, where nn increases -+from 01. The file after mon-99.wav is mon-100.wav. -+ -+.TP -+\fBarecord \-f cd \-t wav \-max-file-time 3600 --use-strftime %Y/%m/%d/listen-%H-%M-%v.wav\fP -+Record in stereo from the default audio source. Create a new file -+every hour. The files are placed in directories based on their start dates -+and have names which include their start times and file numbers. -+ - .SH SEE ALSO - \fB - alsamixer(1), -diff --git a/aplay/aplay.c b/aplay/aplay.c -index 22a5fe0..e1d8e6a 100644 ---- a/aplay/aplay.c -+++ b/aplay/aplay.c -@@ -111,11 +111,19 @@ static int test_position = 0; - static int test_coef = 8; - static int test_nowait = 0; - static snd_output_t *log; -+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 int fd = -1; - static off64_t pbrec_count = LLONG_MAX, fdcount; - static int vocmajor, vocminor; - -+static char *pidfile_name = NULL; -+FILE *pidf = NULL; -+static int pidfile_written = 0; -+ - /* needed prototypes */ - - static void playback(char *filename); -@@ -194,7 +202,11 @@ _("Usage: %s [OPTION]... [FILE]...\n" - " --test-position test ring buffer position\n" - " --test-coef=# test coeficient for ring buffer position (default 8)\n" - " expression for validation is: coef * (buffer_size / 2)\n" --" --test-nowait do not wait for ring buffer - eats whole CPU\n") -+" --test-nowait do not wait for ring buffer - eats whole CPU\n" -+" --max-file-time=# start another output file when the old file has recorded\n" -+" for this many seconds\n" -+" --process-id-file write the process ID here\n" -+" --use-strftime apply the strftime facility to the output file name\n") - , command); - printf(_("Recognized sample formats are:")); - for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) { -@@ -324,6 +336,18 @@ static void version(void) - printf("%s: version " SND_UTIL_VERSION_STR " by Jaroslav Kysela \n", command); - } - -+/* -+ * Subroutine to clean up before exit. -+ */ -+static void prg_exit(int code) -+{ -+ if (handle) -+ snd_pcm_close(handle); -+ if (pidfile_written) -+ remove (pidfile_name); -+ exit(code); -+} -+ - static void signal_handler(int sig) - { - if (verbose==2) -@@ -345,7 +369,14 @@ static void signal_handler(int sig) - snd_pcm_close(handle); - handle = NULL; - } -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); -+} -+ -+/* call on SIGUSR1 signal. */ -+static void signal_handler_recycle (int sig) -+{ -+ /* flag the capture loop to start a new output file */ -+ recycle_capture_file = 1; - } - - enum { -@@ -358,7 +389,10 @@ enum { - OPT_DISABLE_SOFTVOL, - OPT_TEST_POSITION, - OPT_TEST_COEF, -- OPT_TEST_NOWAIT -+ OPT_TEST_NOWAIT, -+ OPT_MAX_FILE_TIME, -+ OPT_PROCESS_ID_FILE, -+ OPT_USE_STRFTIME - }; - - int main(int argc, char *argv[]) -@@ -399,6 +433,9 @@ int main(int argc, char *argv[]) - {"test-position", 0, 0, OPT_TEST_POSITION}, - {"test-coef", 1, 0, OPT_TEST_COEF}, - {"test-nowait", 0, 0, OPT_TEST_NOWAIT}, -+ {"max-file-time", 1, 0, OPT_MAX_FILE_TIME}, -+ {"process-id-file", 1, 0, OPT_PROCESS_ID_FILE}, -+ {"use-strftime", 0, 0, OPT_USE_STRFTIME}, - {0, 0, 0, 0} - }; - char *pcm_name = "default"; -@@ -493,7 +530,7 @@ int main(int argc, char *argv[]) - rhwparams.format = snd_pcm_format_value(optarg); - if (rhwparams.format == SND_PCM_FORMAT_UNKNOWN) { - error(_("wrong extended format '%s'"), optarg); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - break; -@@ -588,6 +625,15 @@ int main(int argc, char *argv[]) - case OPT_TEST_NOWAIT: - test_nowait = 1; - break; -+ case OPT_MAX_FILE_TIME: -+ max_file_time = strtol(optarg, NULL, 0); -+ break; -+ case OPT_PROCESS_ID_FILE: -+ pidfile_name = optarg; -+ break; -+ case OPT_USE_STRFTIME: -+ use_strftime = 1; -+ break; - default: - fprintf(stderr, _("Try `%s --help' for more information.\n"), command); - return 1; -@@ -643,10 +689,24 @@ int main(int argc, char *argv[]) - readn_func = snd_pcm_readn; - } - -+ if (pidfile_name) { -+ errno = 0; -+ pidf = fopen (pidfile_name, "w"); -+ if (pidf) { -+ (void)fprintf (pidf, "%d\n", getpid()); -+ fclose(pidf); -+ pidfile_written = 1; -+ } else { -+ error(_("Cannot create process ID file %s: %s"), -+ pidfile_name, strerror (errno)); -+ return 1; -+ } -+ } - - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGABRT, signal_handler); -+ signal(SIGUSR1, signal_handler_recycle); - if (interleaved) { - if (optind > argc - 1) { - if (stream == SND_PCM_STREAM_PLAYBACK) -@@ -670,10 +730,13 @@ int main(int argc, char *argv[]) - if (verbose==2) - putchar('\n'); - snd_pcm_close(handle); -+ handle = NULL; - free(audiobuf); - __end: - snd_output_close(log); - snd_config_update_free_global(); -+ prg_exit(EXIT_SUCCESS); -+ /* avoid warning */ - return EXIT_SUCCESS; - } - -@@ -725,7 +788,7 @@ static size_t test_wavefile_read(int fd, u_char *buffer, size_t *size, size_t re - return *size; - if ((size_t)safe_read(fd, buffer + *size, reqsize - *size) != reqsize - *size) { - error(_("read error (called from line %i)"), line); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - return *size = reqsize; - } -@@ -735,7 +798,7 @@ static size_t test_wavefile_read(int fd, u_char *buffer, size_t *size, size_t re - blimit = len; \ - if ((buffer = realloc(buffer, blimit)) == NULL) { \ - error(_("not enough memory")); \ -- exit(EXIT_FAILURE); \ -+ prg_exit(EXIT_FAILURE); \ - } \ - } - -@@ -784,7 +847,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) - if (len < sizeof(WaveFmtBody)) { - error(_("unknown length of 'fmt ' chunk (read %u, should be %u at least)"), - len, (u_int)sizeof(WaveFmtBody)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - check_wavefile_space(buffer, len, blimit); - test_wavefile_read(fd, buffer, &size, len, __LINE__); -@@ -794,22 +857,22 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) - if (len < sizeof(WaveFmtExtensibleBody)) { - error(_("unknown length of extensible 'fmt ' chunk (read %u, should be %u at least)"), - len, (u_int)sizeof(WaveFmtExtensibleBody)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (memcmp(fe->guid_tag, WAV_GUID_TAG, 14) != 0) { - error(_("wrong format tag in extensible 'fmt ' chunk")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - f->format = fe->guid_format; - } - if (LE_SHORT(f->format) != WAV_FMT_PCM && - LE_SHORT(f->format) != WAV_FMT_IEEE_FLOAT) { - error(_("can't play WAVE-file format 0x%04x which is not PCM or FLOAT encoded"), LE_SHORT(f->format)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (LE_SHORT(f->channels) < 1) { - error(_("can't play WAVE-files with %d tracks"), LE_SHORT(f->channels)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - hwparams.channels = LE_SHORT(f->channels); - switch (LE_SHORT(f->bit_p_spl)) { -@@ -842,7 +905,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) - default: - error(_(" can't play WAVE-files with sample %d bits in %d bytes wide (%d channels)"), - LE_SHORT(f->bit_p_spl), LE_SHORT(f->byte_p_spl), hwparams.channels); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - break; - case 32: -@@ -854,7 +917,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) - default: - error(_(" can't play WAVE-files with sample %d bits wide"), - LE_SHORT(f->bit_p_spl)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - hwparams.rate = LE_INT(f->sample_fq); - -@@ -936,7 +999,7 @@ static int test_au(int fd, void *buffer) - return -1; - if ((size_t)safe_read(fd, buffer + sizeof(AuHeader), BE_INT(ap->hdr_size) - sizeof(AuHeader)) != BE_INT(ap->hdr_size) - sizeof(AuHeader)) { - error(_("read error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - return 0; - } -@@ -966,7 +1029,7 @@ static void set_params(void) - err = snd_pcm_hw_params_any(handle, params); - if (err < 0) { - error(_("Broken configuration for this PCM: no configurations available")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (mmap_flag) { - snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof()); -@@ -983,18 +1046,18 @@ static void set_params(void) - SND_PCM_ACCESS_RW_NONINTERLEAVED); - if (err < 0) { - error(_("Access type not available")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - err = snd_pcm_hw_params_set_format(handle, params, hwparams.format); - if (err < 0) { - error(_("Sample format non available")); - show_available_sample_formats(params); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - err = snd_pcm_hw_params_set_channels(handle, params, hwparams.channels); - if (err < 0) { - error(_("Channels count non available")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - - #if 0 -@@ -1052,14 +1115,14 @@ static void set_params(void) - if (err < 0) { - error(_("Unable to install hw params:")); - snd_pcm_hw_params_dump(params, log); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - snd_pcm_hw_params_get_period_size(params, &chunk_size, 0); - snd_pcm_hw_params_get_buffer_size(params, &buffer_size); - if (chunk_size == buffer_size) { - error(_("Can't use period equal to buffer size (%lu == %lu)"), - chunk_size, buffer_size); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - snd_pcm_sw_params_current(handle, swparams); - if (avail_min < 0) -@@ -1090,7 +1153,7 @@ static void set_params(void) - if (snd_pcm_sw_params(handle, swparams) < 0) { - error(_("unable to install sw params:")); - snd_pcm_sw_params_dump(swparams, log); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - - if (verbose) -@@ -1102,7 +1165,7 @@ static void set_params(void) - audiobuf = realloc(audiobuf, chunk_bytes); - if (audiobuf == NULL) { - error(_("not enough memory")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - // fprintf(stderr, "real chunk_size = %i, frags = %i, total = %i\n", chunk_size, setup.buf.block.frags, setup.buf.block.frags * chunk_size); - -@@ -1120,7 +1183,7 @@ static void set_params(void) - err = snd_pcm_mmap_begin(handle, &areas, &offset, &size); - if (err < 0) { - error("snd_pcm_mmap_begin problem: %s", snd_strerror(err)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - for (i = 0; i < hwparams.channels; i++) - fprintf(stderr, "mmap_area[%i] = %p,%u,%u (%u)\n", i, areas[i].addr, areas[i].first, areas[i].step, snd_pcm_format_physical_width(hwparams.format)); -@@ -1164,7 +1227,7 @@ static void xrun(void) - snd_pcm_status_alloca(&status); - if ((res = snd_pcm_status(handle, status))<0) { - error(_("status error: %s"), snd_strerror(res)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) { - if (monotonic) { -@@ -1194,7 +1257,7 @@ static void xrun(void) - } - if ((res = snd_pcm_prepare(handle))<0) { - error(_("xrun: prepare error: %s"), snd_strerror(res)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - return; /* ok, data should be accepted again */ - } if (snd_pcm_status_get_state(status) == SND_PCM_STATE_DRAINING) { -@@ -1206,7 +1269,7 @@ static void xrun(void) - fprintf(stderr, _("capture stream format change? attempting recover...\n")); - if ((res = snd_pcm_prepare(handle))<0) { - error(_("xrun(DRAINING): prepare error: %s"), snd_strerror(res)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - return; - } -@@ -1216,7 +1279,7 @@ static void xrun(void) - snd_pcm_status_dump(status, log); - } - error(_("read/write error, state = %s"), snd_pcm_state_name(snd_pcm_status_get_state(status))); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - - /* I/O suspend handler */ -@@ -1233,7 +1296,7 @@ static void suspend(void) - fprintf(stderr, _("Failed. Restarting stream. ")); fflush(stderr); - if ((res = snd_pcm_prepare(handle)) < 0) { - error(_("suspend: prepare error: %s"), snd_strerror(res)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - if (!quiet_mode) -@@ -1538,7 +1601,7 @@ static ssize_t pcm_write(u_char *data, size_t count) - suspend(); - } else if (r < 0) { - error(_("write error: %s"), snd_strerror(r)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (r > 0) { - if (vumeter) -@@ -1584,7 +1647,7 @@ static ssize_t pcm_writev(u_char **data, unsigned int channels, size_t count) - suspend(); - } else if (r < 0) { - error(_("writev error: %s"), snd_strerror(r)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (r > 0) { - if (vumeter) { -@@ -1627,7 +1690,7 @@ static ssize_t pcm_read(u_char *data, size_t rcount) - suspend(); - } else if (r < 0) { - error(_("read error: %s"), snd_strerror(r)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (r > 0) { - if (vumeter) -@@ -1670,7 +1733,7 @@ static ssize_t pcm_readv(u_char **data, unsigned int channels, size_t rcount) - suspend(); - } else if (r < 0) { - error(_("readv error: %s"), snd_strerror(r)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (r > 0) { - if (vumeter) { -@@ -1727,7 +1790,7 @@ static void voc_write_silence(unsigned x) - l = chunk_size; - if (voc_pcm_write(buf, l) != (ssize_t)l) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - x -= l; - } -@@ -1769,7 +1832,7 @@ static void voc_play(int fd, int ofs, char *name) - buffer_pos = 0; - if (data == NULL) { - error(_("malloc error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (!quiet_mode) { - fprintf(stderr, _("Playing Creative Labs Channel file '%s'...\n"), name); -@@ -1778,14 +1841,14 @@ static void voc_play(int fd, int ofs, char *name) - while (ofs > (ssize_t)chunk_bytes) { - if ((size_t)safe_read(fd, buf, chunk_bytes) != chunk_bytes) { - error(_("read error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - ofs -= chunk_bytes; - } - if (ofs) { - if (safe_read(fd, buf, ofs) != ofs) { - error(_("read error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - hwparams.format = DEFAULT_FORMAT; -@@ -1809,7 +1872,7 @@ static void voc_play(int fd, int ofs, char *name) - nextblock = buf[0] = 0; - if (l == -1) { - perror(name); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - } -@@ -1953,12 +2016,12 @@ static void voc_play(int fd, int ofs, char *name) - if (output && !quiet_mode) { - if (write(2, data, l) != l) { /* to stderr */ - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } else { - if (voc_pcm_write(data, l) != l) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - COUNT(l); -@@ -2005,7 +2068,7 @@ static void begin_voc(int fd, size_t cnt) - - if (write(fd, &vh, sizeof(VocHeader)) != sizeof(VocHeader)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (hwparams.channels > 1) { - /* write an extended block */ -@@ -2014,14 +2077,14 @@ static void begin_voc(int fd, size_t cnt) - bt.datalen_m = bt.datalen_h = 0; - if (write(fd, &bt, sizeof(VocBlockType)) != sizeof(VocBlockType)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - eb.tc = LE_SHORT(65536 - 256000000L / (hwparams.rate << 1)); - eb.pack = 0; - eb.mode = 1; - if (write(fd, &eb, sizeof(VocExtBlock)) != sizeof(VocExtBlock)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - bt.type = 1; -@@ -2031,13 +2094,13 @@ static void begin_voc(int fd, size_t cnt) - bt.datalen_h = (u_char) ((cnt & 0xFF0000) >> 16); - if (write(fd, &bt, sizeof(VocBlockType)) != sizeof(VocBlockType)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - vd.tc = (u_char) (256 - (1000000 / hwparams.rate)); - vd.pack = 0; - if (write(fd, &vd, sizeof(VocVoiceData)) != sizeof(VocVoiceData)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - -@@ -2073,7 +2136,7 @@ static void begin_wave(int fd, size_t cnt) - break; - default: - error(_("Wave doesn't support %s format..."), snd_pcm_format_name(hwparams.format)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - h.magic = WAV_RIFF; - tmp = cnt + sizeof(WaveHeader) + sizeof(WaveChunkHeader) + sizeof(WaveFmtBody) + sizeof(WaveChunkHeader) - 8; -@@ -2109,7 +2172,7 @@ static void begin_wave(int fd, size_t cnt) - write(fd, &f, sizeof(WaveFmtBody)) != sizeof(WaveFmtBody) || - write(fd, &cd, sizeof(WaveChunkHeader)) != sizeof(WaveChunkHeader)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - -@@ -2133,13 +2196,13 @@ static void begin_au(int fd, size_t cnt) - break; - default: - error(_("Sparc Audio doesn't support %s format..."), snd_pcm_format_name(hwparams.format)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - ah.sample_rate = BE_INT(hwparams.rate); - ah.channels = BE_INT(hwparams.channels); - if (write(fd, &ah, sizeof(AuHeader)) != sizeof(AuHeader)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - -@@ -2153,7 +2216,7 @@ static void end_voc(int fd) - - if (write(fd, &dummy, 1) != 1) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - length_seek = sizeof(VocHeader); - if (hwparams.channels > 1) -@@ -2261,7 +2324,7 @@ static void playback_go(int fd, size_t loaded, off64_t count, int rtype, char *n - r = safe_read(fd, audiobuf + l, c); - if (r < 0) { - perror(name); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - fdcount += r; - if (r == 0) -@@ -2300,14 +2363,14 @@ static void playback(char *name) - } else { - if ((fd = open64(name, O_RDONLY, 0)) == -1) { - perror(name); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - /* read the file header */ - dta = sizeof(AuHeader); - if ((size_t)safe_read(fd, audiobuf, dta) != dta) { - error(_("read error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (test_au(fd, audiobuf) >= 0) { - rhwparams.format = hwparams.format; -@@ -2319,7 +2382,7 @@ static void playback(char *name) - if ((size_t)safe_read(fd, audiobuf + sizeof(AuHeader), - dta - sizeof(AuHeader)) != dta - sizeof(AuHeader)) { - error(_("read error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE);; - } - if ((ofs = test_vocfile(audiobuf)) >= 0) { - pbrec_count = calc_count(); -@@ -2341,13 +2404,98 @@ static void playback(char *name) - close(fd); - } - -+/** -+ * mystrftime -+ * -+ * Variant of strftime(3) that supports additional format -+ * specifiers in the format string. -+ * -+ * Parameters: -+ * -+ * s - destination string -+ * max - max number of bytes to write -+ * userformat - format string -+ * tm - time information -+ * filenumber - the number of the file, starting at 1 -+ * -+ * Returns: number of bytes written to the string s -+ */ -+size_t mystrftime(char *s, size_t max, const char *userformat, -+ const struct tm *tm, const int filenumber) -+{ -+ char formatstring[PATH_MAX] = ""; -+ char tempstring[PATH_MAX] = ""; -+ char *format, *tempstr; -+ const char *pos_userformat; -+ -+ format = formatstring; -+ -+ /* if mystrftime is called with userformat = NULL we return a zero length string */ -+ if (userformat == NULL) { -+ *s = '\0'; -+ return 0; -+ } -+ -+ for (pos_userformat = userformat; *pos_userformat; ++pos_userformat) { -+ if (*pos_userformat == '%') { -+ tempstr = tempstring; -+ tempstr[0] = '\0'; -+ switch (*++pos_userformat) { -+ -+ case '\0': // end of string -+ --pos_userformat; -+ break; -+ -+ case 'v': // file number -+ sprintf(tempstr, "%02d", filenumber); -+ break; -+ -+ default: // All other codes will be handled by strftime -+ *format++ = '%'; -+ *format++ = *pos_userformat; -+ continue; -+ } -+ -+ /* If a format specifier was found and used, copy the result. */ -+ if (tempstr[0]) { -+ while ((*format = *tempstr++) != '\0') -+ ++format; -+ continue; -+ } -+ } -+ -+ /* For any other character than % we simply copy the character */ -+ *format++ = *pos_userformat; -+ } -+ -+ *format = '\0'; -+ format = formatstring; -+ return strftime(s, max, format, tm); -+} -+ - static int new_capture_file(char *name, char *namebuf, size_t namelen, - int filecount) - { -- /* get a copy of the original filename */ - char *s; - char buf[PATH_MAX+1]; -+ time_t t; -+ struct tm *tmp; -+ -+ if (use_strftime) { -+ t = time(NULL); -+ tmp = localtime(&t); -+ if (tmp == NULL) { -+ perror("localtime"); -+ prg_exit(EXIT_FAILURE); -+ } -+ if (mystrftime(namebuf, namelen, name, tmp, filecount+1) == 0) { -+ fprintf(stderr, "mystrftime returned 0"); -+ prg_exit(EXIT_FAILURE); -+ } -+ return filecount; -+ } - -+ /* get a copy of the original filename */ - strncpy(buf, name, sizeof(buf)); - - /* separate extension from filename */ -@@ -2379,6 +2527,58 @@ static int new_capture_file(char *name, char *namebuf, size_t namelen, - return filecount; - } - -+/** -+ * create_path -+ * -+ * This function creates a file path, like mkdir -p. -+ * -+ * Parameters: -+ * -+ * path - the path to create -+ * -+ * Returns: 0 on success, -1 on failure -+ * On failure, a message has been printed to stderr. -+ */ -+int create_path(const char *path) -+{ -+ char *start; -+ mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; -+ -+ if (path[0] == '/') -+ start = strchr(path + 1, '/'); -+ else -+ start = strchr(path, '/'); -+ -+ while (start) { -+ char *buffer = strdup(path); -+ buffer[start-path] = 0x00; -+ -+ if (mkdir(buffer, mode) == -1 && errno != EEXIST) { -+ fprintf(stderr, "Problem creating directory %s", buffer); -+ perror(" "); -+ free(buffer); -+ return -1; -+ } -+ free(buffer); -+ start = strchr(start + 1, '/'); -+ } -+ return 0; -+} -+ -+static int safe_open(const char *name) -+{ -+ int fd; -+ -+ fd = open64(name, O_WRONLY | O_CREAT, 0644); -+ if (fd == -1) { -+ if (errno != ENOENT || !use_strftime) -+ return -1; -+ if (create_path(name) == 0) -+ fd = open64(name, O_WRONLY | O_CREAT, 0644); -+ } -+ return fd; -+} -+ - static void capture(char *orig_name) - { - int tostdout=0; /* boolean which describes output stream */ -@@ -2391,6 +2591,10 @@ static void capture(char *orig_name) - count = calc_count(); - if (count == 0) - count = LLONG_MAX; -+ /* compute the number of bytes per file */ -+ max_file_size = max_file_time * -+ snd_pcm_format_size(hwparams.format, -+ hwparams.rate * hwparams.channels); - /* WAVE-file should be even (I'm not sure), but wasting one byte - isn't a problem (this can only be in 8 bit mono) */ - if (count < LLONG_MAX) -@@ -2417,7 +2621,7 @@ static void capture(char *orig_name) - /* open a file to write */ - if(!tostdout) { - /* upon the second file we start the numbering scheme */ -- if (filecount) { -+ if (filecount || use_strftime) { - filecount = new_capture_file(orig_name, namebuf, - sizeof(namebuf), - filecount); -@@ -2426,9 +2630,10 @@ static void capture(char *orig_name) - - /* open a new file */ - remove(name); -- if ((fd = open64(name, O_WRONLY | O_CREAT, 0644)) == -1) { -+ fd = safe_open(name); -+ if (fd < 0) { - perror(name); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - filecount++; - } -@@ -2436,6 +2641,8 @@ static void capture(char *orig_name) - rest = count; - if (rest > fmt_rec_table[file_type].max_filesize) - rest = fmt_rec_table[file_type].max_filesize; -+ if (max_file_size && (rest > max_file_size)) -+ rest = max_file_size; - - /* setup sample header */ - if (fmt_rec_table[file_type].start) -@@ -2443,7 +2650,7 @@ static void capture(char *orig_name) - - /* capture */ - fdcount = 0; -- while (rest > 0) { -+ while (rest > 0 && recycle_capture_file == 0) { - size_t c = (rest <= (off64_t)chunk_bytes) ? - (size_t)rest : chunk_bytes; - size_t f = c * 8 / bits_per_frame; -@@ -2451,13 +2658,19 @@ static void capture(char *orig_name) - break; - if (write(fd, audiobuf, c) != c) { - perror(name); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - count -= c; - rest -= c; - fdcount += c; - } - -+ /* re-enable SIGUSR1 signal */ -+ if (recycle_capture_file) { -+ recycle_capture_file = 0; -+ signal(SIGUSR1, signal_handler_recycle); -+ } -+ - /* finish sample container */ - if (fmt_rec_table[file_type].end && !tostdout) { - fmt_rec_table[file_type].end(fd); -@@ -2498,12 +2711,12 @@ static void playbackv_go(int* fds, unsigned int channels, size_t loaded, off64_t - r = safe_read(fds[0], bufs[0], expected); - if (r < 0) { - perror(names[channel]); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - for (channel = 1; channel < channels; ++channel) { - if (safe_read(fds[channel], bufs[channel], r) != r) { - perror(names[channel]); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - if (r == 0) -@@ -2550,7 +2763,7 @@ static void capturev_go(int* fds, unsigned int channels, off64_t count, int rtyp - for (channel = 0; channel < channels; ++channel) { - if ((size_t)write(fds[channel], bufs[channel], rv) != rv) { - perror(names[channel]); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - r = r * bits_per_frame / 8; -@@ -2583,7 +2796,7 @@ static void playbackv(char **names, unsigned int count) - alloced = 1; - } else if (count != channels) { - error(_("You need to specify %d files"), channels); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - - for (channel = 0; channel < channels; ++channel) { -@@ -2609,7 +2822,7 @@ static void playbackv(char **names, unsigned int count) - if (alloced) - free(names); - if (ret) -- exit(ret); -+ prg_exit(ret); - } - - static void capturev(char **names, unsigned int count) -@@ -2636,7 +2849,7 @@ static void capturev(char **names, unsigned int count) - alloced = 1; - } else if (count != channels) { - error(_("You need to specify %d files"), channels); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - - for (channel = 0; channel < channels; ++channel) { -@@ -2662,5 +2875,5 @@ static void capturev(char **names, unsigned int count) - if (alloced) - free(names); - if (ret) -- exit(ret); -+ prg_exit(ret); - } -diff --git a/speaker-test/speaker-test.c b/speaker-test/speaker-test.c -index 053ed3b..d8d68e2 100644 ---- a/speaker-test/speaker-test.c -+++ b/speaker-test/speaker-test.c -@@ -689,6 +689,7 @@ static int write_loop(snd_pcm_t *handle, int channel, int periods, uint8_t *fram - double phase = 0; - int err, n; - -+ fflush(stdout); - if (test_type == TEST_WAV) { - int bufsize = snd_pcm_frames_to_bytes(handle, period_size); - n = 0; diff --git a/alsa-utils.changes b/alsa-utils.changes index 40c062c..e0142fd 100644 --- a/alsa-utils.changes +++ b/alsa-utils.changes @@ -1,3 +1,28 @@ +------------------------------------------------------------------- +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 + +- updated to version 1.0.23: + * including previous fixes + * aconnect -x: Do not update index after removal of connection. + ------------------------------------------------------------------- Mon Mar 8 14:35:52 CET 2010 - tiwai@suse.de diff --git a/alsa-utils.spec b/alsa-utils.spec index 87a34da..f0efc93 100644 --- a/alsa-utils.spec +++ b/alsa-utils.spec @@ -1,5 +1,5 @@ # -# spec file for package alsa-utils (Version 1.0.21) +# spec file for package alsa-utils (Version 1.0.23) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -20,19 +20,32 @@ Name: alsa-utils BuildRequires: alsa-devel ncurses-devel xmlto -%define package_version 1.0.22 +%define package_version 1.0.23 License: GPLv2+ Group: Productivity/Multimedia/Sound/Players Provides: alsa-conf Requires: dialog pciutils AutoReqProv: on Summary: Advanced Linux Sound Architecture Utilities -Version: 1.0.21 -Release: 4 +Version: 1.0.23 +Release: 1 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 +# Patch: alsa-utils-git-fixes.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 +# %patch -p1 %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 From 41e82fa07866a18c6f29d499fdfda87673348ffbf5e3addcc490303a65a9ceef Mon Sep 17 00:00:00 2001 From: OBS User autobuild Date: Fri, 3 Sep 2010 14:46:02 +0000 Subject: [PATCH 3/4] Accepting request 47042 from multimedia:libs checked in (request 47042) OBS-URL: https://build.opensuse.org/request/show/47042 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa-utils?expand=0&rev=22 --- ...sactl-use-snd_config_imake-functions.patch | 332 ------------------ 0002-alsactl-move-alloca-out-of-loop.patch | 50 --- 0003-alsactl-remove-open-coded-search.patch | 79 ----- ...y-restore-dB-values-of-controls-with.patch | 168 --------- ...format-of-comment-node-in-state-file.patch | 88 ----- ...ts-of-alsactl-use-snd_config_imake-f.patch | 269 -------------- ...ded-hardware-pause-support-press-SPA.patch | 192 ---------- ...-settings-return-back-old-c_flag-val.patch | 75 ---- ...-test-pattern-for-PCM-layer-debuggin.patch | 129 ------- ...rm_c_lflag-variable-might-be-unitial.patch | 38 -- ...-Found-hardware-instead-Unknown-hard.patch | 29 -- ...-generic-method-instead-guess-method.patch | 26 -- ...Change-handling-of-inactive-controls.patch | 76 ---- alsa-utils.changes | 18 - alsa-utils.spec | 34 +- 15 files changed, 4 insertions(+), 1599 deletions(-) delete mode 100644 0001-alsactl-use-snd_config_imake-functions.patch delete mode 100644 0002-alsactl-move-alloca-out-of-loop.patch delete mode 100644 0003-alsactl-remove-open-coded-search.patch delete mode 100644 0004-alsactl-correctly-restore-dB-values-of-controls-with.patch delete mode 100644 0005-alsactl-change-format-of-comment-node-in-state-file.patch delete mode 100644 0006-Revert-wrong-parts-of-alsactl-use-snd_config_imake-f.patch delete mode 100644 0007-aplay-arecord-Added-hardware-pause-support-press-SPA.patch delete mode 100644 0008-aplay-fix-termio-settings-return-back-old-c_flag-val.patch delete mode 100644 0009-speaker-test-add-test-pattern-for-PCM-layer-debuggin.patch delete mode 100644 0010-aplay-arecord-term_c_lflag-variable-might-be-unitial.patch delete mode 100644 0011-alsactl-init-Use-Found-hardware-instead-Unknown-hard.patch delete mode 100644 0012-alsactl-init-use-generic-method-instead-guess-method.patch delete mode 100644 0013-alsactl-Change-handling-of-inactive-controls.patch diff --git a/0001-alsactl-use-snd_config_imake-functions.patch b/0001-alsactl-use-snd_config_imake-functions.patch deleted file mode 100644 index d775da8..0000000 --- a/0001-alsactl-use-snd_config_imake-functions.patch +++ /dev/null @@ -1,332 +0,0 @@ -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 deleted file mode 100644 index 12d69bf..0000000 --- a/0002-alsactl-move-alloca-out-of-loop.patch +++ /dev/null @@ -1,50 +0,0 @@ -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 deleted file mode 100644 index 8d8830d..0000000 --- a/0003-alsactl-remove-open-coded-search.patch +++ /dev/null @@ -1,79 +0,0 @@ -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 deleted file mode 100644 index df02e62..0000000 --- a/0004-alsactl-correctly-restore-dB-values-of-controls-with.patch +++ /dev/null @@ -1,168 +0,0 @@ -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 deleted file mode 100644 index cb0cafb..0000000 --- a/0005-alsactl-change-format-of-comment-node-in-state-file.patch +++ /dev/null @@ -1,88 +0,0 @@ -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 deleted file mode 100644 index d057740..0000000 --- a/0006-Revert-wrong-parts-of-alsactl-use-snd_config_imake-f.patch +++ /dev/null @@ -1,269 +0,0 @@ -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 deleted file mode 100644 index 7397b2c..0000000 --- a/0007-aplay-arecord-Added-hardware-pause-support-press-SPA.patch +++ /dev/null @@ -1,192 +0,0 @@ -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 deleted file mode 100644 index d467e48..0000000 --- a/0008-aplay-fix-termio-settings-return-back-old-c_flag-val.patch +++ /dev/null @@ -1,75 +0,0 @@ -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 deleted file mode 100644 index ce002d6..0000000 --- a/0009-speaker-test-add-test-pattern-for-PCM-layer-debuggin.patch +++ /dev/null @@ -1,129 +0,0 @@ -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 deleted file mode 100644 index 0608bf7..0000000 --- a/0010-aplay-arecord-term_c_lflag-variable-might-be-unitial.patch +++ /dev/null @@ -1,38 +0,0 @@ -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 deleted file mode 100644 index 0fbb839..0000000 --- a/0011-alsactl-init-Use-Found-hardware-instead-Unknown-hard.patch +++ /dev/null @@ -1,29 +0,0 @@ -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 deleted file mode 100644 index 8d73f07..0000000 --- a/0012-alsactl-init-use-generic-method-instead-guess-method.patch +++ /dev/null @@ -1,26 +0,0 @@ -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 deleted file mode 100644 index 3572bce..0000000 --- a/0013-alsactl-Change-handling-of-inactive-controls.patch +++ /dev/null @@ -1,76 +0,0 @@ -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 e0142fd..d011a93 100644 --- a/alsa-utils.changes +++ b/alsa-utils.changes @@ -1,21 +1,3 @@ -------------------------------------------------------------------- -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 f0efc93..4bdac04 100644 --- a/alsa-utils.spec +++ b/alsa-utils.spec @@ -31,21 +31,8 @@ Version: 1.0.23 Release: 1 Source: ftp://ftp.alsa-project.org/pub/util/alsa-utils-%{package_version}.tar.bz2 # Patch: alsa-utils-git-fixes.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 +Patch1: alsa-utils-gettext-version-removal.diff +# Patch2: alsa-utils-po-pre-patch.diff Url: http://www.alsa-project.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -65,24 +52,11 @@ 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 -# %patch100 -p1 +# %patch2 -p1 # rm -f po/Makefile* po/*.gmo po/*.pot po/*.header po/stamp-* # %patch -p1 -%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 +%patch1 -p1 %endif %build From 00b65323134035a561eeb6ce3e0cad3c489c8f51cd24536ee7f46544f4bd1771 Mon Sep 17 00:00:00 2001 From: OBS User buildservice-autocommit Date: Fri, 3 Sep 2010 14:46:03 +0000 Subject: [PATCH 4/4] Updating link to change in openSUSE:Factory/alsa-utils revision 44.0 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa-utils?expand=0&rev=f8742572cdd457612a5394a3f2e4416c --- ...sactl-use-snd_config_imake-functions.patch | 332 ++++++++++++++++++ 0002-alsactl-move-alloca-out-of-loop.patch | 50 +++ 0003-alsactl-remove-open-coded-search.patch | 79 +++++ ...y-restore-dB-values-of-controls-with.patch | 168 +++++++++ ...format-of-comment-node-in-state-file.patch | 88 +++++ ...ts-of-alsactl-use-snd_config_imake-f.patch | 269 ++++++++++++++ ...ded-hardware-pause-support-press-SPA.patch | 192 ++++++++++ ...-settings-return-back-old-c_flag-val.patch | 75 ++++ ...-test-pattern-for-PCM-layer-debuggin.patch | 129 +++++++ ...rm_c_lflag-variable-might-be-unitial.patch | 38 ++ ...-Found-hardware-instead-Unknown-hard.patch | 29 ++ ...-generic-method-instead-guess-method.patch | 26 ++ ...Change-handling-of-inactive-controls.patch | 76 ++++ alsa-utils.changes | 18 + alsa-utils.spec | 36 +- 15 files changed, 1600 insertions(+), 5 deletions(-) create mode 100644 0001-alsactl-use-snd_config_imake-functions.patch create mode 100644 0002-alsactl-move-alloca-out-of-loop.patch create mode 100644 0003-alsactl-remove-open-coded-search.patch create mode 100644 0004-alsactl-correctly-restore-dB-values-of-controls-with.patch create mode 100644 0005-alsactl-change-format-of-comment-node-in-state-file.patch create mode 100644 0006-Revert-wrong-parts-of-alsactl-use-snd_config_imake-f.patch create mode 100644 0007-aplay-arecord-Added-hardware-pause-support-press-SPA.patch create mode 100644 0008-aplay-fix-termio-settings-return-back-old-c_flag-val.patch create mode 100644 0009-speaker-test-add-test-pattern-for-PCM-layer-debuggin.patch create mode 100644 0010-aplay-arecord-term_c_lflag-variable-might-be-unitial.patch create mode 100644 0011-alsactl-init-Use-Found-hardware-instead-Unknown-hard.patch create mode 100644 0012-alsactl-init-use-generic-method-instead-guess-method.patch create mode 100644 0013-alsactl-Change-handling-of-inactive-controls.patch 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