[xiph-commits] r15003 - in trunk/vorbis-tools: . oggenc

ivo at svn.xiph.org ivo at svn.xiph.org
Sun Jun 8 17:59:52 PDT 2008


Author: ivo
Date: 2008-06-08 17:59:51 -0700 (Sun, 08 Jun 2008)
New Revision: 15003

Modified:
   trunk/vorbis-tools/CHANGES
   trunk/vorbis-tools/oggenc/audio.c
   trunk/vorbis-tools/oggenc/encode.h
   trunk/vorbis-tools/oggenc/oggenc.c
Log:
Patches by Jose Antonio Peirote:
* fixed remapping channels bug
* support for WAVE_FORMAT_EXTENSIBLE headers
* support for 32 bit WAV files
* --ignorelength; support for WAV files > 4 GB
Closes #1326

Modified: trunk/vorbis-tools/CHANGES
===================================================================
--- trunk/vorbis-tools/CHANGES	2008-06-08 22:52:00 UTC (rev 15002)
+++ trunk/vorbis-tools/CHANGES	2008-06-09 00:59:51 UTC (rev 15003)
@@ -7,6 +7,10 @@
 * ogg123: return value to stop decoding after buffer is shut down (#1357)
 * oggenc: fixed a core dump while resampling from FLAC (#1316)
 * oggenc: fixed a typo in the Skeleton handling routine
+* oggenc: fixed remapping channels bug (#1326)
+* oggenc: support for WAVE_FORMAT_EXTENSIBLE headers (#1326)
+* oggenc: support for 32 bit WAV files (#1326)
+* oggenc: --ignorelength; support for WAV files > 4 GB (#1326)
 * ogginfo: support for information in Kate streams (#1360)
 * vcut: 64 bit fixes (#1366)
 * vorbiscomment: correct memory allocation (#472)

Modified: trunk/vorbis-tools/oggenc/audio.c
===================================================================
--- trunk/vorbis-tools/oggenc/audio.c	2008-06-08 22:52:00 UTC (rev 15002)
+++ trunk/vorbis-tools/oggenc/audio.c	2008-06-09 00:59:51 UTC (rev 15003)
@@ -28,6 +28,9 @@
 #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) \
@@ -377,8 +380,8 @@
     {0,1},
     {0,2,1},
     {0,1,2,3},
-    {0,1,2,3,4}, /* No equivalent in wav? */
-    {0,2,1,5,3,4}
+    {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}
 };
 
 int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
@@ -399,7 +402,7 @@
     if(!find_wav_chunk(in, "fmt ", &len))
         return 0; /* EOF */
 
-    if(len < 16) 
+    if(len < 16)
     {
         fprintf(stderr, _("Warning: Unrecognised format chunk in WAV header\n"));
         return 0; /* Weird format chunk */
@@ -410,13 +413,14 @@
      * 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)
+    if(len!=16 && len!=18 && len!=40)
         fprintf(stderr, 
                 _("Warning: INVALID format chunk in wav header.\n"
                 " Trying to read anyway (may not work)...\n"));
 
-    if(fread(buf,1,16,in) < 16)
+    if(fread(buf,1,len,in) < len)
     {
         fprintf(stderr, _("Warning: Unexpected EOF in reading WAV header\n"));
         return 0;
@@ -424,8 +428,6 @@
 
     /* 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); 
@@ -434,15 +436,18 @@
     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 == 1)
+    if(format.format == WAVE_FORMAT_PCM)
     {
         samplesize = format.samplesize/8;
         opt->read_samples = wav_read;
     }
-    else if(format.format == 3)
+    else if(format.format == WAVE_FORMAT_IEEE_FLOAT)
     {
         samplesize = 4;
         opt->read_samples = wav_ieee_read;
@@ -466,8 +471,7 @@
 
     if(format.samplesize == samplesize*8 && 
             (format.samplesize == 24 || format.samplesize == 16 || 
-             format.samplesize == 8 ||
-         (format.samplesize == 32 && format.format == 3)))
+             format.samplesize == 8 || format.samplesize == 32))
     {
         /* OK, good - we have the one supported format,
            now we want to find the size of the file */
@@ -481,29 +485,29 @@
                                             of trying to abstract stuff. */
         wav->samplesize = format.samplesize;
 
-        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 = 0; /* Give up, like raw format */
+
+        if(!opt->ignorelength) {      // if a new parameter NeroAacEnc style is included
+            if(len)
             {
-                opt->total_samples_per_channel = 0; /* Give up */
+                opt->total_samples_per_channel = len/(format.channels*samplesize);
             }
             else
             {
-                opt->total_samples_per_channel = (ftell(in) - pos)/
-                    (format.channels*samplesize);
-                fseek(in,pos, SEEK_SET);
+                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);
+                }
             }
         }
         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));
@@ -521,7 +525,7 @@
     else
     {
         fprintf(stderr, 
-                _("ERROR: Wav file is unsupported subformat (must be 8,16, or 24 bit PCM\n"
+                _("ERROR: Wav file is unsupported subformat (must be 8,16,24 or 32 bit PCM\n"
                 "or floating point PCM)\n"));
         return 0;
     }
@@ -543,8 +547,8 @@
     }
 
     realsamples = bytes_read/(sampbyte*f->channels);
-    f->samplesread += realsamples;
-        
+    if (f->totalsamples) f->samplesread += realsamples;
+
     if(f->samplesize==8)
     {
         unsigned char *bufu = (unsigned char *)buf;
@@ -602,6 +606,26 @@
             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);

Modified: trunk/vorbis-tools/oggenc/encode.h
===================================================================
--- trunk/vorbis-tools/oggenc/encode.h	2008-06-08 22:52:00 UTC (rev 15002)
+++ trunk/vorbis-tools/oggenc/encode.h	2008-06-09 00:59:51 UTC (rev 15003)
@@ -89,6 +89,7 @@
     unsigned int serial;
     unsigned int skeleton_serial;
         int fixedserial;
+    int ignorelength;
 } oe_options;
 
 typedef struct
@@ -127,6 +128,7 @@
     FILE *out;
     char *filename;
     char *infilename;
+    int ignorelength;
 } oe_enc_opt;
 
 

Modified: trunk/vorbis-tools/oggenc/oggenc.c
===================================================================
--- trunk/vorbis-tools/oggenc/oggenc.c	2008-06-08 22:52:00 UTC (rev 15002)
+++ trunk/vorbis-tools/oggenc/oggenc.c	2008-06-09 00:59:51 UTC (rev 15003)
@@ -63,9 +63,10 @@
     {"managed", 0, 0, 0},
     {"resample",1,0,0},
     {"downmix", 0,0,0},
-    {"scale", 1, 0, 0}, 
+    {"scale", 1, 0, 0},
     {"advanced-encode-option", 1, 0, 0},
     {"discard-comments", 0, 0, 0},
+    {"ignorelength", 0, 0, 0},
     {NULL,0,0,0}
 };
 
@@ -84,7 +85,7 @@
     oe_options opt = {NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL,
               0, NULL, 0, NULL, 0, NULL, 0, 1, 0, 0, 0,16,44100,2, 0, NULL,
               DEFAULT_NAMEFMT_REMOVE, DEFAULT_NAMEFMT_REPLACE,
-              NULL, 0, -1,-1,-1,.3,-1,0, 0,0.f, 0, 0};
+              NULL, 0, -1,-1,-1,.3,-1,0, 0,0.f, 0, 0, 0};
 
     int i;
 
@@ -160,6 +161,7 @@
         enc_opts.comments = &vc;
         enc_opts.copy_comments = opt.copy_comments;
         enc_opts.with_skeleton = opt.with_skeleton;
+        enc_opts.ignorelength = opt.ignorelength;
 
         /* OK, let's build the vorbis_comments structure */
         build_comments(&vc, &opt, i, &artist, &album, &title, &track,
@@ -446,6 +448,8 @@
         "                      stream after the first.\n"
         " --discard-comments   Prevents comments in FLAC and Ogg FLAC files from\n"
         "                      being copied to the output Ogg Vorbis file.\n"
+        " --ignorelength       Ignore the datalength in wav headers. This will allow\n"
+        "                      support for files > 4GB and STDIN data streams. \n"
         "\n"
         " Naming:\n"
         " -o, --output=fn      Write file to fn (only valid in single-file mode)\n"
@@ -670,8 +674,11 @@
                     opt->advopt[opt->advopt_count - 1].val = val;
                 }
                 else if(!strcmp(long_options[option_index].name, "discard-comments")) {
-          opt->copy_comments = 0;
-        }
+                    opt->copy_comments = 0;
+                }
+                else if(!strcmp(long_options[option_index].name, "ignorelength")) {
+                    opt->ignorelength = 1;
+                }
 
                 else {
                     fprintf(stderr, _("Internal error parsing command line options\n"));



More information about the commits mailing list