Message ID | s5h4ljmbnnj.wl-tiwai@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 5/4/2018 11:51 PM, Takashi Iwai wrote: > On Fri, 04 May 2018 21:57:35 +0200, > Jay Foster wrote: >> >> >> On 5/4/2018 12:47 PM, Takashi Iwai wrote: >>> On Fri, 04 May 2018 19:51:05 +0200, >>> Jay Foster wrote: >>>> I recently updated may alsa from 1.1.4.1 to 1.1.6. I now noticed that >>>> aplay does not work properly (the same as 1.1.4.1) when reading the >>>> sound file data from stdin. This might have something to do with the >>>> recent change with reading the sound file header. >>>> >>>> With the previous version of aplay, aplay would report: >>>> >>>> Playing WAVE 'stdin' : Signed 16 bit Little Endian, Rate 22050 Hz, Mono >>>> >>>> With 1.1.6, aplay reports: >>>> >>>> Playing raw data 'stdin' : Unsigned 8 bit, Rate 8000 Hz, Mono >>>> >>>> This results in static/noise output. If I explicitly add the '-f >>>> S16_LE -r 22050' options to aplay, then it does play correctly. >>>> >>>> Is this a known bug and is there a fix? >>> It works fine on my system. >>> >>> % aplay test.wav >>> Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo >>> >>> % aplay < ~/test/test.wav >>> Playing WAVE 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo >>> >>> % aplay --version >>> aplay: version 1.1.6 by Jaroslav Kysela <perex@perex.cz> >>> >>> >>> Takashi >>> >>> >> Well, it does not work for me: >> >> cat bird-calls.wav | /usr/bin/aplay -Dplughw:0 -- >> Playing raw data 'stdin' : Unsigned 8 bit, Rate 8000 Hz, Mono >> ^CAborted by signal Interrupt... >> aplay: pcm_write:2051: write error: Interrupted system call >> >> aplay -Dplughw:0 bird-calls.wav >> Playing WAVE 'bird-calls.wav' : Signed 16 bit Little Endian, Rate >> 44100 Hz, Stereo >> >> Looks like aplay may now have problems reading from stdin if stdin is >> a pipe. > OK, now I see it. It's in the safety check of file stat. > The fix patch is below. > > > thanks, > > Takashi > > --- > diff --git a/aplay/aplay.c b/aplay/aplay.c > index bbd7fffa04fc..2a851a73ba6e 100644 > --- a/aplay/aplay.c > +++ b/aplay/aplay.c > @@ -2808,7 +2808,7 @@ static void playback_go(int fd, size_t loaded, off64_t count, int rtype, char *n > snd_pcm_nonblock(handle, nonblock); > } > > -static int read_header(int *loaded, int header_size) > +static int read_header(int *loaded, int header_size, int is_stdin) > { > int ret; > struct stat buf; > @@ -2821,7 +2821,7 @@ static int read_header(int *loaded, int header_size) > > /* don't be adventurous, get out if file size is smaller than > * requested header size */ > - if (buf.st_size < header_size) > + if (!is_stdin && buf.st_size < header_size) > return -1; > > if (*loaded < header_size) { > @@ -2836,9 +2836,9 @@ static int read_header(int *loaded, int header_size) > return 0; > } > > -static int playback_au(char *name, int *loaded) > +static int playback_au(char *name, int *loaded, int is_stdin) > { > - if (read_header(loaded, sizeof(AuHeader)) < 0) > + if (read_header(loaded, sizeof(AuHeader), is_stdin) < 0) > return -1; > > if (test_au(fd, audiobuf) < 0) > @@ -2851,11 +2851,11 @@ static int playback_au(char *name, int *loaded) > return 0; > } > > -static int playback_voc(char *name, int *loaded) > +static int playback_voc(char *name, int *loaded, int is_stdin) > { > int ofs; > > - if (read_header(loaded, sizeof(VocHeader)) < 0) > + if (read_header(loaded, sizeof(VocHeader), is_stdin) < 0) > return -1; > > if ((ofs = test_vocfile(audiobuf)) < 0) > @@ -2867,11 +2867,11 @@ static int playback_voc(char *name, int *loaded) > return 0; > } > > -static int playback_wave(char *name, int *loaded) > +static int playback_wave(char *name, int *loaded, int is_stdin) > { > ssize_t dtawave; > > - if (read_header(loaded, sizeof(WaveHeader)) < 0) > + if (read_header(loaded, sizeof(WaveHeader), is_stdin) < 0) > return -1; > > if ((dtawave = test_wavefile(fd, audiobuf, *loaded)) < 0) > @@ -2883,7 +2883,7 @@ static int playback_wave(char *name, int *loaded) > return 0; > } > > -static int playback_raw(char *name, int *loaded) > +static int playback_raw(char *name, int *loaded, int is_stdin) > { > init_raw_data(); > pbrec_count = calc_count(); > @@ -2899,13 +2899,16 @@ static int playback_raw(char *name, int *loaded) > static void playback(char *name) > { > int loaded = 0; > + int is_stdin; > > pbrec_count = LLONG_MAX; > fdcount = 0; > if (!name || !strcmp(name, "-")) { > + is_stdin = 1; > fd = fileno(stdin); > name = "stdin"; > } else { > + is_stdin = 0; > init_stdin(); > if ((fd = open(name, O_RDONLY, 0)) == -1) { > perror(name); > @@ -2915,23 +2918,23 @@ static void playback(char *name) > > switch(file_type) { > case FORMAT_AU: > - playback_au(name, &loaded); > + playback_au(name, &loaded, is_stdin); > break; > case FORMAT_VOC: > - playback_voc(name, &loaded); > + playback_voc(name, &loaded, is_stdin); > break; > case FORMAT_WAVE: > - playback_wave(name, &loaded); > + playback_wave(name, &loaded, is_stdin); > break; > case FORMAT_RAW: > - playback_raw(name, &loaded); > + playback_raw(name, &loaded, is_stdin); > break; > default: > /* parse the file header */ > - if (playback_au(name, &loaded) < 0 && > - playback_voc(name, &loaded) < 0 && > - playback_wave(name, &loaded) < 0) > - playback_raw(name, &loaded); /* should be raw data */ > + if (playback_au(name, &loaded, is_stdin) < 0 && > + playback_voc(name, &loaded, is_stdin) < 0 && > + playback_wave(name, &loaded, is_stdin) < 0) > + playback_raw(name, &loaded, is_stdin); /* should be raw data */ > break; > } > > > Thanks. That works. Jay
diff --git a/aplay/aplay.c b/aplay/aplay.c index bbd7fffa04fc..2a851a73ba6e 100644 --- a/aplay/aplay.c +++ b/aplay/aplay.c @@ -2808,7 +2808,7 @@ static void playback_go(int fd, size_t loaded, off64_t count, int rtype, char *n snd_pcm_nonblock(handle, nonblock); } -static int read_header(int *loaded, int header_size) +static int read_header(int *loaded, int header_size, int is_stdin) { int ret; struct stat buf; @@ -2821,7 +2821,7 @@ static int read_header(int *loaded, int header_size) /* don't be adventurous, get out if file size is smaller than * requested header size */ - if (buf.st_size < header_size) + if (!is_stdin && buf.st_size < header_size) return -1; if (*loaded < header_size) { @@ -2836,9 +2836,9 @@ static int read_header(int *loaded, int header_size) return 0; } -static int playback_au(char *name, int *loaded) +static int playback_au(char *name, int *loaded, int is_stdin) { - if (read_header(loaded, sizeof(AuHeader)) < 0) + if (read_header(loaded, sizeof(AuHeader), is_stdin) < 0) return -1; if (test_au(fd, audiobuf) < 0) @@ -2851,11 +2851,11 @@ static int playback_au(char *name, int *loaded) return 0; } -static int playback_voc(char *name, int *loaded) +static int playback_voc(char *name, int *loaded, int is_stdin) { int ofs; - if (read_header(loaded, sizeof(VocHeader)) < 0) + if (read_header(loaded, sizeof(VocHeader), is_stdin) < 0) return -1; if ((ofs = test_vocfile(audiobuf)) < 0) @@ -2867,11 +2867,11 @@ static int playback_voc(char *name, int *loaded) return 0; } -static int playback_wave(char *name, int *loaded) +static int playback_wave(char *name, int *loaded, int is_stdin) { ssize_t dtawave; - if (read_header(loaded, sizeof(WaveHeader)) < 0) + if (read_header(loaded, sizeof(WaveHeader), is_stdin) < 0) return -1; if ((dtawave = test_wavefile(fd, audiobuf, *loaded)) < 0) @@ -2883,7 +2883,7 @@ static int playback_wave(char *name, int *loaded) return 0; } -static int playback_raw(char *name, int *loaded) +static int playback_raw(char *name, int *loaded, int is_stdin) { init_raw_data(); pbrec_count = calc_count(); @@ -2899,13 +2899,16 @@ static int playback_raw(char *name, int *loaded) static void playback(char *name) { int loaded = 0; + int is_stdin; pbrec_count = LLONG_MAX; fdcount = 0; if (!name || !strcmp(name, "-")) { + is_stdin = 1; fd = fileno(stdin); name = "stdin"; } else { + is_stdin = 0; init_stdin(); if ((fd = open(name, O_RDONLY, 0)) == -1) { perror(name); @@ -2915,23 +2918,23 @@ static void playback(char *name) switch(file_type) { case FORMAT_AU: - playback_au(name, &loaded); + playback_au(name, &loaded, is_stdin); break; case FORMAT_VOC: - playback_voc(name, &loaded); + playback_voc(name, &loaded, is_stdin); break; case FORMAT_WAVE: - playback_wave(name, &loaded); + playback_wave(name, &loaded, is_stdin); break; case FORMAT_RAW: - playback_raw(name, &loaded); + playback_raw(name, &loaded, is_stdin); break; default: /* parse the file header */ - if (playback_au(name, &loaded) < 0 && - playback_voc(name, &loaded) < 0 && - playback_wave(name, &loaded) < 0) - playback_raw(name, &loaded); /* should be raw data */ + if (playback_au(name, &loaded, is_stdin) < 0 && + playback_voc(name, &loaded, is_stdin) < 0 && + playback_wave(name, &loaded, is_stdin) < 0) + playback_raw(name, &loaded, is_stdin); /* should be raw data */ break; }