[xiph-commits] r16793 - trunk/vorbis-tools/oggenc

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Thu Jan 21 23:06:57 PST 2010


Author: xiphmont
Date: 2010-01-21 23:06:57 -0800 (Thu, 21 Jan 2010)
New Revision: 16793

Modified:
   trunk/vorbis-tools/oggenc/audio.c
   trunk/vorbis-tools/oggenc/flac.c
Log:
Add proper 6.1/7.1 permutations to WAV input
Add proper channel permutation to FLAC read (all channel counts)



Modified: trunk/vorbis-tools/oggenc/audio.c
===================================================================
--- trunk/vorbis-tools/oggenc/audio.c	2010-01-21 00:36:05 UTC (rev 16792)
+++ trunk/vorbis-tools/oggenc/audio.c	2010-01-22 07:06:57 UTC (rev 16793)
@@ -28,9 +28,6 @@
 #endif
 
 #define WAV_HEADER_SIZE 44
-#define WAVE_FORMAT_PCM        0x0001
-#define WAVE_FORMAT_IEEE_FLOAT 0x0003
-#define WAVE_FORMAT_EXTENSIBLE 0xfffe
 
 /* Macros to read header data */
 #define READ_U32_LE(buf) \
@@ -47,11 +44,11 @@
 
 /* Define the supported formats here */
 input_format formats[] = {
-    {wav_id, 12, wav_open, wav_close, "wav", N_("Wave file reader")},
+    {wav_id, 12, wav_open, wav_close, "wav", N_("WAV file reader")},
     {aiff_id, 12, aiff_open, wav_close, "aiff", N_("AIFF/AIFC file reader")},
 #ifdef HAVE_LIBFLAC
     {flac_id,     4, flac_open, flac_close, "flac", N_("FLAC file reader")},
-    {oggflac_id, 33, flac_open, flac_close, "ogg", N_("Ogg FLAC file reader")},
+    {oggflac_id, 32, flac_open, flac_close, "ogg", N_("Ogg FLAC file reader")},
 #endif
     {NULL, 0, NULL, NULL, NULL, NULL}
 };
@@ -128,7 +125,7 @@
     {
         if(fread(buf,1,8,in) < 8) /* Suck down a chunk specifier */
         {
-            fprintf(stderr, _("WARNING: Unexpected EOF in reading Wave header\n"));
+            fprintf(stderr, _("Warning: Unexpected EOF in reading WAV header\n"));
             return 0; /* EOF before reaching the appropriate chunk */
         }
 
@@ -165,7 +162,7 @@
                 fseek(in, 12, SEEK_SET);
                 continue;
             }
-            fprintf(stderr, _("WARNING: Unexpected EOF in AIFF chunk\n"));
+            fprintf(stderr, _("Warning: Unexpected EOF in AIFF chunk\n"));
             return 0;
         }
 
@@ -251,13 +248,13 @@
 
     if(!find_aiff_chunk(in, "COMM", &len))
     {
-        fprintf(stderr, _("WARNING: No common chunk found in AIFF file\n"));
+        fprintf(stderr, _("Warning: No common chunk found in AIFF file\n"));
         return 0; /* EOF before COMM chunk */
     }
 
     if(len < 18) 
     {
-        fprintf(stderr, _("WARNING: Truncated common chunk in AIFF header\n"));
+        fprintf(stderr, _("Warning: Truncated common chunk in AIFF header\n"));
         return 0; /* Weird common chunk */
     }
 
@@ -265,7 +262,7 @@
 
     if(fread(buffer,1,len,in) < len)
     {
-        fprintf(stderr, _("WARNING: Unexpected EOF in reading AIFF header\n"));
+        fprintf(stderr, _("Warning: Unexpected EOF in reading AIFF header\n"));
         return 0;
     }
 
@@ -280,7 +277,7 @@
     {
         if(len < 22)
         {
-            fprintf(stderr, _("WARNING: AIFF-C header truncated.\n"));
+            fprintf(stderr, _("Warning: AIFF-C header truncated.\n"));
             return 0;
         }
 
@@ -294,26 +291,26 @@
         }
         else
         {
-            fprintf(stderr, _("WARNING: Can't handle compressed AIFF-C (%c%c%c%c)\n"), *(buffer+18), *(buffer+19), *(buffer+20), *(buffer+21));
+            fprintf(stderr, _("Warning: Can't handle compressed AIFF-C (%c%c%c%c)\n"), *(buffer+18), *(buffer+19), *(buffer+20), *(buffer+21));
             return 0; /* Compressed. Can't handle */
         }
     }
 
     if(!find_aiff_chunk(in, "SSND", &len))
     {
-        fprintf(stderr, _("WARNING: No SSND chunk found in AIFF file\n"));
+        fprintf(stderr, _("Warning: No SSND chunk found in AIFF file\n"));
         return 0; /* No SSND chunk -> no actual audio */
     }
 
     if(len < 8) 
     {
-        fprintf(stderr, _("WARNING: Corrupted SSND chunk in AIFF header\n"));
+        fprintf(stderr, _("Warning: Corrupted SSND chunk in AIFF header\n"));
         return 0; 
     }
 
     if(fread(buf2,1,8, in) < 8)
     {
-        fprintf(stderr, _("WARNING: Unexpected EOF reading AIFF header\n"));
+        fprintf(stderr, _("Warning: Unexpected EOF reading AIFF header\n"));
         return 0;
     }
 
@@ -324,7 +321,7 @@
         (format.samplesize == 16 || format.samplesize == 8))
     {
         /* From here on, this is very similar to the wav code. Oh well. */
-
+        
         opt->rate = format.rate;
         opt->channels = format.channels;
         opt->read_samples = wav_read; /* Similar enough, so we use the same */
@@ -350,7 +347,7 @@
     else
     {
         fprintf(stderr, 
-                _("WARNING: oggenc does not support this type of AIFF/AIFC file\n"
+                _("Warning: OggEnc does not support this type of AIFF/AIFC file\n"
                 " Must be 8 or 16 bit PCM.\n"));
         return 0;
     }
@@ -360,7 +357,7 @@
 int wav_id(unsigned char *buf, int len)
 {
     unsigned int flen;
-
+    
     if(len<12) return 0; /* Something screwed up */
 
     if(memcmp(buf, "RIFF", 4))
@@ -374,16 +371,19 @@
     return 1;
 }
 
-static int wav_permute_matrix[6][6] = 
+static int wav_permute_matrix[8][8] = 
 {
-    {0},
-    {0,1},
-    {0,2,1},
-    {0,1,2,3},
-    {0,2,1,3,4},  //{0,1,2,3,4}, /* No equivalent in wav? */
-    {0,2,1,4,5,3} //{0,2,1,5,3,4}
+  {0},              /* 1.0 mono   */
+  {0,1},            /* 2.0 stereo */
+  {0,2,1},          /* 3.0 channel ('wide') stereo */
+  {0,1,2,3},        /* 4.0 discrete quadraphonic */
+  {0,2,1,3,4},      /* 5.0 surround */
+  {0,2,1,4,5,3},    /* 5.1 surround */
+  {0,2,1,4,5,6,3},  /* 6.1 surround */
+  {0,2,1,6,7,4,5,3} /* 7.1 surround (classic theater 8-track) */
 };
 
+
 int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
 {
     unsigned char buf[16];
@@ -402,9 +402,9 @@
     if(!find_wav_chunk(in, "fmt ", &len))
         return 0; /* EOF */
 
-    if(len < 16)
+    if(len < 16) 
     {
-        fprintf(stderr, _("WARNING: Unrecognised format chunk in Wave header\n"));
+        fprintf(stderr, _("Warning: Unrecognised format chunk in WAV header\n"));
         return 0; /* Weird format chunk */
     }
 
@@ -413,21 +413,22 @@
      * it instead of refusing to work with the file.  Please, if you
      * have a program that's creating format chunks of sizes other than
      * 16 or 18 bytes in size, report a bug to the author.
-     * (40 bytes accommodates WAVEFORMATEXTENSIBLE conforming files.)
      */
-    if(len!=16 && len!=18 && len!=40)
+    if(len!=16 && len!=18)
         fprintf(stderr, 
-                _("WARNING: Invalid format chunk in Wave header.\n"
+                _("Warning: INVALID format chunk in wav header.\n"
                 " Trying to read anyway (may not work)...\n"));
 
-    if(fread(buf,1,len,in) < len)
+    if(fread(buf,1,16,in) < 16)
     {
-        fprintf(stderr, _("WARNING: Unexpected EOF in reading Wave header\n"));
+        fprintf(stderr, _("Warning: Unexpected EOF in reading WAV header\n"));
         return 0;
     }
 
     /* Deal with stupid broken apps. Don't use these programs.
      */
+    if(len - 16 > 0 && !seek_forward(in, len-16))
+        return 0;
 
     format.format =      READ_U16_LE(buf); 
     format.channels =    READ_U16_LE(buf+2); 
@@ -436,18 +437,15 @@
     format.align =       READ_U16_LE(buf+12);
     format.samplesize =  READ_U16_LE(buf+14);
 
-    if (format.format == WAVE_FORMAT_EXTENSIBLE && len > 25)
-        format.format =  READ_U16_LE(buf+24);
-
     if(!find_wav_chunk(in, "data", &len))
         return 0; /* EOF */
 
-    if(format.format == WAVE_FORMAT_PCM)
+    if(format.format == 1)
     {
         samplesize = format.samplesize/8;
         opt->read_samples = wav_read;
     }
-    else if(format.format == WAVE_FORMAT_IEEE_FLOAT)
+    else if(format.format == 3)
     {
         samplesize = 4;
         opt->read_samples = wav_ieee_read;
@@ -455,8 +453,8 @@
     else
     {
         fprintf(stderr, 
-                _("ERROR: Wave file is unsupported type (must be standard PCM\n"
-                " or type 3 floating point PCM)\n"));
+                _("ERROR: Wav file is unsupported type (must be standard PCM\n"
+                " or type 3 floating point PCM\n"));
         return 0;
     }
 
@@ -464,14 +462,15 @@
         /* This is incorrect according to the spec. Warn loudly, then ignore
          * this value.
          */
-        fprintf(stderr, _("WARNING: Wave 'block alignment' value is incorrect, "
+        fprintf(stderr, _("Warning: WAV 'block alignment' value is incorrect, "
                     "ignoring.\n" 
                     "The software that created this file is incorrect.\n"));
     }
 
     if(format.samplesize == samplesize*8 && 
             (format.samplesize == 24 || format.samplesize == 16 || 
-             format.samplesize == 8 || format.samplesize == 32))
+             format.samplesize == 8 ||
+         (format.samplesize == 32 && format.format == 3)))
     {
         /* OK, good - we have the one supported format,
            now we want to find the size of the file */
@@ -485,33 +484,33 @@
                                             of trying to abstract stuff. */
         wav->samplesize = format.samplesize;
 
-        opt->total_samples_per_channel = 0; /* Give up, like raw format */
-
-        if(!opt->ignorelength) {      // if a new parameter NeroAacEnc style is included
-            if(len)
+        if(len)
+        {
+            opt->total_samples_per_channel = len/(format.channels*samplesize);
+        }
+        else
+        {
+            long pos;
+            pos = ftell(in);
+            if(fseek(in, 0, SEEK_END) == -1)
             {
-                opt->total_samples_per_channel = len/(format.channels*samplesize);
+                opt->total_samples_per_channel = 0; /* Give up */
             }
             else
             {
-                long pos;
-                pos = ftell(in);
-                if(fseek(in, 0, SEEK_END) != -1)
-                {
-                    opt->total_samples_per_channel = (ftell(in) - pos)/
-                        (format.channels*samplesize);
-                    fseek(in,pos, SEEK_SET);
-                }
+                opt->total_samples_per_channel = (ftell(in) - pos)/
+                    (format.channels*samplesize);
+                fseek(in,pos, SEEK_SET);
             }
         }
         wav->totalsamples = opt->total_samples_per_channel;
 
         opt->readdata = (void *)wav;
-
+        
         /* TODO: Read the extended wav header to get this right in weird cases,
          * and/or error out if neccesary. Suck. */
         wav->channel_permute = malloc(wav->channels * sizeof(int));
-        if (wav->channels <= 6)
+        if (wav->channels <= 8)
             /* Where we know the mappings, use them. */
             memcpy(wav->channel_permute, wav_permute_matrix[wav->channels-1], 
                     sizeof(int) * wav->channels);
@@ -525,8 +524,8 @@
     else
     {
         fprintf(stderr, 
-                _("ERROR: Wave file is unsupported subformat (must be 8, 16, 24 or 32 bit PCM\n"
-                "or floating point PCM)\n"));
+                _("ERROR: Wav file is unsupported subformat (must be 8,16, or 24 bit PCM\n"
+                "or floating point PCM\n"));
         return 0;
     }
 }
@@ -547,8 +546,8 @@
     }
 
     realsamples = bytes_read/(sampbyte*f->channels);
-    if (f->totalsamples) f->samplesread += realsamples;
-
+    f->samplesread += realsamples;
+        
     if(f->samplesize==8)
     {
         unsigned char *bufu = (unsigned char *)buf;
@@ -606,26 +605,6 @@
             return 0;
         }
     }
-    else if (f->samplesize==32)
-    {
-        if (!f->bigendian)
-        {
-            for (i = 0; i < realsamples; i++)
-            {
-                for (j=0; j < f->channels; j++)
-                    buffer[j][i] =            ((buf[i*4*f->channels + 4*ch_permute[j] + 3] << 24) |
-                        (((unsigned char *)buf)[i*4*f->channels + 4*ch_permute[j] + 2] << 16) |
-                        (((unsigned char *)buf)[i*4*f->channels + 4*ch_permute[j] + 1] << 8) |
-                        (((unsigned char *)buf)[i*4*f->channels + 4*ch_permute[j]] & 0xff))
-                        / 2147483648.0f;
-            }
-        }
-        else {
-            fprintf(stderr, _("Big endian 32 bit PCM data is not currently "
-                    "supported, aborting.\n"));
-            return 0;
-        }
-    }
     else {
         fprintf(stderr, _("Internal error: attempt to read unsupported "
                           "bitdepth %d\n"), f->samplesize);
@@ -729,7 +708,7 @@
     out_samples = res_push(&rs->resampler, buffer, (float const **)rs->bufs, in_samples);
 
     if(out_samples <= 0) {
-        fprintf(stderr, _("BUG: Got zero samples from resampler; your file will be truncated. Please report this.\n"));
+        fprintf(stderr, _("BUG: Got zero samples from resampler: your file will be truncated. Please report this.\n"));
     }
 
     return out_samples;
@@ -846,10 +825,10 @@
     downmix *d = calloc(1, sizeof(downmix));
 
     if(opt->channels != 2) {
-        fprintf(stderr, _("Internal error! Please report this bug.\n"));
+        fprintf(stderr, "Internal error! Please report this bug.\n");
         return;
     }
-
+    
     d->bufs = malloc(2 * sizeof(float *));
     d->bufs[0] = malloc(4096 * sizeof(float));
     d->bufs[1] = malloc(4096 * sizeof(float));
@@ -874,3 +853,4 @@
     free(d->bufs);
     free(d);
 }
+

Modified: trunk/vorbis-tools/oggenc/flac.c
===================================================================
--- trunk/vorbis-tools/oggenc/flac.c	2010-01-21 00:36:05 UTC (rev 16792)
+++ trunk/vorbis-tools/oggenc/flac.c	2010-01-22 07:06:57 UTC (rev 16793)
@@ -142,6 +142,19 @@
     return 1;
 }
 
+/* FLAC follows the WAV channel ordering pattern; we must permute to
+   put things in Vorbis channel order */
+static int wav_permute_matrix[8][8] = 
+{
+  {0},              /* 1.0 mono   */
+  {0,1},            /* 2.0 stereo */
+  {0,2,1},          /* 3.0 channel ('wide') stereo */
+  {0,1,2,3},        /* 4.0 discrete quadraphonic */
+  {0,2,1,3,4},      /* 5.0 surround */
+  {0,2,1,4,5,3},    /* 5.1 surround */
+  {0,2,1,4,5,6,3},  /* 6.1 surround */
+  {0,2,1,6,7,4,5,3} /* 7.1 surround (classic theater 8-track) */
+};
 
 long flac_read(void *in, float **buffer, int samples)
 {
@@ -156,10 +169,12 @@
             int copy = flac->buf_fill < (samples - realsamples) ?
                 flac->buf_fill : (samples - realsamples);
 
-            for (i = 0; i < flac->channels; i++)
+            for (i = 0; i < flac->channels; i++){
+              int permute = wav_permute_matrix[flac->channels-1][i];
                 for (j = 0; j < copy; j++)
-                    buffer[i][j+realsamples] = 
-                        flac->buf[i][j+flac->buf_start];
+                    buffer[i][j+realsamples] =
+                        flac->buf[permute][j+flac->buf_start];
+            }
             flac->buf_start += copy;
             flac->buf_fill -= copy;
             realsamples += copy;



More information about the commits mailing list