shithub: sox

Download patch

ref: db11a831b5188094f926527ba4b72eca392f9ecb
parent: 3e264d195ae38ae281cec5c3cc3632a56bb9cb1c
author: Rob Sykes <robs@users.sourceforge.net>
date: Tue Aug 30 06:03:21 EDT 2011

add upsample effect

--- a/sox.1
+++ b/sox.1
@@ -3979,6 +3979,11 @@
 it.  A value of 8000s for the \fIstart\fR parameter will wait until
 8000 samples are read before starting to process audio.
 .TP
+\fBupsample [\fIfactor\fR]
+Upsample the signal by an integer factor: \fIfactor\fR\-1 zero-value
+samples are inserted between each input sample.  Typically use is in
+combination with filtering effects.
+.TP
 \fBvad \fR[\fIoptions\fR]
 Voice Activity Detector.  Attempts to trim silence and quiet
 background sounds from the ends of (fairly high resolution
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -30,9 +30,9 @@
   compandt        fade            noiseprof       reverse         tempo
   contrast        fft4g           noisered        silence         tremolo
   crop            filter          output          sinc            trim
-  dcshift         fir             overdrive       skeleff         vad
-  delay           firfit          pad             speed           vol
-  dft_filter      flanger         pan             splice
+  dcshift         fir             overdrive       skeleff         upsample
+  delay           firfit          pad             speed           vad
+  dft_filter      flanger         pan             splice          vol
 )
 set(formats_srcs
   8svx            dat             htk             s2-fmt          u2-fmt
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -77,7 +77,7 @@
 	rate_poly_fir.h remix.c repeat.c reverb.c reverse.c silence.c \
 	sinc.c skeleff.c speed.c speexdsp.c splice.c stat.c stats.c \
 	stretch.c swap.c synth.c tempo.c tremolo.c trim.c vad.c vol.c \
-	ignore-warning.h
+	ignore-warning.h upsample.c
 if HAVE_PNG
     libsox_la_SOURCES += spectrogram.c
 endif
--- a/src/effects.h
+++ b/src/effects.h
@@ -91,5 +91,6 @@
   EFFECT(treble)
   EFFECT(tremolo)
   EFFECT(trim)
+  EFFECT(upsample)
   EFFECT(vad)
   EFFECT(vol)
--- /dev/null
+++ b/src/upsample.c
@@ -1,0 +1,67 @@
+/* libSoX effect: Upsample (zero stuff)    (c) 2011 robs@users.sourceforge.net
+ *
+ * Sometimes filters perform better at higher sampling rates, so e.g.
+ *   sox -r 48k input output upsample 4 filter rate 48k vol 4
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+
+typedef struct {unsigned factor, pos;} priv_t;
+
+static int create(sox_effect_t * effp, int argc, char * * argv)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  p->factor = 2;
+  --argc, ++argv;
+  do {NUMERIC_PARAMETER(factor, 1, 256)} while (0);
+  /* TODO: something like this may be needed here to inform libSoX client
+   * that the rate change indicated in start() is intended to be the final rate:
+  effp->out_signal.rate = effp->in_signal.rate * p->factor; */
+  return argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+static int start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *) effp->priv;
+  effp->out_signal.rate = effp->in_signal.rate * p->factor;
+  return p->factor == 1? SOX_EFF_NULL : SOX_SUCCESS;
+}
+
+static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
+    sox_sample_t * obuf, size_t * isamp, size_t * osamp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  size_t ilen = *isamp, olen = *osamp;
+  while (sox_true) {
+    for (; p->pos && olen; p->pos = (p->pos + 1) % p->factor, --olen)
+      *obuf++ = 0;
+    if (!ilen || !olen)
+      break;
+    *obuf++ = *ibuf++;
+    --olen, --ilen;
+    ++p->pos;
+  }
+  *isamp -= ilen, *osamp -= olen;
+  return SOX_SUCCESS;
+}
+
+sox_effect_handler_t const * lsx_upsample_effect_fn(void)
+{
+  static sox_effect_handler_t handler = {"upsample", "[factor (2)]",
+    SOX_EFF_RATE, create, start, flow, NULL, NULL, NULL, sizeof(priv_t)};
+  return &handler;
+}