All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: jay@systech.com
Cc: alsa-devel@alsa-project.org
Subject: Re: Aplay Fails When Reading From stdin
Date: Sat, 05 May 2018 08:51:44 +0200	[thread overview]
Message-ID: <s5h4ljmbnnj.wl-tiwai@suse.de> (raw)
In-Reply-To: <399d9244-ae31-84c0-d587-bc62707a873f@systech.com>

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;
         }
 

  reply	other threads:[~2018-05-05  6:51 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-04 17:51 Aplay Fails When Reading From stdin Jay Foster
2018-05-04 19:47 ` Takashi Iwai
2018-05-04 19:57   ` Jay Foster
2018-05-05  6:51     ` Takashi Iwai [this message]
2018-05-07 15:37       ` Jay Foster
2018-05-15 20:21         ` Takashi Iwai
2018-05-16 15:46           ` Jay Foster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=s5h4ljmbnnj.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=jay@systech.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.