shithub: sox

Download patch

ref: a447efea202f06165d60800d33abc38e560f7240
parent: b547a29888c8b6452b3f14c24bb4dda01ade6cd3
author: Ulrich Klauer <ulrich@chirlu.de>
date: Mon Oct 15 22:24:44 EDT 2012

delay: use lsx_parseposition

Use the new lsx_parseposition function for the delay effect and update
the documentation accordingly.

--- a/sox.1
+++ b/sox.1
@@ -1937,14 +1937,15 @@
 .SP
 See also the \fBbass\fR and \fBtreble\fR shelving equalisation effects.
 .TP
-\fBdelay\fR {\fItime\fR}
-Delay one or more audio channels by the given \fItime\fR (a time
-specification).
+\fBdelay\fR {\fIposition(=)\fR}
+Delay one or more audio channels such that they start at the given
+\fIposition\fR.
 For example,
-.B delay 1\*d5 0 3000s
-delays the first channel by 1\*d5 seconds, the third channel by 3000
-samples, and leaves the second channel (and any other channels that may be
-present) un-delayed.
+.B delay 1\*d5 +1 3000s
+delays the first channel by 1\*d5 seconds, the second channel by 2\*d5
+seconds (one second more than the previous channel), the third channel
+by 3000 samples, and leaves any other channels that may be
+present un-delayed.
 The following (one long) command plays a chime sound:
 .EX
 .ne 3
--- a/src/delay.c
+++ b/src/delay.c
@@ -43,7 +43,6 @@
 static int create(sox_effect_t * effp, int argc, char * * argv)
 {
   priv_t * p = (priv_t *)effp->priv;
-  uint64_t dummy;
   unsigned i;
 
   --argc, ++argv;
@@ -51,7 +50,7 @@
   p->args = lsx_calloc(p->argc, sizeof(*p->args));
   p->max_delay = lsx_malloc(sizeof(*p->max_delay));
   for (i = 0; i < p->argc; ++i) {
-    char const * next = lsx_parsesamples(1e5, p->args[i].str = lsx_strdup(argv[i]), &dummy, 't');
+    char const * next = lsx_parseposition(0., p->args[i].str = lsx_strdup(argv[i]), NULL, (uint64_t)0, (uint64_t)0, '=');
     if (!next || *next) {
       lsx_kill(effp);
       return lsx_usage(effp);
@@ -70,7 +69,9 @@
 static int start(sox_effect_t * effp)
 {
   priv_t * p = (priv_t *)effp->priv;
-  uint64_t max_delay = 0, delay;
+  uint64_t max_delay = 0, last_seen = 0, delay;
+  uint64_t in_length = effp->in_signal.length != SOX_UNKNOWN_LEN ?
+    effp->in_signal.length / effp->in_signal.channels : SOX_UNKNOWN_LEN;
 
   if (effp->flow == 0) {
     unsigned i;
@@ -79,8 +80,11 @@
       return SOX_EOF;
     }
     for (i = 0; i < p->argc; ++i) {
-      lsx_parsesamples(effp->in_signal.rate, p->args[i].str, &delay, 't');
-      p->args[i].delay = delay;
+      if (!lsx_parseposition(effp->in_signal.rate, p->args[i].str, &delay, last_seen, in_length, '=') || delay == SOX_UNKNOWN_LEN) {
+        lsx_fail("Position relative to end of audio specified, but audio length is unknown");
+        return SOX_EOF;
+      }
+      p->args[i].delay = last_seen = delay;
       if (delay > max_delay) {
         max_delay = delay;
       }
@@ -152,7 +156,7 @@
 sox_effect_handler_t const * lsx_delay_effect_fn(void)
 {
   static sox_effect_handler_t handler = {
-    "delay", "{length}", SOX_EFF_LENGTH | SOX_EFF_MODIFY,
+    "delay", "{position}", SOX_EFF_LENGTH | SOX_EFF_MODIFY,
     create, start, flow, drain, stop, lsx_kill, sizeof(priv_t)
   };
   return &handler;