1 /*
2 * audio resampling
3 * Copyright (c) 2004-2012 Michael Niedermayer <michaelni@gmx.at>
4 * bessel function: Copyright (c) 2006 Xiaogang Zhang
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file
25 * audio resampling
26 * @author Michael Niedermayer <michaelni@gmx.at>
27 */
28
29 #include "libavutil/avassert.h"
30 #include "libavutil/cpu.h"
31 #include "resample.h"
32
eval_poly(const double * coeff,int size,double x)33 static inline double eval_poly(const double *coeff, int size, double x) {
34 double sum = coeff[size-1];
35 int i;
36 for (i = size-2; i >= 0; --i) {
37 sum *= x;
38 sum += coeff[i];
39 }
40 return sum;
41 }
42
43 /**
44 * 0th order modified bessel function of the first kind.
45 * Algorithm taken from the Boost project, source:
46 * https://searchcode.com/codesearch/view/14918379/
47 * Use, modification and distribution are subject to the
48 * Boost Software License, Version 1.0 (see notice below).
49 * Boost Software License - Version 1.0 - August 17th, 2003
50 Permission is hereby granted, free of charge, to any person or organization
51 obtaining a copy of the software and accompanying documentation covered by
52 this license (the "Software") to use, reproduce, display, distribute,
53 execute, and transmit the Software, and to prepare derivative works of the
54 Software, and to permit third-parties to whom the Software is furnished to
55 do so, all subject to the following:
56
57 The copyright notices in the Software and this entire statement, including
58 the above license grant, this restriction and the following disclaimer,
59 must be included in all copies of the Software, in whole or in part, and
60 all derivative works of the Software, unless such copies or derivative
61 works are solely in the form of machine-executable object code generated by
62 a source language processor.
63
64 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
65 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
66 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
67 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
68 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
69 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
70 DEALINGS IN THE SOFTWARE.
71 */
72
bessel(double x)73 static double bessel(double x) {
74 // Modified Bessel function of the first kind of order zero
75 // minimax rational approximations on intervals, see
76 // Blair and Edwards, Chalk River Report AECL-4928, 1974
77 static const double p1[] = {
78 -2.2335582639474375249e+15,
79 -5.5050369673018427753e+14,
80 -3.2940087627407749166e+13,
81 -8.4925101247114157499e+11,
82 -1.1912746104985237192e+10,
83 -1.0313066708737980747e+08,
84 -5.9545626019847898221e+05,
85 -2.4125195876041896775e+03,
86 -7.0935347449210549190e+00,
87 -1.5453977791786851041e-02,
88 -2.5172644670688975051e-05,
89 -3.0517226450451067446e-08,
90 -2.6843448573468483278e-11,
91 -1.5982226675653184646e-14,
92 -5.2487866627945699800e-18,
93 };
94 static const double q1[] = {
95 -2.2335582639474375245e+15,
96 7.8858692566751002988e+12,
97 -1.2207067397808979846e+10,
98 1.0377081058062166144e+07,
99 -4.8527560179962773045e+03,
100 1.0,
101 };
102 static const double p2[] = {
103 -2.2210262233306573296e-04,
104 1.3067392038106924055e-02,
105 -4.4700805721174453923e-01,
106 5.5674518371240761397e+00,
107 -2.3517945679239481621e+01,
108 3.1611322818701131207e+01,
109 -9.6090021968656180000e+00,
110 };
111 static const double q2[] = {
112 -5.5194330231005480228e-04,
113 3.2547697594819615062e-02,
114 -1.1151759188741312645e+00,
115 1.3982595353892851542e+01,
116 -6.0228002066743340583e+01,
117 8.5539563258012929600e+01,
118 -3.1446690275135491500e+01,
119 1.0,
120 };
121 double y, r, factor;
122 if (x == 0)
123 return 1.0;
124 x = fabs(x);
125 if (x <= 15) {
126 y = x * x;
127 return eval_poly(p1, FF_ARRAY_ELEMS(p1), y) / eval_poly(q1, FF_ARRAY_ELEMS(q1), y);
128 }
129 else {
130 y = 1 / x - 1.0 / 15;
131 r = eval_poly(p2, FF_ARRAY_ELEMS(p2), y) / eval_poly(q2, FF_ARRAY_ELEMS(q2), y);
132 factor = exp(x) / sqrt(x);
133 return factor * r;
134 }
135 }
136
137 /**
138 * builds a polyphase filterbank.
139 * @param factor resampling factor
140 * @param scale wanted sum of coefficients for each filter
141 * @param filter_type filter type
142 * @param kaiser_beta kaiser window beta
143 * @return 0 on success, negative on error
144 */
build_filter(ResampleContext * c,void * filter,double factor,int tap_count,int alloc,int phase_count,int scale,int filter_type,double kaiser_beta)145 static int build_filter(ResampleContext *c, void *filter, double factor, int tap_count, int alloc, int phase_count, int scale,
146 int filter_type, double kaiser_beta){
147 int ph, i;
148 int ph_nb = phase_count % 2 ? phase_count : phase_count / 2 + 1;
149 double x, y, w, t, s;
150 double *tab = av_malloc_array(tap_count+1, sizeof(*tab));
151 double *sin_lut = av_malloc_array(ph_nb, sizeof(*sin_lut));
152 const int center= (tap_count-1)/2;
153 double norm = 0;
154 int ret = AVERROR(ENOMEM);
155
156 if (!tab || !sin_lut)
157 goto fail;
158
159 av_assert0(tap_count == 1 || tap_count % 2 == 0);
160
161 /* if upsampling, only need to interpolate, no filter */
162 if (factor > 1.0)
163 factor = 1.0;
164
165 if (factor == 1.0) {
166 for (ph = 0; ph < ph_nb; ph++)
167 sin_lut[ph] = sin(M_PI * ph / phase_count) * (center & 1 ? 1 : -1);
168 }
169 for(ph = 0; ph < ph_nb; ph++) {
170 s = sin_lut[ph];
171 for(i=0;i<tap_count;i++) {
172 x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
173 if (x == 0) y = 1.0;
174 else if (factor == 1.0)
175 y = s / x;
176 else
177 y = sin(x) / x;
178 switch(filter_type){
179 case SWR_FILTER_TYPE_CUBIC:{
180 const float d= -0.5; //first order derivative = -0.5
181 x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
182 if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x);
183 else y= d*(-4 + 8*x - 5*x*x + x*x*x);
184 break;}
185 case SWR_FILTER_TYPE_BLACKMAN_NUTTALL:
186 w = 2.0*x / (factor*tap_count);
187 t = -cos(w);
188 y *= 0.3635819 - 0.4891775 * t + 0.1365995 * (2*t*t-1) - 0.0106411 * (4*t*t*t - 3*t);
189 break;
190 case SWR_FILTER_TYPE_KAISER:
191 w = 2.0*x / (factor*tap_count*M_PI);
192 y *= bessel(kaiser_beta*sqrt(FFMAX(1-w*w, 0)));
193 break;
194 default:
195 av_assert0(0);
196 }
197
198 tab[i] = y;
199 s = -s;
200 if (!ph)
201 norm += y;
202 }
203
204 /* normalize so that an uniform color remains the same */
205 switch(c->format){
206 case AV_SAMPLE_FMT_S16P:
207 for(i=0;i<tap_count;i++)
208 ((int16_t*)filter)[ph * alloc + i] = av_clip_int16(lrintf(tab[i] * scale / norm));
209 if (phase_count % 2) break;
210 for (i = 0; i < tap_count; i++)
211 ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int16_t*)filter)[ph * alloc + i];
212 break;
213 case AV_SAMPLE_FMT_S32P:
214 for(i=0;i<tap_count;i++)
215 ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm));
216 if (phase_count % 2) break;
217 for (i = 0; i < tap_count; i++)
218 ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int32_t*)filter)[ph * alloc + i];
219 break;
220 case AV_SAMPLE_FMT_FLTP:
221 for(i=0;i<tap_count;i++)
222 ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm;
223 if (phase_count % 2) break;
224 for (i = 0; i < tap_count; i++)
225 ((float*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((float*)filter)[ph * alloc + i];
226 break;
227 case AV_SAMPLE_FMT_DBLP:
228 for(i=0;i<tap_count;i++)
229 ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm;
230 if (phase_count % 2) break;
231 for (i = 0; i < tap_count; i++)
232 ((double*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((double*)filter)[ph * alloc + i];
233 break;
234 }
235 }
236 #if 0
237 {
238 #define LEN 1024
239 int j,k;
240 double sine[LEN + tap_count];
241 double filtered[LEN];
242 double maxff=-2, minff=2, maxsf=-2, minsf=2;
243 for(i=0; i<LEN; i++){
244 double ss=0, sf=0, ff=0;
245 for(j=0; j<LEN+tap_count; j++)
246 sine[j]= cos(i*j*M_PI/LEN);
247 for(j=0; j<LEN; j++){
248 double sum=0;
249 ph=0;
250 for(k=0; k<tap_count; k++)
251 sum += filter[ph * tap_count + k] * sine[k+j];
252 filtered[j]= sum / (1<<FILTER_SHIFT);
253 ss+= sine[j + center] * sine[j + center];
254 ff+= filtered[j] * filtered[j];
255 sf+= sine[j + center] * filtered[j];
256 }
257 ss= sqrt(2*ss/LEN);
258 ff= sqrt(2*ff/LEN);
259 sf= 2*sf/LEN;
260 maxff= FFMAX(maxff, ff);
261 minff= FFMIN(minff, ff);
262 maxsf= FFMAX(maxsf, sf);
263 minsf= FFMIN(minsf, sf);
264 if(i%11==0){
265 av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf);
266 minff=minsf= 2;
267 maxff=maxsf= -2;
268 }
269 }
270 }
271 #endif
272
273 ret = 0;
274 fail:
275 av_free(tab);
276 av_free(sin_lut);
277 return ret;
278 }
279
resample_free(ResampleContext ** cc)280 static void resample_free(ResampleContext **cc){
281 ResampleContext *c = *cc;
282 if(!c)
283 return;
284 av_freep(&c->filter_bank);
285 av_freep(cc);
286 }
287
resample_init(ResampleContext * c,int out_rate,int in_rate,int filter_size,int phase_shift,int linear,double cutoff0,enum AVSampleFormat format,enum SwrFilterType filter_type,double kaiser_beta,double precision,int cheby,int exact_rational)288 static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
289 double cutoff0, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta,
290 double precision, int cheby, int exact_rational)
291 {
292 double cutoff = cutoff0? cutoff0 : 0.97;
293 double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
294 int phase_count= 1<<phase_shift;
295 int phase_count_compensation = phase_count;
296 int filter_length = FFMAX((int)ceil(filter_size/factor), 1);
297
298 if (filter_length > 1)
299 filter_length = FFALIGN(filter_length, 2);
300
301 if (exact_rational) {
302 int phase_count_exact, phase_count_exact_den;
303
304 av_reduce(&phase_count_exact, &phase_count_exact_den, out_rate, in_rate, INT_MAX);
305 if (phase_count_exact <= phase_count) {
306 phase_count_compensation = phase_count_exact * (phase_count / phase_count_exact);
307 phase_count = phase_count_exact;
308 }
309 }
310
311 if (!c || c->phase_count != phase_count || c->linear!=linear || c->factor != factor
312 || c->filter_length != filter_length || c->format != format
313 || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) {
314 resample_free(&c);
315 c = av_mallocz(sizeof(*c));
316 if (!c)
317 return NULL;
318
319 c->format= format;
320
321 c->felem_size= av_get_bytes_per_sample(c->format);
322
323 switch(c->format){
324 case AV_SAMPLE_FMT_S16P:
325 c->filter_shift = 15;
326 break;
327 case AV_SAMPLE_FMT_S32P:
328 c->filter_shift = 30;
329 break;
330 case AV_SAMPLE_FMT_FLTP:
331 case AV_SAMPLE_FMT_DBLP:
332 c->filter_shift = 0;
333 break;
334 default:
335 av_log(NULL, AV_LOG_ERROR, "Unsupported sample format\n");
336 av_assert0(0);
337 }
338
339 if (filter_size/factor > INT32_MAX/256) {
340 av_log(NULL, AV_LOG_ERROR, "Filter length too large\n");
341 goto error;
342 }
343
344 c->phase_count = phase_count;
345 c->linear = linear;
346 c->factor = factor;
347 c->filter_length = filter_length;
348 c->filter_alloc = FFALIGN(c->filter_length, 8);
349 c->filter_bank = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size);
350 c->filter_type = filter_type;
351 c->kaiser_beta = kaiser_beta;
352 c->phase_count_compensation = phase_count_compensation;
353 if (!c->filter_bank)
354 goto error;
355 if (build_filter(c, (void*)c->filter_bank, factor, c->filter_length, c->filter_alloc, phase_count, 1<<c->filter_shift, filter_type, kaiser_beta))
356 goto error;
357 memcpy(c->filter_bank + (c->filter_alloc*phase_count+1)*c->felem_size, c->filter_bank, (c->filter_alloc-1)*c->felem_size);
358 memcpy(c->filter_bank + (c->filter_alloc*phase_count )*c->felem_size, c->filter_bank + (c->filter_alloc - 1)*c->felem_size, c->felem_size);
359 }
360
361 c->compensation_distance= 0;
362 if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2))
363 goto error;
364 while (c->dst_incr < (1<<20) && c->src_incr < (1<<20)) {
365 c->dst_incr *= 2;
366 c->src_incr *= 2;
367 }
368 c->ideal_dst_incr = c->dst_incr;
369 c->dst_incr_div = c->dst_incr / c->src_incr;
370 c->dst_incr_mod = c->dst_incr % c->src_incr;
371
372 c->index= -phase_count*((c->filter_length-1)/2);
373 c->frac= 0;
374
375 swri_resample_dsp_init(c);
376
377 return c;
378 error:
379 av_freep(&c->filter_bank);
380 av_free(c);
381 return NULL;
382 }
383
rebuild_filter_bank_with_compensation(ResampleContext * c)384 static int rebuild_filter_bank_with_compensation(ResampleContext *c)
385 {
386 uint8_t *new_filter_bank;
387 int new_src_incr, new_dst_incr;
388 int phase_count = c->phase_count_compensation;
389 int ret;
390
391 if (phase_count == c->phase_count)
392 return 0;
393
394 av_assert0(!c->frac && !c->dst_incr_mod);
395
396 new_filter_bank = av_calloc(c->filter_alloc, (phase_count + 1) * c->felem_size);
397 if (!new_filter_bank)
398 return AVERROR(ENOMEM);
399
400 ret = build_filter(c, new_filter_bank, c->factor, c->filter_length, c->filter_alloc,
401 phase_count, 1 << c->filter_shift, c->filter_type, c->kaiser_beta);
402 if (ret < 0) {
403 av_freep(&new_filter_bank);
404 return ret;
405 }
406 memcpy(new_filter_bank + (c->filter_alloc*phase_count+1)*c->felem_size, new_filter_bank, (c->filter_alloc-1)*c->felem_size);
407 memcpy(new_filter_bank + (c->filter_alloc*phase_count )*c->felem_size, new_filter_bank + (c->filter_alloc - 1)*c->felem_size, c->felem_size);
408
409 if (!av_reduce(&new_src_incr, &new_dst_incr, c->src_incr,
410 c->dst_incr * (int64_t)(phase_count/c->phase_count), INT32_MAX/2))
411 {
412 av_freep(&new_filter_bank);
413 return AVERROR(EINVAL);
414 }
415
416 c->src_incr = new_src_incr;
417 c->dst_incr = new_dst_incr;
418 while (c->dst_incr < (1<<20) && c->src_incr < (1<<20)) {
419 c->dst_incr *= 2;
420 c->src_incr *= 2;
421 }
422 c->ideal_dst_incr = c->dst_incr;
423 c->dst_incr_div = c->dst_incr / c->src_incr;
424 c->dst_incr_mod = c->dst_incr % c->src_incr;
425 c->index *= phase_count / c->phase_count;
426 c->phase_count = phase_count;
427 av_freep(&c->filter_bank);
428 c->filter_bank = new_filter_bank;
429 return 0;
430 }
431
set_compensation(ResampleContext * c,int sample_delta,int compensation_distance)432 static int set_compensation(ResampleContext *c, int sample_delta, int compensation_distance){
433 int ret;
434
435 if (compensation_distance && sample_delta) {
436 ret = rebuild_filter_bank_with_compensation(c);
437 if (ret < 0)
438 return ret;
439 }
440
441 c->compensation_distance= compensation_distance;
442 if (compensation_distance)
443 c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance;
444 else
445 c->dst_incr = c->ideal_dst_incr;
446
447 c->dst_incr_div = c->dst_incr / c->src_incr;
448 c->dst_incr_mod = c->dst_incr % c->src_incr;
449
450 return 0;
451 }
452
multiple_resample(ResampleContext * c,AudioData * dst,int dst_size,AudioData * src,int src_size,int * consumed)453 static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){
454 int i;
455 int64_t max_src_size = (INT64_MAX/2 / c->phase_count) / c->src_incr;
456
457 if (c->compensation_distance)
458 dst_size = FFMIN(dst_size, c->compensation_distance);
459 src_size = FFMIN(src_size, max_src_size);
460
461 *consumed = 0;
462
463 if (c->filter_length == 1 && c->phase_count == 1) {
464 int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*c->index;
465 int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;
466 int new_size = (src_size * (int64_t)c->src_incr - c->frac + c->dst_incr - 1) / c->dst_incr;
467
468 dst_size = FFMAX(FFMIN(dst_size, new_size), 0);
469 if (dst_size > 0) {
470 for (i = 0; i < dst->ch_count; i++) {
471 c->dsp.resample_one(dst->ch[i], src->ch[i], dst_size, index2, incr);
472 if (i+1 == dst->ch_count) {
473 c->index += dst_size * c->dst_incr_div;
474 c->index += (c->frac + dst_size * (int64_t)c->dst_incr_mod) / c->src_incr;
475 av_assert2(c->index >= 0);
476 *consumed = c->index;
477 c->frac = (c->frac + dst_size * (int64_t)c->dst_incr_mod) % c->src_incr;
478 c->index = 0;
479 }
480 }
481 }
482 } else {
483 int64_t end_index = (1LL + src_size - c->filter_length) * c->phase_count;
484 int64_t delta_frac = (end_index - c->index) * c->src_incr - c->frac;
485 int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr;
486 int (*resample_func)(struct ResampleContext *c, void *dst,
487 const void *src, int n, int update_ctx);
488
489 dst_size = FFMAX(FFMIN(dst_size, delta_n), 0);
490 if (dst_size > 0) {
491 /* resample_linear and resample_common should have same behavior
492 * when frac and dst_incr_mod are zero */
493 resample_func = (c->linear && (c->frac || c->dst_incr_mod)) ?
494 c->dsp.resample_linear : c->dsp.resample_common;
495 for (i = 0; i < dst->ch_count; i++)
496 *consumed = resample_func(c, dst->ch[i], src->ch[i], dst_size, i+1 == dst->ch_count);
497 }
498 }
499
500 if (c->compensation_distance) {
501 c->compensation_distance -= dst_size;
502 if (!c->compensation_distance) {
503 c->dst_incr = c->ideal_dst_incr;
504 c->dst_incr_div = c->dst_incr / c->src_incr;
505 c->dst_incr_mod = c->dst_incr % c->src_incr;
506 }
507 }
508
509 return dst_size;
510 }
511
get_delay(struct SwrContext * s,int64_t base)512 static int64_t get_delay(struct SwrContext *s, int64_t base){
513 ResampleContext *c = s->resample;
514 int64_t num = s->in_buffer_count - (c->filter_length-1)/2;
515 num *= c->phase_count;
516 num -= c->index;
517 num *= c->src_incr;
518 num -= c->frac;
519 return av_rescale(num, base, s->in_sample_rate*(int64_t)c->src_incr * c->phase_count);
520 }
521
get_out_samples(struct SwrContext * s,int in_samples)522 static int64_t get_out_samples(struct SwrContext *s, int in_samples) {
523 ResampleContext *c = s->resample;
524 // The + 2 are added to allow implementations to be slightly inaccurate, they should not be needed currently.
525 // They also make it easier to proof that changes and optimizations do not
526 // break the upper bound.
527 int64_t num = s->in_buffer_count + 2LL + in_samples;
528 num *= c->phase_count;
529 num -= c->index;
530 num = av_rescale_rnd(num, s->out_sample_rate, ((int64_t)s->in_sample_rate) * c->phase_count, AV_ROUND_UP) + 2;
531
532 if (c->compensation_distance) {
533 if (num > INT_MAX)
534 return AVERROR(EINVAL);
535
536 num = FFMAX(num, (num * c->ideal_dst_incr - 1) / c->dst_incr + 1);
537 }
538 return num;
539 }
540
resample_flush(struct SwrContext * s)541 static int resample_flush(struct SwrContext *s) {
542 ResampleContext *c = s->resample;
543 AudioData *a= &s->in_buffer;
544 int i, j, ret;
545 int reflection = (FFMIN(s->in_buffer_count, c->filter_length) + 1) / 2;
546
547 if((ret = swri_realloc_audio(a, s->in_buffer_index + s->in_buffer_count + reflection)) < 0)
548 return ret;
549 av_assert0(a->planar);
550 for(i=0; i<a->ch_count; i++){
551 for(j=0; j<reflection; j++){
552 memcpy(a->ch[i] + (s->in_buffer_index+s->in_buffer_count+j )*a->bps,
553 a->ch[i] + (s->in_buffer_index+s->in_buffer_count-j-1)*a->bps, a->bps);
554 }
555 }
556 s->in_buffer_count += reflection;
557 return 0;
558 }
559
560 // in fact the whole handle multiple ridiculously small buffers might need more thinking...
invert_initial_buffer(ResampleContext * c,AudioData * dst,const AudioData * src,int in_count,int * out_idx,int * out_sz)561 static int invert_initial_buffer(ResampleContext *c, AudioData *dst, const AudioData *src,
562 int in_count, int *out_idx, int *out_sz)
563 {
564 int n, ch, num = FFMIN(in_count + *out_sz, c->filter_length + 1), res;
565
566 if (c->index >= 0)
567 return 0;
568
569 if ((res = swri_realloc_audio(dst, c->filter_length * 2 + 1)) < 0)
570 return res;
571
572 // copy
573 for (n = *out_sz; n < num; n++) {
574 for (ch = 0; ch < src->ch_count; ch++) {
575 memcpy(dst->ch[ch] + ((c->filter_length + n) * c->felem_size),
576 src->ch[ch] + ((n - *out_sz) * c->felem_size), c->felem_size);
577 }
578 }
579
580 // if not enough data is in, return and wait for more
581 if (num < c->filter_length + 1) {
582 *out_sz = num;
583 *out_idx = c->filter_length;
584 return INT_MAX;
585 }
586
587 // else invert
588 for (n = 1; n <= c->filter_length; n++) {
589 for (ch = 0; ch < src->ch_count; ch++) {
590 memcpy(dst->ch[ch] + ((c->filter_length - n) * c->felem_size),
591 dst->ch[ch] + ((c->filter_length + n) * c->felem_size),
592 c->felem_size);
593 }
594 }
595
596 res = num - *out_sz;
597 *out_idx = c->filter_length;
598 while (c->index < 0) {
599 --*out_idx;
600 c->index += c->phase_count;
601 }
602 *out_sz = FFMAX(*out_sz + c->filter_length,
603 1 + c->filter_length * 2) - *out_idx;
604
605 return FFMAX(res, 0);
606 }
607
608 struct Resampler const swri_resampler={
609 resample_init,
610 resample_free,
611 multiple_resample,
612 resample_flush,
613 set_compensation,
614 get_delay,
615 invert_initial_buffer,
616 get_out_samples,
617 };
618