[alsa-devel] [PATCH] aplay: Fix header for raw format

Takashi Iwai tiwai at suse.de
Fri Jun 30 16:20:12 CEST 2017


On Fri, 30 Jun 2017 15:11:38 +0200,
Daniel Baluta wrote:
> 
> Hi Takashi,
> 
> Thanks a lot for your feedback.
> 
> On Fri, Jun 30, 2017 at 9:54 AM, Takashi Iwai <tiwai at suse.de> wrote:
> > On Thu, 29 Jun 2017 13:17:16 +0200,
> > Ion-Horia Petrisor wrote:
> >>
> >> Raw format has no header, so use 0 when calling playback_go.
> >
> > It's the value passed for the length that has been already loaded.
> > The program has read dta bytes for parsing the header, and it's raw
> > data without header.  Thus you need to pass dta there.
> >
> With the current code we assume that the raw files have at least 26 bytes.
> (sizeof (VocHeader).
> 
> I think it doesn't matter here that dta bytes has already been loaded. These
> bytes useful to figure out the file header type.
> 
> To keep things simple we can assume that in the case of raw files there is no
> header, so second parameter of playback_go (named loaded) can be set to 0.

The loaded parameter of playback_go() doesn't mean that.  It's the
size that has been already read onto the audio buffer.  If you pass 0
there, it means that you discard the first 26 bytes samples you have
already read without playing.

> The worst things that can happen is that we re-read the first 26 bytes
> (previously
> read as VoC header).

Where is re-read...?

> We are trying to introduce a new parameter --samples which tells aplay to  only
> playback/record s number of samples.
> 
> We modified calc_count() accordingly so that when receives the
> --samples parameter
> computes the correct number of bytes to be read.
> 
> Anyhow, it doesn't work as expected because aplay expects files to have at least
> 26 bytes.
> 
> The correct solution would be that in the case of raw files not assume
> any header
> and read samples * sample_size bytes from the beginning of the file.

I see now what you want, but the patch is incorrect.
I guess a patch something like below is what you want.


thanks,

Takashi

---
diff --git a/aplay/aplay.c b/aplay/aplay.c
index 00af66246cad..a902be5cf9cb 100644
--- a/aplay/aplay.c
+++ b/aplay/aplay.c
@@ -2782,12 +2782,65 @@ static void playback_go(int fd, size_t loaded, off64_t count, int rtype, char *n
  *  let's play or capture it (capture_type says VOC/WAVE/raw)
  */
 
-static void playback(char *name)
+static void read_header(int *loaded, int header_size)
+{
+	if (*loaded < header_size) {
+		header_size -= *loaded;
+		if (safe_read(fd, audiobuf, header_size) != header_size) {
+			error(_("read error"));
+			prg_exit(EXIT_FAILURE);
+		}
+		*loaded += header_size;
+	}
+}
+
+static int playback_au(char *name, int *loaded)
+{
+	read_header(loaded, sizeof(AuHeader));
+	if (test_au(fd, audiobuf) < 0)
+		return -1;
+	rhwparams.format = hwparams.format;
+	pbrec_count = calc_count();
+	playback_go(fd, *loaded - sizeof(AuHeader), pbrec_count, FORMAT_AU, name);
+	return 0;
+}
+
+static int playback_voc(char *name, int *loaded)
 {
 	int ofs;
-	size_t dta;
+
+	read_header(loaded, sizeof(VocHeader));
+	if ((ofs = test_vocfile(audiobuf)) < 0)
+		return -1;
+	pbrec_count = calc_count();
+	voc_play(fd, ofs, name);
+	return 0;
+}
+
+static int playback_wave(char *name, int *loaded)
+{
 	ssize_t dtawave;
 
+	read_header(loaded, sizeof(WaveHeader));
+	if ((dtawave = test_wavefile(fd, audiobuf, *loaded)) < 0)
+		return -1;
+	pbrec_count = calc_count();
+	playback_go(fd, dtawave, pbrec_count, FORMAT_WAVE, name);
+	return 0;
+}
+
+static int playback_raw(char *name, int *loaded)
+{
+	init_raw_data();
+	pbrec_count = calc_count();
+	playback_go(fd, *loaded, pbrec_count, FORMAT_RAW, name);
+	return 0;
+}
+
+static void playback(char *name)
+{
+	int loaded = 0;
+
 	pbrec_count = LLONG_MAX;
 	fdcount = 0;
 	if (!name || !strcmp(name, "-")) {
@@ -2800,40 +2853,29 @@ static void playback(char *name)
 			prg_exit(EXIT_FAILURE);
 		}
 	}
-	/* read the file header */
-	dta = sizeof(AuHeader);
-	if ((size_t)safe_read(fd, audiobuf, dta) != dta) {
-		error(_("read error"));
-		prg_exit(EXIT_FAILURE);
-	}
-	if (test_au(fd, audiobuf) >= 0) {
-		rhwparams.format = hwparams.format;
-		pbrec_count = calc_count();
-		playback_go(fd, 0, pbrec_count, FORMAT_AU, name);
-		goto __end;
-	}
-	dta = sizeof(VocHeader);
-	if ((size_t)safe_read(fd, audiobuf + sizeof(AuHeader),
-		 dta - sizeof(AuHeader)) != dta - sizeof(AuHeader)) {
-		error(_("read error"));
-		prg_exit(EXIT_FAILURE);;
-	}
-	if ((ofs = test_vocfile(audiobuf)) >= 0) {
-		pbrec_count = calc_count();
-		voc_play(fd, ofs, name);
-		goto __end;
-	}
-	/* read bytes for WAVE-header */
-	if ((dtawave = test_wavefile(fd, audiobuf, dta)) >= 0) {
-		pbrec_count = calc_count();
-		playback_go(fd, dtawave, pbrec_count, FORMAT_WAVE, name);
-	} else {
-		/* should be raw data */
-		init_raw_data();
-		pbrec_count = calc_count();
-		playback_go(fd, dta, pbrec_count, FORMAT_RAW, name);
+
+	switch (file_type) {
+	case FORMAT_AU:
+		playback_au(name, &loaded);
+		break;
+	case FORMAT_VOC:
+		playback_voc(name, &loaded);
+		break;
+	case FORMAT_WAVE:
+		playback_wave(name, &loaded);
+		break;
+	case FORMAT_RAW:
+		playback_raw(name, &loaded);
+		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 */
+		break;
 	}
-      __end:
+
 	if (fd != 0)
 		close(fd);
 }


More information about the Alsa-devel mailing list