shithub: sox

Download patch

ref: f37f0c8758b985ad853a3d7b06176a3bd76982e7
parent: 5c55ce9fdcbec4b08785337edea5a941d72b0c1b
author: cbagwell <cbagwell>
date: Sun Jan 23 20:13:00 EST 2005

Add RIFX support to WAV. Auto-detect DEC-style .sd headers.

--- a/Changelog
+++ b/Changelog
@@ -7,6 +7,10 @@
 sox-12.17.8
 -----------
   o noisered effect had compile problems with some compilers.
+  o "-x" option was being ignored since 12.17.7.
+  o Stuart Brady added support for reading and writing RIFX files (big
+    endian RIFF/WAV files).  Also added support for auto detecting
+    DEC-style ".sd\0" files.
 
 sox-12.17.7
 -----------
--- a/sox.1
+++ b/sox.1
@@ -625,6 +625,7 @@
 (Obviously, Windows was of such incredible importance
 to the computer industry that it just had to have its own 
 sound file format.)
+.br
 Normally \fB.wav\fR files have all formatting information
 in their headers, and so do not need any format options
 specified for an input file. If any are, they will
@@ -632,10 +633,13 @@
 You had better know what you are doing! Output format
 options will cause a format conversion, and the \fB.wav\fR
 will written appropriately.
+.br
 SoX currently can read PCM, ULAW, ALAW, MS ADPCM, and IMA (or DVI) ADPCM.
-It can write all of these formats including
-.B (NEW!)
-the ADPCM encoding.
+It can write all of these formats including the ADPCM encoding.
+Big endian versions of RIFF files, called RIFX, can also be read
+and written.  To write a RIFX file, use the 
+.I -x
+option with the output file options.
 .TP 10
 .B .wve
 Psion 8-bit A-law
--- a/src/auto.c
+++ b/src/auto.c
@@ -45,8 +45,11 @@
         {
             /* Look for .snd or dns. header of AU files */
             if ((strncmp(header, ".snd", 4) == 0) ||
-                    (strncmp(header, "dns.", 4) == 0) ||
-                    ((header[0] == '\0') && (strncmp(header+1, "ds.", 3) == 0))) 
+                (strncmp(header, "dns.", 4) == 0) ||
+                ((header[0] == '\0') && 
+                 (strncmp(header+1, "ds.", 3) == 0)) ||
+                ((strncmp(header, "sd.", 3) == 0) && 
+                 (header[3] == '\0')))
             {
                 type = "au";
             }
--- a/src/sox.c
+++ b/src/sox.c
@@ -291,6 +291,7 @@
         file_desc[offset]->filetype = "auto";
     else
         file_desc[offset]->filetype = strdup(file_opts[offset]->filetype);
+    file_desc[offset]->swap = file_opts[offset]->swap;
 
     if (st_gettype(file_desc[offset]))
         st_fail("Unknown input file format for '%s':  %s", 
@@ -330,7 +331,8 @@
     file_desc[offset]->info = file_opts[offset]->info;
     file_desc[offset]->filename = file_opts[offset]->filename;
     file_desc[offset]->filetype = file_opts[offset]->filetype;
- 
+    file_desc[offset]->swap = file_opts[offset]->swap;
+
     if (writing && !file_desc[offset]->filetype) {
         /* Use filename extension to determine audio type. */
 
--- a/src/wav.c
+++ b/src/wav.c
@@ -457,12 +457,20 @@
 
     if (ST_IS_BIGENDIAN) ft->swap = ft->swap ? 0 : 1;
 
-    if (st_reads(ft, magic, 4) == ST_EOF || strncmp("RIFF", magic, 4))
+    if (st_reads(ft, magic, 4) == ST_EOF || (strncmp("RIFF", magic, 4) != 0 &&
+                                             strncmp("RIFX", magic, 4) != 0))
     {
         st_fail_errno(ft,ST_EHDR,"WAVE: RIFF header not found");
         return ST_EOF;
     }
 
+    /* RIFX is a Big-endian RIFF */
+    if (strncmp("RIFX", magic, 4) == 0) 
+    {
+        st_report("Found RIFX header, swapping bytes");
+        ft->swap = ft->swap ? 0 : 1;
+    }
+
     st_readdw(ft, &dwRiffLength);
 
     if (st_reads(ft, magic, 4) == ST_EOF || strncmp("WAVE", magic, 4))
@@ -1174,39 +1182,40 @@
 
 int st_wavstartwrite(ft_t ft) 
 {
-        wav_t   wav = (wav_t) ft->priv;
-        int     rc;
+    wav_t wav = (wav_t) ft->priv;
+    int rc;
 
-        ft->st_errno = ST_SUCCESS;
+    ft->st_errno = ST_SUCCESS;
 
-        if (ST_IS_BIGENDIAN) ft->swap = ft->swap ? 0 : 1;
+    if (ST_IS_BIGENDIAN) ft->swap = ft->swap ? 0 : 1;
 
-        /* FIXME: This reserves memory but things could fail
-         * later on and not release this memory.
-         */
-        if (ft->info.encoding != ST_ENCODING_ADPCM &&
-            ft->info.encoding != ST_ENCODING_IMA_ADPCM &&
-            ft->info.encoding != ST_ENCODING_GSM)
-        {
-                rc = st_rawstartwrite(ft);
-                if (rc)
-                    return rc;
-        }
-
-        wav->numSamples = 0;
-        wav->dataLength = 0;
-        if (!ft->seekable)
-                st_warn("Length in output .wav header will be wrong since can't seek to fix it");
-        rc = wavwritehdr(ft, 0);  /* also calculates various wav->* info */
-        if (rc != 0)
+    /* FIXME: This reserves memory but things could fail
+     * later on and not release this memory.
+     */
+    if (ft->info.encoding != ST_ENCODING_ADPCM &&
+        ft->info.encoding != ST_ENCODING_IMA_ADPCM &&
+        ft->info.encoding != ST_ENCODING_GSM)
+    {
+        rc = st_rawstartwrite(ft);
+        if (rc)
             return rc;
+    }
 
-        wav->packet = NULL;
-        wav->samples = NULL;
-        wav->iCoefs = NULL;
-        switch (wav->formatTag)
-        {
+    wav->numSamples = 0;
+    wav->dataLength = 0;
+    if (!ft->seekable)
+        st_warn("Length in output .wav header will be wrong since can't seek to fix it");
+    rc = wavwritehdr(ft, 0);  /* also calculates various wav->* info */
+    if (rc != 0)
+        return rc;
+
+    wav->packet = NULL;
+    wav->samples = NULL;
+    wav->iCoefs = NULL;
+    switch (wav->formatTag)
+    {
         int ch, sbsize;
+
         case WAVE_FORMAT_IMA_ADPCM:
             initImaTable();
         /* intentional case fallthru! */
@@ -1233,14 +1242,14 @@
 #endif
         default:
             break;
-        }
-        return ST_SUCCESS;
+    }
+    return ST_SUCCESS;
 }
 
 /* wavwritehdr:  write .wav headers as follows:
  
 bytes      variable      description
-0  - 3     'RIFF'
+0  - 3     'RIFF'/'RIFX' Little/Big-endian
 4  - 7     wRiffLength   length of file minus the 8 byte riff header
 8  - 11    'WAVE'
 12 - 15    'fmt '
@@ -1492,7 +1501,20 @@
     dwAvgBytesPerSec = (double)wBlockAlign*ft->info.rate / (double)wSamplesPerBlock + 0.5;
 
     /* figured out header info, so write it */
-    st_writes(ft, "RIFF");
+
+
+    /* If user specified opposite swap then we think, assume they are
+     * asking to write a RIFX file.
+     */
+    if ((!ST_IS_BIGENDIAN && ft->swap) || 
+        (ST_IS_BIGENDIAN && !ft->swap))
+    {
+        if (!second_header)
+            st_report("Requested to swap bytes so writing  RIFX header");
+        st_writes(ft, "RIFX");
+    }
+    else
+        st_writes(ft, "RIFF");
     st_writedw(ft, wRiffLength);
     st_writes(ft, "WAVE");
     st_writes(ft, "fmt ");