shithub: sox

Download patch

ref: 32f8c561a4bfea01559dae9d2c21ccced15c1c16
parent: a9fddb06a4e0fba4ef9fd585626bd674b959934b
author: cbagwell <cbagwell>
date: Tue Feb 9 22:05:51 EST 1999

Fix an endian problem and got aiff working with a known invalid aiff
header.

--- a/src/aiff.c
+++ b/src/aiff.c
@@ -27,20 +27,25 @@
  *
  * Sept 9, 1998 - fixed loop markers.
  *
+ * Feb. 9, 1999 - Small fix to work with invalid headers that include
+ *   a INST block with markers that equal 0.  It should ingore those.
+ *   Also fix endian problems when ran on Intel machines.  The check
+ *   for endianness was being performed AFTER reading the header instead
+ *   of before reading it.
+ *
  */
 
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
-#include "st.h"
+#include <stdio.h>
 
-#ifndef SEEK_SET
-#define SEEK_SET 0		/* nasty nasty */
+#ifdef unix
+#include <unistd.h>	/* For SEEK_* defines if not found in stdio */
 #endif
-#ifndef SEEK_CUR
-#define SEEK_CUR 1		/* nasty nasty */
-#endif /* SEEK_CUR */
 
+#include "st.h"
+
 /* Private data used by writer */
 struct aiffpriv {
 	ULONG nsamples;	/* number of 1-channel samples read or written */
@@ -69,7 +74,7 @@
 	double rate = 0.0;
 	ULONG offset = 0;
 	ULONG blocksize = 0;
-	int littlendian = 0;
+	int littlendian;
 	char *endptr;
 	int foundcomm = 0, foundmark = 0, foundinstr = 0;
 	struct mark {
@@ -86,6 +91,15 @@
 	char *nametext;
 
 
+	/* AIFF is in Big Endian format.  Swap whats read in on Little */
+	/* Endian machines.                                            */
+	littlendian = 1;
+	endptr = (char *) &littlendian;
+	if (*endptr)
+	{
+	    ft->swap = ft->swap ? 0 : 1;
+	}
+
 	/* FORM chunk */
 	if (fread(buf, 1, 4, ft->fp) != 4 || strncmp(buf, "FORM", 4) != 0)
 		fail("AIFF header does not begin with magic word 'FORM'");
@@ -172,7 +186,15 @@
 			ft->loops[1].type = rbshort(ft); /* release loop */
 			releaseLoopBegin = rbshort(ft);  /* begin marker */
 			releaseLoopEnd = rbshort(ft);    /* end marker */
-			foundinstr = 1;
+
+			/* At least one known program generates an INST */
+			/* block with everything zeroed out (meaning    */
+			/* no Loops used).  In this case it should just */
+			/* be ingorned.				        */
+			if (sustainLoopBegin == 0 && releaseLoopBegin == 0)
+				foundinstr = 0;
+			else
+				foundinstr = 1;
 		}
 		else if (strncmp(buf, "APPL", 4) == 0) {
 			chunksize = rblong(ft);
@@ -284,7 +306,6 @@
 
 	p->nsamples = ssndsize / ft->info.size;	/* leave out channels */
 
-	/* process instrument and marker notations. */
 	if (foundmark && !foundinstr)
 		fail("Bogus AIFF file: MARKers but no INSTrument.");
 	if (!foundmark && foundinstr)
@@ -328,11 +349,6 @@
 	}
 	if (verbose)
 	  reportInstrument(ft);
-
-	endptr = (char *) &littlendian;
-	*endptr = 1;
-	if (littlendian == 1)
-		ft->swap = 1;
 }
 
 /* print out the MIDI key allocations, loop points, directions etc */
@@ -435,9 +451,18 @@
 ft_t ft;
 {
 	struct aiffpriv *p = (struct aiffpriv *) ft->priv;
-	int littlendian = 0;
+	int littlendian;
 	char *endptr;
 
+	/* AIFF is in Big Endian format.  Swap whats read in on Little */
+	/* Endian machines.                                            */
+	littlendian = 1;
+	endptr = (char *) &littlendian;
+	if (*endptr)
+	{
+	    ft->swap = ft->swap ? 0 : 1;
+	}
+
 	p->nsamples = 0;
 	if (ft->info.style == ULAW && ft->info.size == BYTE) {
 		report("expanding 8-bit u-law to 16 bits");
@@ -451,11 +476,6 @@
 	   Sorry, the AIFF format does not provide for an "infinite"
 	   number of samples. */
 	aiffwriteheader(ft, 0x7f000000L / (ft->info.size*ft->info.channels));
-
-	endptr = (char *) &littlendian;
-	*endptr = 1;
-	if (littlendian == 1)
-		ft->swap = 1;
 }
 
 void aiffwrite(ft, buf, len)