ref: eb04277997cce429f14473ae15277eac03b69e85
parent: 6763cba31dea9a680d10d085e5e8e3f04e8cf3ce
author: robs <robs>
date: Sat Mar 8 14:24:23 EST 2008
new delay effect
--- a/ChangeLog
+++ b/ChangeLog
@@ -39,8 +39,6 @@
encoding/decoding; display name of unsupported encoding. (robs)
o Can now write .amb (.wav variant) files [FR 1902232]. (robs)
o Can now read 2,3(2.6),4 bit ADPCM .voc files [FR 1714991]. (robs)
- o Fix auto-detect of hcom files. (robs)
- o Added auto-detect for caf, txw & sf files. (robs)
Effects:
@@ -47,6 +45,7 @@
o New `splice' effect; splice together audio sections. (robs)
o New `remix' effect; complements the mixer effect. (robs)
o New `norm' (normalise) effect. (robs)
+ o New `delay' effect; delay one or more channels. (robs)
o Fix crash on 64-bit arch. with tempo & key effects. (Sami Liedes)
o Fix synth max. level setting for some output encodings. (robs)
@@ -70,6 +69,8 @@
o Fix [1890983] rec shortcut should apply bit depth (8-bit,
16-bit, etc.) to input handler. (robs)
+ o Fix auto-detect of hcom files. (robs)
+ o Added auto-detect for caf, txw & sf files. (robs)
Internal improvements:
--- a/soxeffect.7
+++ b/soxeffect.7
@@ -254,6 +254,22 @@
.SP
See also the \fBbass\fR and \fBtreble\fR shelving equalisation effects.
.TP
+\fBdelay\fR {\fIlength\fR}
+Delay one or more audio channels.
+.I length
+can specify a time or, if appended with an `s', a number of samples.
+For example,
+.B delay 1\*d5 0 0\*d5
+delays the first channel by 1\*d5 seconds, the third channel by 0\*d5
+seconds, and leaves the second channel (and any other channels that may be
+present) un-delayed.
+The following (one long) command plays a chime sound:
+.EX
+ play -n synth sin %-21.5 sin %-14.5 sin %-9.5 sin %-5.5 \\
+ sin %-2.5 sin %2.5 gain -5.4 fade h 0.008 2 1.5 \\
+ delay 0 .27 .54 .76 1.01 1.3 remix - fade h 0.1 2.72 2.5
+.EE
+.TP
\fBdither\fR [\fIdepth\fR]
Apply dithering to the audio.
Dithering deliberately adds digital white noise to the signal
@@ -624,7 +640,7 @@
.I position
is optional for the first and last lengths specified and
if omitted correspond to the beginning and the end of the audio respectively.
-For example:
+For example,
.B pad 1\*d5 1\*d5
adds 1\*d5 seconds of silence padding at each end of the audio, whilst
.B pad 4000s@3:00
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -19,15 +19,15 @@
# Format with: !xargs echo|tr ' ' '\n'|sort|column|expand|sed 's/^/ /'
set(effects_srcs
- biquad echos noiseprof repeat stretch
- biquads effects noisered resample swap
- chorus fade normalise reverb synth
- compand FFT pad reverse tempo
+ FFT earwax mixer remix stat
+ biquad echo noiseprof repeat stretch
+ biquads echos noisered resample swap
+ chorus effects normalise reverb synth
+ compand fade pad reverse tempo
compandt filter pan silence tremolo
dcshift flanger phaser skeleff trim
- dither key pitch speed vol
- earwax mcompand polyphas splice
- echo mixer remix stat
+ delay key pitch speed vol
+ dither mcompand polyphas splice
)
set(formats_srcs
8svx cvsd-fmt htk s1-fmt u2-fmt
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -198,7 +198,7 @@
pan.c phaser.c pitch.c polyphas.c rabbit.c remix.c repeat.c \
resample.c reverb.c reverse.c silence.c skeleff.c speed.c \
splice.c stat.c stretch.c swap.c synth.c tempo.c tremolo.c trim.c \
- vol.c normalise.c
+ vol.c normalise.c delay.c
libsfx_la_CFLAGS = @SAMPLERATE_CFLAGS@
libsfx_la_LIBADD = @SAMPLERATE_LIBS@ libsox.la
--- /dev/null
+++ b/src/delay.c
@@ -1,0 +1,129 @@
+/*
+ * Effect: Delay one or more channels. (c) 2008 robs@users.sourceforge.net
+ *
+ * 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 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,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
+ */
+
+#include "sox_i.h"
+#include <string.h>
+
+typedef struct delay {
+ size_t argc;
+ char * * argv, * max_arg;
+ sox_size_t delay, pad, buffer_size, buffer_index;
+ sox_sample_t * buffer;
+} * priv_t;
+
+assert_static(sizeof(struct delay) <= SOX_MAX_EFFECT_PRIVSIZE,
+ /* else */ delay_PRIVSIZE_too_big);
+
+static int kill(sox_effect_t * effp)
+{
+ priv_t p = (priv_t) effp->priv;
+ unsigned i;
+
+ for (i = 0; i < p->argc; ++i)
+ free(p->argv[i]);
+ free(p->argv);
+ return SOX_SUCCESS;
+}
+
+static int create(sox_effect_t * effp, int argc, char * * argv)
+{
+ priv_t p = (priv_t) effp->priv;
+ sox_size_t delay, max_samples = 0;
+ unsigned i;
+
+ p->argv = xcalloc(p->argc = argc, sizeof(*p->argv));
+ for (i = 0; i < p->argc; ++i) {
+ char const * next = sox_parsesamples(96000., p->argv[i] = xstrdup(argv[i]), &delay, 't');
+ if (!next || *next) {
+ kill(effp);
+ return sox_usage(effp);
+ }
+ if (delay > max_samples) {
+ max_samples = delay;
+ p->max_arg = p->argv[i];
+ }
+ }
+ return SOX_SUCCESS;
+}
+
+static int stop(sox_effect_t * effp)
+{
+ priv_t p = (priv_t) effp->priv;
+ free(p->buffer);
+ return SOX_SUCCESS;
+}
+
+static int start(sox_effect_t * effp)
+{
+ priv_t p = (priv_t) effp->priv;
+ sox_size_t max_delay;
+
+ if (!p->max_arg)
+ return SOX_EFF_NULL;
+ if (effp->flow < p->argc)
+ sox_parsesamples(effp->in_signal.rate, p->argv[effp->flow], &p->buffer_size, 't');
+ sox_parsesamples(effp->in_signal.rate, p->max_arg, &max_delay, 't');
+ p->buffer_index = p->delay = 0;
+ p->pad = max_delay - p->buffer_size;
+ p->buffer = xmalloc(p->buffer_size * sizeof(*p->buffer));
+ return SOX_SUCCESS;
+}
+
+static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
+ sox_sample_t * obuf, sox_size_t * isamp, sox_size_t * osamp)
+{
+ priv_t p = (priv_t) effp->priv;
+ sox_size_t len = *isamp = *osamp = min(*isamp, *osamp);
+
+ if (!p->buffer_size)
+ memcpy(obuf, ibuf, len * sizeof(*obuf));
+ else for (; len; --len) {
+ if (p->delay < p->buffer_size) {
+ p->buffer[p->delay++] = *ibuf++;
+ *obuf++ = 0;
+ } else {
+ *obuf++ = p->buffer[p->buffer_index];
+ p->buffer[p->buffer_index++] = *ibuf++;
+ p->buffer_index %= p->buffer_size;
+ }
+ }
+ return SOX_SUCCESS;
+}
+
+static int drain(sox_effect_t * effp, sox_sample_t * obuf, sox_size_t * osamp)
+{
+ priv_t p = (priv_t) effp->priv;
+ sox_size_t len = *osamp = min(p->delay + p->pad, *osamp);
+
+ for (; p->delay && len; --p->delay, --len) {
+ *obuf++ = p->buffer[p->buffer_index++];
+ p->buffer_index %= p->buffer_size;
+ }
+ for (; p->pad && len; --p->pad, --len)
+ *obuf++ = 0;
+ return SOX_SUCCESS;
+}
+
+sox_effect_handler_t const * sox_delay_effect_fn(void)
+{
+ static sox_effect_handler_t handler = {
+ "delay", "{length}", SOX_EFF_LENGTH,
+ create, start, flow, drain, stop, kill
+ };
+ return &handler;
+}
--- a/src/effects.h
+++ b/src/effects.h
@@ -9,6 +9,7 @@
EFFECT(compand)
EFFECT(dcshift)
EFFECT(deemph)
+ EFFECT(delay)
EFFECT(dither)
EFFECT(earwax)
EFFECT(echo)