shithub: sox

Download patch

ref: 2e02e5c7d0508039ff116c574733a44426fcd1b9
parent: d6f4cbe9d7570431dd9b56210cd0da17976a442b
author: cbagwell <cbagwell>
date: Sun Sep 19 11:18:30 EDT 2004

Fixes to trim optimization.

--- a/src/aiff.c
+++ b/src/aiff.c
@@ -74,13 +74,18 @@
 int st_aiffseek(ft_t ft, st_size_t offset) 
 {
     aiff_t aiff = (aiff_t ) ft->priv;
-    st_size_t new_offset, align;
+    st_size_t new_offset, channel_block, alignment;
 
     new_offset = offset * ft->info.size;
-    /* Make sure requests aligns to a channel offset */
-    align = new_offset % (ft->info.channels*ft->info.size);
-    if (align != 0)
-        new_offset += align;
+    /* Make sure request aligns to a channel block (ie left+right) */
+    channel_block = ft->info.channels * ft->info.size;
+    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 += aiff->dataStart;
 
     ft->st_errno = st_seek(ft, new_offset, SEEK_SET);
--- a/src/au.c
+++ b/src/au.c
@@ -111,13 +111,18 @@
     }
     else 
     {
-        st_size_t new_offset, align;
+        st_size_t new_offset, channel_block, alignment;
 
         new_offset = offset * ft->info.size;
-        /* Make sure requests aligns to a channel offset */
-        align = new_offset % (ft->info.channels*ft->info.size);
-        if (align != 0)
-            new_offset += align;
+        /* Make sure request aligns to a channel block (ie left+right) */
+        channel_block = ft->info.channels * ft->info.size;
+        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 += au->dataStart;
 
         ft->st_errno = st_seek(ft, new_offset, SEEK_SET);
--- a/src/prc.c
+++ b/src/prc.c
@@ -45,13 +45,18 @@
 int st_prcseek(ft_t ft, st_size_t offset)
 {
     prc_t prc = (prc_t ) ft->priv;
-    st_size_t new_offset, align;
+    st_size_t new_offset, channel_block, alignment;
 
     new_offset = offset * ft->info.size;
-    /* Make sure requests aligns to a channel offset */
-    align = new_offset % (ft->info.channels*ft->info.size);
-    if (align != 0)
-        new_offset += align;
+    /* Make sure request aligns to a channel block (ie left+right) */
+    channel_block = ft->info.channels * ft->info.size;
+    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 += prc->dataStart;
 
     return st_seek(ft, new_offset, SEEK_SET);
--- a/src/raw.c
+++ b/src/raw.c
@@ -83,7 +83,7 @@
 
 int st_rawseek(ft_t ft, st_size_t offset)
 {
-    st_size_t new_offset, align;
+    st_size_t new_offset, channel_block, alignment;
 
     switch(ft->info.size) {
         case ST_SIZE_BYTE:
@@ -97,10 +97,15 @@
     }
 
     new_offset = offset * ft->info.size;
-    /* Make sure requests aligns to a channel offset */
-    align = new_offset % (ft->info.channels*ft->info.size);
-    if (align != 0)
-        new_offset += align;
+    /* Make sure request aligns to a channel block (ie left+right) */
+    channel_block = ft->info.channels * ft->info.size;
+    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);
 
     ft->st_errno = st_seek(ft, new_offset, SEEK_SET);
 
--- a/src/sf.c
+++ b/src/sf.c
@@ -70,14 +70,19 @@
 
 int st_sfseek(ft_t ft, st_size_t offset)
 {
-    st_size_t new_offset, align;
+    st_size_t new_offset, channel_block, alignment;
 
     sf_t sf = (sf_t ) ft->priv;
     new_offset = offset * ft->info.size;
-    /* Make sure requests aligns to a channel offset */
-    align = new_offset % (ft->info.channels*ft->info.size);
-    if (align != 0)
-        new_offset += align;
+    /* Make sure request aligns to a channel block (ie left+right) */
+    channel_block = ft->info.channels * ft->info.size;
+    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 += sf->dataStart;
 
     return st_seek(ft, new_offset, SEEK_SET);
--- a/src/smp.c
+++ b/src/smp.c
@@ -171,14 +171,19 @@
 
 int st_smpseek(ft_t ft, st_size_t offset) 
 {
-    int new_offset, align;
+    int new_offset, channel_block, alignment;
     smp_t smp = (smp_t) ft->priv;
 
     new_offset = offset * ft->info.size;
-    /* Make sure requests aligns to a channel offset */
-    align = new_offset % (ft->info.channels*ft->info.size);
-    if (align != 0)
-        new_offset += align;
+    /* Make sure request aligns to a channel block (ie left+right) */
+    channel_block = ft->info.channels * ft->info.size;
+    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 += smp->dataStart;
 
     ft->st_errno = st_seek(ft, new_offset, SEEK_SET);
--- a/src/sndrtool.c
+++ b/src/sndrtool.c
@@ -33,14 +33,19 @@
 
 int st_sndseek(ft_t ft, st_size_t offset) 
 {
-    st_size_t new_offset, align;
+    st_size_t new_offset, channel_block, alignment;
     snd_t snd = (snd_t ) ft->priv;
 
     new_offset = offset * ft->info.size;
-    /* Make sure requests aligns to a channel offset */
-    align = new_offset % (ft->info.channels*ft->info.size);
-    if (align != 0)
-        new_offset += align;
+    /* Make sure request aligns to a channel block (ie left+right) */
+    channel_block = ft->info.channels * ft->info.size;
+    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 += snd->dataStart;
 
     return st_seek(ft, new_offset, SEEK_SET);
--- a/src/sox.c
+++ b/src/sox.c
@@ -528,51 +528,26 @@
 
 void optimize_trim(void)
 {
-    int f;
-
     /* Speed hack.  If the "trim" effect is the first effect then
      * peak inside its "effect descriptor" and see what the
-     * start location is.  This has to be done after the start()
+     * start location is.  This has to be done after its start()
      * is called to have the correct location.
+     * Also, only do this when only working with one input file.
+     * This is because the logic to do it for multiple files is
+     * complex and problably never used.
      */
-    if (neffects > 1 && strcmp(efftab[1].name, "trim") == 0)
+    if (input_count == 1 && neffects > 1 && 
+        strcmp(efftab[1].name, "trim") == 0)
     {
-        int ok_to_seek = 1;
-        int seek_worked = 1;
-
-        /* Make sure all support seeking */
-        for (f = 0; f < input_count; f++)
+        if ((file_desc[0]->h->flags & ST_FILE_SEEK) && file_desc[0]->seekable)
         {
-            if (!(file_desc[f]->h->flags & ST_FILE_SEEK) || 
-                !file_desc[f]->seekable)
-                ok_to_seek = 0;
-        }
-        if (ok_to_seek)
-        {
-            for (f = 0; f < input_count; f++)
+            if (file_desc[0]->h->seek(file_desc[0], 
+                                      st_trim_get_start(&efftab[1])) != ST_EOF)
             {
-                if (file_desc[f]->h->seek(file_desc[f], 
-                                          st_trim_get_seek(&efftab[1])) == ST_EOF)
-                {
-                    seek_worked = 0;
-                    break;
-                }
-            }
-            /* If any seek didn't work then try our best to go back
-             * to the beginning of file and do it the slow way.
-             * This can easily happen if some input files are shorter
-             * then the rest.  Code below will fill in silence
-             * for those cases.
-             */
-            if (!seek_worked)
-            {
-                for (f = 0; f < input_count; f++)
-                {
-                    file_desc[f]->h->seek(file_desc[f], 0);
-                }
-            }
-            else
-            {
+                /* Assuming a failed seek stayed where it was.  If the
+                 * seek worked then reset the start location of
+                 * trim so that it skips that part.
+                 */
                 st_trim_clear_start(&efftab[1]);
             }
         }
--- a/src/st_i.h
+++ b/src/st_i.h
@@ -595,7 +595,7 @@
 int st_trim_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
                  st_size_t *isamp, st_size_t *osamp);
 int st_trim_stop(eff_t effp);
-st_size_t st_trim_get_seek(eff_t effp);
+st_size_t st_trim_get_start(eff_t effp);
 void st_trim_clear_start(eff_t effp);
 
 int st_vibro_getopts(eff_t effp, int argc, char **argv);
--- a/src/trim.c
+++ b/src/trim.c
@@ -207,7 +207,7 @@
     return (ST_SUCCESS);
 }
 
-st_size_t st_trim_get_seek(eff_t effp)
+st_size_t st_trim_get_start(eff_t effp)
 {
     trim_t trim = (trim_t)effp->priv;
     return trim->start;
--- a/src/wav.c
+++ b/src/wav.c
@@ -1639,7 +1639,7 @@
 int st_wavseek(ft_t ft, st_size_t offset) 
 {
     wav_t   wav = (wav_t) ft->priv;
-    int new_offset, align;
+    int new_offset, channel_block, alignment;
 
     switch (wav->formatTag)
     {
@@ -1652,10 +1652,15 @@
             break;
         default:
             new_offset = offset * ft->info.size;
-            /* Make sure requests aligns to a channel offset */
-            align = new_offset % (ft->info.channels*ft->info.size);
-            if (align != 0)
-                new_offset += align;
+            /* Make sure request aligns to a channel block (ie left+right) */
+            channel_block = ft->info.channels * ft->info.size;
+            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->st_errno = st_seek(ft, new_offset, SEEK_SET);
--- a/src/wve.c
+++ b/src/wve.c
@@ -29,14 +29,19 @@
 
 int st_wveseek(ft_t ft, st_size_t offset)
 {
-    int new_offset, align;
+    int new_offset, channel_block, alignment;
     wve_t wve = (wve_t ) ft->priv;
 
     new_offset = offset * ft->info.size;
-    /* Make sure requests aligns to a channel offset */
-    align = new_offset % (ft->info.channels*ft->info.size);
-    if (align != 0)
-        new_offset += align;
+    /* Make sure request aligns to a channel block (ie left+right) */
+    channel_block = ft->info.channels * ft->info.size;
+    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 += wve->dataStart;
 
     return st_seek(ft, offset, SEEK_SET);