66 static void *speex_alloc (
int size) {
return calloc(size,1);}
67 static void *speex_realloc (
void *ptr,
int size) {
return realloc(ptr, size);}
68 static void speex_free (
void *ptr) {free(ptr);}
69 #include "speex_resampler.h"
73 #include "speex/speex_resampler.h"
75 #include "os_support.h"
83 #define M_PI 3.14159265358979323846
87 #define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x)))
89 #define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x))))
92 #define IMAX(a,b) ((a) > (b) ? (a) : (b))
93 #define IMIN(a,b) ((a) < (b) ? (a) : (b))
104 #include "resample_neon.h"
109 #define FIXED_STACK_ALLOC 8192
111 #define FIXED_STACK_ALLOC 1024
114 typedef int (*resampler_basic_func)(
SpeexResamplerState *, spx_uint32_t ,
const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *);
117 spx_uint32_t in_rate;
118 spx_uint32_t out_rate;
119 spx_uint32_t num_rate;
120 spx_uint32_t den_rate;
123 spx_uint32_t nb_channels;
124 spx_uint32_t filt_len;
125 spx_uint32_t mem_alloc_size;
126 spx_uint32_t buffer_size;
130 spx_uint32_t oversample;
135 spx_int32_t *last_sample;
136 spx_uint32_t *samp_frac_num;
137 spx_uint32_t *magic_samples;
140 spx_word16_t *sinc_table;
141 spx_uint32_t sinc_table_length;
142 resampler_basic_func resampler_ptr;
148 static const double kaiser12_table[68] = {
149 0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076,
150 0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014,
151 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601,
152 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014,
153 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490,
154 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546,
155 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178,
156 0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947,
157 0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058,
158 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438,
159 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734,
160 0.00001000, 0.00000000};
170 static const double kaiser10_table[36] = {
171 0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446,
172 0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347,
173 0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962,
174 0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451,
175 0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739,
176 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000};
178 static const double kaiser8_table[36] = {
179 0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200,
180 0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126,
181 0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272,
182 0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758,
183 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490,
184 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000};
186 static const double kaiser6_table[36] = {
187 0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003,
188 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565,
189 0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561,
190 0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058,
191 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600,
192 0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000};
199 static const struct FuncDef _KAISER12 = {kaiser12_table, 64};
200 #define KAISER12 (&_KAISER12)
203 static const struct FuncDef _KAISER10 = {kaiser10_table, 32};
204 #define KAISER10 (&_KAISER10)
205 static const struct FuncDef _KAISER8 = {kaiser8_table, 32};
206 #define KAISER8 (&_KAISER8)
207 static const struct FuncDef _KAISER6 = {kaiser6_table, 32};
208 #define KAISER6 (&_KAISER6)
213 float downsample_bandwidth;
214 float upsample_bandwidth;
215 const struct FuncDef *window_func;
229 { 8, 4, 0.830f, 0.860f, KAISER6 },
230 { 16, 4, 0.850f, 0.880f, KAISER6 },
231 { 32, 4, 0.882f, 0.910f, KAISER6 },
232 { 48, 8, 0.895f, 0.917f, KAISER8 },
233 { 64, 8, 0.921f, 0.940f, KAISER8 },
234 { 80, 16, 0.922f, 0.940f, KAISER10},
235 { 96, 16, 0.940f, 0.945f, KAISER10},
236 {128, 16, 0.950f, 0.950f, KAISER10},
237 {160, 16, 0.960f, 0.960f, KAISER10},
238 {192, 32, 0.968f, 0.968f, KAISER12},
239 {256, 32, 0.975f, 0.975f, KAISER12},
242 static double compute_func(
float x,
const struct FuncDef *func)
247 y = x*func->oversample;
251 interp[3] = -0.1666666667*frac + 0.1666666667*(frac*frac*frac);
252 interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac);
254 interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac);
256 interp[1] = 1.f-interp[3]-interp[2]-interp[0];
259 return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3];
264 int main(
int argc,
char **argv)
269 printf (
"%f\n", compute_func(i/256., KAISER12));
277 static spx_word16_t sinc(
float cutoff,
float x,
int N,
const struct FuncDef *window_func)
280 float xx = x * cutoff;
282 return WORD2INT(32768.*cutoff);
283 else if (fabs(x) > .5f*N)
286 return WORD2INT(32768.*cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func));
290 static spx_word16_t sinc(
float cutoff,
float x,
int N,
const struct FuncDef *window_func)
293 float xx = x * cutoff;
296 else if (fabs(x) > .5*N)
299 return cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func);
304 static void cubic_coef(spx_word16_t x, spx_word16_t interp[4])
309 x2 = MULT16_16_P15(x, x);
310 x3 = MULT16_16_P15(x, x2);
311 interp[0] = PSHR32(MULT16_16(QCONST16(-0.16667f, 15),x) + MULT16_16(QCONST16(0.16667f, 15),x3),15);
312 interp[1] = EXTRACT16(EXTEND32(x) + SHR32(SUB32(EXTEND32(x2),EXTEND32(x3)),1));
313 interp[3] = PSHR32(MULT16_16(QCONST16(-0.33333f, 15),x) + MULT16_16(QCONST16(.5f,15),x2) - MULT16_16(QCONST16(0.16667f, 15),x3),15);
315 interp[2] = Q15_ONE-interp[0]-interp[1]-interp[3];
320 static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4])
324 interp[0] = -0.16667f*frac + 0.16667f*frac*frac*frac;
325 interp[1] = frac + 0.5f*frac*frac - 0.5f*frac*frac*frac;
327 interp[3] = -0.33333f*frac + 0.5f*frac*frac - 0.16667f*frac*frac*frac;
329 interp[2] = 1.-interp[0]-interp[1]-interp[3];
333 static int resampler_basic_direct_single(
SpeexResamplerState *st, spx_uint32_t channel_index,
const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
335 const int N = st->filt_len;
337 int last_sample = st->last_sample[channel_index];
338 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
339 const spx_word16_t *sinc_table = st->sinc_table;
340 const int out_stride = st->out_stride;
341 const int int_advance = st->int_advance;
342 const int frac_advance = st->frac_advance;
343 const spx_uint32_t den_rate = st->den_rate;
346 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
348 const spx_word16_t *sinct = & sinc_table[samp_frac_num*N];
349 const spx_word16_t *iptr = & in[last_sample];
351 #ifndef OVERRIDE_INNER_PRODUCT_SINGLE
354 for(j=0;j<N;j++) sum += MULT16_16(sinct[j], iptr[j]);
368 sum = SATURATE32PSHR(sum, 15, 32767);
370 sum = inner_product_single(sinct, iptr, N);
373 out[out_stride * out_sample++] = sum;
374 last_sample += int_advance;
375 samp_frac_num += frac_advance;
376 if (samp_frac_num >= den_rate)
378 samp_frac_num -= den_rate;
383 st->last_sample[channel_index] = last_sample;
384 st->samp_frac_num[channel_index] = samp_frac_num;
391 static int resampler_basic_direct_double(
SpeexResamplerState *st, spx_uint32_t channel_index,
const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
393 const int N = st->filt_len;
395 int last_sample = st->last_sample[channel_index];
396 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
397 const spx_word16_t *sinc_table = st->sinc_table;
398 const int out_stride = st->out_stride;
399 const int int_advance = st->int_advance;
400 const int frac_advance = st->frac_advance;
401 const spx_uint32_t den_rate = st->den_rate;
404 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
406 const spx_word16_t *sinct = & sinc_table[samp_frac_num*N];
407 const spx_word16_t *iptr = & in[last_sample];
409 #ifndef OVERRIDE_INNER_PRODUCT_DOUBLE
411 double accum[4] = {0,0,0,0};
414 accum[0] += sinct[j]*iptr[j];
415 accum[1] += sinct[j+1]*iptr[j+1];
416 accum[2] += sinct[j+2]*iptr[j+2];
417 accum[3] += sinct[j+3]*iptr[j+3];
419 sum = accum[0] + accum[1] + accum[2] + accum[3];
421 sum = inner_product_double(sinct, iptr, N);
424 out[out_stride * out_sample++] = PSHR32(sum, 15);
425 last_sample += int_advance;
426 samp_frac_num += frac_advance;
427 if (samp_frac_num >= den_rate)
429 samp_frac_num -= den_rate;
434 st->last_sample[channel_index] = last_sample;
435 st->samp_frac_num[channel_index] = samp_frac_num;
440 static int resampler_basic_interpolate_single(
SpeexResamplerState *st, spx_uint32_t channel_index,
const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
442 const int N = st->filt_len;
444 int last_sample = st->last_sample[channel_index];
445 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
446 const int out_stride = st->out_stride;
447 const int int_advance = st->int_advance;
448 const int frac_advance = st->frac_advance;
449 const spx_uint32_t den_rate = st->den_rate;
452 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
454 const spx_word16_t *iptr = & in[last_sample];
456 const int offset = samp_frac_num*st->oversample/st->den_rate;
458 const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);
460 const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;
462 spx_word16_t interp[4];
465 #ifndef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
467 spx_word32_t accum[4] = {0,0,0,0};
470 const spx_word16_t curr_in=iptr[j];
471 accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
472 accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
473 accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);
474 accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
477 cubic_coef(frac, interp);
478 sum = MULT16_32_Q15(interp[0],SHR32(accum[0], 1)) + MULT16_32_Q15(interp[1],SHR32(accum[1], 1)) + MULT16_32_Q15(interp[2],SHR32(accum[2], 1)) + MULT16_32_Q15(interp[3],SHR32(accum[3], 1));
479 sum = SATURATE32PSHR(sum, 15, 32767);
481 cubic_coef(frac, interp);
482 sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);
485 out[out_stride * out_sample++] = sum;
486 last_sample += int_advance;
487 samp_frac_num += frac_advance;
488 if (samp_frac_num >= den_rate)
490 samp_frac_num -= den_rate;
495 st->last_sample[channel_index] = last_sample;
496 st->samp_frac_num[channel_index] = samp_frac_num;
503 static int resampler_basic_interpolate_double(
SpeexResamplerState *st, spx_uint32_t channel_index,
const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
505 const int N = st->filt_len;
507 int last_sample = st->last_sample[channel_index];
508 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
509 const int out_stride = st->out_stride;
510 const int int_advance = st->int_advance;
511 const int frac_advance = st->frac_advance;
512 const spx_uint32_t den_rate = st->den_rate;
515 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
517 const spx_word16_t *iptr = & in[last_sample];
519 const int offset = samp_frac_num*st->oversample/st->den_rate;
521 const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);
523 const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;
525 spx_word16_t interp[4];
528 #ifndef OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
530 double accum[4] = {0,0,0,0};
533 const double curr_in=iptr[j];
534 accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
535 accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
536 accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);
537 accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
540 cubic_coef(frac, interp);
541 sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]);
543 cubic_coef(frac, interp);
544 sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);
547 out[out_stride * out_sample++] = PSHR32(sum,15);
548 last_sample += int_advance;
549 samp_frac_num += frac_advance;
550 if (samp_frac_num >= den_rate)
552 samp_frac_num -= den_rate;
557 st->last_sample[channel_index] = last_sample;
558 st->samp_frac_num[channel_index] = samp_frac_num;
567 static int resampler_basic_zero(
SpeexResamplerState *st, spx_uint32_t channel_index,
const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
570 int last_sample = st->last_sample[channel_index];
571 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
572 const int out_stride = st->out_stride;
573 const int int_advance = st->int_advance;
574 const int frac_advance = st->frac_advance;
575 const spx_uint32_t den_rate = st->den_rate;
577 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
579 out[out_stride * out_sample++] = 0;
580 last_sample += int_advance;
581 samp_frac_num += frac_advance;
582 if (samp_frac_num >= den_rate)
584 samp_frac_num -= den_rate;
589 st->last_sample[channel_index] = last_sample;
590 st->samp_frac_num[channel_index] = samp_frac_num;
596 spx_uint32_t old_length = st->filt_len;
597 spx_uint32_t old_alloc_size = st->mem_alloc_size;
599 spx_uint32_t min_sinc_table_length;
600 spx_uint32_t min_alloc_size;
602 st->int_advance = st->num_rate/st->den_rate;
603 st->frac_advance = st->num_rate%st->den_rate;
604 st->oversample = quality_map[st->quality].oversample;
605 st->filt_len = quality_map[st->quality].base_length;
607 if (st->num_rate > st->den_rate)
610 st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate;
612 st->filt_len = st->filt_len*st->num_rate / st->den_rate;
614 st->filt_len = ((st->filt_len-1)&(~0x7))+8;
615 if (2*st->den_rate < st->num_rate)
616 st->oversample >>= 1;
617 if (4*st->den_rate < st->num_rate)
618 st->oversample >>= 1;
619 if (8*st->den_rate < st->num_rate)
620 st->oversample >>= 1;
621 if (16*st->den_rate < st->num_rate)
622 st->oversample >>= 1;
623 if (st->oversample < 1)
627 st->cutoff = quality_map[st->quality].upsample_bandwidth;
631 #ifdef RESAMPLE_FULL_SINC_TABLE
633 if (INT_MAX/
sizeof(spx_word16_t)/st->den_rate < st->filt_len)
636 use_direct = st->filt_len*st->den_rate <= st->filt_len*st->oversample+8
637 && INT_MAX/
sizeof(spx_word16_t)/st->den_rate >= st->filt_len;
641 min_sinc_table_length = st->filt_len*st->den_rate;
643 if ((INT_MAX/
sizeof(spx_word16_t)-8)/st->oversample < st->filt_len)
646 min_sinc_table_length = st->filt_len*st->oversample+8;
648 if (st->sinc_table_length < min_sinc_table_length)
650 spx_word16_t *sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,min_sinc_table_length*
sizeof(spx_word16_t));
654 st->sinc_table = sinc_table;
655 st->sinc_table_length = min_sinc_table_length;
660 for (i=0;i<st->den_rate;i++)
663 for (j=0;j<st->filt_len;j++)
665 st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((
float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func);
669 st->resampler_ptr = resampler_basic_direct_single;
672 st->resampler_ptr = resampler_basic_direct_double;
674 st->resampler_ptr = resampler_basic_direct_single;
679 for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++)
680 st->sinc_table[i+4] = sinc(st->cutoff,(i/(
float)st->oversample - st->filt_len/2), st->filt_len, quality_map[st->quality].window_func);
682 st->resampler_ptr = resampler_basic_interpolate_single;
685 st->resampler_ptr = resampler_basic_interpolate_double;
687 st->resampler_ptr = resampler_basic_interpolate_single;
698 min_alloc_size = st->filt_len-1 + st->buffer_size;
699 if (min_alloc_size > st->mem_alloc_size)
702 if (INT_MAX/
sizeof(spx_word16_t)/st->nb_channels < min_alloc_size)
704 else if (!(mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*min_alloc_size *
sizeof(*mem))))
708 st->mem_alloc_size = min_alloc_size;
713 for (i=0;i<st->nb_channels*st->mem_alloc_size;i++)
716 }
else if (st->filt_len > old_length)
721 for (i=st->nb_channels;i--;)
724 spx_uint32_t olen = old_length;
730 olen = old_length + 2*st->magic_samples[i];
731 for (j=old_length-1+st->magic_samples[i];j--;)
732 st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j];
733 for (j=0;j<st->magic_samples[i];j++)
734 st->mem[i*st->mem_alloc_size+j] = 0;
735 st->magic_samples[i] = 0;
737 if (st->filt_len > olen)
741 for (j=0;j<olen-1;j++)
742 st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)];
744 for (;j<st->filt_len-1;j++)
745 st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0;
747 st->last_sample[i] += (st->filt_len - olen)/2;
750 st->magic_samples[i] = (olen - st->filt_len)/2;
751 for (j=0;j<st->filt_len-1+st->magic_samples[i];j++)
752 st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];
755 }
else if (st->filt_len < old_length)
760 for (i=0;i<st->nb_channels;i++)
763 spx_uint32_t old_magic = st->magic_samples[i];
764 st->magic_samples[i] = (old_length - st->filt_len)/2;
767 for (j=0;j<st->filt_len-1+st->magic_samples[i]+old_magic;j++)
768 st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];
769 st->magic_samples[i] += old_magic;
772 return RESAMPLER_ERR_SUCCESS;
775 st->resampler_ptr = resampler_basic_zero;
779 st->filt_len = old_length;
780 return RESAMPLER_ERR_ALLOC_FAILED;
783 EXPORT
SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate,
int quality,
int *err)
785 return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err);
788 EXPORT
SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate,
int quality,
int *err)
794 if (quality > 10 || quality < 0)
797 *err = RESAMPLER_ERR_INVALID_ARG;
808 st->sinc_table_length = 0;
809 st->mem_alloc_size = 0;
812 st->resampler_ptr = 0;
815 st->nb_channels = nb_channels;
819 st->buffer_size = 160;
822 st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*
sizeof(spx_int32_t));
823 st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*
sizeof(spx_uint32_t));
824 st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*
sizeof(spx_uint32_t));
825 for (i=0;i<nb_channels;i++)
827 st->last_sample[i] = 0;
828 st->magic_samples[i] = 0;
829 st->samp_frac_num[i] = 0;
832 speex_resampler_set_quality(st, quality);
833 speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate);
835 filter_err = update_filter(st);
836 if (filter_err == RESAMPLER_ERR_SUCCESS)
840 speex_resampler_destroy(st);
852 speex_free(st->sinc_table);
853 speex_free(st->last_sample);
854 speex_free(st->magic_samples);
855 speex_free(st->samp_frac_num);
859 static int speex_resampler_process_native(
SpeexResamplerState *st, spx_uint32_t channel_index, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
862 const int N = st->filt_len;
864 spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
870 out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len);
872 if (st->last_sample[channel_index] < (spx_int32_t)*in_len)
873 *in_len = st->last_sample[channel_index];
874 *out_len = out_sample;
875 st->last_sample[channel_index] -= *in_len;
880 mem[j] = mem[j+ilen];
882 return RESAMPLER_ERR_SUCCESS;
885 static int speex_resampler_magic(
SpeexResamplerState *st, spx_uint32_t channel_index, spx_word16_t **out, spx_uint32_t out_len) {
886 spx_uint32_t tmp_in_len = st->magic_samples[channel_index];
887 spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
888 const int N = st->filt_len;
890 speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len);
892 st->magic_samples[channel_index] -= tmp_in_len;
895 if (st->magic_samples[channel_index])
898 for (i=0;i<st->magic_samples[channel_index];i++)
899 mem[N-1+i]=mem[N-1+i+tmp_in_len];
901 *out += out_len*st->out_stride;
906 EXPORT
int speex_resampler_process_int(
SpeexResamplerState *st, spx_uint32_t channel_index,
const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
908 EXPORT
int speex_resampler_process_float(
SpeexResamplerState *st, spx_uint32_t channel_index,
const float *in, spx_uint32_t *in_len,
float *out, spx_uint32_t *out_len)
912 spx_uint32_t ilen = *in_len;
913 spx_uint32_t olen = *out_len;
914 spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;
915 const int filt_offs = st->filt_len - 1;
916 const spx_uint32_t xlen = st->mem_alloc_size - filt_offs;
917 const int istride = st->in_stride;
919 if (st->magic_samples[channel_index])
920 olen -= speex_resampler_magic(st, channel_index, &out, olen);
921 if (! st->magic_samples[channel_index]) {
922 while (ilen && olen) {
923 spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;
924 spx_uint32_t ochunk = olen;
927 for(j=0;j<ichunk;++j)
928 x[j+filt_offs]=in[j*istride];
930 for(j=0;j<ichunk;++j)
933 speex_resampler_process_native(st, channel_index, &ichunk, out, &ochunk);
936 out += ochunk * st->out_stride;
938 in += ichunk * istride;
943 return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
947 EXPORT
int speex_resampler_process_float(
SpeexResamplerState *st, spx_uint32_t channel_index,
const float *in, spx_uint32_t *in_len,
float *out, spx_uint32_t *out_len)
949 EXPORT
int speex_resampler_process_int(
SpeexResamplerState *st, spx_uint32_t channel_index,
const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
953 const int istride_save = st->in_stride;
954 const int ostride_save = st->out_stride;
955 spx_uint32_t ilen = *in_len;
956 spx_uint32_t olen = *out_len;
957 spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;
958 const spx_uint32_t xlen = st->mem_alloc_size - (st->filt_len - 1);
960 const unsigned int ylen = (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC;
962 ALLOC(ystack, ylen, spx_word16_t);
964 const unsigned int ylen = FIXED_STACK_ALLOC;
965 spx_word16_t ystack[FIXED_STACK_ALLOC];
970 while (ilen && olen) {
971 spx_word16_t *y = ystack;
972 spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;
973 spx_uint32_t ochunk = (olen > ylen) ? ylen : olen;
974 spx_uint32_t omagic = 0;
976 if (st->magic_samples[channel_index]) {
977 omagic = speex_resampler_magic(st, channel_index, &y, ochunk);
981 if (! st->magic_samples[channel_index]) {
983 for(j=0;j<ichunk;++j)
985 x[j+st->filt_len-1]=WORD2INT(in[j*istride_save]);
987 x[j+st->filt_len-1]=in[j*istride_save];
990 for(j=0;j<ichunk;++j)
991 x[j+st->filt_len-1]=0;
994 speex_resampler_process_native(st, channel_index, &ichunk, y, &ochunk);
1000 for (j=0;j<ochunk+omagic;++j)
1002 out[j*ostride_save] = ystack[j];
1004 out[j*ostride_save] = WORD2INT(ystack[j]);
1009 out += (ochunk+omagic) * ostride_save;
1011 in += ichunk * istride_save;
1013 st->out_stride = ostride_save;
1017 return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
1020 EXPORT
int speex_resampler_process_interleaved_float(
SpeexResamplerState *st,
const float *in, spx_uint32_t *in_len,
float *out, spx_uint32_t *out_len)
1023 int istride_save, ostride_save;
1024 spx_uint32_t bak_out_len = *out_len;
1025 spx_uint32_t bak_in_len = *in_len;
1026 istride_save = st->in_stride;
1027 ostride_save = st->out_stride;
1028 st->in_stride = st->out_stride = st->nb_channels;
1029 for (i=0;i<st->nb_channels;i++)
1031 *out_len = bak_out_len;
1032 *in_len = bak_in_len;
1034 speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len);
1036 speex_resampler_process_float(st, i, NULL, in_len, out+i, out_len);
1038 st->in_stride = istride_save;
1039 st->out_stride = ostride_save;
1040 return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
1043 EXPORT
int speex_resampler_process_interleaved_int(
SpeexResamplerState *st,
const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
1046 int istride_save, ostride_save;
1047 spx_uint32_t bak_out_len = *out_len;
1048 spx_uint32_t bak_in_len = *in_len;
1049 istride_save = st->in_stride;
1050 ostride_save = st->out_stride;
1051 st->in_stride = st->out_stride = st->nb_channels;
1052 for (i=0;i<st->nb_channels;i++)
1054 *out_len = bak_out_len;
1055 *in_len = bak_in_len;
1057 speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len);
1059 speex_resampler_process_int(st, i, NULL, in_len, out+i, out_len);
1061 st->in_stride = istride_save;
1062 st->out_stride = ostride_save;
1063 return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
1066 EXPORT
int speex_resampler_set_rate(
SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate)
1068 return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);
1071 EXPORT
void speex_resampler_get_rate(
SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate)
1073 *in_rate = st->in_rate;
1074 *out_rate = st->out_rate;
1077 EXPORT
int speex_resampler_set_rate_frac(
SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate)
1080 spx_uint32_t old_den;
1082 if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)
1083 return RESAMPLER_ERR_SUCCESS;
1085 old_den = st->den_rate;
1086 st->in_rate = in_rate;
1087 st->out_rate = out_rate;
1088 st->num_rate = ratio_num;
1089 st->den_rate = ratio_den;
1091 for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++)
1093 while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))
1095 st->num_rate /= fact;
1096 st->den_rate /= fact;
1102 for (i=0;i<st->nb_channels;i++)
1104 st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den;
1106 if (st->samp_frac_num[i] >= st->den_rate)
1107 st->samp_frac_num[i] = st->den_rate-1;
1111 if (st->initialised)
1112 return update_filter(st);
1113 return RESAMPLER_ERR_SUCCESS;
1116 EXPORT
void speex_resampler_get_ratio(
SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den)
1118 *ratio_num = st->num_rate;
1119 *ratio_den = st->den_rate;
1124 if (quality > 10 || quality < 0)
1125 return RESAMPLER_ERR_INVALID_ARG;
1126 if (st->quality == quality)
1127 return RESAMPLER_ERR_SUCCESS;
1128 st->quality = quality;
1129 if (st->initialised)
1130 return update_filter(st);
1131 return RESAMPLER_ERR_SUCCESS;
1136 *quality = st->quality;
1139 EXPORT
void speex_resampler_set_input_stride(
SpeexResamplerState *st, spx_uint32_t stride)
1141 st->in_stride = stride;
1144 EXPORT
void speex_resampler_get_input_stride(
SpeexResamplerState *st, spx_uint32_t *stride)
1146 *stride = st->in_stride;
1149 EXPORT
void speex_resampler_set_output_stride(
SpeexResamplerState *st, spx_uint32_t stride)
1151 st->out_stride = stride;
1154 EXPORT
void speex_resampler_get_output_stride(
SpeexResamplerState *st, spx_uint32_t *stride)
1156 *stride = st->out_stride;
1161 return st->filt_len / 2;
1166 return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate;
1172 for (i=0;i<st->nb_channels;i++)
1173 st->last_sample[i] = st->filt_len/2;
1174 return RESAMPLER_ERR_SUCCESS;
1180 for (i=0;i<st->nb_channels;i++)
1182 st->last_sample[i] = 0;
1183 st->magic_samples[i] = 0;
1184 st->samp_frac_num[i] = 0;
1186 for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
1188 return RESAMPLER_ERR_SUCCESS;
1191 EXPORT
const char *speex_resampler_strerror(
int err)
1195 case RESAMPLER_ERR_SUCCESS:
1197 case RESAMPLER_ERR_ALLOC_FAILED:
1198 return "Memory allocation failed.";
1199 case RESAMPLER_ERR_BAD_STATE:
1200 return "Bad resampler state.";
1201 case RESAMPLER_ERR_INVALID_ARG:
1202 return "Invalid argument.";
1203 case RESAMPLER_ERR_PTR_OVERLAP:
1204 return "Input and output buffers overlap.";
1206 return "Unknown error. Bad error code or strange version mismatch.";
Resampler functions (SSE version)
#define ALLOC(var, size, type)
Temporary memory allocation on stack.
Various architecture definitions Speex.
int main(int argc, char *argv[])