shithub: sox

Download patch

ref: 1b53d0c746a5de122278d0dcfc4d25fd0a7f25bb
parent: 9e4e9ca14b0b980de13420acbe479e133af045a9
author: Ulrich Klauer <ulrich@chirlu.de>
date: Wed Jan 18 19:34:09 EST 2012

Distinguish between unknown and zero length

Within the effects chain, indicate unknown audio length with a new
SOX_UNKNOWN_LEN special value, instead of overloading 0 to mean
both "unknown length" and "zero length".

Future to-do: extend this to format handlers also.

--- a/src/chorus.c
+++ b/src/chorus.c
@@ -228,6 +228,9 @@
 
         chorus->counter = 0;
         chorus->fade_out = chorus->maxsamples;
+
+  effp->out_signal.length = SOX_UNKNOWN_LEN; /* TODO: calculate actual length */
+
         return (SOX_SUCCESS);
 }
 
--- a/src/delay.c
+++ b/src/delay.c
@@ -85,8 +85,9 @@
   }
   lsx_parsesamples(effp->in_signal.rate, p->max_arg, &max_delay, 't');
   if (effp->flow == 0) {
-    effp->out_signal.length = effp->in_signal.length ?
-       effp->in_signal.length + max_delay * effp->in_signal.channels : 0;
+    effp->out_signal.length = effp->in_signal.length != SOX_UNKNOWN_LEN ?
+       effp->in_signal.length + max_delay * effp->in_signal.channels :
+       SOX_UNKNOWN_LEN;
     lsx_debug("extending audio by %" PRIu64 " samples", max_delay);
   }
   p->buffer_index = p->delay = p->pre_pad = 0;
--- a/src/echo.c
+++ b/src/echo.c
@@ -156,6 +156,9 @@
                 lsx_warn("echo: warning >>> gain-out can cause saturation of output <<<");
         echo->counter = 0;
         echo->fade_out = echo->maxsamples;
+
+  effp->out_signal.length = SOX_UNKNOWN_LEN; /* TODO: calculate actual length */
+
         return (SOX_SUCCESS);
 }
 
--- a/src/echos.c
+++ b/src/echos.c
@@ -153,6 +153,9 @@
                 sum_in_volume += echos->decay[i];
         if ( sum_in_volume * echos->in_gain > 1.0 / echos->out_gain )
                 lsx_warn("echos: warning >>> gain-out can cause saturation of output <<<");
+
+  effp->out_signal.length = SOX_UNKNOWN_LEN; /* TODO: calculate actual length */
+
         return (SOX_SUCCESS);
 }
 
--- a/src/effects.c
+++ b/src/effects.c
@@ -171,12 +171,14 @@
 
   if (!(effp->handler.flags & SOX_EFF_LENGTH)) {
     effp->out_signal.length = in->length;
-    if (effp->handler.flags & SOX_EFF_CHAN)
-      effp->out_signal.length =
-        effp->out_signal.length / in->channels * effp->out_signal.channels;
-    if (effp->handler.flags & SOX_EFF_RATE)
-      effp->out_signal.length =
-        effp->out_signal.length / in->rate * effp->out_signal.rate + .5;
+    if (effp->out_signal.length != SOX_UNKNOWN_LEN) {
+      if (effp->handler.flags & SOX_EFF_CHAN)
+        effp->out_signal.length =
+          effp->out_signal.length / in->channels * effp->out_signal.channels;
+      if (effp->handler.flags & SOX_EFF_RATE)
+        effp->out_signal.length =
+          effp->out_signal.length / in->rate * effp->out_signal.rate + .5;
+    }
   }
 
   *in = effp->out_signal;
--- a/src/fade.c
+++ b/src/fade.c
@@ -138,7 +138,9 @@
         fade->out_stop = samples;
 
         if (!(truncate = !!fade->out_stop)) {
-          fade->out_stop = effp->in_signal.length / effp->in_signal.channels;
+          fade->out_stop = effp->in_signal.length != SOX_UNKNOWN_LEN ?
+              effp->in_signal.length / effp->in_signal.channels :
+              0;
           if (!fade->out_stop) {
             lsx_fail("cannot fade out: audio length is neither known nor given");
             return SOX_EOF;
--- a/src/input.c
+++ b/src/input.c
@@ -50,7 +50,7 @@
 sox_effect_handler_t const * lsx_input_effect_fn(void)
 {
   static sox_effect_handler_t handler = {
-    "input", NULL, SOX_EFF_MCHAN | SOX_EFF_INTERNAL,
+    "input", NULL, SOX_EFF_MCHAN | SOX_EFF_LENGTH | SOX_EFF_INTERNAL,
     getopts, NULL, NULL, drain, NULL, NULL, sizeof(priv_t)
   };
   return &handler;
--- a/src/noisered.c
+++ b/src/noisered.c
@@ -130,6 +130,8 @@
     if (ifp != stdin)
       fclose(ifp);
 
+  effp->out_signal.length = SOX_UNKNOWN_LEN; /* TODO: calculate actual length */
+
     return (SOX_SUCCESS);
 }
 
--- a/src/pad.c
+++ b/src/pad.c
@@ -80,7 +80,7 @@
   if (parse(effp, 0, effp->in_signal.rate) != SOX_SUCCESS)
     return SOX_EOF;
 
-  if ((effp->out_signal.length = effp->in_signal.length) != 0) {
+  if ((effp->out_signal.length = effp->in_signal.length) != SOX_UNKNOWN_LEN) {
     for (i = 0; i < p->npads; ++i)
       effp->out_signal.length +=
         p->pads[i].pad * effp->in_signal.channels;
--- a/src/phaser.c
+++ b/src/phaser.c
@@ -104,6 +104,8 @@
       1., (double)p->delay_buf_len, M_PI_2);
 
   p->delay_pos = p->mod_pos = 0;
+
+  effp->out_signal.length = SOX_UNKNOWN_LEN; /* TODO: calculate actual length */
   return SOX_SUCCESS;
 }
 
--- a/src/repeat.c
+++ b/src/repeat.c
@@ -45,7 +45,8 @@
   }
   p->num_samples = p->remaining_samples = 0;
   p->remaining_repeats = p->num_repeats;
-  effp->out_signal.length = effp->in_signal.length * (p->num_repeats + 1);
+  effp->out_signal.length = effp->in_signal.length != SOX_UNKNOWN_LEN ?
+      effp->in_signal.length * (p->num_repeats + 1) : SOX_UNKNOWN_LEN;
   return SOX_SUCCESS;
 }
 
--- a/src/silence.c
+++ b/src/silence.c
@@ -273,6 +273,8 @@
     silence->stop_holdoff_end = 0;
     silence->stop_found_periods = 0;
 
+    effp->out_signal.length = SOX_UNKNOWN_LEN; /* depends on input data */
+
     return(SOX_SUCCESS);
 }
 
--- a/src/sox.c
+++ b/src/sox.c
@@ -1114,7 +1114,7 @@
         effp->out_signal.channels,
         (effp->handler.flags & SOX_EFF_MCHAN)? "(multi)" : "",
         effp->out_signal.precision,
-        effp->out_signal.length ?
+        effp->out_signal.length != SOX_UNKNOWN_LEN ?
           str_time(effp->out_signal.length/effp->out_signal.channels/effp->out_signal.rate) :
           "unknown length"
         );
@@ -1661,7 +1661,7 @@
   /* Report all input files and gather info on differing rates & numbers of
    * channels, and on the resulting output audio length: */
   for (i = 0; i < input_count; i++) {
-    known_length = known_length && files[i]->ft->signal.length != 0;
+    known_length = known_length && files[i]->ft->signal.length != SOX_UNSPEC;
     if (combine_method == sox_concatenate)
       olen += files[i]->ft->signal.length / files[i]->ft->signal.channels;
     else
--- a/src/sox.h
+++ b/src/sox.h
@@ -1049,7 +1049,8 @@
 #define SOX_SIZE_MAX ((size_t)(-1)) /**< Client API: Maximum value of size_t. */
 
 #define SOX_UNSPEC 0                         /**< Client API: Members of sox_signalinfo_t are set to SOX_UNSPEC (= 0) if the actual value is not yet known. */
-#define SOX_IGNORE_LENGTH (sox_uint64_t)(-1) /**< Client API: sox_signalinfo_t.length is set to SOX_IGNORE_LENGTH (= -1) if the actual length is not yet known. */
+#define SOX_UNKNOWN_LEN (sox_uint64_t)(-1) /**< Client API: sox_signalinfo_t.length is set to SOX_UNKNOWN_LEN (= -1) within the effects chain if the actual length is not known. Format handlers currently use SOX_UNSPEC instead. */
+#define SOX_IGNORE_LENGTH (sox_uint64_t)(-2) /**< Client API: sox_signalinfo_t.length is set to SOX_IGNORE_LENGTH (= -2) to indicate that a format handler should ignore length information in file headers. */
 
 #define SOX_DEFAULT_CHANNELS  2     /**< Client API: Default channel count is 2 (stereo). */
 #define SOX_DEFAULT_RATE      48000 /**< Client API: Default rate is 48000Hz. */
--- a/src/splice.c
+++ b/src/splice.c
@@ -185,6 +185,7 @@
         *effp->in_signal.mult *= pow(.5, .5);
       return SOX_SUCCESS;
     }
+  effp->out_signal.length = SOX_UNKNOWN_LEN; /* depends on input data */
   return SOX_EFF_NULL;
 }
 
--- a/src/stretch.c
+++ b/src/stretch.c
@@ -180,6 +180,7 @@
       p->factor, p->window, p->shift, p->fading, p->state,
       p->segment, p->index, p->ishift, p->oindex, p->oshift, p->overlap);
 
+  effp->out_signal.length = SOX_UNKNOWN_LEN; /* TODO: calculate actual length */
   return SOX_SUCCESS;
 }
 
--- a/src/synth.c
+++ b/src/synth.c
@@ -419,7 +419,8 @@
     if (lsx_parsesamples(effp->in_signal.rate, p->length_str, &p->samples_to_do, 't') == NULL)
       return lsx_usage(effp);
   } else
-    p->samples_to_do = effp->in_signal.length / effp->in_signal.channels;
+    p->samples_to_do = effp->in_signal.length != SOX_UNKNOWN_LEN ?
+        effp->in_signal.length / effp->in_signal.channels : 0;
 
   p->number_of_channels = effp->in_signal.channels;
   p->channels = lsx_calloc(p->number_of_channels, sizeof(*p->channels));
@@ -525,7 +526,8 @@
   }
   p->gain = 1;
   effp->out_signal.mult = p->no_headroom? NULL : &p->gain;
-  effp->out_signal.length = p->samples_to_do * effp->out_signal.channels;
+  effp->out_signal.length = p->samples_to_do ?
+    p->samples_to_do * effp->out_signal.channels : SOX_UNKNOWN_LEN;
   return SOX_SUCCESS;
 }
 
--- a/src/tempo.c
+++ b/src/tempo.c
@@ -256,6 +256,7 @@
   p->tempo = tempo_create((size_t)effp->in_signal.channels);
   tempo_setup(p->tempo, effp->in_signal.rate, p->quick_search, p->factor,
       p->segment_ms, p->search_ms, p->overlap_ms);
+  effp->out_signal.length = SOX_UNKNOWN_LEN; /* TODO: calculate actual length */
   return SOX_SUCCESS;
 }
 
--- a/src/trim.c
+++ b/src/trim.c
@@ -107,7 +107,7 @@
     trim->index = 0;
     trim->trimmed = 0;
 
-    if (effp->in_signal.length) {
+    if (effp->in_signal.length != SOX_UNKNOWN_LEN) {
       if (trim->start >= effp->in_signal.length) {
         lsx_fail("start position after end of file");
         return SOX_EOF;
@@ -117,9 +117,12 @@
       }
     }
 
-    effp->out_signal.length = trim->length;
-    if (!effp->out_signal.length && effp->in_signal.length > trim->start)
-        effp->out_signal.length = effp->in_signal.length - trim->start;
+    if (trim->end_str)
+      effp->out_signal.length = trim->length;
+    else if (effp->in_signal.length != SOX_UNKNOWN_LEN)
+      effp->out_signal.length = effp->in_signal.length - trim->start;
+    else
+      effp->out_signal.length = SOX_UNKNOWN_LEN;
 
     return (SOX_SUCCESS);
 }
--- a/src/vad.c
+++ b/src/vad.c
@@ -142,7 +142,7 @@
   for (i = 0; i < p->spectrumEnd - p->spectrumStart; ++i)
     p->cepstrumWindow[i] = 2 / sqrt((double)p->spectrumEnd - p->spectrumStart);
   lsx_apply_hann(p->cepstrumWindow,(int)(p->spectrumEnd - p->spectrumStart));
-  
+
   p->cepstrumStart = ceil(effp->in_signal.rate * .5 / p->lpLifterFreq);
   p->cepstrumEnd  = floor(effp->in_signal.rate * .5 / p->hpLifterFreq);
   p->cepstrumEnd = min(p->cepstrumEnd, p->dftLen_ws / 4);
@@ -157,6 +157,8 @@
   p->bootCountMax = p->bootTime * p->measureFreq - .5;
   p->measureTimer_ns = p->measureLen_ns;
   p->bootCount = p->measuresIndex = p->flushedLen_ns = p->samplesIndex_ns = 0;
+
+  effp->out_signal.length = SOX_UNKNOWN_LEN; /* depends on input data */
   return SOX_SUCCESS;
 }