Subject: pkg/34519: [patch] audio/toolame to work on Big-Endian
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: None <marco@ununoctium.homeunix.org>
List: pkgsrc-bugs
Date: 09/13/2006 16:00:01
>Number:         34519
>Category:       pkg
>Synopsis:       patch to make the audio/toolame package work on big-endian platforms
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Sep 13 16:00:00 +0000 2006
>Originator:     marcotrillo@gmail.com
>Release:        NetBSD 3.1_RC2
>Organization:
>Environment:
System: NetBSD ununoctium 3.1_RC2 NetBSD 3.1_RC2 (EMAC) #1: Sun Sep 10 18:42:14 UTC 2006 marco@ununoctium:/usr/src/sys/arch/macppc/compile/EMAC macppc
Architecture: powerpc
Machine: macppc
>Description:
	The audio/toolame package (toolame-0.2l) only works on little-endian
	architectures. It won't work even if you specify the '-x' switch to
	supposedly swap the bytes of input PCM files.

	It includes some byte-swapping support but it is broken. The attached
	patch tries to fix it and make it work on both little-endian and big-endian
	architectures.

	The patch has been tested on both little-endian & big-endian platforms on
	NetBSD and Darwin/Mac OS X. I think this patch improves the portability
	of the audio/toolame package.

>How-To-Repeat:
>Fix:

	This patch adds the patches patch-ae to patch-ah in audio/toolame/patches,
	and updates the audio/toolame/distinfo file to include them.

	It's probably needed to increment the PKG_REVISION variable in the Makefile.


Index: distinfo
===================================================================
RCS file: /cvsroot/pkgsrc/audio/toolame/distinfo,v
retrieving revision 1.4
diff -u -r1.4 distinfo
--- distinfo	30 Jul 2005 11:30:03 -0000	1.4
+++ distinfo	13 Sep 2006 13:38:25 -0000
@@ -7,3 +7,7 @@
 SHA1 (patch-ab) = 3dae25436a931eea5fe33aa0dcca16c46e529ed7
 SHA1 (patch-ac) = 6a4df822e31858a52203a62ce8d5d1f20931dbbb
 SHA1 (patch-ad) = 9b3f8fc15012714da8b1c701103b5aa2ed77ac87
+SHA1 (patch-ae) = 6e685f6ace455fd01b44e77d72bd360731eb442e
+SHA1 (patch-af) = 68e5e06f376f42f7ec009a5315237d1d0047c853
+SHA1 (patch-ag) = c3923c7cc3cdbf53ea48b40fc1aa4b16c840eb6d
+SHA1 (patch-ah) = 4764db4c9c905d3610bd3d4ac30f9c40b503e608
Index: patches/patch-ae
===================================================================
RCS file: patches/patch-ae
diff -N patches/patch-ae
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-ae	13 Sep 2006 13:38:25 -0000
@@ -0,0 +1,208 @@
+
+--- audio_read.c.orig	2003-03-02 02:18:30.000000000 +0100
++++ audio_read.c	2006-09-08 16:11:55.000000000 +0200
+@@ -22,7 +22,8 @@
+ 
+ unsigned long
+ read_samples (FILE * musicin, short sample_buffer[2304],
+-	      unsigned long num_samples, unsigned long frame_size)
++	      unsigned long num_samples, unsigned long frame_size,
++		  enum byte_order bord)
+ {
+   unsigned long samples_read;
+   static unsigned long samples_to_read;
+@@ -41,8 +42,8 @@
+ 	      musicin)) == 0)
+     fprintf (stderr, "Hit end of audio data\n");
+   /*
+-     Samples are big-endian. If this is a little-endian machine
+-     we must swap
++	 If the native byte-order is not the samples' byte order,
++	 then we must swap
+    */
+   if (NativeByteOrder == order_unknown) {
+     NativeByteOrder = DetermineByteOrder ();
+@@ -51,7 +52,7 @@
+       exit (1);
+     }
+   }
+-  if (NativeByteOrder != order_littleEndian || (glopts.byteswap == TRUE))
++  if (NativeByteOrder != bord || (glopts.byteswap == TRUE))
+     SwapBytesInWords (sample_buffer, samples_read);
+ 
+   if (num_samples != MAX_U_32_NUM)
+@@ -78,7 +79,7 @@
+ ************************************************************************/
+ unsigned long
+ get_audio (FILE * musicin, short buffer[2][1152], unsigned long num_samples,
+-	   int nch, frame_header *header)
++	   int nch, frame_header *header, enum byte_order bord)
+ {
+   int j;
+   short insamp[2304];
+@@ -86,7 +87,7 @@
+ 
+   if (nch == 2) {		/* stereo */
+     samples_read =
+-      read_samples (musicin, insamp, num_samples, (unsigned long) 2304);
++      read_samples (musicin, insamp, num_samples, 2304L, bord);
+     if (glopts.channelswap == TRUE) {
+       for (j = 0; j < 1152; j++) {
+ 	buffer[1][j] = insamp[2 * j];
+@@ -100,13 +101,13 @@
+     }
+   } else if (glopts.downmix == TRUE) {
+     samples_read =
+-      read_samples (musicin, insamp, num_samples, (unsigned long) 2304);
++      read_samples (musicin, insamp, num_samples, 2304L, bord);
+     for (j = 0; j < 1152; j++) {
+       buffer[0][j] = 0.5 * (insamp[2 * j] + insamp[2 * j + 1]);
+     }
+   } else {			/* mono */
+     samples_read =
+-      read_samples (musicin, insamp, num_samples, (unsigned long) 1152);
++      read_samples (musicin, insamp, num_samples, 1152L, bord);
+     for (j = 0; j < 1152; j++) {
+       buffer[0][j] = insamp[j];
+       /* buffer[1][j] = 0;  don't bother zeroing this buffer. MFC Nov 99 */
+@@ -124,34 +125,26 @@
+ 
+ enum byte_order DetermineByteOrder (void)
+ {
+-  char s[sizeof (long) + 1];
+   union {
+     long longval;
+     char charval[sizeof (long)];
+   } probe;
+   probe.longval = 0x41424344L;	/* ABCD in ASCII */
+-  strncpy (s, probe.charval, sizeof (long));
+-  s[sizeof (long)] = '\0';
+-  /* fprintf( stderr, "byte order is %s\n", s ); */
+-  if (strcmp (s, "ABCD") == 0)
+-    return order_bigEndian;
+-  else if (strcmp (s, "DCBA") == 0)
+-    return order_littleEndian;
++
++  if (memcmp (probe.charval, "ABCD", 4) == 0)
++	  return order_bigEndian;
++  else if (memcmp (probe.charval, "DCBA", 4) == 0)
++	  return order_littleEndian;
+   else
+-    return order_unknown;
++	  return order_unknown;
+ }
+ 
+ void SwapBytesInWords (short *loc, int words)
+ {
+-  int i;
+-  short thisval;
+-  char *dst, *src;
+-  src = (char *) &thisval;
+-  for (i = 0; i < words; i++) {
+-    thisval = *loc;
+-    dst = (char *) loc++;
+-    dst[0] = src[1];
+-    dst[1] = src[0];
++  register int i = words;
++
++  while (i-- > 0) {
++	  loc[i] = ((loc[i] & 0xFF00) >> 8) | ((loc[i] & 0x00FF) << 8);
+   }
+ }
+ 
+@@ -252,7 +245,7 @@
+ **************************************************************/
+ void
+ parse_input_file (FILE * musicin, char inPath[MAX_NAME_SIZE], frame_header *header,
+-		  unsigned long *num_samples)
++		  unsigned long *num_samples, enum byte_order *pbord)
+ {
+ 
+   IFF_AIFF pcm_aiff_data;
+@@ -263,6 +256,7 @@
+   int wave_header_stereo = -1;
+   int wave_header_16bit = -1;
+   unsigned long samplerate;
++  enum byte_order bord;
+ 
+   /*************************** STDIN ********************************/
+   /* check if we're reading from stdin. Assume it's a raw PCM file. */
+@@ -278,6 +272,8 @@
+   /****************************  AIFF ********************************/
+   if ((soundPosition = aiff_read_headers (musicin, &pcm_aiff_data)) != -1) {
+     fprintf (stderr, ">>> Using Audio IFF sound file headers\n");
++	bord = order_bigEndian; /* AIFF samples are always big-endian */
++
+     aiff_check (inPath, &pcm_aiff_data, &header->version);
+     if (fseek (musicin, soundPosition, SEEK_SET) != 0) {
+       fprintf (stderr, "Could not seek to PCM sound data in \"%s\".\n",
+@@ -297,6 +293,8 @@
+       header->mode = MPG_MD_MONO;
+       header->mode_ext = 0;
+     }
++
++	*pbord = bord;
+     return;
+   }
+ 
+@@ -314,7 +312,7 @@
+   /*                16bit Mono)    */
+   /*       04 = x4 (16bit Stereo)  */
+   /*********************************/
+-
++  bord = order_littleEndian; /* WAVE samples are little-endian */
+   fseek (musicin, 0, SEEK_SET);
+   fread (wave_header_buffer, 1, 40, musicin);
+ 
+@@ -328,13 +326,18 @@
+ 	exit (1);
+       }
+     }
+-    if (NativeByteOrder == order_littleEndian) {
+-      samplerate = *(unsigned long *) (&wave_header_buffer[24]);
+-    } else {
+-      samplerate = wave_header_buffer[27] +
+-	(wave_header_buffer[26] << 8) +
+-	(wave_header_buffer[25] << 16) + (wave_header_buffer[24] << 24);
+-    }
++
++	samplerate = *( (unsigned long *) &(wave_header_buffer[24]) );
++
++	if (NativeByteOrder == order_unknown)
++		NativeByteOrder = DetermineByteOrder ();
++
++	/* 32-bit swap */
++	if (NativeByteOrder != order_littleEndian) {
++		samplerate = ((samplerate & 0xFF) << 24) | ((samplerate & 0xFF00) << 8)
++			       | ((samplerate & 0xFF0000) >> 8) | ((samplerate & 0xFF000000) >> 24);
++	}
++
+     /* Wave File */
+     wave_header_read = 1;
+     switch (samplerate) {
+@@ -399,6 +402,8 @@
+ 	       inPath);
+       exit (1);
+     }
++
++	*pbord = bord;
+     return;
+   }
+ 
+@@ -409,6 +414,7 @@
+   /* Assume it is a huge sound file since there's no real info available */
+   /* FIXME: Could always fstat the file? Probably not worth it. MFC Feb 2003 */
+   *num_samples = MAX_U_32_NUM;
++  *pbord = order_unknown; /* unnown endian. Only swap if user requested it. */
+ }
+ 
+ 
+@@ -436,7 +442,7 @@
+ 
+   if (pcm_aiff_data->sampleSize != sizeof (short) * BITS_IN_A_BYTE) {
+     fprintf (stderr, "Sound data is not %d bits in \"%s\".\n",
+-	     sizeof (short) * BITS_IN_A_BYTE, file_name);
++	     (int) (sizeof (short) * BITS_IN_A_BYTE), file_name);
+     exit (1);
+   }
+ 
Index: patches/patch-af
===================================================================
RCS file: patches/patch-af
diff -N patches/patch-af
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-af	13 Sep 2006 13:38:25 -0000
@@ -0,0 +1,22 @@
+ 
+--- audio_read.h.orig	2003-02-22 06:42:57.000000000 +0100
++++ audio_read.h	2006-09-08 16:07:22.000000000 +0200
+@@ -28,7 +28,8 @@
+ }
+ IFF_AIFF;
+ 
+-void parse_input_file (FILE *musicin, char *, frame_header *header, unsigned long *num_samples);
++void parse_input_file (FILE *musicin, char *, frame_header *header, unsigned long *,
++		               enum byte_order *);
+ void aiff_check (char *file_name, IFF_AIFF * pcm_aiff_data, int *version);
+ 
+ int aiff_read_headers (FILE *, IFF_AIFF *);
+@@ -36,6 +37,6 @@
+ enum byte_order DetermineByteOrder (void);
+ void SwapBytesInWords (short *loc, int words);
+  unsigned long read_samples (FILE *, short[2304], unsigned long,
+-				   unsigned long);
++				   unsigned long, enum byte_order);
+  unsigned long get_audio (FILE *, short[2][1152], unsigned long,
+-				int, frame_header *header);
++				int, frame_header *header, enum byte_order);
Index: patches/patch-ag
===================================================================
RCS file: patches/patch-ag
diff -N patches/patch-ag
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-ag	13 Sep 2006 13:38:25 -0000
@@ -0,0 +1,47 @@
+
+--- toolame.c.orig	2003-03-02 03:56:15.000000000 +0100
++++ toolame.c	2006-09-08 16:05:42.000000000 +0200
+@@ -118,6 +118,7 @@
+   unsigned long num_samples;
+   int lg_frame;
+   int i;
++  enum byte_order bord; /* endianness of the audio input */
+ 
+   /* Used to keep the SNR values for the fast/quick psy models */
+   static FLOAT smrdef[2][32];
+@@ -156,7 +157,7 @@
+     short_usage ();
+   else
+     parse_args (argc, argv, &frame, &model, &num_samples, original_file_name,
+-		encoded_file_name);
++		encoded_file_name, &bord);
+   print_config (&frame, &model, original_file_name, encoded_file_name);
+ 
+   /* this will load the alloc tables and do some other stuff */
+@@ -164,7 +165,7 @@
+   nch = frame.nch;
+   error_protection = header.error_protection;
+ 
+-  while (get_audio (musicin, buffer, num_samples, nch, &header) > 0) {
++  while (get_audio (musicin, buffer, num_samples, nch, &header, bord) > 0) {
+     if (glopts.verbosity > 1)
+       if (++frameNum % 10 == 0)
+ 	fprintf (stderr, "[%4u]\r", frameNum);
+@@ -632,7 +633,7 @@
+ 
+ void parse_args (int argc, char **argv, frame_info * frame, int *psy,
+ 		 unsigned long *num_samples, char inPath[MAX_NAME_SIZE],
+-		 char outPath[MAX_NAME_SIZE])
++		 char outPath[MAX_NAME_SIZE], enum byte_order *bord)
+ {
+   FLOAT srate;
+   int brate;
+@@ -894,7 +895,7 @@
+       fprintf (stderr, "Could not find \"%s\".\n", inPath);
+       exit (1);
+     }
+-    parse_input_file (musicin, inPath, header, num_samples);
++    parse_input_file (musicin, inPath, header, num_samples, bord);
+   }
+ 
+   /* check for a valid bitrate */
Index: patches/patch-ah
===================================================================
RCS file: patches/patch-ah
diff -N patches/patch-ah
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-ah	13 Sep 2006 13:38:25 -0000
@@ -0,0 +1,12 @@
+
+--- toolame.h.orig	2003-03-02 02:26:22.000000000 +0100
++++ toolame.h	2006-09-08 16:07:57.000000000 +0200
+@@ -6,7 +6,7 @@
+ void obtain_parameters (frame_info *, int *, unsigned long *,
+ 			       char[MAX_NAME_SIZE], char[MAX_NAME_SIZE]);
+ void parse_args (int, char **, frame_info *, int *, unsigned long *,
+-			char[MAX_NAME_SIZE], char[MAX_NAME_SIZE]);
++			char[MAX_NAME_SIZE], char[MAX_NAME_SIZE], enum byte_order *);
+ void print_config (frame_info *, int *,
+ 			  char[MAX_NAME_SIZE], char[MAX_NAME_SIZE]);
+ void usage (void);