ref: c6ceb7f6ad6f535119c7f16cc7190bf532326448
parent: 230fa2c37c4bd9252ee9e5d8ccdf5862f93acd7d
author: robs <robs>
date: Wed Feb 4 17:01:17 EST 2009
new fir effect
--- a/ChangeLog
+++ b/ChangeLog
@@ -70,6 +70,7 @@
Effects:
o New `sinc' FFT filter effect; replacement for `filter'. (robs)
+ o New `fir' filter effect using external coefficients file. (robs)
o New `overdrive' effect. (robs)
o New `pluck' and `tpdf' types for `synth'. (robs)
o Can now set common parameters for multiple `synth' channels. (robs)
--- a/sox.1
+++ b/sox.1
@@ -1763,6 +1763,32 @@
.SP
An optional \fItype\fR can be specified to change the type of envelope. Choices are \fBq\fR for quarter of a sine wave, \fBh\fR for half a sine wave, \fBt\fR for linear slope, \fBl\fR for logarithmic, and \fBp\fR for inverted parabola. The default is logarithmic.
.TP
+\fBfir\fR [\fIcoefs-file\fR\^|\^\fIcoefs\fR]
+Use SoX's FFT convolution engine with given FIR filter
+coefficients.
+If a single argument is given then this is treated as the name of a file
+containing the filter coefficients (white-space separated; may contain
+`#' comments). If the given filename is `\-', or if no argument is
+given, then the coefficients are read from the `standard input' (stdin);
+otherwise, coefficients may be given on the command line.
+Examples:
+.EX
+ sox infile outfile fir 0.0195 -0.082 0.234 0.891 -0.145 0.043
+.EE
+.EX
+ sox infile outfile fir coefs.txt
+.EE
+with coefs.txt containing
+.EX
+ # HP filter
+ # freq=10000
+ 1.2311233052619888e-01
+ -4.4777096106211783e-01
+ 5.1031563346705155e-01
+ -6.6502926320995331e-02
+ ...
+.EE
+.TP
\fBflanger\fR [\fIdelay depth regen width speed shape phase interp\fR]
Apply a flanging effect to the audio.
See [3] for a detailed description of flanging.
@@ -1852,7 +1878,7 @@
.B \-B
and
.B \-b
-are synonomous.
+are synonymous.
.SP
The
.B \-r
@@ -1882,7 +1908,7 @@
option invokes a simple limiter, e.g.
.EX
sox infile outfile gain -l 6
-.SP
+.EE
will apply 6dB of gain but never clip. Note that limiting more than a
few dBs more than occasionally (in a piece of audio) is not recommended
as it can cause audible distortion.
--- 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 dither loudness rate stat
- biquad earwax mcompand remix stretch
- biquads echo mixer repeat swap
- chorus echos noiseprof reverb synth
- compand fade noisered reverse tempo
- compandt fft4g output silence tremolo
- contrast filter overdrive sinc trim
- dcshift flanger pad skeleff vol
- delay gain pan speed
- dft_filter input phaser splice
+ bend dither gain pan speed
+ biquad earwax input phaser splice
+ biquads echo loudness rate stat
+ chorus echos mcompand remix stretch
+ compand fade mixer repeat swap
+ compandt fft4g noiseprof reverb synth
+ contrast filter noisered reverse tempo
+ dcshift fir output silence tremolo
+ delay firfit overdrive sinc trim
+ dft_filter flanger pad skeleff vol
)
set(formats_srcs
8svx dat ima-fmt s3-fmt u3-fmt
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -270,16 +270,16 @@
# Effects source
libsox_la_SOURCES += \
band.h bend.c biquad.c biquad.h biquads.c chorus.c compand.c \
- compandt.c compandt.h contrast.c dcshift.c delay.c dither.c \
- dither_fir.h dither_iir.h earwax.c echo.c echos.c effects.c effects.h \
- effects_i.c fade.c fft4g.c fft4g.h fifo.h filter.c flanger.c input.c \
+ compandt.c compandt.h contrast.c dcshift.c delay.c dft_filter.c \
+ dft_filter.h dither.c dither_fir.h dither_iir.h earwax.c echo.c \
+ echos.c effects.c effects.h effects_i.c effects_i_dsp.c fade.c fft4g.c \
+ fft4g.h fifo.h filter.c fir.c firfit.c flanger.c gain.c input.c \
ladspa.c loudness.c mcompand.c mcompand_xover.h mixer.c noiseprof.c \
- noisered.c noisered.h gain.c output.c pad.c pan.c phaser.c \
- rate.c rate_filters.h rate_half_fir.h \
- rate_poly_fir0.h rate_poly_fir.h remix.c repeat.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 \
- dft_filter.c dft_filter.h sinc.c
+ noisered.c noisered.h output.c overdrive.c pad.c pan.c phaser.c rate.c \
+ rate_filters.h rate_half_fir.h rate_poly_fir0.h rate_poly_fir.h \
+ remix.c repeat.c reverb.c reverse.c silence.c sinc.c skeleff.c speed.c \
+ splice.c stat.c stretch.c swap.c synth.c tempo.c tremolo.c trim.c \
+ vol.c
if HAVE_PNG
libsox_la_SOURCES += spectrogram.c
endif
--- a/src/dft_filter.c
+++ b/src/dft_filter.c
@@ -20,8 +20,21 @@
#include "dft_filter.h"
#include <string.h>
-typedef dft_filter_filter_t filter_t;
+typedef dft_filter_t filter_t;
typedef dft_filter_priv_t priv_t;
+
+void lsx_set_dft_filter(dft_filter_t *f, double *h, int n, int post_peak)
+{
+ int i;
+ f->num_taps = n;
+ f->post_peak = post_peak;
+ 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;
+ lsx_safe_rdft(f->dft_length, 1, f->coefs);
+ free(h);
+}
static int start(sox_effect_t * effp)
{
--- a/src/dft_filter.h
+++ b/src/dft_filter.h
@@ -4,12 +4,13 @@
typedef struct {
int dft_length, num_taps, post_peak;
- double * coefs;
-} dft_filter_filter_t;
+ double * coefs;
+} dft_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_t filter, * filter_ptr;
} dft_filter_priv_t;
+void lsx_set_dft_filter(dft_filter_t * f, double * h, int n, int post_peak);
--- a/src/effects.h
+++ b/src/effects.h
@@ -35,6 +35,8 @@
EFFECT(equalizer)
EFFECT(fade)
EFFECT(filter)
+ EFFECT(fir)
+ EFFECT(firfit)
EFFECT(flanger)
EFFECT(gain)
EFFECT(highpass)
--- a/src/effects_i.c
+++ b/src/effects_i.c
@@ -306,6 +306,25 @@
return result < 0 ? -1 : result;
}
+FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename)
+{
+ FILE * file;
+
+ if (!filename || !strcmp(filename, "-")) {
+ if (effp->global_info->global_info->stdin_in_use_by) {
+ lsx_fail("stdin already in use by '%s'", effp->global_info->global_info->stdin_in_use_by);
+ return NULL;
+ }
+ effp->global_info->global_info->stdin_in_use_by = effp->handler.name;
+ file = stdin;
+ }
+ else if (!(file = fopen(filename, "r"))) {
+ lsx_fail("couldn't open file %s: %s", filename, strerror(errno));
+ return NULL;
+ }
+ return file;
+}
+
int lsx_effects_init(void)
{
init_fft_cache();
--- /dev/null
+++ b/src/fir.c
@@ -1,0 +1,83 @@
+/* Effect: fir filter from coefs Copyright (c) 2009 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"
+
+typedef struct {
+ dft_filter_priv_t base;
+ char const * filename;
+ double * h;
+ int n;
+} 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;
+ double d;
+ char c;
+
+ b->filter_ptr = &b->filter;
+ --argc, ++argv;
+ if (argc == 1)
+ p->filename = argv[0], --argc;
+ else for (; argc && sscanf(*argv, "%lf%c", &d, &c) == 1; --argc, ++argv)
+ (p->h = lsx_realloc(p->h, ++p->n * sizeof(*p->h)))[p->n - 1] = d;
+ return argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+static int start(sox_effect_t * effp)
+{
+ priv_t * p = (priv_t *)effp->priv;
+ dft_filter_t * f = p->base.filter_ptr;
+ double d;
+ char c;
+ int i;
+
+ if (!f->num_taps) {
+ if (!p->n) {
+ FILE * file = lsx_open_input_file(effp, p->filename);
+ if (!file)
+ return SOX_EOF;
+ while (fscanf(file, " #%*[^\n]%c", &c) + (i = fscanf(file, "%lf", &d)) >0)
+ if (i > 0)
+ (p->h = lsx_realloc(p->h, ++p->n * sizeof(*p->h)))[p->n - 1] = d;
+ lsx_report("%i coefficients", p->n);
+ if (!feof(file)) {
+ lsx_fail("error reading coefficient file");
+ if (file != stdin) fclose(file);
+ return SOX_EOF;
+ }
+ if (file != stdin) fclose(file);
+ }
+ lsx_set_dft_filter(f, p->h, p->n, p->n >> 1);
+ }
+ return sox_dft_filter_effect_fn()->start(effp);
+}
+
+sox_effect_handler_t const * sox_fir_effect_fn(void)
+{
+ static sox_effect_handler_t handler;
+ handler = *sox_dft_filter_effect_fn();
+ handler.name = "fir";
+ handler.usage = "[coef-file|coefs]";
+ handler.getopts = create;
+ handler.start = start;
+ handler.priv_size = sizeof(priv_t);
+ return &handler;
+}
--- /dev/null
+++ b/src/firfit.c
@@ -1,0 +1,134 @@
+/* Effect: firfit filter Copyright (c) 2009 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
+ */
+
+/* This is W.I.P. hence marked SOX_EFF_DEPRECATED for now.
+ * Need to add other interpolation types e.g. linear, bspline, window types,
+ * and filter length, maybe phase response type too.
+ */
+
+#include "sox_i.h"
+#include "dft_filter.h"
+
+typedef struct {
+ dft_filter_priv_t base;
+ char const * filename;
+ struct {double f, gain;} * knots;
+ int num_knots, n;
+} 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;
+ b->filter_ptr = &b->filter;
+ --argc, ++argv;
+ if (argc == 1)
+ p->filename = argv[0], --argc;
+ p->n = 2047;
+ return argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+static double * make_filter(sox_effect_t * effp)
+{
+ priv_t * p = (priv_t *)effp->priv;
+ double * log_freqs, * gains, * d, * work, * h;
+ sox_rate_t rate = effp->in_signal.rate;
+ int i, work_len;
+
+ lsx_valloc(log_freqs , p->num_knots);
+ lsx_valloc(gains, p->num_knots);
+ lsx_valloc(d , p->num_knots);
+ for (i = 0; i < p->num_knots; ++i) {
+ log_freqs[i] = log(max(p->knots[i].f, 1));
+ gains[i] = p->knots[i].gain;
+ }
+ lsx_prepare_spline3(log_freqs, gains, p->num_knots, HUGE_VAL, HUGE_VAL, d);
+
+ for (work_len = 8192; work_len < rate / 2; work_len <<= 1);
+ work = lsx_calloc(work_len + 2, sizeof(*work));
+ lsx_valloc(h, p->n);
+
+ for (i = 0; i <= work_len; i += 2) {
+ double f = rate * 0.5 * i / work_len;
+ double spl1 = f < max(p->knots[0].f, 1)? gains[0] :
+ f > p->knots[p->num_knots - 1].f? gains[p->num_knots - 1] :
+ lsx_spline3(log_freqs, gains, d, p->num_knots, log(f));
+ work[i] = dB_to_linear(spl1);
+ }
+ LSX_PACK(work, work_len);
+ lsx_safe_rdft(work_len, -1, work);
+ for (i = 0; i < p->n; ++i)
+ h[i] = work[(work_len - p->n / 2 + i) % work_len] * 2. / work_len;
+ lsx_apply_blackman_nutall(h, p->n);
+
+ free(work);
+ return h;
+}
+
+static sox_bool read_knots(sox_effect_t * effp)
+{
+ priv_t * p = (priv_t *) effp->priv;
+ FILE * file = lsx_open_input_file(effp, p->filename);
+ sox_bool result = sox_false;
+ int num_converted;
+ char c;
+
+ if (file) {
+ lsx_valloc(p->knots, 1);
+ while (fscanf(file, " #%*[^\n]%c", &c) >= 0) {
+ num_converted = fscanf(file, "%lf %lf",
+ &p->knots[p->num_knots].f, &p->knots[p->num_knots].gain);
+ if (num_converted == 2)
+ lsx_revalloc(p->knots, ++p->num_knots + 1);
+ else if (num_converted != 0)
+ break;
+ }
+ lsx_report("%i knots", p->num_knots);
+ if (feof(file) && num_converted != 1)
+ result = sox_true;
+ else lsx_fail("error reading knot file");
+ if (file != stdin)
+ fclose(file);
+ }
+ return result;
+}
+
+static int start(sox_effect_t * effp)
+{
+ priv_t * p = (priv_t *) effp->priv;
+ dft_filter_t * f = p->base.filter_ptr;
+
+ if (!f->num_taps) {
+ if (!p->num_knots && !read_knots(effp))
+ return SOX_EOF;
+ lsx_set_dft_filter(f, make_filter(effp), p->n, p->n >> 1);
+ }
+ return sox_dft_filter_effect_fn()->start(effp);
+}
+
+sox_effect_handler_t const * sox_firfit_effect_fn(void)
+{
+ static sox_effect_handler_t handler;
+ handler = *sox_dft_filter_effect_fn();
+ handler.name = "firfit";
+ handler.usage = "[knots-file]";
+ handler.flags |= SOX_EFF_DEPRECATED;
+ handler.getopts = create;
+ handler.start = start;
+ handler.priv_size = sizeof(priv_t);
+ return &handler;
+}
--- a/src/loudness.c
+++ b/src/loudness.c
@@ -78,7 +78,7 @@
work = lsx_calloc(work_len, sizeof(*work));
h = lsx_calloc(n, sizeof(*h));
- for (i = 1; i <= work_len / 2; ++i) {
+ for (i = 0; i <= work_len / 2; ++i) {
double f = rate * i / work_len;
double spl1 = f < 1? spl[0] : lsx_spline3(fs, spl, d, (int)LEN, log(f));
work[i < work_len / 2 ? 2 * i : 1] = dB_to_linear(spl1);
@@ -97,7 +97,7 @@
static int start(sox_effect_t * effp)
{
priv_t * p = (priv_t *) effp->priv;
- dft_filter_filter_t * f = p->base.filter_ptr;
+ dft_filter_t * f = p->base.filter_ptr;
if (p->delta == 0)
return SOX_EFF_NULL;
@@ -104,16 +104,14 @@
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)
- f->coefs[(i + dft_length - p->n + 1) & (dft_length - 1)]
- = h[i] / dft_length * 2;
- free(h);
- 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);
+ if (effp->global_info->plot != sox_plot_off) {
+ char title[100];
+ sprintf(title, "SoX effect: loudness %g (%g)", p->delta, p->start);
+ lsx_plot_fir(h, p->n, effp->in_signal.rate,
+ effp->global_info->plot, title, p->delta - 5, 0.);
+ return SOX_EOF;
+ }
+ lsx_set_dft_filter(f, h, p->n, p->n >> 1);
}
return sox_dft_filter_effect_fn()->start(effp);
}
--- a/src/noisered.c
+++ b/src/noisered.c
@@ -86,8 +86,11 @@
size_t fchannels = 0;
size_t channels = effp->in_signal.channels;
size_t i;
- FILE* ifp;
+ FILE * ifp = lsx_open_input_file(effp, data->profile_filename);
+ if (!ifp)
+ return SOX_EOF;
+
data->chandata = lsx_calloc(channels, sizeof(*(data->chandata)));
data->bufdata = 0;
for (i = 0; i < channels; i ++) {
@@ -95,22 +98,6 @@
data->chandata[i].smoothing = lsx_calloc(FREQCOUNT, sizeof(float));
data->chandata[i].lastwindow = NULL;
}
-
- /* Here we actually open the input file. */
- if (!data->profile_filename || !strcmp(data->profile_filename, "-")) {
- if (effp->global_info->global_info->stdin_in_use_by) {
- lsx_fail("stdin already in use by '%s'", effp->global_info->global_info->stdin_in_use_by);
- return SOX_EOF;
- }
- effp->global_info->global_info->stdin_in_use_by = effp->handler.name;
- ifp = stdin;
- }
- else if ((ifp = fopen(data->profile_filename, "r")) == NULL) {
- lsx_fail("Couldn't open profile file %s: %s",
- data->profile_filename, strerror(errno));
- return SOX_EOF;
- }
-
while (1) {
unsigned long i1_ul;
size_t i1;
@@ -127,7 +114,7 @@
data->chandata[fchannels].noisegate[0] = f1;
for (i = 1; i < FREQCOUNT; i ++) {
if (1 != fscanf(ifp, ", %f", &f1)) {
- lsx_fail("noisered: Not enough datums for channel %lu "
+ lsx_fail("noisered: Not enough data for channel %lu "
"(expected %d, got %lu)", (unsigned long)fchannels, FREQCOUNT, (unsigned long)i);
return SOX_EOF;
}
--- a/src/rate.c
+++ b/src/rate.c
@@ -26,8 +26,7 @@
#include "sox_i.h"
#include "fft4g.h"
#include "getopt.h"
-#define FIFO_SIZE_T int
-#include "fifo.h"
+#include "dft_filter.h"
#include <assert.h>
#include <string.h>
@@ -69,14 +68,9 @@
return result;
}
-typedef struct {
- int dft_length, num_taps, post_peak;
- sample_t * coefs;
-} half_band_t; /* Note: not half-band as in symmetric about Fn/2 (Fs/4) */
-
typedef struct { /* Data that are shared between channels and filters */
sample_t * poly_fir_coefs;
- half_band_t half_band[2]; /* [0]: halve; [1]: down/up: halve/double */
+ dft_filter_t half_band[2]; /* [0]: halve; [1]: down/up: halve/double */
} rate_shared_t;
struct stage;
@@ -130,7 +124,7 @@
sample_t * output;
int i, j, num_in = max(0, fifo_occupancy(&p->fifo));
rate_shared_t const * s = p->shared;
- half_band_t const * f = &s->half_band[p->which];
+ dft_filter_t const * f = &s->half_band[p->which];
int const overlap = f->num_taps - 1;
while (num_in >= f->dft_length) {
@@ -162,7 +156,7 @@
sample_t * output;
int i, j, num_in = max(0, fifo_occupancy(&p->fifo));
rate_shared_t const * s = p->shared;
- half_band_t const * f = &s->half_band[1];
+ dft_filter_t const * f = &s->half_band[1];
int const overlap = f->num_taps - 1;
while (num_in > f->dft_length >> 1) {
@@ -191,7 +185,7 @@
int num_taps, sample_t const h[], double Fp, double att, int multiplier,
double phase, sox_bool allow_aliasing)
{
- half_band_t * f = &p->half_band[which];
+ dft_filter_t * f = &p->half_band[which];
int dft_length, i;
if (f->num_taps)
--- a/src/sinc.c
+++ b/src/sinc.c
@@ -98,12 +98,12 @@
static int start(sox_effect_t * effp)
{
priv_t * p = (priv_t *)effp->priv;
- dft_filter_filter_t * f = p->base.filter_ptr;
+ dft_filter_t * f = p->base.filter_ptr;
if (!f->num_taps) {
double Fn = effp->in_signal.rate * .5;
double * h[2];
- int i, longer;
+ int i, n, post_peak, longer;
if (p->Fc0 >= Fn || p->Fc1 >= Fn) {
lsx_fail("filter frequency must be less than sample-rate / 2");
@@ -110,38 +110,34 @@
return SOX_EOF;
}
h[0] = lpf(Fn, p->Fc0, p->tbw0, &p->num_taps[0], p->att, &p->beta,p->round);
- if (h[0]) invert(h[0], p->num_taps[0]);
h[1] = lpf(Fn, p->Fc1, p->tbw1, &p->num_taps[1], p->att, &p->beta,p->round);
+ if (h[0])
+ invert(h[0], p->num_taps[0]);
longer = p->num_taps[1] > p->num_taps[0];
- f->num_taps = p->num_taps[longer];
+ n = p->num_taps[longer];
if (h[0] && h[1]) {
for (i = 0; i < p->num_taps[!longer]; ++i)
- h[longer][i + (f->num_taps - p->num_taps[!longer])/2] += h[!longer][i];
+ h[longer][i + (n - p->num_taps[!longer])/2] += h[!longer][i];
if (p->Fc0 < p->Fc1)
- invert(h[longer], f->num_taps);
+ invert(h[longer], n);
free(h[!longer]);
}
if (p->phase != 50)
- lsx_fir_to_phase(&h[longer], &f->num_taps, &f->post_peak, p->phase);
- else f->post_peak = f->num_taps / 2;
+ lsx_fir_to_phase(&h[longer], &n, &post_peak, p->phase);
+ else post_peak = n >> 1;
if (effp->global_info->plot != sox_plot_off) {
char title[100];
sprintf(title, "SoX effect: sinc filter freq=%g-%g",
p->Fc0, p->Fc1? p->Fc1 : Fn);
- lsx_plot_fir(h[longer], f->num_taps, effp->in_signal.rate,
+ lsx_plot_fir(h[longer], n, effp->in_signal.rate,
effp->global_info->plot, title, -p->beta * 10 - 25, 5.);
return SOX_EOF;
}
- 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[longer][i] / f->dft_length * 2;
- free(h[longer]);
- lsx_safe_rdft(f->dft_length, 1, f->coefs);
+ lsx_set_dft_filter(f, h[longer], n, post_peak);
}
return sox_dft_filter_effect_fn()->start(effp);
}
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -83,6 +83,7 @@
double phase); /* Phase at 1st point; 0..2pi. (e.g. pi/2 for cosine) */
char const * lsx_parsesamples(sox_rate_t rate, const char *str, size_t *samples, int def);
double lsx_parse_frequency(char const * text, char * * end_ptr);
+FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename);
void lsx_prepare_spline3(double const * x, double const * y, int n,
double start_1d, double end_1d, double * y_2d);
--- a/src/xmalloc.h
+++ b/src/xmalloc.h
@@ -28,5 +28,7 @@
#define lsx_calloc(n,s) ((n)*(s)? memset(lsx_malloc((n)*(s)),0,(n)*(s)) : NULL)
#define lsx_strdup(p) ((p)? strcpy((char *)lsx_malloc(strlen(p) + 1), p) : NULL)
#define lsx_memdup(p,s) ((p)? memcpy(lsx_malloc(s), p, s) : NULL)
+#define lsx_valloc(v,n) v = lsx_malloc((n)*sizeof(*(v)))
+#define lsx_revalloc(v,n) v = lsx_realloc(v, (n)*sizeof(*(v)))
#endif