History

new loudness effect

robs committed 18 years ago

Commit 2ce9ae31 parent fe3741512 files · +345 −34Browse files

Unified · Split

12 files
  1. AUTHORS +1 −1
  2. ChangeLog +3 −1
  3. README +1 −0
  4. soxeffect.7 +19 −2
  5. src/CMakeLists.txt +10 −9
  6. src/Makefile.am +1 −1
  7. src/effects.h +1 −0
  8. src/effects_i.c +77 −0
  9. src/loudness.c +221 −0
  10. src/rate.c +2 −11
  11. src/sox_i.h +8 −0
  12. src/test-srcs +1 −9
AUTHORS+1−1
@@ -17,7 +17,7 @@ Mantainers: · 16 unmodified lines
1717 EFFECTS: tempo, pad, bass, treble, delay, new reverb, new
1818 flanger, soft-knee companding, speed via resampling, filters
1919 makeover inc. gnuplot & octave plotting, splice, remix, norm,
20− contrast, new rate, spectrogram, new pitch, riaa;
20+ contrast, new rate, spectrogram, new pitch, riaa, loudness;
2121 new effects chain with buffering and any # channels.
2222 OTHERS: open input files via URL, file merge, play
2323 multiple files with mixed format types, play with replay-gain,
ChangeLog+3−1
@@ -44,7 +44,9 @@ File formats: · 43 unmodified lines
4444
4545 Effects:
4646
47− o New `riaa' effect; RIAA vinyl playback EQ. (robs)
47+ o New `riaa' effect: RIAA vinyl playback EQ. (robs)
48+ o New `loudness' effect: gain control with ISO 226 loudness
49+ compensation. (robs)
4850 o New -b option for the norm effect; can be used to fix stereo
4951 imbalance. (robs)
5052 o Change default settings for `rate' effect; add -s -L options to
README+1−0
@@ -127,6 +127,7 @@ The audio effects/tools included in this release are as follows: · 126 unmodified lines
127127 o dcshift Apply or remove DC offset
128128 o fade Apply a fade-in and/or fade-out to the audio
129129 o gain Apply gain or attenuation
130+ o loudness Gain control with ISO 226 loudness compensation
130131 o mcompand Multi-band compression/expansion/limiting
131132 o norm Normalise to 0dB (or other), or fix imbalance
132133 o vol Adjust audio volume
soxeffect.7+19−2
@@ -652,6 +652,23 @@ default values if possible. Only plugins with at most one audio input · 651 unmodified lines
652652 and one audio output port can be used. If found, the environment varible
653653 LADSPA_PATH will be used as search path for plugins.
654654 .TP
655+\fBloudness [\fIgain\fR [\fIreference\fR]]
656+Loudness control\*msimilar to the
657+.B gain
658+effect, but provides equalisation for the human auditory system. See
659+http://en.wikipedia.org/wiki/Loudness for a detailed description of
660+loudness. The gain is adjusted by the given
661+.I gain
662+parameter (usually negative) and the signal equalised according to ISO
663+226 w.r.t. a reference level of 65dB, though an alternative
664+.I reference
665+level may be given if the original audio has been equalised for some
666+other optimal level.
667+.SP
668+See also the
669+.B gain
670+effect.
671+.TP
655672 \fBlowpass\fR [\fB\-1\fR|\fB\-2\fR] \fIfrequency\fR[\fBk\fR]\fR [\fRwidth\fR[\fBq\fR\^|\^\fBo\fR\^|\^\fBh\fR\^|\^\fBk\fR]]
656673 Apply a low-pass filter.
657674 See the description of the \fBhighpass\fR effect for details.
@@ -967,7 +984,7 @@ quality come at the expense of increasing amounts of time to process the · 309 unmodified lines
967984 audio. If no quality option is given, the quality level used is `high'.
968985 .SP
969986 The `quick' algorithm uses cubic interpolation; all others use
970−band-width limited interpolation. The `quick' and `low' quality
987+band-limited interpolation. The `quick' and `low' quality
971988 algorithms have a `linear' phase response; for `medium', `high' and
972989 `very high', the phase response is configurable (see below), but
973990 defaults to `intermediate'.
@@ -1010,7 +1027,7 @@ lB lw52. · 36 unmodified lines
10101027 Any phase response (0 = minimum, 25 = intermediate, 50 = linear, 100 = maximum)
10111028 T}
10121029 \-s Steep filter (band-width = 99%)
1013−\-b\ 74\-99.7 Any band-width %
1030+\-b\ 74\-99\*d7 Any band-width %
10141031 \-a Allow aliasing above the pass-band
10151032 .TE
10161033 .DT
src/CMakeLists.txt+10−9
@@ -28,15 +28,16 @@ add_custom_command( · 27 unmodified lines
2828
2929 # Format with: !xargs echo|tr ' ' '\n'|sort|column|expand|sed 's/^/ /'
3030 set(effects_srcs
31− biquad earwax mixer polyphas speed
32− biquads echo noiseprof rate splice
33− chorus echos noisered remix stat
34− compand fade normalise repeat swap
35− compandt fft4g output resample synth
36− contrast filter pad reverb tempo
37− dcshift flanger pan reverse tremolo
38− delay input phaser silence trim
39− dither mcompand pitch skeleff vol
31+ biquad echo noiseprof remix swap
32+ biquads echos noisered repeat synth
33+ chorus fade normalise resample tempo
34+ compand fft4g output reverb tremolo
35+ compandt filter pad reverse trim
36+ contrast flanger pan silence vol
37+ dcshift input phaser skeleff
38+ delay loudness pitch speed
39+ dither mcompand polyphas splice
40+ earwax mixer rate stat
4041 )
4142 set(formats_srcs
4243 8svx dat ima-fmt s3-fmt u4-fmt
src/Makefile.am+1−1
@@ -252,7 +252,7 @@ libsfx_la_SOURCES = \ · 251 unmodified lines
252252 band.h biquad.c biquad.h biquads.c chorus.c compand.c compandt.c \
253253 compandt.h contrast.c dcshift.c delay.c dither.c earwax.c echo.c \
254254 echos.c effects.c effects.h effects_i.c fade.c fft4g.c fft4g.h \
255− fifo.h filter.c flanger.c input.c ladspa.c mcompand.c \
255+ fifo.h filter.c flanger.c input.c ladspa.c loudness.c mcompand.c \
256256 mixer.c noiseprof.c noisered.c noisered.h normalise.c output.c pad.c \
257257 pan.c phaser.c pitch.c polyphas.c rabbit.c rate.c \
258258 rate_filters.h rate_half_fir.h rate_poly_fir0.h rate_poly_fir.h \
src/effects.h+1−0
@@ -41,6 +41,7 @@ · 40 unmodified lines
4141 #ifdef HAVE_LADSPA_H
4242 EFFECT(ladspa)
4343 #endif
44+ EFFECT(loudness)
4445 EFFECT(lowpass)
4546 EFFECT(mcompand)
4647 EFFECT(mixer)
src/effects_i.c+77−0
@@ -68,6 +68,56 @@ unsigned lsx_lcm(unsigned a, unsigned b) · 67 unmodified lines
6868 return a * (b / lsx_gcd(a, b));
6969 }
7070
71+/* Numerical Recipes cubic spline */
72+
73+void lsx_prepare_spline3(double const * x, double const * y, int n,
74+ double start_1d, double end_1d, double * y_2d)
75+{
76+ double p, qn, sig, un, * u = lsx_malloc((n - 1) * sizeof(*u));
77+ int i;
78+
79+ if (start_1d == HUGE_VAL)
80+ y_2d[0] = u[0] = 0; /* Start with natural spline or */
81+ else { /* set the start first derivative */
82+ y_2d[0] = -.5;
83+ u[0] = (3 / (x[1] - x[0])) * ((y[1] - y[0]) / (x[1] - x[0]) - start_1d);
84+ }
85+
86+ for (i = 1; i < n - 1; ++i) {
87+ sig = (x[i] - x[i - 1]) / (x[i + 1] - x[i - 1]);
88+ p = sig * y_2d[i - 1] + 2;
89+ y_2d[i] = (sig - 1) / p;
90+ u[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]) -
91+ (y[i] - y[i - 1]) / (x[i] - x[i - 1]);
92+ u[i] = (6 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p;
93+ }
94+ if (end_1d == HUGE_VAL)
95+ qn = un = 0; /* End with natural spline or */
96+ else { /* set the end first derivative */
97+ qn = .5;
98+ un = 3 / (x[n - 1] - x[n - 2]) * (end_1d - (y[n - 1] - y[n - 2]) / (x[n - 1] - x[n - 2]));
99+ }
100+ y_2d[n - 1] = (un - qn * u[n - 2]) / (qn * y_2d[n - 2] + 1);
101+ for (i = n - 2; i >= 0; --i)
102+ y_2d[i] = y_2d[i] * y_2d[i + 1] + u[i];
103+ free(u);
104+}
105+
106+double lsx_spline3(double const * x, double const * y, double const * y_2d,
107+ int n, double x1)
108+{
109+ int t, i[2] = {0, 0};
110+ double d, a, b;
111+
112+ for (i[1] = n - 1; i[1] - i[0] > 1; t = (i[1] + i[0]) >> 1, i[x[t] > x1] = t);
113+ d = x[i[1]] - x[i[0]];
114+ assert(d != 0);
115+ a = (x[i[1]] - x1) / d;
116+ b = (x1 - x[i[0]]) / d;
117+ return a * y[i[0]] + b * y[i[1]] +
118+ ((a * a * a - a) * y_2d[i[0]] + (b * b * b - b) * y_2d[i[1]]) * d * d / 6;
119+}
120+
71121 enum_item const lsx_wave_enum[] = {
72122 ENUM_ITEM(SOX_WAVE_,SINE)
73123 ENUM_ITEM(SOX_WAVE_,TRIANGLE)
@@ -279,6 +329,15 @@ double lsx_bessel_I_0(double x) · 205 unmodified lines
279329 return sum;
280330 }
281331
332+int lsx_set_dft_length(int num_taps) /* Set to 4 x nearest power of 2 */
333+{
334+ int result, n = num_taps;
335+ for (result = 8; n > 2; result <<= 1, n >>= 1);
336+ result = range_limit(result, 4096, 131072);
337+ assert(num_taps * 2 < result);
338+ return result;
339+}
340+
282341 #include "fft4g.h"
283342 int * lsx_fft_br;
284343 double * lsx_fft_sc;
@@ -384,6 +443,24 @@ void lsx_apply_bartlett(double h[], const int num_points) · 99 unmodified lines
384443 }
385444 }
386445
446+void lsx_apply_blackman(double h[], const int num_points, double alpha)
447+{
448+ int i, m = num_points - 1;
449+ for (i = 0; i < num_points; ++i) {
450+ double x = 2 * M_PI * i / m;
451+ h[i] *= (1 - alpha) *.5 - .5 * cos(x) + alpha * .5 * cos(2 * x);
452+ }
453+}
454+
455+void lsx_apply_blackman_nutall(double h[], const int num_points)
456+{
457+ int i, m = num_points - 1;
458+ for (i = 0; i < num_points; ++i) {
459+ double x = 2 * M_PI * i / m;
460+ h[i] *= .3635819 - .4891775 * cos(x) + .1365995 * cos(2 * x) - .0106411 * cos(3 * x);
461+ }
462+}
463+
387464 double lsx_kaiser_beta(double att)
388465 {
389466 if (att > 100 ) return .1117 * att - 1.11;
src/loudness.c+221−0
@@ -0,0 +1,221 @@
1+/* Effect: loudness filter Copyright (c) 2008 robs@users.sourceforge.net
2+ *
3+ * This library is free software; you can redistribute it and/or modify it
4+ * under the terms of the GNU Lesser General Public License as published by
5+ * the Free Software Foundation; either version 2.1 of the License, or (at
6+ * your option) any later version.
7+ *
8+ * This library is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11+ * General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this library; if not, write to the Free Software Foundation,
15+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16+ */
17+
18+#include "sox_i.h"
19+#include "fft4g.h"
20+#define FIFO_SIZE_T int
21+#include "fifo.h"
22+#include <string.h>
23+
24+typedef struct {
25+ int dft_length, num_taps;
26+ double * coefs;
27+} filter_t;
28+
29+typedef struct {
30+ double delta, start;
31+ int n;
32+ size_t samples_in, samples_out;
33+ fifo_t input_fifo, output_fifo;
34+ filter_t filter, * filter_ptr;
35+} priv_t;
36+
37+static int create(sox_effect_t * effp, int argc, char **argv)
38+{
39+ priv_t * p = (priv_t *)effp->priv;
40+ p->filter_ptr = &p->filter;
41+ p->delta = -10;
42+ p->start = 65;
43+ p->n = 1023;
44+ do { /* break-able block */
45+ NUMERIC_PARAMETER(delta,-50 , 15)
46+ NUMERIC_PARAMETER(start, 50 , 75)
47+ NUMERIC_PARAMETER(n ,127 ,2047)
48+ } while (0);
49+ p->n = 2 * p->n + 1;
50+ return argc? lsx_usage(effp) : SOX_SUCCESS;
51+}
52+
53+static double * make_filter(int n, double start, double delta, double rate)
54+{
55+ static const struct {double f, af, lu, tf;} iso226_table[] = {
56+ { 20,0.532,-31.6,78.5},{ 25,0.506,-27.2,68.7},{ 31.5,0.480,-23.0,59.5},
57+ { 40,0.455,-19.1,51.1},{ 50,0.432,-15.9,44.0},{ 63,0.409,-13.0,37.5},
58+ { 80,0.387,-10.3,31.5},{ 100,0.367, -8.1,26.5},{ 125,0.349, -6.2,22.1},
59+ { 160,0.330, -4.5,17.9},{ 200,0.315, -3.1,14.4},{ 250,0.301, -2.0,11.4},
60+ { 315,0.288, -1.1, 8.6},{ 400,0.276, -0.4, 6.2},{ 500,0.267, 0.0, 4.4},
61+ { 630,0.259, 0.3, 3.0},{ 800,0.253, 0.5, 2.2},{ 1000,0.250, 0.0, 2.4},
62+ { 1250,0.246, -2.7, 3.5},{ 1600,0.244, -4.1, 1.7},{ 2000,0.243, -1.0,-1.3},
63+ { 2500,0.243, 1.7,-4.2},{ 3150,0.243, 2.5,-6.0},{ 4000,0.242, 1.2,-5.4},
64+ { 5000,0.242, -2.1,-1.5},{ 6300,0.245, -7.1, 6.0},{ 8000,0.254,-11.2,12.6},
65+ {10000,0.271,-10.7,13.9},{12500,0.301, -3.1,12.3},
66+ };
67+ #define LEN (array_length(iso226_table) + 2)
68+ #define SPL(phon, t) (10 / t.af * log10(4.47e-3 * (pow(10., .025 * (phon)) - \
69+ 1.15) + pow(.4 * pow(10., (t.tf + t.lu) / 10 - 9), t.af)) - t.lu + 94)
70+ double fs[LEN], spl[LEN], d[LEN], * work, * h;
71+ int i, work_len;
72+
73+ fs[0] = log(1.);
74+ spl[0] = delta * .2;
75+ for (i = 0; i < (int)LEN - 2; ++i) {
76+ spl[i + 1] = SPL(start + delta, iso226_table[i]) -
77+ SPL(start , iso226_table[i]);
78+ fs[i + 1] = log(iso226_table[i].f);
79+ }
80+ fs[i + 1] = log(100000.);
81+ spl[i + 1] = spl[0];
82+ lsx_prepare_spline3(fs, spl, LEN, HUGE_VAL, HUGE_VAL, d);
83+
84+ for (work_len = 8192; work_len < rate / 2; work_len <<= 1);
85+ work = lsx_calloc(work_len, sizeof(*work));
86+ h = lsx_calloc(n, sizeof(*h));
87+
88+ for (i = 1; i <= work_len / 2; ++i) {
89+ double f = rate * i / work_len;
90+ double spl1 = f < 1? spl[0] : lsx_spline3(fs, spl, d, LEN, log(f));
91+ work[i < work_len / 2 ? 2 * i : 1] = dB_to_linear(spl1);
92+ }
93+ lsx_safe_rdft(work_len, -1, work);
94+ for (i = 0; i < n; ++i)
95+ h[i] = work[(work_len - n / 2 + i) % work_len] * 2. / work_len;
96+ lsx_apply_kaiser(h, n, lsx_kaiser_beta(40 + 2./3 * fabs(delta)));
97+
98+ free(work);
99+ return h;
100+ #undef SPL
101+ #undef LEN
102+}
103+
104+static int start(sox_effect_t * effp)
105+{
106+ priv_t * p = (priv_t *) effp->priv;
107+ int i, half = p->n / 2, dft_length = lsx_set_dft_length(p->n);
108+ double * h;
109+
110+ if (p->delta == 0)
111+ return SOX_EFF_NULL;
112+
113+ if (!p->filter_ptr->num_taps) {
114+ h = make_filter(p->n, p->start, p->delta, effp->in_signal.rate);
115+ p->filter_ptr->coefs = lsx_calloc(dft_length, sizeof(*p->filter_ptr->coefs));
116+ for (i = 0; i < p->n; ++i)
117+ p->filter_ptr->coefs[(i + dft_length - p->n + 1) & (dft_length - 1)]
118+ = h[i] / dft_length * 2;
119+ free(h);
120+ p->filter_ptr->num_taps = p->n;
121+ p->filter_ptr->dft_length = dft_length;
122+ lsx_safe_rdft(dft_length, 1, p->filter_ptr->coefs);
123+ }
124+ fifo_create(&p->input_fifo, (int)sizeof(double));
125+ memset(fifo_reserve(&p->input_fifo, half), 0, sizeof(double) * half);
126+ fifo_create(&p->output_fifo, (int)sizeof(double));
127+ return SOX_SUCCESS;
128+}
129+
130+static void filter(priv_t * p)
131+{
132+ int i, num_in = max(0, fifo_occupancy(&p->input_fifo));
133+ filter_t const * f = p->filter_ptr;
134+ int const overlap = f->num_taps - 1;
135+ double * output;
136+
137+ while (num_in >= f->dft_length) {
138+ double const * input = fifo_read_ptr(&p->input_fifo);
139+ fifo_read(&p->input_fifo, f->dft_length - overlap, NULL);
140+ num_in -= f->dft_length - overlap;
141+
142+ output = fifo_reserve(&p->output_fifo, f->dft_length);
143+ fifo_trim_by(&p->output_fifo, overlap);
144+ memcpy(output, input, f->dft_length * sizeof(*output));
145+
146+ lsx_rdft(f->dft_length, 1, output, lsx_fft_br, lsx_fft_sc);
147+ output[0] *= f->coefs[0];
148+ output[1] *= f->coefs[1];
149+ for (i = 2; i < f->dft_length; i += 2) {
150+ double tmp = output[i];
151+ output[i ] = f->coefs[i ] * tmp - f->coefs[i+1] * output[i+1];
152+ output[i+1] = f->coefs[i+1] * tmp + f->coefs[i ] * output[i+1];
153+ }
154+ lsx_rdft(f->dft_length, -1, output, lsx_fft_br, lsx_fft_sc);
155+ }
156+}
157+
158+static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
159+ sox_sample_t * obuf, size_t * isamp, size_t * osamp)
160+{
161+ priv_t * p = (priv_t *)effp->priv;
162+ size_t i, odone = min(*osamp, (size_t)fifo_occupancy(&p->output_fifo));
163+ double const * s = fifo_read(&p->output_fifo, (int)odone, NULL);
164+
165+ for (i = 0; i < odone; ++i)
166+ *obuf++ = SOX_FLOAT_64BIT_TO_SAMPLE(*s++, effp->clips);
167+ p->samples_out += odone;
168+
169+ if (*isamp && odone < *osamp) {
170+ double * t = fifo_write(&p->input_fifo, (int)*isamp, NULL);
171+ p->samples_in += (int)*isamp;
172+
173+ for (i = *isamp; i; --i)
174+ *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, effp->clips);
175+ filter(p);
176+ }
177+ else *isamp = 0;
178+ *osamp = odone;
179+ return SOX_SUCCESS;
180+}
181+
182+static int drain(sox_effect_t * effp, sox_sample_t * obuf, size_t * osamp)
183+{
184+ priv_t * p = (priv_t *)effp->priv;
185+ static size_t isamp = 0;
186+ size_t samples_out = p->samples_in;
187+ size_t remaining = samples_out - p->samples_out;
188+ double * buff = lsx_calloc(1024, sizeof(*buff));
189+
190+ if ((int)remaining > 0) {
191+ while ((size_t)fifo_occupancy(&p->output_fifo) < remaining) {
192+ fifo_write(&p->input_fifo, 1024, buff);
193+ p->samples_in += 1024;
194+ filter(p);
195+ }
196+ fifo_trim_to(&p->output_fifo, (int)remaining);
197+ p->samples_in = 0;
198+ }
199+ free(buff);
200+ return flow(effp, 0, obuf, &isamp, osamp);
201+}
202+
203+static int stop(sox_effect_t * effp)
204+{
205+ priv_t * p = (priv_t *) effp->priv;
206+
207+ fifo_delete(&p->input_fifo);
208+ fifo_delete(&p->output_fifo);
209+ free(p->filter_ptr->coefs);
210+ memset(p->filter_ptr, 0, sizeof(*p->filter_ptr));
211+ return SOX_SUCCESS;
212+}
213+
214+sox_effect_handler_t const * sox_loudness_effect_fn(void)
215+{
216+ static sox_effect_handler_t handler = {
217+ "loudness", "[gain [ref]]", 0,
218+ create, start, flow, drain, stop, NULL, sizeof(priv_t)
219+ };
220+ return &handler;
221+}
src/rate.c+2−11
@@ -301,15 +301,6 @@ static void fir_to_phase(double * * h, int * len, · 300 unmodified lines
301301 free(work);
302302 }
303303
304−static int set_dft_length(int num_taps) /* Set to 4 x nearest power of 2 */
305−{
306− int result, n = num_taps;
307− for (result = 8; n > 2; result <<= 1, n >>= 1);
308− result = range_limit(result, 4096, 131072);
309− assert(num_taps * 2 < result);
310− return result;
311−}
312−
313304 static void half_band_filter_init(rate_shared_t * p, unsigned which,
314305 int num_taps, sample_t const h[], double Fp, double atten, int multiplier,
315306 double phase, sox_bool allow_aliasing)
@@ -320,7 +311,7 @@ static void half_band_filter_init(rate_shared_t * p, unsigned which, · 4 unmodified lines
320311 if (f->num_taps)
321312 return;
322313 if (h) {
323− dft_length = set_dft_length(num_taps);
314+ dft_length = lsx_set_dft_length(num_taps);
324315 f->coefs = calloc(dft_length, sizeof(*f->coefs));
325316 for (i = 0; i < num_taps; ++i)
326317 f->coefs[(i + dft_length - num_taps + 1) & (dft_length - 1)]
@@ -337,7 +328,7 @@ static void half_band_filter_init(rate_shared_t * p, unsigned which, · 10 unmodified lines
337328 fir_to_phase(&h, &num_taps, &f->post_peak, phase);
338329 else f->post_peak = num_taps / 2;
339330
340− dft_length = set_dft_length(num_taps);
331+ dft_length = lsx_set_dft_length(num_taps);
341332 f->coefs = calloc(dft_length, sizeof(*f->coefs));
342333 for (i = 0; i < num_taps; ++i)
343334 f->coefs[(i + dft_length - num_taps + 1) & (dft_length - 1)]
src/sox_i.h+8−0
@@ -61,7 +61,13 @@ double lsx_parse_frequency(char const * text, char * * end_ptr); · 60 unmodified lines
6161 unsigned lsx_gcd(unsigned a, unsigned b);
6262 unsigned lsx_lcm(unsigned a, unsigned b);
6363
64+void lsx_prepare_spline3(double const * x, double const * y, int n,
65+ double start_1d, double end_1d, double * y_2d);
66+double lsx_spline3(double const * x, double const * y, double const * y_2d,
67+ int n, double x1);
68+
6469 double lsx_bessel_I_0(double x);
70+int lsx_set_dft_length(int num_taps);
6571 extern int * lsx_fft_br;
6672 extern double * lsx_fft_sc;
6773 void lsx_safe_rdft(int len, int type, double * d);
@@ -72,6 +78,8 @@ void lsx_apply_hann_f(float h[], const int num_points); · 4 unmodified lines
7278 void lsx_apply_hann(double h[], const int num_points);
7379 void lsx_apply_hamming(double h[], const int num_points);
7480 void lsx_apply_bartlett(double h[], const int num_points);
81+void lsx_apply_blackman(double h[], const int num_points, double alpha);
82+void lsx_apply_blackman_nutall(double h[], const int num_points);
7583 double lsx_kaiser_beta(double att);
7684 void lsx_apply_kaiser(double h[], const int num_points, double beta);
7785
src/test-srcs+1−9
@@ -20,15 +20,7 @@ test_converters () { · 19 unmodified lines
2020 # Create input file
2121 $SOX -r $1 -n -twavpcm $IN synth 20 sin 0:`expr $1 / 2` gain -2
2222 for src in \
23− "polyphase" \
24− "rabbit -c0" \
25− "rabbit -c1" \
26− "rate -h" \
27− "rate -v" \
28− "resample -q" \
29− "resample -ql" \
30− "ssrc" \
31− "ssrc_hp" \
23+ "rate -vsL" \
3224 ; do
3325 echo $src
3426 case "$src" in

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t