shithub: sox

Download patch

ref: d763943a35890aba582ae85660bc75cad2717c9f
parent: 9285511b84be6be47fda82500fb0c57c88282329
author: Mans Rullgard <mans@mansr.com>
date: Thu Aug 6 09:50:15 EDT 2020

wav: prettify wav_read_fmt() function

--- a/src/wav.c
+++ b/src/wav.c
@@ -376,83 +376,78 @@
 
 static int wav_read_fmt(sox_format_t *ft, uint32_t len)
 {
-    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 */
-    uint16_t wBitsPerSample;  /* bits per sample */
-    uint32_t wFmtSize;
-    uint16_t wExtSize = 0;    /* extended field for non-PCM */
+    priv_t  *wav = ft->priv;
+    uint16_t wChannels;          /* number of channels */
+    uint32_t dwSamplesPerSecond; /* samples per second per channel */
+    uint32_t dwAvgBytesPerSec;   /* estimate of bytes per second needed */
+    uint16_t wBitsPerSample;     /* bits per sample */
+    uint16_t wExtSize = 0;       /* extended field for non-PCM */
+    size_t   bytesPerBlock = 0;
+    int      bytespersample;     /* bytes per sample (per channel */
 
-    size_t    bytesPerBlock = 0;
-    int    bytespersample;          /* bytes per sample (per channel */
-
-    wFmtSize = len;
-
-    if (wFmtSize < 16)
-    {
-        lsx_fail_errno(ft,SOX_EHDR,"WAVE file fmt chunk is too short");
+    if (len < 16) {
+        lsx_fail_errno(ft, SOX_EHDR, "WAVE file fmt chunk is too short");
         return SOX_EOF;
     }
 
-    lsx_readw(ft, &(wav->formatTag));
+    lsx_readw(ft, &wav->formatTag);
     lsx_readw(ft, &wChannels);
     lsx_readdw(ft, &dwSamplesPerSecond);
     lsx_readdw(ft, &dwAvgBytesPerSec);   /* Average bytes/second */
-    lsx_readw(ft, &(wav->blockAlign));   /* Block align */
+    lsx_readw(ft, &wav->blockAlign);     /* Block align */
     lsx_readw(ft, &wBitsPerSample);      /* bits per sample per channel */
     len -= 16;
 
-    if (wav->formatTag == WAVE_FORMAT_EXTENSIBLE)
-    {
-      uint16_t extensionSize;
-      uint16_t numberOfValidBits;
-      uint32_t speakerPositionMask;
-      uint16_t subFormatTag;
-      uint8_t dummyByte;
-      int i;
+    if (wav->formatTag == WAVE_FORMAT_EXTENSIBLE) {
+        uint16_t extensionSize;
+        uint16_t numberOfValidBits;
+        uint32_t speakerPositionMask;
+        uint16_t subFormatTag;
 
-      if (wFmtSize < 18)
-      {
-        lsx_fail_errno(ft,SOX_EHDR,"WAVE file fmt chunk is too short");
-        return SOX_EOF;
-      }
-      lsx_readw(ft, &extensionSize);
-      len -= 2;
-      if (extensionSize < 22)
-      {
-        lsx_fail_errno(ft,SOX_EHDR,"WAVE file fmt chunk is too short");
-        return SOX_EOF;
-      }
-      lsx_readw(ft, &numberOfValidBits);
-      lsx_readdw(ft, &speakerPositionMask);
-      lsx_readw(ft, &subFormatTag);
-      for (i = 0; i < 14; ++i) lsx_readb(ft, &dummyByte);
-      len -= 22;
-      if (numberOfValidBits != wBitsPerSample)
-      {
-        lsx_fail_errno(ft,SOX_EHDR,"WAVE file fmt with padded samples is not supported yet");
-        return SOX_EOF;
-      }
-      wav->formatTag = subFormatTag;
-      lsx_report("EXTENSIBLE");
+        if (len < 2) {
+            lsx_fail_errno(ft, SOX_EHDR, "WAVE file fmt chunk is too short");
+            return SOX_EOF;
+        }
+
+        lsx_readw(ft, &extensionSize);
+        len -= 2;
+
+        if (extensionSize < 22) {
+            lsx_fail_errno(ft, SOX_EHDR, "WAVE file fmt chunk is too short");
+            return SOX_EOF;
+        }
+
+        lsx_readw(ft, &numberOfValidBits);
+        lsx_readdw(ft, &speakerPositionMask);
+        lsx_readw(ft, &subFormatTag);
+        lsx_skipbytes(ft, 14);
+        len -= 22;
+
+        if (numberOfValidBits != wBitsPerSample) {
+            lsx_fail_errno(ft, SOX_EHDR, "WAVE file fmt with padded samples is not supported yet");
+            return SOX_EOF;
+        }
+
+        wav->formatTag = subFormatTag;
+        lsx_report("EXTENSIBLE");
     }
 
-    switch (wav->formatTag)
-    {
+    switch (wav->formatTag) {
     case WAVE_FORMAT_UNKNOWN:
-        lsx_fail_errno(ft,SOX_EHDR,"WAVE file is in unsupported Microsoft Official Unknown format.");
+        lsx_fail_errno(ft, SOX_EHDR, "WAVE file is in unsupported Microsoft Official Unknown format.");
         return SOX_EOF;
 
     case WAVE_FORMAT_PCM:
         /* Default (-1) depends on sample size.  Set that later on. */
-        if (ft->encoding.encoding != SOX_ENCODING_UNKNOWN && ft->encoding.encoding != SOX_ENCODING_UNSIGNED &&
+        if (ft->encoding.encoding != SOX_ENCODING_UNKNOWN &&
+            ft->encoding.encoding != SOX_ENCODING_UNSIGNED &&
             ft->encoding.encoding != SOX_ENCODING_SIGN2)
             lsx_report("User options overriding encoding read in .wav header");
         break;
 
     case WAVE_FORMAT_IMA_ADPCM:
-        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_IMA_ADPCM)
+        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN ||
+            ft->encoding.encoding == SOX_ENCODING_IMA_ADPCM)
             ft->encoding.encoding = SOX_ENCODING_IMA_ADPCM;
         else
             lsx_report("User options overriding encoding read in .wav header");
@@ -459,7 +454,8 @@
         break;
 
     case WAVE_FORMAT_ADPCM:
-        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_MS_ADPCM)
+        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN ||
+            ft->encoding.encoding == SOX_ENCODING_MS_ADPCM)
             ft->encoding.encoding = SOX_ENCODING_MS_ADPCM;
         else
             lsx_report("User options overriding encoding read in .wav header");
@@ -466,7 +462,8 @@
         break;
 
     case WAVE_FORMAT_IEEE_FLOAT:
-        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_FLOAT)
+        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN ||
+            ft->encoding.encoding == SOX_ENCODING_FLOAT)
             ft->encoding.encoding = SOX_ENCODING_FLOAT;
         else
             lsx_report("User options overriding encoding read in .wav header");
@@ -473,7 +470,8 @@
         break;
 
     case WAVE_FORMAT_ALAW:
-        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_ALAW)
+        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN ||
+            ft->encoding.encoding == SOX_ENCODING_ALAW)
             ft->encoding.encoding = SOX_ENCODING_ALAW;
         else
             lsx_report("User options overriding encoding read in .wav header");
@@ -480,7 +478,8 @@
         break;
 
     case WAVE_FORMAT_MULAW:
-        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_ULAW)
+        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN ||
+            ft->encoding.encoding == SOX_ENCODING_ULAW)
             ft->encoding.encoding = SOX_ENCODING_ULAW;
         else
             lsx_report("User options overriding encoding read in .wav header");
@@ -494,12 +493,15 @@
         return wavfail(ft, "Digifix");
     case WAVE_FORMAT_DOLBY_AC2:
         return wavfail(ft, "Dolby AC2");
+
     case WAVE_FORMAT_GSM610:
-        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_GSM )
+        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN ||
+            ft->encoding.encoding == SOX_ENCODING_GSM )
             ft->encoding.encoding = SOX_ENCODING_GSM;
         else
             lsx_report("User options overriding encoding read in .wav header");
         break;
+
     case WAVE_FORMAT_ROCKWELL_ADPCM:
         return wavfail(ft, "Rockwell ADPCM");
     case WAVE_FORMAT_ROCKWELL_DIGITALK:
@@ -517,7 +519,8 @@
     case WAVE_FORMAT_G722_ADPCM:
         return wavfail(ft, "G.722 ADPCM");
     default:
-        lsx_fail_errno(ft, SOX_EHDR, "Unknown WAV file encoding (type %x)", wav->formatTag);
+        lsx_fail_errno(ft, SOX_EHDR, "Unknown WAV file encoding (type %x)",
+                       wav->formatTag);
         return SOX_EOF;
     }
 
@@ -537,7 +540,6 @@
     else
         lsx_report("User options overriding rate read in .wav header");
 
-
     /* non-PCM formats except alaw and mulaw formats have extended fmt chunk.
      * Check for those cases.
      */
@@ -552,66 +554,76 @@
         }
     }
 
-    if (wExtSize > len)
-    {
-        lsx_fail_errno(ft,SOX_EOF,"wave header error: wExtSize inconsistent with wFmtLen");
+    if (wExtSize > len) {
+        lsx_fail_errno(ft, SOX_EOF,
+                       "wave header error: wExtSize inconsistent with wFmtLen");
         return SOX_EOF;
     }
 
-    switch (wav->formatTag)
-    {
+    switch (wav->formatTag) {
     case WAVE_FORMAT_ADPCM:
-        if (wExtSize < 4)
-        {
-            lsx_fail_errno(ft,SOX_EOF,"format[%s]: expects wExtSize >= %d",
-                        wav_format_str(wav->formatTag), 4);
+        if (wExtSize < 4) {
+            lsx_fail_errno(ft, SOX_EOF, "format[%s]: expects wExtSize >= %d",
+                           wav_format_str(wav->formatTag), 4);
             return SOX_EOF;
         }
 
-        if (wBitsPerSample != 4)
-        {
-            lsx_fail_errno(ft,SOX_EOF,"Can only handle 4-bit MS ADPCM in wav files");
+        if (wBitsPerSample != 4) {
+            lsx_fail_errno(ft, SOX_EOF,
+                           "Can only handle 4-bit MS ADPCM in wav files");
             return SOX_EOF;
         }
 
-        lsx_readw(ft, &(wav->samplesPerBlock));
-        bytesPerBlock = lsx_ms_adpcm_bytes_per_block((size_t) ft->signal.channels, (size_t) wav->samplesPerBlock);
-        if (bytesPerBlock != wav->blockAlign)
-        {
-            lsx_fail_errno(ft,SOX_EOF,"format[%s]: samplesPerBlock(%d) incompatible with blockAlign(%d)",
-                wav_format_str(wav->formatTag), wav->samplesPerBlock, wav->blockAlign);
+        lsx_readw(ft, &wav->samplesPerBlock);
+        lsx_readw(ft, &wav->nCoefs);
+        len -= 4;
+
+        bytesPerBlock = lsx_ms_adpcm_bytes_per_block(ft->signal.channels,
+                                                     wav->samplesPerBlock);
+
+        if (bytesPerBlock != wav->blockAlign) {
+            lsx_fail_errno(ft, SOX_EOF,
+                           "format[%s]: samplesPerBlock(%d) != blockAlign(%d)",
+                           wav_format_str(wav->formatTag),
+                           wav->samplesPerBlock, wav->blockAlign);
             return SOX_EOF;
         }
 
-        lsx_readw(ft, &(wav->nCoefs));
         if (wav->nCoefs < 7 || wav->nCoefs > 0x100) {
-            lsx_fail_errno(ft,SOX_EOF,"ADPCM file nCoefs (%.4hx) makes no sense", wav->nCoefs);
+            lsx_fail_errno(ft, SOX_EOF,
+                           "ADPCM file nCoefs (%.4hx) makes no sense",
+                           wav->nCoefs);
             return SOX_EOF;
         }
-        wav->packet = lsx_malloc((size_t)wav->blockAlign);
 
-        len -= 4;
-
-        if (wExtSize < 4 + 4*wav->nCoefs)
-        {
-            lsx_fail_errno(ft,SOX_EOF,"wave header error: wExtSize(%d) too small for nCoefs(%d)", wExtSize, wav->nCoefs);
+        if (wExtSize < 4 + 4 * wav->nCoefs) {
+            lsx_fail_errno(ft, SOX_EOF, "wave header error: wExtSize(%d) too small for nCoefs(%d)", wExtSize, wav->nCoefs);
             return SOX_EOF;
         }
 
-        wav->samples = lsx_malloc(wChannels*wav->samplesPerBlock*sizeof(short));
+        wav->packet = lsx_malloc(wav->blockAlign);
+        wav->samples =
+            lsx_malloc(wChannels * wav->samplesPerBlock * sizeof(short));
 
         /* nCoefs, lsx_ms_adpcm_i_coefs used by adpcm.c */
         wav->lsx_ms_adpcm_i_coefs = lsx_malloc(wav->nCoefs * 2 * sizeof(short));
         wav->ms_adpcm_data = lsx_ms_adpcm_alloc(wChannels);
+
         {
-            int i, errct=0;
-            for (i=0; len>=2 && i < 2*wav->nCoefs; i++) {
-                lsx_readsw(ft, &(wav->lsx_ms_adpcm_i_coefs[i]));
+            int i, errct = 0;
+
+            for (i = 0; len >= 2 && i < 2 * wav->nCoefs; i++) {
+                lsx_readsw(ft, &wav->lsx_ms_adpcm_i_coefs[i]);
                 len -= 2;
-                if (i<14) errct += (wav->lsx_ms_adpcm_i_coefs[i] != lsx_ms_adpcm_i_coef[i/2][i%2]);
-                /* lsx_debug("lsx_ms_adpcm_i_coefs[%2d] %4d",i,wav->lsx_ms_adpcm_i_coefs[i]); */
+
+                if (i < 14)
+                    errct += wav->lsx_ms_adpcm_i_coefs[i] !=
+                        lsx_ms_adpcm_i_coef[i / 2][i % 2];
             }
-            if (errct) lsx_warn("base lsx_ms_adpcm_i_coefs differ in %d/14 positions",errct);
+
+            if (errct)
+                lsx_warn("base lsx_ms_adpcm_i_coefs differ in %d/14 positions",
+                         errct);
         }
 
         bytespersample = 2;  /* AFTER de-compression */
@@ -618,94 +630,104 @@
         break;
 
     case WAVE_FORMAT_IMA_ADPCM:
-        if (wExtSize < 2)
-        {
-            lsx_fail_errno(ft,SOX_EOF,"format[%s]: expects wExtSize >= %d",
-                    wav_format_str(wav->formatTag), 2);
+        if (wExtSize < 2) {
+            lsx_fail_errno(ft, SOX_EOF, "format[%s]: expects wExtSize >= %d",
+                           wav_format_str(wav->formatTag), 2);
             return SOX_EOF;
         }
 
-        if (wBitsPerSample != 4)
-        {
-            lsx_fail_errno(ft,SOX_EOF,"Can only handle 4-bit IMA ADPCM in wav files");
+        if (wBitsPerSample != 4) {
+            lsx_fail_errno(ft, SOX_EOF,
+                           "Can only handle 4-bit IMA ADPCM in wav files");
             return SOX_EOF;
         }
 
-        lsx_readw(ft, &(wav->samplesPerBlock));
-        bytesPerBlock = lsx_ima_bytes_per_block((size_t) ft->signal.channels, (size_t) wav->samplesPerBlock);
-        if (bytesPerBlock != wav->blockAlign || wav->samplesPerBlock%8 != 1)
-        {
-            lsx_fail_errno(ft,SOX_EOF,"format[%s]: samplesPerBlock(%d) incompatible with blockAlign(%d)",
-                wav_format_str(wav->formatTag), wav->samplesPerBlock, wav->blockAlign);
+        lsx_readw(ft, &wav->samplesPerBlock);
+        len -= 2;
+
+        bytesPerBlock = lsx_ima_bytes_per_block(ft->signal.channels,
+                                                wav->samplesPerBlock);
+
+        if (bytesPerBlock != wav->blockAlign || wav->samplesPerBlock % 8 != 1) {
+            lsx_fail_errno(ft, SOX_EOF,
+                           "format[%s]: samplesPerBlock(%d) != blockAlign(%d)",
+                           wav_format_str(wav->formatTag),
+                           wav->samplesPerBlock, wav->blockAlign);
             return SOX_EOF;
         }
 
-        wav->packet = lsx_malloc((size_t)wav->blockAlign);
-        len -= 2;
+        wav->packet = lsx_malloc(wav->blockAlign);
+        wav->samples =
+            lsx_malloc(wChannels * wav->samplesPerBlock * sizeof(short));
 
-        wav->samples = lsx_malloc(wChannels*wav->samplesPerBlock*sizeof(short));
-
         bytespersample = 2;  /* AFTER de-compression */
         break;
 
     /* GSM formats have extended fmt chunk.  Check for those cases. */
     case WAVE_FORMAT_GSM610:
-        if (wExtSize < 2)
-        {
-            lsx_fail_errno(ft,SOX_EOF,"format[%s]: expects wExtSize >= %d",
-                    wav_format_str(wav->formatTag), 2);
+        if (wExtSize < 2) {
+            lsx_fail_errno(ft, SOX_EOF, "format[%s]: expects wExtSize >= %d",
+                           wav_format_str(wav->formatTag), 2);
             return SOX_EOF;
         }
+
         lsx_readw(ft, &wav->samplesPerBlock);
+        len -= 2;
+
         bytesPerBlock = 65;
-        if (wav->blockAlign != 65)
-        {
-            lsx_fail_errno(ft,SOX_EOF,"format[%s]: expects blockAlign(%d) = %d",
-                    wav_format_str(wav->formatTag), wav->blockAlign, 65);
+
+        if (wav->blockAlign != 65) {
+            lsx_fail_errno(ft, SOX_EOF,
+                           "format[%s]: expects blockAlign(%d) = %d",
+                           wav_format_str(wav->formatTag), wav->blockAlign, 65);
             return SOX_EOF;
         }
-        if (wav->samplesPerBlock != 320)
-        {
-            lsx_fail_errno(ft,SOX_EOF,"format[%s]: expects samplesPerBlock(%d) = %d",
-                    wav_format_str(wav->formatTag), wav->samplesPerBlock, 320);
+
+        if (wav->samplesPerBlock != 320) {
+            lsx_fail_errno(ft, SOX_EOF,
+                           "format[%s]: expects samplesPerBlock(%d) = %d",
+                           wav_format_str(wav->formatTag),
+                           wav->samplesPerBlock, 320);
             return SOX_EOF;
         }
+
         bytespersample = 2;  /* AFTER de-compression */
-        len -= 2;
         break;
 
     default:
-      bytespersample = (wBitsPerSample + 7)/8;
-
+        bytespersample = (wBitsPerSample + 7) / 8;
+        break;
     }
 
     /* User options take precedence */
-    if (!ft->encoding.bits_per_sample || ft->encoding.bits_per_sample == wBitsPerSample)
-      ft->encoding.bits_per_sample = wBitsPerSample;
+    if (!ft->encoding.bits_per_sample ||
+        ft->encoding.bits_per_sample == wBitsPerSample)
+        ft->encoding.bits_per_sample = wBitsPerSample;
     else
-      lsx_warn("User options overriding size read in .wav header");
+        lsx_warn("User options overriding size read in .wav header");
 
     /* Now we have enough information to set default encodings. */
-    switch (bytespersample)
-    {
+    switch (bytespersample) {
     case 1:
-      if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
-        ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
-      break;
+        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+            ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
+        break;
 
-    case 2: case 3: case 4:
-      if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
-        ft->encoding.encoding = SOX_ENCODING_SIGN2;
-      break;
+    case 2:
+    case 3:
+    case 4:
+        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+            ft->encoding.encoding = SOX_ENCODING_SIGN2;
+        break;
 
     case 8:
-      if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
-        ft->encoding.encoding = SOX_ENCODING_FLOAT;
-      break;
+        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+            ft->encoding.encoding = SOX_ENCODING_FLOAT;
+        break;
 
     default:
-      lsx_fail_errno(ft,SOX_EFMT,"Sorry, don't understand .wav size");
-      return SOX_EOF;
+        lsx_fail_errno(ft, SOX_EFMT, "Sorry, don't understand .wav size");
+        return SOX_EOF;
     }
 
     return 0;