shithub: sox

Download patch

ref: c290ba369a4af8ba4ed7df2d4ed401fd1a02c9ca
parent: 5259fd4d5897b15b669523d01f7f2883d0c256e1
author: Ulrich Klauer <ulrich@chirlu.de>
date: Wed Jan 25 20:44:44 EST 2012

trim: only warn about positions beyond end of file

If the user specifies positions after the input audio length, warn but
don't fail; they might intend "at most ..." semantics.

It's especially important for cases like the man page example
  sox infile.wav outfile.wav trim 0 30 : newfile : restart
that would otherwise fail if the input length is not exactly a
multiple of 30 seconds.

--- a/src/trim.c
+++ b/src/trim.c
@@ -92,11 +92,12 @@
       case a_start: res = s; break;
       case a_latest: res = last_seen + s; break;
       case a_end:
-        if (s > in_length) {
+        if (s <= in_length)
+          res = in_length - s;
+        else {
           lsx_fail("Position %u is before start of audio.", i+1);
           return SOX_EOF;
         }
-        res = in_length - s;
         break;
     }
     last_seen = p->pos[i].sample = res;
@@ -112,16 +113,11 @@
     }
     last_seen = p->pos[i].sample;
   }
-  if (p->num_pos && in_length != SOX_UNKNOWN_LEN &&
-      p->pos[0].sample > in_length) {
-    lsx_fail("Start position after end of audio.");
-    return SOX_EOF;
-  }
-  if (p->num_pos && in_length != SOX_UNKNOWN_LEN &&
-      p->pos[p->num_pos-1].sample > in_length) {
-    lsx_fail("End position after end of audio.");
-    return SOX_EOF;
-  }
+  if (p->num_pos && in_length != SOX_UNKNOWN_LEN)
+    if (p->pos[0].sample > in_length ||
+        p->pos[p->num_pos-1].sample > in_length)
+      lsx_warn("%s position after expected end of audio.",
+          p->pos[0].sample > in_length? "Start" : "End");
 
   if (p->num_pos == 1 && !p->pos[0].sample)
     return SOX_EFF_NULL;
@@ -134,10 +130,10 @@
     effp->out_signal.length = 0;
     for (i = 0; i+1 < p->num_pos ; i += 2)
       effp->out_signal.length +=
-        p->pos[i+1].sample - p->pos[i].sample;
+        min(p->pos[i+1].sample, in_length) - min(p->pos[i].sample, in_length);
     if (open_end)
       effp->out_signal.length +=
-        in_length - p->pos[p->num_pos-1].sample;
+        in_length - min(p->pos[p->num_pos-1].sample, in_length);
     effp->out_signal.length *= effp->in_signal.channels;
   }