64#define SPEEX_USE_CBLAS
75static void *
speex_alloc(
int size) {
return calloc(size,1);}
76static void *
speex_realloc(
void *ptr,
int size) {
return realloc(ptr, size);}
96#define M_PI 3.14159265358979323846
99#define IMAX(a,b) ((a) > (b) ? (a) : (b))
100#define IMIN(a,b) ((a) < (b) ? (a) : (b))
107#define UINT32_MAX 4294967295U
120#define FIXED_STACK_ALLOC 8192
122#define FIXED_STACK_ALLOC 1024
125typedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t ,
const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *);
128 spx_uint32_t in_rate;
129 spx_uint32_t out_rate;
130 spx_uint32_t num_rate;
131 spx_uint32_t den_rate;
134 spx_uint32_t nb_channels;
135 spx_uint32_t filt_len;
136 spx_uint32_t mem_alloc_size;
137 spx_uint32_t buffer_size;
141 spx_uint32_t oversample;
146 spx_int32_t *last_sample;
147 spx_uint32_t *samp_frac_num;
148 spx_uint32_t *magic_samples;
151 spx_word16_t *sinc_table;
152 spx_uint32_t sinc_table_length;
153 resampler_basic_func resampler_ptr;
159static const double kaiser12_table[68] = {
160 0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076,
161 0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014,
162 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601,
163 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014,
164 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490,
165 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546,
166 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178,
167 0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947,
168 0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058,
169 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438,
170 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734,
171 0.00001000, 0.00000000};
181static const double kaiser10_table[36] = {
182 0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446,
183 0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347,
184 0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962,
185 0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451,
186 0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739,
187 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000};
189static const double kaiser8_table[36] = {
190 0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200,
191 0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126,
192 0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272,
193 0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758,
194 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490,
195 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000};
197static const double kaiser6_table[36] = {
198 0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003,
199 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565,
200 0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561,
201 0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058,
202 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600,
203 0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000};
210static const struct FuncDef kaiser12_funcdef = {kaiser12_table, 64};
211#define KAISER12 (&kaiser12_funcdef)
212static const struct FuncDef kaiser10_funcdef = {kaiser10_table, 32};
213#define KAISER10 (&kaiser10_funcdef)
214static const struct FuncDef kaiser8_funcdef = {kaiser8_table, 32};
215#define KAISER8 (&kaiser8_funcdef)
216static const struct FuncDef kaiser6_funcdef = {kaiser6_table, 32};
217#define KAISER6 (&kaiser6_funcdef)
222 float downsample_bandwidth;
223 float upsample_bandwidth;
224 const struct FuncDef *window_func;
238 { 8, 4, 0.830f, 0.860f, KAISER6 },
239 { 16, 4, 0.850f, 0.880f, KAISER6 },
240 { 32, 4, 0.882f, 0.910f, KAISER6 },
241 { 48, 8, 0.895f, 0.917f, KAISER8 },
242 { 64, 8, 0.921f, 0.940f, KAISER8 },
243 { 80, 16, 0.922f, 0.940f, KAISER10},
244 { 96, 16, 0.940f, 0.945f, KAISER10},
245 {128, 16, 0.950f, 0.950f, KAISER10},
246 {160, 16, 0.960f, 0.960f, KAISER10},
247 {192, 32, 0.968f, 0.968f, KAISER12},
248 {256, 32, 0.975f, 0.975f, KAISER12},
251static double compute_func(
float x,
const struct FuncDef *func)
256 y = x*func->oversample;
260 interp[3] = -0.1666666667*frac + 0.1666666667*(frac*frac*frac);
261 interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac);
263 interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac);
265 interp[1] = 1.f-interp[3]-interp[2]-interp[0];
268 return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3];
273int main(
int argc,
char **argv)
278 printf (
"%f\n", compute_func(i/256., KAISER12));
286static spx_word16_t sinc(
float cutoff,
float x,
int N,
const struct FuncDef *window_func)
289 float xx = x * cutoff;
291 return WORD2INT(32768.*cutoff);
292 else if (fabs(x) > .5f*N)
295 return WORD2INT(32768.*cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func));
299static spx_word16_t sinc(
float cutoff,
float x,
int N,
const struct FuncDef *window_func)
302 float xx = x * cutoff;
305 else if (fabs(x) > .5*N)
308 return cutoff*sinf((
float)M_PI*xx)/((float)M_PI*xx) * (float)compute_func(fabsf(2.0f*x/(
float)N), window_func);
313static void cubic_coef(spx_word16_t x, spx_word16_t interp[4])
318 x2 = MULT16_16_P15(x, x);
319 x3 = MULT16_16_P15(x, x2);
320 interp[0] = PSHR32(MULT16_16(QCONST16(-0.16667f, 15),x) + MULT16_16(QCONST16(0.16667f, 15),x3),15);
321 interp[1] = EXTRACT16(EXTEND32(x) + SHR32(SUB32(EXTEND32(x2),EXTEND32(x3)),1));
322 interp[3] = PSHR32(MULT16_16(QCONST16(-0.33333f, 15),x) + MULT16_16(QCONST16(.5f,15),x2) - MULT16_16(QCONST16(0.16667f, 15),x3),15);
324 interp[2] = Q15_ONE-interp[0]-interp[1]-interp[3];
329static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4])
333 interp[0] = -0.16667f*frac + 0.16667f*frac*frac*frac;
334 interp[1] = frac + 0.5f*frac*frac - 0.5f*frac*frac*frac;
336 interp[3] = -0.33333f*frac + 0.5f*frac*frac - 0.16667f*frac*frac*frac;
338 interp[2] = 1.f-interp[0]-interp[1]-interp[3];
342static 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)
344 const int N = st->filt_len;
346 int last_sample = st->last_sample[channel_index];
347 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
348 const spx_word16_t *sinc_table = st->sinc_table;
349 const int out_stride = st->out_stride;
350 const int int_advance = st->int_advance;
351 const int frac_advance = st->frac_advance;
352 const spx_uint32_t den_rate = st->den_rate;
355 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
357 const spx_word16_t *sinct = & sinc_table[samp_frac_num*N];
358 const spx_word16_t *iptr = & in[last_sample];
360#ifndef OVERRIDE_INNER_PRODUCT_SINGLE
361# ifdef SPEEX_USE_CBLAS
362 sum = cblas_sdot(N, sinct, 1, iptr, 1);
366 for(j=0;j<N;j++) sum += MULT16_16(sinct[j], iptr[j]);
382 sum = SATURATE32PSHR(sum, 15, 32767);
384 sum = inner_product_single(sinct, iptr, N);
387 out[out_stride * out_sample++] = sum;
388 last_sample += int_advance;
389 samp_frac_num += frac_advance;
390 if (samp_frac_num >= den_rate)
392 samp_frac_num -= den_rate;
397 st->last_sample[channel_index] = last_sample;
398 st->samp_frac_num[channel_index] = samp_frac_num;
405static 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)
407 const int N = st->filt_len;
409 int last_sample = st->last_sample[channel_index];
410 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
411 const spx_word16_t *sinc_table = st->sinc_table;
412 const int out_stride = st->out_stride;
413 const int int_advance = st->int_advance;
414 const int frac_advance = st->frac_advance;
415 const spx_uint32_t den_rate = st->den_rate;
418 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
420 const spx_word16_t *sinct = & sinc_table[samp_frac_num*N];
421 const spx_word16_t *iptr = & in[last_sample];
423#ifndef OVERRIDE_INNER_PRODUCT_DOUBLE
424# ifdef SPEEX_USE_CBLAS
425 sum = (double)cblas_sdot(N, sinct, 1, iptr, 1);
428 double accum[4] = {0,0,0,0};
431 accum[0] += sinct[j]*iptr[j];
432 accum[1] += sinct[j+1]*iptr[j+1];
433 accum[2] += sinct[j+2]*iptr[j+2];
434 accum[3] += sinct[j+3]*iptr[j+3];
436 sum = accum[0] + accum[1] + accum[2] + accum[3];
439 sum = inner_product_double(sinct, iptr, N);
442 out[out_stride * out_sample++] = (spx_word16_t)PSHR32(sum, 15);
443 last_sample += int_advance;
444 samp_frac_num += frac_advance;
445 if (samp_frac_num >= den_rate)
447 samp_frac_num -= den_rate;
452 st->last_sample[channel_index] = last_sample;
453 st->samp_frac_num[channel_index] = samp_frac_num;
458static 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)
460 const int N = st->filt_len;
462 int last_sample = st->last_sample[channel_index];
463 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
464 const int out_stride = st->out_stride;
465 const int int_advance = st->int_advance;
466 const int frac_advance = st->frac_advance;
467 const spx_uint32_t den_rate = st->den_rate;
470 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
472 const spx_word16_t *iptr = & in[last_sample];
474 const int offset = samp_frac_num*st->oversample/st->den_rate;
476 const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);
478 const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;
480 spx_word16_t interp[4];
483#ifndef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
485 spx_word32_t accum[4] = {0,0,0,0};
488 const spx_word16_t curr_in=iptr[j];
489 accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
490 accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
491 accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);
492 accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
495 cubic_coef(frac, interp);
496 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]);
497 sum = SATURATE32PSHR(sum, 15, 32767);
499 cubic_coef(frac, interp);
500 sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);
503 out[out_stride * out_sample++] = sum;
504 last_sample += int_advance;
505 samp_frac_num += frac_advance;
506 if (samp_frac_num >= den_rate)
508 samp_frac_num -= den_rate;
513 st->last_sample[channel_index] = last_sample;
514 st->samp_frac_num[channel_index] = samp_frac_num;
521static 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)
523 const int N = st->filt_len;
525 int last_sample = st->last_sample[channel_index];
526 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
527 const int out_stride = st->out_stride;
528 const int int_advance = st->int_advance;
529 const int frac_advance = st->frac_advance;
530 const spx_uint32_t den_rate = st->den_rate;
533 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
535 const spx_word16_t *iptr = & in[last_sample];
537 const int offset = samp_frac_num*st->oversample/st->den_rate;
539 const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);
541 const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;
543 spx_word16_t interp[4];
546#ifndef OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
548 double accum[4] = {0,0,0,0};
551 const double curr_in=iptr[j];
552 accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
553 accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
554 accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);
555 accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
558 cubic_coef(frac, interp);
559 sum = (spx_word32_t)(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]));
561 cubic_coef(frac, interp);
562 sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);
565 out[out_stride * out_sample++] = PSHR32(sum,15);
566 last_sample += int_advance;
567 samp_frac_num += frac_advance;
568 if (samp_frac_num >= den_rate)
570 samp_frac_num -= den_rate;
575 st->last_sample[channel_index] = last_sample;
576 st->samp_frac_num[channel_index] = samp_frac_num;
585static 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)
588 int last_sample = st->last_sample[channel_index];
589 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
590 const int out_stride = st->out_stride;
591 const int int_advance = st->int_advance;
592 const int frac_advance = st->frac_advance;
593 const spx_uint32_t den_rate = st->den_rate;
596 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
598 out[out_stride * out_sample++] = 0;
599 last_sample += int_advance;
600 samp_frac_num += frac_advance;
601 if (samp_frac_num >= den_rate)
603 samp_frac_num -= den_rate;
608 st->last_sample[channel_index] = last_sample;
609 st->samp_frac_num[channel_index] = samp_frac_num;
613static int multiply_frac(spx_uint32_t *result, spx_uint32_t value, spx_uint32_t num, spx_uint32_t den)
615 spx_uint32_t major = value / den;
616 spx_uint32_t remain = value % den;
618 if (remain > UINT32_MAX / num || major > UINT32_MAX / num
619 || major * num > UINT32_MAX - remain * num / den)
620 return RESAMPLER_ERR_OVERFLOW;
621 *result = remain * num / den + major * num;
622 return RESAMPLER_ERR_SUCCESS;
625static int update_filter(SpeexResamplerState *st)
627 spx_uint32_t old_length = st->filt_len;
628 spx_uint32_t old_alloc_size = st->mem_alloc_size;
630 spx_uint32_t min_sinc_table_length;
631 spx_uint32_t min_alloc_size;
633 st->int_advance = st->num_rate/st->den_rate;
634 st->frac_advance = st->num_rate%st->den_rate;
635 st->oversample = quality_map[st->quality].oversample;
636 st->filt_len = quality_map[st->quality].base_length;
638 if (st->num_rate > st->den_rate)
641 st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate;
642 if (multiply_frac(&st->filt_len,st->filt_len,st->num_rate,st->den_rate) != RESAMPLER_ERR_SUCCESS)
645 st->filt_len = ((st->filt_len-1)&(~0x7))+8;
646 if (2*st->den_rate < st->num_rate)
647 st->oversample >>= 1;
648 if (4*st->den_rate < st->num_rate)
649 st->oversample >>= 1;
650 if (8*st->den_rate < st->num_rate)
651 st->oversample >>= 1;
652 if (16*st->den_rate < st->num_rate)
653 st->oversample >>= 1;
654 if (st->oversample < 1)
658 st->cutoff = quality_map[st->quality].upsample_bandwidth;
661#ifdef RESAMPLE_FULL_SINC_TABLE
663 if (INT_MAX/
sizeof(spx_word16_t)/st->den_rate < st->filt_len)
667 use_direct = st->filt_len*st->den_rate <= st->filt_len*st->oversample+8
668 && INT_MAX/
sizeof(spx_word16_t)/st->den_rate >= st->filt_len;
672 min_sinc_table_length = st->filt_len*st->den_rate;
674 if ((INT_MAX/
sizeof(spx_word16_t)-8)/st->oversample < st->filt_len)
677 min_sinc_table_length = st->filt_len*st->oversample+8;
679 if (st->sinc_table_length < min_sinc_table_length)
681 spx_word16_t *sinc_table = (spx_word16_t *)
speex_realloc(st->sinc_table,min_sinc_table_length*
sizeof(spx_word16_t));
685 st->sinc_table = sinc_table;
686 st->sinc_table_length = min_sinc_table_length;
691 for (i=0;i<st->den_rate;i++)
694 for (j=0;j<(spx_int32_t)st->filt_len;j++)
696 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);
700 st->resampler_ptr = resampler_basic_direct_single;
703 st->resampler_ptr = resampler_basic_direct_double;
705 st->resampler_ptr = resampler_basic_direct_single;
710 for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++)
711 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);
713 st->resampler_ptr = resampler_basic_interpolate_single;
716 st->resampler_ptr = resampler_basic_interpolate_double;
718 st->resampler_ptr = resampler_basic_interpolate_single;
729 min_alloc_size = st->filt_len-1 + st->buffer_size;
730 if (min_alloc_size > st->mem_alloc_size)
733 if (INT_MAX/
sizeof(spx_word16_t)/st->nb_channels < min_alloc_size)
735 else if (!(mem = (spx_word16_t*)
speex_realloc(st->mem, st->nb_channels*min_alloc_size *
sizeof(*mem))))
739 st->mem_alloc_size = min_alloc_size;
744 for (i=0;i<st->nb_channels*st->mem_alloc_size;i++)
747 }
else if (st->filt_len > old_length)
752 for (i=st->nb_channels;i--;)
755 spx_uint32_t olen = old_length;
761 olen = old_length + 2*st->magic_samples[i];
762 for (j=old_length-1+st->magic_samples[i];j--;)
763 st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j];
764 for (j=0;j<st->magic_samples[i];j++)
765 st->mem[i*st->mem_alloc_size+j] = 0;
766 st->magic_samples[i] = 0;
768 if (st->filt_len > olen)
772 for (j=0;j<olen-1;j++)
773 st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)];
775 for (;j<st->filt_len-1;j++)
776 st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0;
778 st->last_sample[i] += (st->filt_len - olen)/2;
781 st->magic_samples[i] = (olen - st->filt_len)/2;
782 for (j=0;j<st->filt_len-1+st->magic_samples[i];j++)
783 st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];
786 }
else if (st->filt_len < old_length)
791 for (i=0;i<st->nb_channels;i++)
794 spx_uint32_t old_magic = st->magic_samples[i];
795 st->magic_samples[i] = (old_length - st->filt_len)/2;
798 for (j=0;j<st->filt_len-1+st->magic_samples[i]+old_magic;j++)
799 st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];
800 st->magic_samples[i] += old_magic;
803 return RESAMPLER_ERR_SUCCESS;
806 st->resampler_ptr = resampler_basic_zero;
810 st->filt_len = old_length;
811 return RESAMPLER_ERR_ALLOC_FAILED;
814EXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate,
int quality,
int *err)
816 return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err);
819EXPORT 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)
821 SpeexResamplerState *st;
824 if (nb_channels == 0 || ratio_num == 0 || ratio_den == 0 || quality > 10 || quality < 0)
827 *err = RESAMPLER_ERR_INVALID_ARG;
830 st = (SpeexResamplerState *)
speex_alloc(
sizeof(SpeexResamplerState));
834 *err = RESAMPLER_ERR_ALLOC_FAILED;
844 st->sinc_table_length = 0;
845 st->mem_alloc_size = 0;
848 st->resampler_ptr = 0;
851 st->nb_channels = nb_channels;
855 st->buffer_size = 160;
858 if (!(st->last_sample = (spx_int32_t*)
speex_alloc(nb_channels*
sizeof(spx_int32_t))))
860 if (!(st->magic_samples = (spx_uint32_t*)
speex_alloc(nb_channels*
sizeof(spx_uint32_t))))
862 if (!(st->samp_frac_num = (spx_uint32_t*)
speex_alloc(nb_channels*
sizeof(spx_uint32_t))))
865 speex_resampler_set_quality(st, quality);
866 speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate);
868 filter_err = update_filter(st);
869 if (filter_err == RESAMPLER_ERR_SUCCESS)
873 speex_resampler_destroy(st);
883 *err = RESAMPLER_ERR_ALLOC_FAILED;
884 speex_resampler_destroy(st);
888EXPORT
void speex_resampler_destroy(SpeexResamplerState *st)
898static 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)
901 const int N = st->filt_len;
903 spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
909 out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len);
911 if (st->last_sample[channel_index] < (spx_int32_t)*in_len)
912 *in_len = st->last_sample[channel_index];
913 *out_len = out_sample;
914 st->last_sample[channel_index] -= *in_len;
919 mem[j] = mem[j+ilen];
921 return RESAMPLER_ERR_SUCCESS;
924static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_index, spx_word16_t **out, spx_uint32_t out_len) {
925 spx_uint32_t tmp_in_len = st->magic_samples[channel_index];
926 spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
927 const int N = st->filt_len;
929 speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len);
931 st->magic_samples[channel_index] -= tmp_in_len;
934 if (st->magic_samples[channel_index])
937 for (i=0;i<st->magic_samples[channel_index];i++)
938 mem[N-1+i]=mem[N-1+i+tmp_in_len];
940 *out += out_len*st->out_stride;
945EXPORT
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)
947EXPORT
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)
951 spx_uint32_t ilen = *in_len;
952 spx_uint32_t olen = *out_len;
953 spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;
954 const int filt_offs = st->filt_len - 1;
955 const spx_uint32_t xlen = st->mem_alloc_size - filt_offs;
956 const int istride = st->in_stride;
958 if (st->magic_samples[channel_index])
959 olen -= speex_resampler_magic(st, channel_index, &out, olen);
960 if (! st->magic_samples[channel_index]) {
961 while (ilen && olen) {
962 spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;
963 spx_uint32_t ochunk = olen;
966 for(j=0;j<(int)ichunk;++j)
967 x[j+filt_offs]=in[j*istride];
969 for(j=0;j<(int)ichunk;++j)
972 speex_resampler_process_native(st, channel_index, &ichunk, out, &ochunk);
975 out += ochunk * st->out_stride;
977 in += ichunk * istride;
982 return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
986EXPORT
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)
988EXPORT
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)
992 const int istride_save = st->in_stride;
993 const int ostride_save = st->out_stride;
994 spx_uint32_t ilen = *in_len;
995 spx_uint32_t olen = *out_len;
996 spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;
997 const spx_uint32_t xlen = st->mem_alloc_size - (st->filt_len - 1);
999 const unsigned int ylen = (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC;
1000 spx_word16_t ystack[ylen];
1002 const unsigned int ylen = FIXED_STACK_ALLOC;
1003 spx_word16_t ystack[FIXED_STACK_ALLOC];
1008 while (ilen && olen) {
1009 spx_word16_t *y = ystack;
1010 spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;
1011 spx_uint32_t ochunk = (olen > ylen) ? ylen : olen;
1012 spx_uint32_t omagic = 0;
1014 if (st->magic_samples[channel_index]) {
1015 omagic = speex_resampler_magic(st, channel_index, &y, ochunk);
1019 if (! st->magic_samples[channel_index]) {
1021 for(j=0;j<(int)ichunk;++j)
1023 x[j+st->filt_len-1]=WORD2INT(in[j*istride_save]);
1025 x[j+st->filt_len-1]=in[j*istride_save];
1028 for(j=0;j<(int)ichunk;++j)
1029 x[j+st->filt_len-1]=0;
1032 speex_resampler_process_native(st, channel_index, &ichunk, y, &ochunk);
1038 for (j=0;j<(int)(ochunk+omagic);++j)
1040 out[j*ostride_save] = ystack[j];
1042 out[j*ostride_save] = WORD2INT(ystack[j]);
1047 out += (ochunk+omagic) * ostride_save;
1049 in += ichunk * istride_save;
1051 st->out_stride = ostride_save;
1055 return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
1058EXPORT
int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
const float *in, spx_uint32_t *in_len,
float *out, spx_uint32_t *out_len)
1061 int istride_save, ostride_save;
1062 spx_uint32_t bak_out_len = *out_len;
1063 spx_uint32_t bak_in_len = *in_len;
1064 istride_save = st->in_stride;
1065 ostride_save = st->out_stride;
1066 st->in_stride = st->out_stride = st->nb_channels;
1067 for (i=0;i<st->nb_channels;i++)
1069 *out_len = bak_out_len;
1070 *in_len = bak_in_len;
1072 speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len);
1074 speex_resampler_process_float(st, i, NULL, in_len, out+i, out_len);
1076 st->in_stride = istride_save;
1077 st->out_stride = ostride_save;
1078 return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
1081EXPORT
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)
1084 int istride_save, ostride_save;
1085 spx_uint32_t bak_out_len = *out_len;
1086 spx_uint32_t bak_in_len = *in_len;
1087 istride_save = st->in_stride;
1088 ostride_save = st->out_stride;
1089 st->in_stride = st->out_stride = st->nb_channels;
1090 for (i=0;i<st->nb_channels;i++)
1092 *out_len = bak_out_len;
1093 *in_len = bak_in_len;
1095 speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len);
1097 speex_resampler_process_int(st, i, NULL, in_len, out+i, out_len);
1099 st->in_stride = istride_save;
1100 st->out_stride = ostride_save;
1101 return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
1104EXPORT
int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate)
1106 return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);
1109EXPORT
void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate)
1111 *in_rate = st->in_rate;
1112 *out_rate = st->out_rate;
1115static inline spx_uint32_t compute_gcd(spx_uint32_t a, spx_uint32_t b)
1119 spx_uint32_t temp = a;
1127EXPORT
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)
1130 spx_uint32_t old_den;
1133 if (ratio_num == 0 || ratio_den == 0)
1134 return RESAMPLER_ERR_INVALID_ARG;
1136 if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)
1137 return RESAMPLER_ERR_SUCCESS;
1139 old_den = st->den_rate;
1140 st->in_rate = in_rate;
1141 st->out_rate = out_rate;
1142 st->num_rate = ratio_num;
1143 st->den_rate = ratio_den;
1145 fact = compute_gcd(st->num_rate, st->den_rate);
1147 st->num_rate /= fact;
1148 st->den_rate /= fact;
1152 for (i=0;i<st->nb_channels;i++)
1154 if (multiply_frac(&st->samp_frac_num[i],st->samp_frac_num[i],st->den_rate,old_den) != RESAMPLER_ERR_SUCCESS)
1155 return RESAMPLER_ERR_OVERFLOW;
1157 if (st->samp_frac_num[i] >= st->den_rate)
1158 st->samp_frac_num[i] = st->den_rate-1;
1162 if (st->initialised)
1163 return update_filter(st);
1164 return RESAMPLER_ERR_SUCCESS;
1167EXPORT
void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den)
1169 *ratio_num = st->num_rate;
1170 *ratio_den = st->den_rate;
1173EXPORT
int speex_resampler_set_quality(SpeexResamplerState *st,
int quality)
1175 if (quality > 10 || quality < 0)
1176 return RESAMPLER_ERR_INVALID_ARG;
1177 if (st->quality == quality)
1178 return RESAMPLER_ERR_SUCCESS;
1179 st->quality = quality;
1180 if (st->initialised)
1181 return update_filter(st);
1182 return RESAMPLER_ERR_SUCCESS;
1185EXPORT
void speex_resampler_get_quality(SpeexResamplerState *st,
int *quality)
1187 *quality = st->quality;
1190EXPORT
void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride)
1192 st->in_stride = stride;
1195EXPORT
void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride)
1197 *stride = st->in_stride;
1200EXPORT
void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride)
1202 st->out_stride = stride;
1205EXPORT
void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride)
1207 *stride = st->out_stride;
1210EXPORT
int speex_resampler_get_input_latency(SpeexResamplerState *st)
1212 return st->filt_len / 2;
1215EXPORT
int speex_resampler_get_output_latency(SpeexResamplerState *st)
1217 return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate;
1220EXPORT
int speex_resampler_skip_zeros(SpeexResamplerState *st)
1223 for (i=0;i<st->nb_channels;i++)
1224 st->last_sample[i] = st->filt_len/2;
1225 return RESAMPLER_ERR_SUCCESS;
1228EXPORT
int speex_resampler_reset_mem(SpeexResamplerState *st)
1231 for (i=0;i<st->nb_channels;i++)
1233 st->last_sample[i] = 0;
1234 st->magic_samples[i] = 0;
1235 st->samp_frac_num[i] = 0;
1237 for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
1239 return RESAMPLER_ERR_SUCCESS;
1242EXPORT
const char *speex_resampler_strerror(
int err)
1246 case RESAMPLER_ERR_SUCCESS:
1248 case RESAMPLER_ERR_ALLOC_FAILED:
1249 return "Memory allocation failed.";
1250 case RESAMPLER_ERR_BAD_STATE:
1251 return "Bad resampler state.";
1252 case RESAMPLER_ERR_INVALID_ARG:
1253 return "Invalid argument.";
1254 case RESAMPLER_ERR_PTR_OVERLAP:
1255 return "Input and output buffers overlap.";
1257 return "Unknown error. Bad error code or strange version mismatch.";
Various architecture definitions Speex.
Supported OSs for Speex resampler.
static void * speex_alloc(int size)
Speex wrapper for calloc.
static void * speex_realloc(void *ptr, int size)
Speex wrapper for realloc.
static void speex_free(void *ptr)
Speex wrapper for calloc.
Resampler functions (NEON version)
Resampler functions (SSE version)
Include header for SAF externals.
Main header file for the Speex resampler.