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
17 EFFECTS: tempo, pad, bass, treble, delay, new reverb, new17 EFFECTS: tempo, pad, bass, treble, delay, new reverb, new
18 flanger, soft-knee companding, speed via resampling, filters18 flanger, soft-knee companding, speed via resampling, filters
19 makeover inc. gnuplot & octave plotting, splice, remix, norm,19 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;
21 new effects chain with buffering and any # channels.21 new effects chain with buffering and any # channels.
22 OTHERS: open input files via URL, file merge, play22 OTHERS: open input files via URL, file merge, play
23 multiple files with mixed format types, play with replay-gain,23 multiple files with mixed format types, play with replay-gain,
ChangeLog+3−1
@@ -44,7 +44,9 @@ File formats: · 43 unmodified lines
44 44
45Effects:45Effects:
46 46
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)
48 o New -b option for the norm effect; can be used to fix stereo50 o New -b option for the norm effect; can be used to fix stereo
49 imbalance. (robs)51 imbalance. (robs)
50 o Change default settings for `rate' effect; add -s -L options to52 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
127 o dcshift Apply or remove DC offset127 o dcshift Apply or remove DC offset
128 o fade Apply a fade-in and/or fade-out to the audio128 o fade Apply a fade-in and/or fade-out to the audio
129 o gain Apply gain or attenuation129 o gain Apply gain or attenuation
130 o loudness Gain control with ISO 226 loudness compensation
130 o mcompand Multi-band compression/expansion/limiting131 o mcompand Multi-band compression/expansion/limiting
131 o norm Normalise to 0dB (or other), or fix imbalance132 o norm Normalise to 0dB (or other), or fix imbalance
132 o vol Adjust audio volume133 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
652and one audio output port can be used. If found, the environment varible652and one audio output port can be used. If found, the environment varible
653LADSPA_PATH will be used as search path for plugins.653LADSPA_PATH will be used as search path for plugins.
654.TP654.TP
655\fBloudness [\fIgain\fR [\fIreference\fR]]
656Loudness control\*msimilar to the
657.B gain
658effect, but provides equalisation for the human auditory system. See
659http://en.wikipedia.org/wiki/Loudness for a detailed description of
660loudness. The gain is adjusted by the given
661.I gain
662parameter (usually negative) and the signal equalised according to ISO
663226 w.r.t. a reference level of 65dB, though an alternative
664.I reference
665level may be given if the original audio has been equalised for some
666other optimal level.
667.SP
668See also the
669.B gain
670effect.
671.TP
655\fBlowpass\fR [\fB\-1\fR|\fB\-2\fR] \fIfrequency\fR[\fBk\fR]\fR [\fRwidth\fR[\fBq\fR\^|\^\fBo\fR\^|\^\fBh\fR\^|\^\fBk\fR]]672\fBlowpass\fR [\fB\-1\fR|\fB\-2\fR] \fIfrequency\fR[\fBk\fR]\fR [\fRwidth\fR[\fBq\fR\^|\^\fBo\fR\^|\^\fBh\fR\^|\^\fBk\fR]]
656Apply a low-pass filter.673Apply a low-pass filter.
657See the description of the \fBhighpass\fR effect for details.674See 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
967audio. If no quality option is given, the quality level used is `high'.984audio. If no quality option is given, the quality level used is `high'.
968.SP985.SP
969The `quick' algorithm uses cubic interpolation; all others use986The `quick' algorithm uses cubic interpolation; all others use
970band-width limited interpolation. The `quick' and `low' quality987band-limited interpolation. The `quick' and `low' quality
971algorithms have a `linear' phase response; for `medium', `high' and988algorithms have a `linear' phase response; for `medium', `high' and
972`very high', the phase response is configurable (see below), but989`very high', the phase response is configurable (see below), but
973defaults to `intermediate'.990defaults to `intermediate'.
@@ -1010,7 +1027,7 @@ lB lw52. · 36 unmodified lines
1010Any phase response (0 = minimum, 25 = intermediate, 50 = linear, 100 = maximum)1027Any phase response (0 = minimum, 25 = intermediate, 50 = linear, 100 = maximum)
1011T}1028T}
1012\-s Steep filter (band-width = 99%)1029\-s Steep filter (band-width = 99%)
1013\-b\ 74\-99.7 Any band-width %1030\-b\ 74\-99\*d7 Any band-width %
1014\-a Allow aliasing above the pass-band1031\-a Allow aliasing above the pass-band
1015.TE1032.TE
1016.DT1033.DT
src/CMakeLists.txt+10−9
@@ -28,15 +28,16 @@ add_custom_command( · 27 unmodified lines
28 28
29# Format with: !xargs echo|tr ' ' '\n'|sort|column|expand|sed 's/^/ /'29# Format with: !xargs echo|tr ' ' '\n'|sort|column|expand|sed 's/^/ /'
30set(effects_srcs30set(effects_srcs
31 biquad earwax mixer polyphas speed31 biquad echo noiseprof remix swap
32 biquads echo noiseprof rate splice32 biquads echos noisered repeat synth
33 chorus echos noisered remix stat33 chorus fade normalise resample tempo
34 compand fade normalise repeat swap34 compand fft4g output reverb tremolo
35 compandt fft4g output resample synth35 compandt filter pad reverse trim
36 contrast filter pad reverb tempo36 contrast flanger pan silence vol
37 dcshift flanger pan reverse tremolo37 dcshift input phaser skeleff
38 delay input phaser silence trim38 delay loudness pitch speed
39 dither mcompand pitch skeleff vol39 dither mcompand polyphas splice
40 earwax mixer rate stat
40)41)
41set(formats_srcs42set(formats_srcs
42 8svx dat ima-fmt s3-fmt u4-fmt43 8svx dat ima-fmt s3-fmt u4-fmt
src/Makefile.am+1−1
@@ -252,7 +252,7 @@ libsfx_la_SOURCES = \ · 251 unmodified lines
252 band.h biquad.c biquad.h biquads.c chorus.c compand.c compandt.c \252 band.h biquad.c biquad.h biquads.c chorus.c compand.c compandt.c \
253 compandt.h contrast.c dcshift.c delay.c dither.c earwax.c echo.c \253 compandt.h contrast.c dcshift.c delay.c dither.c earwax.c echo.c \
254 echos.c effects.c effects.h effects_i.c fade.c fft4g.c fft4g.h \254 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 \
256 mixer.c noiseprof.c noisered.c noisered.h normalise.c output.c pad.c \256 mixer.c noiseprof.c noisered.c noisered.h normalise.c output.c pad.c \
257 pan.c phaser.c pitch.c polyphas.c rabbit.c rate.c \257 pan.c phaser.c pitch.c polyphas.c rabbit.c rate.c \
258 rate_filters.h rate_half_fir.h rate_poly_fir0.h rate_poly_fir.h \258 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
41#ifdef HAVE_LADSPA_H41#ifdef HAVE_LADSPA_H
42 EFFECT(ladspa)42 EFFECT(ladspa)
43#endif43#endif
44 EFFECT(loudness)
44 EFFECT(lowpass)45 EFFECT(lowpass)
45 EFFECT(mcompand)46 EFFECT(mcompand)
46 EFFECT(mixer)47 EFFECT(mixer)
src/effects_i.c+77−0
@@ -68,6 +68,56 @@ unsigned lsx_lcm(unsigned a, unsigned b) · 67 unmodified lines
68 return a * (b / lsx_gcd(a, b));68 return a * (b / lsx_gcd(a, b));
69}69}
70 70
71/* Numerical Recipes cubic spline */
72
73void 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
106double 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
71enum_item const lsx_wave_enum[] = {121enum_item const lsx_wave_enum[] = {
72 ENUM_ITEM(SOX_WAVE_,SINE)122 ENUM_ITEM(SOX_WAVE_,SINE)
73 ENUM_ITEM(SOX_WAVE_,TRIANGLE)123 ENUM_ITEM(SOX_WAVE_,TRIANGLE)
@@ -279,6 +329,15 @@ double lsx_bessel_I_0(double x) · 205 unmodified lines
279 return sum;329 return sum;
280}330}
281 331
332int 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
282#include "fft4g.h"341#include "fft4g.h"
283int * lsx_fft_br;342int * lsx_fft_br;
284double * lsx_fft_sc;343double * lsx_fft_sc;
@@ -384,6 +443,24 @@ void lsx_apply_bartlett(double h[], const int num_points) · 99 unmodified lines
384 }443 }
385}444}
386 445
446void 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
455void 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
387double lsx_kaiser_beta(double att)464double lsx_kaiser_beta(double att)
388{465{
389 if (att > 100 ) return .1117 * att - 1.11;466 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
24typedef struct {
25 int dft_length, num_taps;
26 double * coefs;
27} filter_t;
28
29typedef 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
37static 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
53static 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
104static 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
130static 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
158static 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
182static 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
203static 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
214sox_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
301 free(work);301 free(work);
302}302}
303 303
304static 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
313static void half_band_filter_init(rate_shared_t * p, unsigned which,304static void half_band_filter_init(rate_shared_t * p, unsigned which,
314 int num_taps, sample_t const h[], double Fp, double atten, int multiplier,305 int num_taps, sample_t const h[], double Fp, double atten, int multiplier,
315 double phase, sox_bool allow_aliasing)306 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
320 if (f->num_taps)311 if (f->num_taps)
321 return;312 return;
322 if (h) {313 if (h) {
323 dft_length = set_dft_length(num_taps);314 dft_length = lsx_set_dft_length(num_taps);
324 f->coefs = calloc(dft_length, sizeof(*f->coefs));315 f->coefs = calloc(dft_length, sizeof(*f->coefs));
325 for (i = 0; i < num_taps; ++i)316 for (i = 0; i < num_taps; ++i)
326 f->coefs[(i + dft_length - num_taps + 1) & (dft_length - 1)]317 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
337 fir_to_phase(&h, &num_taps, &f->post_peak, phase);328 fir_to_phase(&h, &num_taps, &f->post_peak, phase);
338 else f->post_peak = num_taps / 2;329 else f->post_peak = num_taps / 2;
339 330
340 dft_length = set_dft_length(num_taps);331 dft_length = lsx_set_dft_length(num_taps);
341 f->coefs = calloc(dft_length, sizeof(*f->coefs));332 f->coefs = calloc(dft_length, sizeof(*f->coefs));
342 for (i = 0; i < num_taps; ++i)333 for (i = 0; i < num_taps; ++i)
343 f->coefs[(i + dft_length - num_taps + 1) & (dft_length - 1)]334 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
61unsigned lsx_gcd(unsigned a, unsigned b);61unsigned lsx_gcd(unsigned a, unsigned b);
62unsigned lsx_lcm(unsigned a, unsigned b);62unsigned lsx_lcm(unsigned a, unsigned b);
63 63
64void lsx_prepare_spline3(double const * x, double const * y, int n,
65 double start_1d, double end_1d, double * y_2d);
66double lsx_spline3(double const * x, double const * y, double const * y_2d,
67 int n, double x1);
68
64double lsx_bessel_I_0(double x);69double lsx_bessel_I_0(double x);
70int lsx_set_dft_length(int num_taps);
65extern int * lsx_fft_br;71extern int * lsx_fft_br;
66extern double * lsx_fft_sc;72extern double * lsx_fft_sc;
67void lsx_safe_rdft(int len, int type, double * d);73void 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
72void lsx_apply_hann(double h[], const int num_points);78void lsx_apply_hann(double h[], const int num_points);
73void lsx_apply_hamming(double h[], const int num_points);79void lsx_apply_hamming(double h[], const int num_points);
74void lsx_apply_bartlett(double h[], const int num_points);80void lsx_apply_bartlett(double h[], const int num_points);
81void lsx_apply_blackman(double h[], const int num_points, double alpha);
82void lsx_apply_blackman_nutall(double h[], const int num_points);
75double lsx_kaiser_beta(double att);83double lsx_kaiser_beta(double att);
76void lsx_apply_kaiser(double h[], const int num_points, double beta);84void lsx_apply_kaiser(double h[], const int num_points, double beta);
77 85
src/test-srcs+1−9
@@ -20,15 +20,7 @@ test_converters () { · 19 unmodified lines
20 # Create input file20 # Create input file
21 $SOX -r $1 -n -twavpcm $IN synth 20 sin 0:`expr $1 / 2` gain -2 21 $SOX -r $1 -n -twavpcm $IN synth 20 sin 0:`expr $1 / 2` gain -2
22 for src in \22 for src in \
23 "polyphase" \23 "rate -vsL" \
24 "rabbit -c0" \
25 "rabbit -c1" \
26 "rate -h" \
27 "rate -v" \
28 "resample -q" \
29 "resample -ql" \
30 "ssrc" \
31 "ssrc_hp" \
32 ; do24 ; do
33 echo $src25 echo $src
34 case "$src" in26 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