ref: 0e004134fdfe3a63e7dd44e2e44f5009489fd248
parent: ab3579456b8484ef94615d30e59f6871833cd5e7
author: robs <robs>
date: Sat Dec 13 17:08:06 EST 2008
moving some things around
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,16 +28,16 @@
# Format with: !xargs echo|tr ' ' '\n'|sort|column|expand|sed 's/^/ /'
set(effects_srcs
- bend earwax mixer rate stat
- biquad echo noiseprof remix stretch
- biquads echos noisered repeat swap
- chorus fade normalise resample synth
- compand fft4g output reverb tempo
- compandt filter overdrive reverse tremolo
- contrast flanger pad silence trim
- dcshift input pan skeleff vol
- delay loudness phaser speed effects_i_dsp
- dither mcompand polyphas splice
+ bend dither lowfir phaser speed
+ biquad earwax mcompand polyphas splice
+ biquads echo mixer rate stat
+ chorus echos noiseprof remix stretch
+ compand fade noisered repeat swap
+ compandt fft4g normalise resample synth
+ contrast filter output reverb tempo
+ dcshift flanger overdrive reverse tremolo
+ delay input pad silence trim
+ dft_filter loudness pan skeleff vol
)
set(formats_srcs
8svx dat ima-fmt s3-fmt u3-fmt
@@ -54,11 +54,11 @@
cvsd-fmt htk s2-fmt u2-fmt
)
add_library(lib${PROJECT_NAME}
- effects ${formats_srcs} ${optional_srcs}
- effects_i getopt soxstdint
+ effects formats_i libsox_i
+ effects_i ${formats_srcs} ${optional_srcs}
+ effects_i_dsp getopt soxstdint
${effects_srcs} getopt1 util
formats libsox xmalloc
- formats_i libsox_i
)
add_executable(${PROJECT_NAME} ${PROJECT_NAME}.c)
target_link_libraries(${PROJECT_NAME} lib${PROJECT_NAME} lpc10 ${optional_libs})
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -273,7 +273,8 @@
polyphas.c rabbit.c rate.c rate_filters.h rate_half_fir.h \
rate_poly_fir0.h rate_poly_fir.h remix.c repeat.c resample.c reverb.c \
reverse.c silence.c skeleff.c speed.c splice.c stat.c swap.c stretch.c \
- synth.c tempo.c tremolo.c trim.c vol.c overdrive.c effects_i_dsp.c
+ synth.c tempo.c tremolo.c trim.c vol.c overdrive.c effects_i_dsp.c \
+ dft_filter.c dft_filter.h lowfir.c
if HAVE_PNG
libsox_la_SOURCES += spectrogram.c
endif
--- /dev/null
+++ b/src/dft_filter.c
@@ -1,0 +1,129 @@
+/* Effect: dft filter Copyright (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.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"
+#include "fft4g.h"
+#include "dft_filter.h"
+#include <string.h>
+
+typedef dft_filter_filter_t filter_t;
+typedef dft_filter_priv_t priv_t;
+
+static int start(sox_effect_t * effp)
+{
+ priv_t * p = (priv_t *) effp->priv;
+
+ fifo_create(&p->input_fifo, (int)sizeof(double));
+ memset(fifo_reserve(&p->input_fifo,
+ p->filter_ptr->post_peak), 0, sizeof(double) * p->filter_ptr->post_peak);
+ fifo_create(&p->output_fifo, (int)sizeof(double));
+ return SOX_SUCCESS;
+}
+
+static void filter(priv_t * p)
+{
+ int i, num_in = max(0, fifo_occupancy(&p->input_fifo));
+ filter_t const * f = p->filter_ptr;
+ int const overlap = f->num_taps - 1;
+ double * output;
+
+ while (num_in >= f->dft_length) {
+ double const * input = fifo_read_ptr(&p->input_fifo);
+ fifo_read(&p->input_fifo, f->dft_length - overlap, NULL);
+ num_in -= f->dft_length - overlap;
+
+ output = fifo_reserve(&p->output_fifo, f->dft_length);
+ fifo_trim_by(&p->output_fifo, overlap);
+ memcpy(output, input, f->dft_length * sizeof(*output));
+
+ lsx_rdft(f->dft_length, 1, output, lsx_fft_br, lsx_fft_sc);
+ output[0] *= f->coefs[0];
+ output[1] *= f->coefs[1];
+ for (i = 2; i < f->dft_length; i += 2) {
+ double tmp = output[i];
+ output[i ] = f->coefs[i ] * tmp - f->coefs[i+1] * output[i+1];
+ output[i+1] = f->coefs[i+1] * tmp + f->coefs[i ] * output[i+1];
+ }
+ lsx_rdft(f->dft_length, -1, output, lsx_fft_br, lsx_fft_sc);
+ }
+}
+
+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 i, odone = min(*osamp, (size_t)fifo_occupancy(&p->output_fifo));
+ double const * s = fifo_read(&p->output_fifo, (int)odone, NULL);
+ SOX_SAMPLE_LOCALS;
+
+ for (i = 0; i < odone; ++i)
+ *obuf++ = SOX_FLOAT_64BIT_TO_SAMPLE(*s++, effp->clips);
+ p->samples_out += odone;
+
+ if (*isamp && odone < *osamp) {
+ double * t = fifo_write(&p->input_fifo, (int)*isamp, NULL);
+ p->samples_in += (int)*isamp;
+
+ for (i = *isamp; i; --i)
+ *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, effp->clips);
+ filter(p);
+ }
+ else *isamp = 0;
+ *osamp = odone;
+ return SOX_SUCCESS;
+}
+
+static int drain(sox_effect_t * effp, sox_sample_t * obuf, size_t * osamp)
+{
+ priv_t * p = (priv_t *)effp->priv;
+ static size_t isamp = 0;
+ size_t samples_out = p->samples_in;
+ size_t remaining = samples_out - p->samples_out;
+ double * buff = lsx_calloc(1024, sizeof(*buff));
+
+ if ((int)remaining > 0) {
+ while ((size_t)fifo_occupancy(&p->output_fifo) < remaining) {
+ fifo_write(&p->input_fifo, 1024, buff);
+ p->samples_in += 1024;
+ filter(p);
+ }
+ fifo_trim_to(&p->output_fifo, (int)remaining);
+ p->samples_in = 0;
+ }
+ free(buff);
+ return flow(effp, 0, obuf, &isamp, osamp);
+}
+
+static int stop(sox_effect_t * effp)
+{
+ priv_t * p = (priv_t *) effp->priv;
+
+ fifo_delete(&p->input_fifo);
+ fifo_delete(&p->output_fifo);
+ free(p->filter_ptr->coefs);
+ memset(p->filter_ptr, 0, sizeof(*p->filter_ptr));
+ return SOX_SUCCESS;
+}
+
+sox_effect_handler_t const * sox_dft_filter_effect_fn(void)
+{
+ static sox_effect_handler_t handler = {
+ "dft_filter", NULL, SOX_EFF_DEPRECATED,
+ NULL, start, flow, drain, stop, NULL, 0
+ };
+ return &handler;
+}
--- /dev/null
+++ b/src/dft_filter.h
@@ -1,0 +1,15 @@
+#include "fft4g.h"
+#define FIFO_SIZE_T int
+#include "fifo.h"
+
+typedef struct {
+ int dft_length, num_taps, post_peak;
+ double * coefs;
+} dft_filter_filter_t;
+
+typedef struct {
+ size_t samples_in, samples_out;
+ fifo_t input_fifo, output_fifo;
+ dft_filter_filter_t filter, * filter_ptr;
+} dft_filter_priv_t;
+
--- a/src/effects.h
+++ b/src/effects.h
@@ -27,6 +27,7 @@
EFFECT(dcshift)
EFFECT(deemph)
EFFECT(delay)
+ EFFECT(dft_filter)
EFFECT(dither)
EFFECT(earwax)
EFFECT(echo)
@@ -43,6 +44,7 @@
EFFECT(ladspa)
#endif
EFFECT(loudness)
+ EFFECT(lowfir)
EFFECT(lowpass)
EFFECT(mcompand)
EFFECT(mixer)
--- a/src/effects_i.c
+++ b/src/effects_i.c
@@ -1,7 +1,7 @@
/* Implements a libSoX internal interface for implementing effects.
* All public functions & data are prefixed with lsx_ .
*
- * (c) 2005-8 Chris Bagwell and SoX contributors
+ * Copyright (c) 2005-8 Chris Bagwell and SoX contributors
*
* 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
--- a/src/loudness.c
+++ b/src/loudness.c
@@ -16,28 +16,20 @@
*/
#include "sox_i.h"
-#include "fft4g.h"
-#define FIFO_SIZE_T int
-#include "fifo.h"
+#include "dft_filter.h"
#include <string.h>
typedef struct {
- int dft_length, num_taps;
- double * coefs;
-} filter_t;
-
-typedef struct {
+ dft_filter_priv_t base;
double delta, start;
int n;
- size_t samples_in, samples_out;
- fifo_t input_fifo, output_fifo;
- filter_t filter, * filter_ptr;
} priv_t;
static int create(sox_effect_t * effp, int argc, char **argv)
{
priv_t * p = (priv_t *)effp->priv;
- p->filter_ptr = &p->filter;
+ dft_filter_priv_t * b = &p->base;
+ b->filter_ptr = &b->filter;
p->delta = -10;
p->start = 65;
p->n = 1023;
@@ -104,119 +96,36 @@
static int start(sox_effect_t * effp)
{
priv_t * p = (priv_t *) effp->priv;
- int i, half = p->n / 2, dft_length = lsx_set_dft_length(p->n);
- double * h;
+ dft_filter_filter_t * f = p->base.filter_ptr;
if (p->delta == 0)
return SOX_EFF_NULL;
- if (!p->filter_ptr->num_taps) {
- h = make_filter(p->n, p->start, p->delta, effp->in_signal.rate);
- p->filter_ptr->coefs = lsx_calloc(dft_length, sizeof(*p->filter_ptr->coefs));
+ if (!f->num_taps) {
+ double * h = make_filter(p->n, p->start, p->delta, effp->in_signal.rate);
+ int i, dft_length = lsx_set_dft_length(p->n);
+ f->coefs = lsx_calloc(dft_length, sizeof(*f->coefs));
for (i = 0; i < p->n; ++i)
- p->filter_ptr->coefs[(i + dft_length - p->n + 1) & (dft_length - 1)]
+ f->coefs[(i + dft_length - p->n + 1) & (dft_length - 1)]
= h[i] / dft_length * 2;
free(h);
- p->filter_ptr->num_taps = p->n;
- p->filter_ptr->dft_length = dft_length;
- lsx_safe_rdft(dft_length, 1, p->filter_ptr->coefs);
+ f->num_taps = p->n;
+ f->post_peak = f->num_taps / 2;
+ f->dft_length = dft_length;
+ lsx_safe_rdft(dft_length, 1, f->coefs);
}
- fifo_create(&p->input_fifo, (int)sizeof(double));
- memset(fifo_reserve(&p->input_fifo, half), 0, sizeof(double) * half);
- fifo_create(&p->output_fifo, (int)sizeof(double));
- return SOX_SUCCESS;
+ return sox_dft_filter_effect_fn()->start(effp);
}
-static void filter(priv_t * p)
-{
- int i, num_in = max(0, fifo_occupancy(&p->input_fifo));
- filter_t const * f = p->filter_ptr;
- int const overlap = f->num_taps - 1;
- double * output;
-
- while (num_in >= f->dft_length) {
- double const * input = fifo_read_ptr(&p->input_fifo);
- fifo_read(&p->input_fifo, f->dft_length - overlap, NULL);
- num_in -= f->dft_length - overlap;
-
- output = fifo_reserve(&p->output_fifo, f->dft_length);
- fifo_trim_by(&p->output_fifo, overlap);
- memcpy(output, input, f->dft_length * sizeof(*output));
-
- lsx_rdft(f->dft_length, 1, output, lsx_fft_br, lsx_fft_sc);
- output[0] *= f->coefs[0];
- output[1] *= f->coefs[1];
- for (i = 2; i < f->dft_length; i += 2) {
- double tmp = output[i];
- output[i ] = f->coefs[i ] * tmp - f->coefs[i+1] * output[i+1];
- output[i+1] = f->coefs[i+1] * tmp + f->coefs[i ] * output[i+1];
- }
- lsx_rdft(f->dft_length, -1, output, lsx_fft_br, lsx_fft_sc);
- }
-}
-
-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 i, odone = min(*osamp, (size_t)fifo_occupancy(&p->output_fifo));
- double const * s = fifo_read(&p->output_fifo, (int)odone, NULL);
- SOX_SAMPLE_LOCALS;
-
- for (i = 0; i < odone; ++i)
- *obuf++ = SOX_FLOAT_64BIT_TO_SAMPLE(*s++, effp->clips);
- p->samples_out += odone;
-
- if (*isamp && odone < *osamp) {
- double * t = fifo_write(&p->input_fifo, (int)*isamp, NULL);
- p->samples_in += (int)*isamp;
-
- for (i = *isamp; i; --i)
- *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, effp->clips);
- filter(p);
- }
- else *isamp = 0;
- *osamp = odone;
- return SOX_SUCCESS;
-}
-
-static int drain(sox_effect_t * effp, sox_sample_t * obuf, size_t * osamp)
-{
- priv_t * p = (priv_t *)effp->priv;
- static size_t isamp = 0;
- size_t samples_out = p->samples_in;
- size_t remaining = samples_out - p->samples_out;
- double * buff = lsx_calloc(1024, sizeof(*buff));
-
- if ((int)remaining > 0) {
- while ((size_t)fifo_occupancy(&p->output_fifo) < remaining) {
- fifo_write(&p->input_fifo, 1024, buff);
- p->samples_in += 1024;
- filter(p);
- }
- fifo_trim_to(&p->output_fifo, (int)remaining);
- p->samples_in = 0;
- }
- free(buff);
- return flow(effp, 0, obuf, &isamp, osamp);
-}
-
-static int stop(sox_effect_t * effp)
-{
- priv_t * p = (priv_t *) effp->priv;
-
- fifo_delete(&p->input_fifo);
- fifo_delete(&p->output_fifo);
- free(p->filter_ptr->coefs);
- memset(p->filter_ptr, 0, sizeof(*p->filter_ptr));
- return SOX_SUCCESS;
-}
-
sox_effect_handler_t const * sox_loudness_effect_fn(void)
{
- static sox_effect_handler_t handler = {
- "loudness", "[gain [ref]]", 0,
- create, start, flow, drain, stop, NULL, sizeof(priv_t)
- };
+ static sox_effect_handler_t handler;
+ handler = *sox_dft_filter_effect_fn();
+ handler.name = "loudness";
+ handler.usage = "[gain [ref]]";
+ handler.flags &= ~SOX_EFF_DEPRECATED;
+ handler.getopts = create;
+ handler.start = start;
+ handler.priv_size = sizeof(priv_t);
return &handler;
}
--- /dev/null
+++ b/src/lowfir.c
@@ -1,0 +1,78 @@
+/* Effect: lowfir filter Copyright (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.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"
+#include "dft_filter.h"
+#include <string.h>
+
+typedef struct {
+ dft_filter_priv_t base;
+ double Fp, Fc, Fn, att, phase;
+ int allow_aliasing, num_taps, k;
+} priv_t;
+
+static int create(sox_effect_t * effp, int argc, char **argv)
+{
+ priv_t * p = (priv_t *)effp->priv;
+ dft_filter_priv_t * b = &p->base;
+ dft_filter_filter_t * f = &b->filter;
+ double * h;
+ int i;
+ b->filter_ptr = &b->filter;
+ do { /* break-able block */
+ NUMERIC_PARAMETER(Fp, 0, 100);
+ NUMERIC_PARAMETER(Fc, 0, 100);
+ NUMERIC_PARAMETER(Fn, 0, 100);
+ NUMERIC_PARAMETER(allow_aliasing, 0, 1);
+ NUMERIC_PARAMETER(att, 80, 200);
+ NUMERIC_PARAMETER(num_taps, 0, 65536);
+ NUMERIC_PARAMETER(k, 0, 512);
+ NUMERIC_PARAMETER(phase, 0, 100);
+ } while (0);
+
+ if (p->phase != 0 && p->phase != 50 && p->phase != 100)
+ p->att *= 34./33; /* negate degradation with intermediate phase */
+ h = lsx_design_lpf(
+ p->Fp, p->Fc, p->Fn, p->allow_aliasing, p->att, &p->num_taps, p->k);
+ f->num_taps = p->num_taps;
+
+ if (p->phase != 50)
+ lsx_fir_to_phase(&h, &f->num_taps, &f->post_peak, p->phase);
+ else f->post_peak = f->num_taps / 2;
+ lsx_debug("%i %i %g%%",
+ f->num_taps, f->post_peak, 100 - 100. * f->post_peak / (f->num_taps - 1));
+
+ f->dft_length = lsx_set_dft_length(f->num_taps);
+ f->coefs = lsx_calloc(f->dft_length, sizeof(*f->coefs));
+ for (i = 0; i < f->num_taps; ++i)
+ f->coefs[(i + f->dft_length - f->num_taps + 1) & (f->dft_length - 1)] = h[i] / f->dft_length * 2;
+ free(h);
+ lsx_safe_rdft(f->dft_length, 1, f->coefs);
+ return argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+sox_effect_handler_t const * sox_lowfir_effect_fn(void)
+{
+ static sox_effect_handler_t handler;
+ handler = *sox_dft_filter_effect_fn();
+ handler.name = "lowfir";
+ handler.usage = "[options]";
+ handler.flags &= ~SOX_EFF_DEPRECATED;
+ handler.getopts = create;
+ handler.priv_size = sizeof(priv_t);
+ return &handler;
+}
--
⑨