shithub: sox

Download patch

ref: d2b295b9eaa96e09e002034992e1d72451c6d6b1
parent: 22d5cf2a8dcf6534ddf146012ffd8bb0f0692a5a
author: robs <robs>
date: Sat Jun 21 03:09:51 EDT 2008

fix [ 1997637 ] Trim effect loses samples

--- a/ChangeLog
+++ b/ChangeLog
@@ -48,6 +48,7 @@
   o Fix 24-bit read/write on big-endian systems.  (robs)
   o Fix crash trying to open non-existent play-list.  (robs)
   o Fix FLAC read from stdin with libFLAC >= 8.  (Patrick Taylor Ramsey/robs)
+  o Fix [1997637] Trim effect loses samples (with wav).  (robs)
 
 Effects:
 
--- a/src/wav.c
+++ b/src/wav.c
@@ -1135,8 +1135,7 @@
             break;
 
         case WAVE_FORMAT_GSM610:
-            wavgsminit(ft);
-            break;
+            return wavgsminit(ft);
 
         default:
             break;
@@ -1561,60 +1560,39 @@
 
 static int seek(sox_format_t * ft, sox_size_t offset)
 {
-    priv_t *   wav = (priv_t *) ft->priv;
-    int new_offset, channel_block, alignment;
+  priv_t *   wav = (priv_t *) ft->priv;
 
-    switch (wav->formatTag)
-    {
-        case WAVE_FORMAT_IMA_ADPCM:
-        case WAVE_FORMAT_ADPCM:
-            lsx_fail_errno(ft,SOX_ENOTSUP,"ADPCM not supported");
-            break;
+  if (ft->encoding.bits_per_sample & 7)
+    lsx_fail_errno(ft, SOX_ENOTSUP, "seeking not supported with this encoding");
+  else if (wav->formatTag == WAVE_FORMAT_GSM610) {
+    int new_offset, alignment;
+    sox_size_t gsmoff;
 
-        case WAVE_FORMAT_GSM610:
-            {
-                sox_size_t gsmoff;
+    /* rounding bytes to blockAlign so that we
+     * don't have to decode partial block. */
+    gsmoff = offset * wav->blockAlign / wav->samplesPerBlock +
+             wav->blockAlign * ft->signal.channels / 2;
+    gsmoff -= gsmoff % (wav->blockAlign * ft->signal.channels);
 
-                /* rounding bytes to blockAlign so that we
-                 * don't have to decode partial block. */
-                gsmoff = offset * wav->blockAlign / wav->samplesPerBlock +
-                         wav->blockAlign * ft->signal.channels / 2;
-                gsmoff -= gsmoff % (wav->blockAlign * ft->signal.channels);
-
-                ft->sox_errno = lsx_seeki(ft, (sox_ssize_t)(gsmoff + wav->dataStart), SEEK_SET);
-                if (ft->sox_errno != SOX_SUCCESS)
-                    return SOX_EOF;
-
-                /* offset is in samples */
-                new_offset = offset;
-                alignment = offset % wav->samplesPerBlock;
-                if (alignment != 0)
-                    new_offset += (wav->samplesPerBlock - alignment);
-                wav->numSamples = ft->signal.length - (new_offset / ft->signal.channels);
-            }
-            break;
-
-        default:
-            new_offset = offset * (ft->encoding.bits_per_sample >> 3);
-            /* Make sure request aligns to a channel block (ie left+right) */
-            channel_block = ft->signal.channels * (ft->encoding.bits_per_sample >> 3);
-            alignment = new_offset % channel_block;
-            /* Most common mistaken is to compute something like
-             * "skip everthing upto and including this sample" so
-             * advance to next sample block in this case.
-             */
-            if (alignment != 0)
-                new_offset += (channel_block - alignment);
-            new_offset += wav->dataStart;
-
-            ft->sox_errno = lsx_seeki(ft, new_offset, SEEK_SET);
-
-            if( ft->sox_errno == SOX_SUCCESS )
-                wav->numSamples = (ft->signal.length / ft->signal.channels) -
-                                  (new_offset / (ft->encoding.bits_per_sample >> 3) / ft->signal.channels);
+    ft->sox_errno = lsx_seeki(ft, (sox_ssize_t)(gsmoff + wav->dataStart), SEEK_SET);
+    if (ft->sox_errno == SOX_SUCCESS) {
+      /* offset is in samples */
+      new_offset = offset;
+      alignment = offset % wav->samplesPerBlock;
+      if (alignment != 0)
+          new_offset += (wav->samplesPerBlock - alignment);
+      wav->numSamples = ft->signal.length - (new_offset / ft->signal.channels);
     }
+  } else {
+    double wide_sample = offset - (offset % ft->signal.channels);
+    double to_d = wide_sample * ft->encoding.bits_per_sample / 8;
+    off_t to = to_d;
+    ft->sox_errno = (to != to_d)? SOX_EOF : lsx_seeki(ft, (sox_ssize_t)wav->dataStart + to, SEEK_SET);
+    if (ft->sox_errno == SOX_SUCCESS)
+      wav->numSamples -= (sox_size_t)wide_sample / ft->signal.channels;
+  }
 
-    return(ft->sox_errno);
+  return ft->sox_errno;
 }
 
 SOX_FORMAT_HANDLER(wav)