1 /* Effect: change sample rate Copyright (c) 2008,12 robs@users.sourceforge.net
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.
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.
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
18 /* Inspired by, and builds upon some of the ideas presented in:
19 * `The Quest For The Perfect Resampler' by Laurent De Soras;
20 * http://ldesoras.free.fr/doc/articles/resampler-en.pdf */
22 #ifdef NDEBUG /* Enable assert always. */
23 #undef NDEBUG /* Must undef above assert.h or other that might include it. */
29 #include "dft_filter.h"
33 #define calloc lsx_calloc
34 #define malloc lsx_malloc
35 #define raw_coef_t double
37 #if 0 /* For float32 version, as used in foobar */
38 #define sample_t float
39 #define num_coefs4 ((num_coefs + 3) & ~3) /* align coefs for SSE */
40 #define coefs4_check(i) ((i) < num_coefs)
42 #define sample_t double
43 #define num_coefs4 num_coefs
44 #define coefs4_check(i) 1
48 #define hi_prec_clock_t long double /* __float128 is also a (slow) option */
50 #define hi_prec_clock_t double
53 #define coef(coef_p, interp_order, fir_len, phase_num, coef_interp_num, fir_coef_num) coef_p[(fir_len) * ((interp_order) + 1) * (phase_num) + ((interp_order) + 1) * (fir_coef_num) + (interp_order - coef_interp_num)]
55 static sample_t
* prepare_coefs(raw_coef_t
const * coefs
, int num_coefs
,
56 int num_phases
, int interp_order
, int multiplier
)
58 int i
, j
, length
= num_coefs4
* num_phases
;
59 sample_t
* result
= malloc(length
* (interp_order
+ 1) * sizeof(*result
));
60 double fm1
= coefs
[0], f1
= 0, f2
= 0;
62 for (i
= num_coefs4
- 1; i
>= 0; --i
)
63 for (j
= num_phases
- 1; j
>= 0; --j
) {
64 double f0
= fm1
, b
= 0, c
= 0, d
= 0; /* = 0 to kill compiler warning */
65 int pos
= i
* num_phases
+ j
- 1;
66 fm1
= coefs4_check(i
) && pos
> 0 ? coefs
[pos
- 1] * multiplier
: 0;
67 switch (interp_order
) {
68 case 1: b
= f1
- f0
; break;
69 case 2: b
= f1
- (.5 * (f2
+f0
) - f1
) - f0
; c
= .5 * (f2
+f0
) - f1
; break;
70 case 3: c
=.5*(f1
+fm1
)-f0
;d
=(1/6.)*(f2
-f1
+fm1
-f0
-4*c
);b
=f1
-f0
-d
-c
; break;
71 default: if (interp_order
) assert(0);
73 #define coef_coef(x) \
74 coef(result, interp_order, num_coefs4, j, x, num_coefs4 - 1 - i)
76 if (interp_order
> 0) coef_coef(1) = b
;
77 if (interp_order
> 1) coef_coef(2) = c
;
78 if (interp_order
> 2) coef_coef(3) = d
;
85 typedef struct { /* So generated filter coefs may be shared between channels */
86 sample_t
* poly_fir_coefs
;
87 dft_filter_t dft_filter
[2];
91 typedef void (* stage_fn_t
)(struct stage
* input
, fifo_t
* output
);
92 typedef struct stage
{
93 /* Common to all stage types: */
96 int pre
; /* Number of past samples to store */
97 int pre_post
; /* pre + number of future samples to store */
98 int preload
; /* Number of zero samples to pre-load the fifo */
99 double out_in_ratio
; /* For buffer management. */
101 /* For a stage with variable (run-time generated) filter coefs: */
102 rate_shared_t
* shared
;
103 int dft_filter_num
; /* Which, if any, of the 2 DFT filters to use */
105 /* For a stage with variable L/M: */
106 union { /* 32bit.32bit fixed point arithmetic */
107 #if defined(WORDS_BIGENDIAN)
108 struct {int32_t integer
; uint32_t fraction
;} parts
;
110 struct {uint32_t fraction
; int32_t integer
;} parts
;
113 #define MULT32 (65536. * 65536.)
115 hi_prec_clock_t hi_prec_clock
;
117 sox_bool use_hi_prec_clock
;
122 #define stage_occupancy(s) max(0, fifo_occupancy(&(s)->fifo) - (s)->pre_post)
123 #define stage_read_p(s) ((sample_t *)fifo_read_ptr(&(s)->fifo) + (s)->pre)
125 static void cubic_stage_fn(stage_t
* p
, fifo_t
* output_fifo
)
127 int i
, num_in
= stage_occupancy(p
), max_num_out
= 1 + num_in
*p
->out_in_ratio
;
128 sample_t
const * input
= stage_read_p(p
);
129 sample_t
* output
= fifo_reserve(output_fifo
, max_num_out
);
131 for (i
= 0; p
->at
.parts
.integer
< num_in
; ++i
, p
->at
.all
+= p
->step
.all
) {
132 sample_t
const * s
= input
+ p
->at
.parts
.integer
;
133 sample_t x
= p
->at
.parts
.fraction
* (1 / MULT32
);
134 sample_t b
= .5*(s
[1]+s
[-1])-*s
, a
= (1/6.)*(s
[2]-s
[1]+s
[-1]-*s
-4*b
);
135 sample_t c
= s
[1]-*s
-a
-b
;
136 output
[i
] = ((a
*x
+ b
)*x
+ c
)*x
+ *s
;
138 assert(max_num_out
- i
>= 0);
139 fifo_trim_by(output_fifo
, max_num_out
- i
);
140 fifo_read(&p
->fifo
, p
->at
.parts
.integer
, NULL
);
141 p
->at
.parts
.integer
= 0;
144 static void dft_stage_fn(stage_t
* p
, fifo_t
* output_fifo
)
146 sample_t
* output
, tmp
;
147 int i
, j
, num_in
= max(0, fifo_occupancy(&p
->fifo
));
148 rate_shared_t
const * s
= p
->shared
;
149 dft_filter_t
const * f
= &s
->dft_filter
[p
->dft_filter_num
];
150 int const overlap
= f
->num_taps
- 1;
152 while (p
->remL
+ p
->L
* num_in
>= f
->dft_length
) {
153 div_t divd
= div(f
->dft_length
- overlap
- p
->remL
+ p
->L
- 1, p
->L
);
154 sample_t
const * input
= fifo_read_ptr(&p
->fifo
);
155 fifo_read(&p
->fifo
, divd
.quot
, NULL
);
158 output
= fifo_reserve(output_fifo
, f
->dft_length
);
159 if (lsx_is_power_of_2(p
->L
)) { /* F-domain */
160 int portion
= f
->dft_length
/ p
->L
;
161 memcpy(output
, input
, (unsigned)portion
* sizeof(*output
));
162 lsx_safe_rdft(portion
, 1, output
);
163 for (i
= portion
+ 2; i
< (portion
<< 1); i
+= 2)
164 output
[i
] = output
[(portion
<< 1) - i
],
165 output
[i
+1] = -output
[(portion
<< 1) - i
+ 1];
166 output
[portion
] = output
[1];
167 output
[portion
+ 1] = 0;
168 output
[1] = output
[0];
169 for (portion
<<= 1; i
< f
->dft_length
; i
+= portion
, portion
<<= 1) {
170 memcpy(output
+ i
, output
, portion
* sizeof(*output
));
175 memcpy(output
, input
, f
->dft_length
* sizeof(*output
));
177 memset(output
, 0, f
->dft_length
* sizeof(*output
));
178 for (j
= 0, i
= p
->remL
; i
< f
->dft_length
; ++j
, i
+= p
->L
)
179 output
[i
] = input
[j
];
180 p
->remL
= p
->L
- 1 - divd
.rem
;
182 lsx_safe_rdft(f
->dft_length
, 1, output
);
184 output
[0] *= f
->coefs
[0];
185 if (p
->step
.parts
.integer
> 0) {
186 output
[1] *= f
->coefs
[1];
187 for (i
= 2; i
< f
->dft_length
; i
+= 2) {
189 output
[i
] = f
->coefs
[i
] * tmp
- f
->coefs
[i
+1] * output
[i
+1];
190 output
[i
+1] = f
->coefs
[i
+1] * tmp
+ f
->coefs
[i
] * output
[i
+1];
192 lsx_safe_rdft(f
->dft_length
, -1, output
);
193 if (p
->step
.parts
.integer
!= 1) {
194 for (j
= 0, i
= p
->remM
; i
< f
->dft_length
- overlap
; ++j
,
195 i
+= p
->step
.parts
.integer
)
196 output
[j
] = output
[i
];
197 p
->remM
= i
- (f
->dft_length
- overlap
);
198 fifo_trim_by(output_fifo
, f
->dft_length
- j
);
200 else fifo_trim_by(output_fifo
, overlap
);
202 else { /* F-domain */
203 int m
= -p
->step
.parts
.integer
;
204 for (i
= 2; i
< (f
->dft_length
>> m
); i
+= 2) {
206 output
[i
] = f
->coefs
[i
] * tmp
- f
->coefs
[i
+1] * output
[i
+1];
207 output
[i
+1] = f
->coefs
[i
+1] * tmp
+ f
->coefs
[i
] * output
[i
+1];
209 output
[1] = f
->coefs
[i
] * output
[i
] - f
->coefs
[i
+1] * output
[i
+1];
210 lsx_safe_rdft(f
->dft_length
>> m
, -1, output
);
211 fifo_trim_by(output_fifo
, (((1 << m
) - 1) * f
->dft_length
+ overlap
) >>m
);
216 static void dft_stage_init(
217 unsigned instance
, double Fp
, double Fs
, double Fn
, double att
,
218 double phase
, stage_t
* stage
, int L
, int M
)
220 dft_filter_t
* f
= &stage
->shared
->dft_filter
[instance
];
223 int num_taps
= 0, dft_length
, i
;
224 int k
= phase
== 50 && lsx_is_power_of_2(L
) && Fn
== L
? L
<< 1 : 4;
225 double * h
= lsx_design_lpf(Fp
, Fs
, Fn
, att
, &num_taps
, -k
, -1.);
228 lsx_fir_to_phase(&h
, &num_taps
, &f
->post_peak
, phase
);
229 else f
->post_peak
= num_taps
/ 2;
231 dft_length
= lsx_set_dft_length(num_taps
);
232 f
->coefs
= calloc(dft_length
, sizeof(*f
->coefs
));
233 for (i
= 0; i
< num_taps
; ++i
)
234 f
->coefs
[(i
+ dft_length
- num_taps
+ 1) & (dft_length
- 1)]
235 = h
[i
] / dft_length
* 2 * L
;
237 f
->num_taps
= num_taps
;
238 f
->dft_length
= dft_length
;
239 lsx_safe_rdft(dft_length
, 1, f
->coefs
);
240 lsx_debug("fir_len=%i dft_length=%i Fp=%g Fs=%g Fn=%g att=%g %i/%i",
241 num_taps
, dft_length
, Fp
, Fs
, Fn
, att
, L
, M
);
243 stage
->fn
= dft_stage_fn
;
244 stage
->preload
= f
->post_peak
/ L
;
245 stage
->remL
= f
->post_peak
% L
;
247 stage
->step
.parts
.integer
= abs(3-M
) == 1 && Fs
== 1? -M
/2 : M
;
248 stage
->dft_filter_num
= instance
;
251 #include "rate_filters.h"
255 uint64_t samples_in
, samples_out
;
260 #define pre_stage p->stages[shift]
261 #define arb_stage p->stages[shift + have_pre_stage]
262 #define post_stage p->stages[shift + have_pre_stage + have_arb_stage]
263 #define have_pre_stage (preM * preL != 1)
264 #define have_arb_stage (arbM * arbL != 1)
265 #define have_post_stage (postM * postL != 1)
267 #define TO_3dB(a) ((1.6e-6*a-7.5e-4)*a+.646)
268 #define LOW_Q_BW0_PC (67 + 5 / 8.)
271 rolloff_none
, rolloff_small
/* <= 0.01 dB */, rolloff_medium
/* <= 0.35 dB */
274 static void rate_init(
275 /* Private work areas (to be supplied by the client): */
276 rate_t
* p
, /* Per audio channel. */
277 rate_shared_t
* shared
, /* Between channels (undergoing same rate change)*/
279 /* Public parameters: Typically */
280 double factor
, /* Input rate divided by output rate. */
281 double bits
, /* Required bit-accuracy (pass + stop) 16|20|28 */
282 double phase
, /* Linear/minimum etc. filter phase. 50 */
283 double bw_pc
, /* Pass-band % (0dB pt.) to preserve. 91.3|98.4*/
284 double anti_aliasing_pc
, /* % bandwidth without aliasing 100 */
285 rolloff_t rolloff
, /* Pass-band roll-off small */
286 sox_bool maintain_3dB_pt
, /* true */
288 /* Primarily for test/development purposes: */
289 sox_bool use_hi_prec_clock
,/* Increase irrational ratio accuracy. false */
290 int interpolator
, /* Force a particular coef interpolator. -1 */
291 int max_coefs_size
, /* k bytes of coefs to try to keep below. 400 */
292 sox_bool noSmallIntOpt
) /* Disable small integer optimisations. false */
294 double att
= (bits
+ 1) * linear_to_dB(2.), attArb
= att
; /* pass + stop */
295 double tbw0
= 1 - bw_pc
/ 100, Fs_a
= 2 - anti_aliasing_pc
/ 100;
296 double arbM
= factor
, tbw_tighten
= 1;
297 int n
= 0, i
, preL
= 1, preM
= 1, shift
= 0, arbL
= 1, postL
= 1, postM
= 1;
298 sox_bool upsample
= sox_false
, rational
= sox_false
, iOpt
= !noSmallIntOpt
;
299 int mode
= rolloff
> rolloff_small
? factor
> 1 || bw_pc
> LOW_Q_BW0_PC
:
300 ceil(2 + (bits
- 17) / 4);
304 assert(!bits
|| (15 <= bits
&& bits
<= 33));
305 assert(0 <= phase
&& phase
<= 100);
306 assert(53 <= bw_pc
&& bw_pc
<= 100);
307 assert(85 <= anti_aliasing_pc
&& anti_aliasing_pc
<= 100);
310 if (bits
) while (!n
++) { /* Determine stages: */
311 int try, L
, M
, x
, maxL
= interpolator
> 0? 1 : mode
? 2048 :
312 ceil(max_coefs_size
* 1000. / (U100_l
* sizeof(sample_t
)));
313 double d
, epsilon
= 0, frac
;
315 for (i
= arbM
* .5, shift
= 0; i
>>= 1; arbM
*= .5, ++shift
);
316 preM
= upsample
|| (arbM
> 1.5 && arbM
< 2);
317 postM
= 1 + (arbM
> 1 && preM
), arbM
/= postM
;
318 preL
= 1 + (!preM
&& arbM
< 2) + (upsample
&& mode
), arbM
*= preL
;
319 if ((frac
= arbM
- (int)arbM
))
320 epsilon
= fabs((uint32_t)(frac
* MULT32
+ .5) / (frac
* MULT32
) - 1);
321 for (i
= 1, rational
= !frac
; i
<= maxL
&& !rational
; ++i
) {
322 d
= frac
* i
, try = d
+ .5;
323 if ((rational
= fabs(try / d
- 1) <= epsilon
)) { /* No long doubles! */
325 arbM
= ceil(arbM
), shift
+= arbM
> 2, arbM
/= 1 + (arbM
> 2);
326 else arbM
= i
* (int)arbM
+ try, arbL
= i
;
329 L
= preL
* arbL
, M
= arbM
* postM
, x
= (L
|M
)&1, L
>>= !x
, M
>>= !x
;
330 if (iOpt
&& postL
== 1 && (d
= preL
* arbL
/ arbM
) > 4 && d
!= 5) {
331 for (postL
= 4, i
= d
/ 16; i
>>= 1; postL
<<= 1);
332 arbM
= arbM
* postL
/ arbL
/ preL
, arbL
= 1, n
= 0;
333 } else if (rational
&& (max(L
, M
) < 3 + 2 * iOpt
|| L
* M
< 6 * iOpt
))
334 preL
= L
, preM
= M
, arbM
= arbL
= postM
= 1;
335 if (!mode
&& (!rational
|| !n
))
339 p
->num_stages
= shift
+ have_pre_stage
+ have_arb_stage
+ have_post_stage
;
344 p
->stages
= calloc(p
->num_stages
+ 1, sizeof(*p
->stages
));
345 for (i
= 0; i
< p
->num_stages
; ++i
)
346 p
->stages
[i
].shared
= shared
;
348 if ((n
= p
->num_stages
) > 1) { /* Att. budget: */
350 att
+= linear_to_dB(2.), attArb
= att
, --n
;
351 att
+= linear_to_dB((double)n
);
354 for (n
= 0; n
+ 1u < array_length(half_firs
) && att
> half_firs
[n
].att
; ++n
);
355 for (i
= 0, s
= p
->stages
; i
< shift
; ++i
, ++s
) {
356 s
->fn
= half_firs
[n
].fn
;
357 s
->pre_post
= 4 * half_firs
[n
].num_coefs
;
358 s
->preload
= s
->pre
= s
->pre_post
>> 1;
361 if (have_pre_stage
) {
362 if (maintain_3dB_pt
&& have_post_stage
) { /* Trans. bands overlapping. */
363 double tbw3
= tbw0
* TO_3dB(att
); /* TODO: consider Fs_a. */
364 double x
= ((2.1429e-4 - 5.2083e-7 * att
) * att
- .015863) * att
+ 3.95;
365 x
= att
* pow((tbw0
- tbw3
) / (postM
/ (factor
* postL
) - 1 + tbw0
), x
);
367 tbw_tighten
= ((4.3074e-3 - 3.9121e-4 * x
) * x
- .040009) * x
+ 1.0014;
368 lsx_debug("x=%g tbw_tighten=%g", x
, tbw_tighten
);
371 dft_stage_init(0, 1 - tbw0
* tbw_tighten
, Fs_a
, preM
? max(preL
, preM
) :
372 arbM
/ arbL
, att
, phase
, &pre_stage
, preL
, max(preM
, 1));
375 if (!bits
) { /* Quick and dirty arb stage: */
376 arb_stage
.fn
= cubic_stage_fn
;
377 arb_stage
.step
.all
= arbM
* MULT32
+ .5;
378 arb_stage
.pre_post
= max(3, arb_stage
.step
.parts
.integer
);
379 arb_stage
.preload
= arb_stage
.pre
= 1;
380 arb_stage
.out_in_ratio
= MULT32
* arbL
/ arb_stage
.step
.all
;
382 else if (have_arb_stage
) { /* Higher quality arb stage: */
383 poly_fir_t
const * f
= &poly_firs
[6*(upsample
+ !!preM
) + mode
- !upsample
];
384 int order
, num_coefs
= f
->interp
[0].scalar
, phase_bits
, phases
, coefs_size
;
385 double x
= .5, at
, Fp
, Fs
, Fn
, mult
= upsample
? 1 : arbL
/ arbM
;
386 poly_fir1_t
const * f1
;
388 Fn
= !upsample
&& preM
? x
= arbM
/ arbL
: 1;
389 Fp
= !preM
? mult
: mode
? .5 : 1;
390 Fs
= 2 - Fp
; /* Ignore Fs_a; it would have little benefit here. */
392 if (rolloff
> rolloff_small
&& mode
)
393 Fp
= !preM
? mult
* .5 - .125 : mult
* .05 + .1;
394 else if (rolloff
== rolloff_small
)
395 Fp
= Fs
- (Fs
- .148 * x
- Fp
* .852) * (.00813 * bits
+ .973);
397 i
= (interpolator
< 0? !rational
: max(interpolator
, !rational
)) - 1;
399 f1
= &f
->interp
[++i
];
402 arbM
/= arbL
, arbL
= 1, rational
= sox_false
;
403 phase_bits
= ceil(f1
->scalar
+ log(mult
)/log(2.));
404 phases
= !rational
? (1 << phase_bits
) : arbL
;
405 if (!f
->interp
[0].scalar
) {
406 int phases0
= max(phases
, 19), n0
= 0;
407 lsx_design_lpf(Fp
, Fs
, -Fn
, attArb
, &n0
, phases0
, f
->beta
);
408 num_coefs
= n0
/ phases0
+ 1, num_coefs
+= num_coefs
& !preM
;
410 if ((num_coefs
& 1) && rational
&& (arbL
& 1))
411 phases
<<= 1, arbL
<<= 1, arbM
*= 2;
412 at
= arbL
* .5 * (num_coefs
& 1);
413 order
= i
+ (i
&& mode
> 4);
414 coefs_size
= num_coefs4
* phases
* (order
+ 1) * sizeof(sample_t
);
415 } while (interpolator
< 0 && i
< 2 && f
->interp
[i
+1].fn
&&
416 coefs_size
/ 1000 > max_coefs_size
);
418 if (!arb_stage
.shared
->poly_fir_coefs
) {
419 int num_taps
= num_coefs
* phases
- 1;
420 raw_coef_t
* coefs
= lsx_design_lpf(
421 Fp
, Fs
, Fn
, attArb
, &num_taps
, phases
, f
->beta
);
422 arb_stage
.shared
->poly_fir_coefs
= prepare_coefs(
423 coefs
, num_coefs
, phases
, order
, 1);
424 lsx_debug("fir_len=%i phases=%i coef_interp=%i size=%s",
425 num_coefs
, phases
, order
, lsx_sigfigs3((double)coefs_size
));
428 arb_stage
.fn
= f1
->fn
;
429 arb_stage
.pre_post
= num_coefs4
- 1;
430 arb_stage
.preload
= (num_coefs
- 1) >> 1;
431 arb_stage
.n
= num_coefs4
;
432 arb_stage
.phase_bits
= phase_bits
;
434 arb_stage
.use_hi_prec_clock
= mode
> 1 && use_hi_prec_clock
&& !rational
;
435 if (arb_stage
.use_hi_prec_clock
) {
436 arb_stage
.at
.hi_prec_clock
= at
;
437 arb_stage
.step
.hi_prec_clock
= arbM
;
438 arb_stage
.out_in_ratio
= arbL
/ arb_stage
.step
.hi_prec_clock
;
440 arb_stage
.at
.all
= at
* MULT32
+ .5;
441 arb_stage
.step
.all
= arbM
* MULT32
+ .5;
442 arb_stage
.out_in_ratio
= MULT32
* arbL
/ arb_stage
.step
.all
;
447 dft_stage_init(1, 1 - (1 - (1 - tbw0
) *
448 (upsample
? factor
* postL
/ postM
: 1)) * tbw_tighten
, Fs_a
,
449 (double)max(postL
, postM
), att
, phase
, &post_stage
, postL
, postM
);
451 for (i
= 0, s
= p
->stages
; i
< p
->num_stages
; ++i
, ++s
) {
452 fifo_create(&s
->fifo
, (int)sizeof(sample_t
));
453 memset(fifo_reserve(&s
->fifo
, s
->preload
), 0, sizeof(sample_t
)*s
->preload
);
454 lsx_debug("%5i|%-5i preload=%i remL=%i",
455 s
->pre
, s
->pre_post
- s
->pre
, s
->preload
, s
->remL
);
457 fifo_create(&s
->fifo
, (int)sizeof(sample_t
));
460 static void rate_process(rate_t
* p
)
462 stage_t
* stage
= p
->stages
;
465 for (i
= 0; i
< p
->num_stages
; ++i
, ++stage
)
466 stage
->fn(stage
, &(stage
+1)->fifo
);
469 static sample_t
* rate_input(rate_t
* p
, sample_t
const * samples
, size_t n
)
472 return fifo_write(&p
->stages
[0].fifo
, (int)n
, samples
);
475 static sample_t
const * rate_output(rate_t
* p
, sample_t
* samples
, size_t * n
)
477 fifo_t
* fifo
= &p
->stages
[p
->num_stages
].fifo
;
478 p
->samples_out
+= *n
= min(*n
, (size_t)fifo_occupancy(fifo
));
479 return fifo_read(fifo
, (int)*n
, samples
);
482 static void rate_flush(rate_t
* p
)
484 fifo_t
* fifo
= &p
->stages
[p
->num_stages
].fifo
;
485 uint64_t samples_out
= p
->samples_in
/ p
->factor
+ .5;
486 size_t remaining
= samples_out
> p
->samples_out
?
487 (size_t)(samples_out
- p
->samples_out
) : 0;
488 sample_t
* buff
= calloc(1024, sizeof(*buff
));
491 while ((size_t)fifo_occupancy(fifo
) < remaining
) {
492 rate_input(p
, buff
, (size_t) 1024);
495 fifo_trim_to(fifo
, (int)remaining
);
501 static void rate_close(rate_t
* p
)
503 rate_shared_t
*shared
;
509 shared
= p
->stages
[0].shared
;
511 for (i
= 0; i
<= p
->num_stages
; ++i
)
512 fifo_delete(&p
->stages
[i
].fifo
);
513 free(shared
->dft_filter
[0].coefs
);
514 free(shared
->dft_filter
[1].coefs
);
515 free(shared
->poly_fir_coefs
);
516 memset(shared
, 0, sizeof(*shared
));
520 /*------------------------------- SoX Wrapper --------------------------------*/
524 int rolloff
, coef_interp
, max_coefs_size
;
525 double bit_depth
, phase
, bw_0dB_pc
, anti_aliasing_pc
;
526 sox_bool use_hi_prec_clock
, noIOpt
, given_0dB_pt
;
528 rate_shared_t shared
, * shared_ptr
;
531 static int create(sox_effect_t
* effp
, int argc
, char **argv
)
533 priv_t
* p
= (priv_t
*) effp
->priv
;
535 char * dummy_p
, * found_at
;
536 char const * opts
= "+i:c:b:B:A:p:Q:R:d:MILafnost" "qlmghevu";
537 char const * qopts
= strchr(opts
, 'q');
538 double rej
= 0, bw_3dB_pc
= 0;
539 sox_bool allow_aliasing
= sox_false
;
540 lsx_getopt_t optstate
;
541 lsx_getopt_init(argc
, argv
, opts
, NULL
, lsx_getopt_flag_none
, 1, &optstate
);
543 p
->coef_interp
= quality
= -1;
544 p
->rolloff
= rolloff_small
;
546 p
->max_coefs_size
= 400;
547 p
->shared_ptr
= &p
->shared
;
549 while ((c
= lsx_getopt(&optstate
)) != -1) switch (c
) {
550 GETOPT_NUMERIC(optstate
, 'i', coef_interp
, -1, 2)
551 GETOPT_NUMERIC(optstate
, 'c', max_coefs_size
, 100, INT_MAX
)
552 GETOPT_NUMERIC(optstate
, 'p', phase
, 0, 100)
553 GETOPT_NUMERIC(optstate
, 'B', bw_0dB_pc
, 53, 99.5)
554 GETOPT_NUMERIC(optstate
, 'A', anti_aliasing_pc
, 85, 100)
555 GETOPT_NUMERIC(optstate
, 'd', bit_depth
, 15, 33)
556 GETOPT_LOCAL_NUMERIC(optstate
, 'b', bw_3dB_pc
, 74, 99.7)
557 GETOPT_LOCAL_NUMERIC(optstate
, 'R', rej
, 90, 200)
558 GETOPT_LOCAL_NUMERIC(optstate
, 'Q', quality
, 0, 7)
559 case 'M': p
->phase
= 0; break;
560 case 'I': p
->phase
= 25; break;
561 case 'L': p
->phase
= 50; break;
562 case 'a': allow_aliasing
= sox_true
; break;
563 case 'f': p
->rolloff
= rolloff_none
; break;
564 case 'n': p
->noIOpt
= sox_true
; break;
565 case 's': bw_3dB_pc
= 99; break;
566 case 't': p
->use_hi_prec_clock
= sox_true
; break;
568 if ((found_at
= strchr(qopts
, c
)))
569 quality
= found_at
- qopts
;
571 lsx_fail("unknown option `-%c'", optstate
.opt
);
572 return lsx_usage(effp
);
575 argc
-= optstate
.ind
, argv
+= optstate
.ind
;
577 if ((unsigned)quality
< 2 && (p
->bw_0dB_pc
|| bw_3dB_pc
|| p
->phase
!= 50 ||
578 allow_aliasing
|| rej
|| p
->bit_depth
|| p
->anti_aliasing_pc
)) {
579 lsx_fail("override options not allowed with this quality level");
582 if (quality
< 0 && rej
== 0 && p
->bit_depth
== 0)
585 p
->bit_depth
= rej
/ linear_to_dB(2.);
588 p
->bit_depth
= quality
? 16 + 4 * max(quality
- 3, 0) : 0;
590 p
->rolloff
= rolloff_medium
;
592 rej
= p
->bit_depth
* linear_to_dB(2.);
595 if (bw_3dB_pc
&& p
->bw_0dB_pc
) {
596 lsx_fail("conflicting bandwidth options");
599 allow_aliasing
|= p
->anti_aliasing_pc
!= 0;
600 if (!bw_3dB_pc
&& !p
->bw_0dB_pc
)
601 p
->bw_0dB_pc
= quality
== 1? LOW_Q_BW0_PC
: 100 - 5 / TO_3dB(rej
);
602 else if (bw_3dB_pc
&& bw_3dB_pc
< 85 && allow_aliasing
) {
603 lsx_fail("minimum allowed 3dB bandwidth with aliasing is %g%%", 85.);
606 else if (p
->bw_0dB_pc
&& p
->bw_0dB_pc
< 74 && allow_aliasing
) {
607 lsx_fail("minimum allowed bandwidth with aliasing is %g%%", 74.);
611 p
->bw_0dB_pc
= 100 - (100 - bw_3dB_pc
) / TO_3dB(rej
);
613 bw_3dB_pc
= 100 - (100 - p
->bw_0dB_pc
) * TO_3dB(rej
);
614 p
->given_0dB_pt
= sox_true
;
616 p
->anti_aliasing_pc
= p
->anti_aliasing_pc
? p
->anti_aliasing_pc
:
617 allow_aliasing
? bw_3dB_pc
: 100;
620 if ((p
->out_rate
= lsx_parse_frequency(*argv
, &dummy_p
)) <= 0 || *dummy_p
)
621 return lsx_usage(effp
);
623 effp
->out_signal
.rate
= p
->out_rate
;
625 return argc
? lsx_usage(effp
) : SOX_SUCCESS
;
628 static int start(sox_effect_t
* effp
)
630 priv_t
* p
= (priv_t
*) effp
->priv
;
631 double out_rate
= p
->out_rate
!= 0 ? p
->out_rate
: effp
->out_signal
.rate
;
633 if (effp
->in_signal
.rate
== out_rate
)
636 if (effp
->in_signal
.mult
)
637 *effp
->in_signal
.mult
*= .705; /* 1/(2/sinc(pi/3)-1); see De Soras 4.1.2 */
639 effp
->out_signal
.channels
= effp
->in_signal
.channels
;
640 effp
->out_signal
.rate
= out_rate
;
641 rate_init(&p
->rate
, p
->shared_ptr
, effp
->in_signal
.rate
/out_rate
,p
->bit_depth
,
642 p
->phase
, p
->bw_0dB_pc
, p
->anti_aliasing_pc
, p
->rolloff
, !p
->given_0dB_pt
,
643 p
->use_hi_prec_clock
, p
->coef_interp
, p
->max_coefs_size
, p
->noIOpt
);
645 if (!p
->rate
.num_stages
) {
646 lsx_warn("input and output rates too close, skipping resampling");
653 static int flow(sox_effect_t
* effp
, const sox_sample_t
* ibuf
,
654 sox_sample_t
* obuf
, size_t * isamp
, size_t * osamp
)
656 priv_t
* p
= (priv_t
*)effp
->priv
;
657 size_t odone
= *osamp
;
659 sample_t
const * s
= rate_output(&p
->rate
, NULL
, &odone
);
660 lsx_save_samples(obuf
, s
, odone
, &effp
->clips
);
662 if (*isamp
&& odone
< *osamp
) {
663 sample_t
* t
= rate_input(&p
->rate
, NULL
, *isamp
);
664 lsx_load_samples(t
, ibuf
, *isamp
);
665 rate_process(&p
->rate
);
672 static int drain(sox_effect_t
* effp
, sox_sample_t
* obuf
, size_t * osamp
)
674 priv_t
* p
= (priv_t
*)effp
->priv
;
675 static size_t isamp
= 0;
676 rate_flush(&p
->rate
);
677 return flow(effp
, 0, obuf
, &isamp
, osamp
);
680 static int stop(sox_effect_t
* effp
)
682 priv_t
* p
= (priv_t
*) effp
->priv
;
683 rate_close(&p
->rate
);
687 sox_effect_handler_t
const * lsx_rate_effect_fn(void)
689 static sox_effect_handler_t handler
= {
690 "rate", 0, SOX_EFF_RATE
, create
, start
, flow
, drain
, stop
, 0, sizeof(priv_t
)
692 static char const * lines
[] = {
693 "[-q|-l|-m|-h|-v] [override-options] RATE[k]",
695 " QUALITY WIDTH REJ dB TYPICAL USE",
696 " -q quick n/a ~30 @ Fs/4 playback on ancient hardware",
697 " -l low 80% 100 playback on old hardware",
698 " -m medium 95% 100 audio playback",
699 " -h high (default) 95% 125 16-bit mastering (use with dither)",
700 " -v very high 95% 175 24-bit mastering",
701 " OVERRIDE OPTIONS (only with -m, -h, -v)",
702 " -M/-I/-L Phase response = minimum/intermediate/linear(default)",
703 " -s Steep filter (band-width = 99%)",
704 " -a Allow aliasing above the pass-band",
705 " -b 74-99.7 Any band-width %",
706 " -p 0-100 Any phase response (0 = minimum, 25 = intermediate,",
707 " 50 = linear, 100 = maximum)",
710 handler
.usage
= lsx_usage_lines(&usage
, lines
, array_length(lines
));