shithub: sox

Download patch

ref: bf27592b54f18a7c4d6beb0f3d2f195087138434
parent: b190c3d473a96a48c27c01186b1740ecd6753b87
author: Mans Rullgard <mans@mansr.com>
date: Wed Aug 5 14:20:36 EDT 2020

wav: move fmt chunk parsing to a separate function

--- a/src/wav.c
+++ b/src/wav.c
@@ -484,22 +484,9 @@
     return SOX_EOF;
 }
 
-/*
- * Do anything required before you start reading samples.
- * Read file header.
- *      Find out sampling rate,
- *      size and encoding of samples,
- *      mono/stereo/quad.
- */
-static int startread(sox_format_t * ft)
+static int wav_read_fmt(sox_format_t *ft, uint32_t len)
 {
-    priv_t *       wav = (priv_t *) ft->priv;
-    char        magic[5];
-    uint64_t    len;
-
-    /* wave file characteristics */
-    uint64_t      qwRiffLength;
-    uint32_t      dwRiffLength_tmp;
+    priv_t *wav = ft->priv;
     unsigned short wChannels;       /* number of channels */
     uint32_t      dwSamplesPerSecond; /* samples per second per channel */
     uint32_t      dwAvgBytesPerSec;/* estimate of bytes per second needed */
@@ -507,69 +494,9 @@
     uint32_t wFmtSize;
     uint16_t wExtSize = 0;    /* extended field for non-PCM */
 
-    uint64_t      qwDataLength;    /* length of sound data in bytes */
     size_t    bytesPerBlock = 0;
     int    bytespersample;          /* bytes per sample (per channel */
-    char text[256];
-    uint32_t      dwLoopPos;
 
-    ft->sox_errno = SOX_SUCCESS;
-    wav->ignoreSize = ft->signal.length == SOX_IGNORE_LENGTH;
-
-    if (lsx_reads(ft, magic, (size_t)4) == SOX_EOF || (strncmp("RIFF", magic, (size_t)4) != 0 &&
-                                             strncmp("RIFX", magic, (size_t)4) != 0 && strncmp("RF64", magic, (size_t)4)!=0 ))
-    {
-        lsx_fail_errno(ft,SOX_EHDR,"WAVE: RIFF header not found");
-        return SOX_EOF;
-    }
-
-    /* RIFX is a Big-endian RIFF */
-    if (strncmp("RIFX", magic, (size_t)4) == 0)
-    {
-        lsx_debug("Found RIFX header");
-        ft->encoding.reverse_bytes = MACHINE_IS_LITTLEENDIAN;
-    }
-    else ft->encoding.reverse_bytes = MACHINE_IS_BIGENDIAN;
-
-    if (strncmp("RF64", magic, (size_t)4) == 0)
-    {
-        wav->isRF64 = sox_true;
-    }
-    else
-    {
-        wav->isRF64 = sox_false;
-    }
-
-    lsx_readdw(ft, &dwRiffLength_tmp);
-    qwRiffLength = dwRiffLength_tmp;
-
-    if (lsx_reads(ft, magic, (size_t)4) == SOX_EOF || strncmp("WAVE", magic, (size_t)4))
-    {
-        lsx_fail_errno(ft,SOX_EHDR,"WAVE header not found");
-        return SOX_EOF;
-    }
-
-    if (wav->isRF64 && findChunk(ft, "ds64", &len) != SOX_EOF) {
-        lsx_debug("Found ds64 header");
-
-        if (dwRiffLength_tmp==0xffffffff)
-        {
-            lsx_readqw(ft, &qwRiffLength);
-        }
-        else
-        {
-            lsx_skipbytes(ft, (size_t)8);
-        }
-        lsx_readqw(ft, &wav->ds64_dataSize);
-        lsx_skipbytes(ft, (size_t)len-16);
-    }
-
-    /* Now look for the format chunk */
-    if (findChunk(ft, "fmt ", &len) == SOX_EOF)
-    {
-        lsx_fail_errno(ft,SOX_EHDR,"WAVE chunk fmt not found");
-        return SOX_EOF;
-    }
     wFmtSize = len;
 
     if (wFmtSize < 16)
@@ -898,6 +825,92 @@
     /* Skip anything left over from fmt chunk */
     lsx_seeki(ft, (off_t)len, SEEK_CUR);
 
+    return 0;
+}
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ *      Find out sampling rate,
+ *      size and encoding of samples,
+ *      mono/stereo/quad.
+ */
+static int startread(sox_format_t * ft)
+{
+    priv_t *       wav = (priv_t *) ft->priv;
+    char        magic[5];
+    uint64_t    len;
+    int err;
+
+    /* wave file characteristics */
+    uint64_t      qwRiffLength;
+    uint32_t      dwRiffLength_tmp;
+    uint64_t      qwDataLength;    /* length of sound data in bytes */
+    char text[256];
+    uint32_t      dwLoopPos;
+
+    ft->sox_errno = SOX_SUCCESS;
+    wav->ignoreSize = ft->signal.length == SOX_IGNORE_LENGTH;
+
+    if (lsx_reads(ft, magic, (size_t)4) == SOX_EOF || (strncmp("RIFF", magic, (size_t)4) != 0 &&
+                                             strncmp("RIFX", magic, (size_t)4) != 0 && strncmp("RF64", magic, (size_t)4)!=0 ))
+    {
+        lsx_fail_errno(ft,SOX_EHDR,"WAVE: RIFF header not found");
+        return SOX_EOF;
+    }
+
+    /* RIFX is a Big-endian RIFF */
+    if (strncmp("RIFX", magic, (size_t)4) == 0)
+    {
+        lsx_debug("Found RIFX header");
+        ft->encoding.reverse_bytes = MACHINE_IS_LITTLEENDIAN;
+    }
+    else ft->encoding.reverse_bytes = MACHINE_IS_BIGENDIAN;
+
+    if (strncmp("RF64", magic, (size_t)4) == 0)
+    {
+        wav->isRF64 = sox_true;
+    }
+    else
+    {
+        wav->isRF64 = sox_false;
+    }
+
+    lsx_readdw(ft, &dwRiffLength_tmp);
+    qwRiffLength = dwRiffLength_tmp;
+
+    if (lsx_reads(ft, magic, (size_t)4) == SOX_EOF || strncmp("WAVE", magic, (size_t)4))
+    {
+        lsx_fail_errno(ft,SOX_EHDR,"WAVE header not found");
+        return SOX_EOF;
+    }
+
+    if (wav->isRF64 && findChunk(ft, "ds64", &len) != SOX_EOF) {
+        lsx_debug("Found ds64 header");
+
+        if (dwRiffLength_tmp==0xffffffff)
+        {
+            lsx_readqw(ft, &qwRiffLength);
+        }
+        else
+        {
+            lsx_skipbytes(ft, (size_t)8);
+        }
+        lsx_readqw(ft, &wav->ds64_dataSize);
+        lsx_skipbytes(ft, (size_t)len-16);
+    }
+
+    /* Now look for the format chunk */
+    if (findChunk(ft, "fmt ", &len) == SOX_EOF)
+    {
+        lsx_fail_errno(ft,SOX_EHDR,"WAVE chunk fmt not found");
+        return SOX_EOF;
+    }
+
+    err = wav_read_fmt(ft, len);
+    if (err)
+        return err;
+
     /* for non-PCM formats, there's a 'fact' chunk before
      * the upcoming 'data' chunk */
 
@@ -960,40 +973,6 @@
      */
     if (wav->ignoreSize)
       ft->signal.length = SOX_UNSPEC;
-
-    lsx_debug("Reading Wave file: %s format, %d channel%s, %d samp/sec",
-           wav_format_str(wav->formatTag), ft->signal.channels,
-           wChannels == 1 ? "" : "s", dwSamplesPerSecond);
-    lsx_debug("        %d byte/sec, %d block align, %d bits/samp, %lu data bytes",
-           dwAvgBytesPerSec, wav->blockAlign, wBitsPerSample, qwDataLength);
-
-    /* Can also report extended fmt information */
-    switch (wav->formatTag)
-    {
-        case WAVE_FORMAT_ADPCM:
-            lsx_debug("        %d Extsize, %d Samps/block, %lu bytes/block %d Num Coefs, %lu Samps/chan",
-                      wExtSize,wav->samplesPerBlock,
-                      (unsigned long)bytesPerBlock,wav->nCoefs,
-                      (unsigned long)wav->numSamples);
-            break;
-
-        case WAVE_FORMAT_IMA_ADPCM:
-            lsx_debug("        %d Extsize, %d Samps/block, %lu bytes/block %lu Samps/chan",
-                      wExtSize, wav->samplesPerBlock, 
-                      (unsigned long)bytesPerBlock,
-                      (unsigned long)wav->numSamples);
-            break;
-
-        case WAVE_FORMAT_GSM610:
-            lsx_debug("GSM .wav: %d Extsize, %d Samps/block, %lu Samples/chan",
-                      wExtSize, wav->samplesPerBlock, 
-                      (unsigned long)wav->numSamples);
-            break;
-
-        default:
-            lsx_debug("        %lu Samps/chans", 
-                      (unsigned long)wav->numSamples);
-    }
 
     /* Horrible way to find Cool Edit marker points. Taken from Quake source*/
     ft->oob.loops[0].start = SOX_IGNORE_LENGTH;