Asterisk - The Open Source Telephony Project GIT-master-67613d1
Data Structures | Macros | Typedefs | Functions | Variables
resample.c File Reference
#include "speex/speex_resampler.h"
#include "arch.h"
#include "os_support.h"
#include "stack_alloc.h"
#include <math.h>
#include <limits.h>
Include dependency graph for resample.c:

Go to the source code of this file.

Data Structures

struct  FuncDef
 
struct  QualityMapping
 
struct  SpeexResamplerState_
 

Macros

#define FIXED_STACK_ALLOC   1024
 
#define IMAX(a, b)   ((a) > (b) ? (a) : (b))
 
#define IMIN(a, b)   ((a) < (b) ? (a) : (b))
 
#define KAISER10   (&_KAISER10)
 
#define KAISER12   (&_KAISER12)
 
#define KAISER6   (&_KAISER6)
 
#define KAISER8   (&_KAISER8)
 
#define M_PI   3.14159265358979323846
 
#define NULL   0
 
#define WORD2INT(x)   ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x)))
 

Typedefs

typedef int(* resampler_basic_func) (SpeexResamplerState *, spx_uint32_t, const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *)
 

Functions

static double compute_func (float x, const struct FuncDef *func)
 
static void cubic_coef (spx_word16_t x, spx_word16_t interp[4])
 
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)
 
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)
 
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)
 
static spx_word16_t sinc (float cutoff, float x, int N, const struct FuncDef *window_func)
 
EXPORT void speex_resampler_destroy (SpeexResamplerState *st)
 
EXPORT int speex_resampler_get_input_latency (SpeexResamplerState *st)
 
EXPORT void speex_resampler_get_input_stride (SpeexResamplerState *st, spx_uint32_t *stride)
 
EXPORT int speex_resampler_get_output_latency (SpeexResamplerState *st)
 
EXPORT void speex_resampler_get_output_stride (SpeexResamplerState *st, spx_uint32_t *stride)
 
EXPORT void speex_resampler_get_quality (SpeexResamplerState *st, int *quality)
 
EXPORT void speex_resampler_get_rate (SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate)
 
EXPORT void speex_resampler_get_ratio (SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den)
 
EXPORT SpeexResamplerStatespeex_resampler_init (spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)
 Create a new resampler with integer input and output rates. More...
 
EXPORT SpeexResamplerStatespeex_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)
 
static int speex_resampler_magic (SpeexResamplerState *st, spx_uint32_t channel_index, spx_word16_t **out, spx_uint32_t out_len)
 
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)
 
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)
 
EXPORT int speex_resampler_process_interleaved_float (SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
 
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)
 
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)
 
EXPORT int speex_resampler_reset_mem (SpeexResamplerState *st)
 
EXPORT void speex_resampler_set_input_stride (SpeexResamplerState *st, spx_uint32_t stride)
 
EXPORT void speex_resampler_set_output_stride (SpeexResamplerState *st, spx_uint32_t stride)
 
EXPORT int speex_resampler_set_quality (SpeexResamplerState *st, int quality)
 
EXPORT int speex_resampler_set_rate (SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate)
 
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)
 
EXPORT int speex_resampler_skip_zeros (SpeexResamplerState *st)
 
EXPORT const char * speex_resampler_strerror (int err)
 
static int update_filter (SpeexResamplerState *st)
 

Variables

static const struct FuncDef _KAISER10 = {kaiser10_table, 32}
 
static const struct FuncDef _KAISER12 = {kaiser12_table, 64}
 
static const struct FuncDef _KAISER6 = {kaiser6_table, 32}
 
static const struct FuncDef _KAISER8 = {kaiser8_table, 32}
 
static const double kaiser10_table [36]
 
static const double kaiser12_table [68]
 
static const double kaiser6_table [36]
 
static const double kaiser8_table [36]
 
static const struct QualityMapping quality_map [11]
 

Macro Definition Documentation

◆ FIXED_STACK_ALLOC

#define FIXED_STACK_ALLOC   1024

Definition at line 111 of file resample.c.

◆ IMAX

#define IMAX (   a,
  b 
)    ((a) > (b) ? (a) : (b))

Definition at line 92 of file resample.c.

◆ IMIN

#define IMIN (   a,
  b 
)    ((a) < (b) ? (a) : (b))

Definition at line 93 of file resample.c.

◆ KAISER10

#define KAISER10   (&_KAISER10)

Definition at line 204 of file resample.c.

◆ KAISER12

#define KAISER12   (&_KAISER12)

Definition at line 200 of file resample.c.

◆ KAISER6

#define KAISER6   (&_KAISER6)

Definition at line 208 of file resample.c.

◆ KAISER8

#define KAISER8   (&_KAISER8)

Definition at line 206 of file resample.c.

◆ M_PI

#define M_PI   3.14159265358979323846

Definition at line 83 of file resample.c.

◆ NULL

#define NULL   0
Examples
app_skel.c.

Definition at line 96 of file resample.c.

◆ WORD2INT

#define WORD2INT (   x)    ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x)))

Definition at line 87 of file resample.c.

Typedef Documentation

◆ resampler_basic_func

typedef int(* resampler_basic_func) (SpeexResamplerState *, spx_uint32_t, const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *)

Definition at line 114 of file resample.c.

Function Documentation

◆ compute_func()

static double compute_func ( float  x,
const struct FuncDef func 
)
static

Definition at line 242 of file resample.c.

243{
244 float y, frac;
245 double interp[4];
246 int ind;
247 y = x*func->oversample;
248 ind = (int)floor(y);
249 frac = (y-ind);
250 /* CSE with handle the repeated powers */
251 interp[3] = -0.1666666667*frac + 0.1666666667*(frac*frac*frac);
252 interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac);
253 /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/
254 interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac);
255 /* Just to make sure we don't have rounding problems */
256 interp[1] = 1.f-interp[3]-interp[2]-interp[0];
257
258 /*sum = frac*accum[1] + (1-frac)*accum[2];*/
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];
260}
const double * table
Definition: resample.c:195
int oversample
Definition: resample.c:196

References FuncDef::oversample, and FuncDef::table.

Referenced by sinc().

◆ cubic_coef()

static void cubic_coef ( spx_word16_t  x,
spx_word16_t  interp[4] 
)
static

Definition at line 304 of file resample.c.

305{
306 /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation
307 but I know it's MMSE-optimal on a sinc */
308 spx_word16_t x2, x3;
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);
314 /* Just to make sure we don't have rounding problems */
315 interp[2] = Q15_ONE-interp[0]-interp[1]-interp[3];
316 if (interp[2]<32767)
317 interp[2]+=1;
318}
#define Q15_ONE
Definition: arch.h:109
spx_int16_t spx_word16_t
Definition: arch.h:85
#define QCONST16(x, bits)
Definition: fixed_generic.h:38
#define SHR32(a, shift)
Definition: fixed_generic.h:47
#define MULT16_16(a, b)
Definition: fixed_generic.h:75
#define PSHR32(a, shift)
Definition: fixed_generic.h:50
#define EXTEND32(x)
Definition: fixed_generic.h:44
#define EXTRACT16(x)
Definition: fixed_generic.h:43
#define SUB32(a, b)
Definition: fixed_generic.h:68
#define MULT16_16_P15(a, b)

References EXTEND32, EXTRACT16, MULT16_16, MULT16_16_P15, PSHR32, Q15_ONE, QCONST16, SHR32, and SUB32.

Referenced by resampler_basic_interpolate_single().

◆ resampler_basic_direct_single()

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 
)
static

Definition at line 333 of file resample.c.

334{
335 const int N = st->filt_len;
336 int out_sample = 0;
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;
344 spx_word32_t sum;
345
346 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
347 {
348 const spx_word16_t *sinct = & sinc_table[samp_frac_num*N];
349 const spx_word16_t *iptr = & in[last_sample];
350
351#ifndef OVERRIDE_INNER_PRODUCT_SINGLE
352 int j;
353 sum = 0;
354 for(j=0;j<N;j++) sum += MULT16_16(sinct[j], iptr[j]);
355
356/* This code is slower on most DSPs which have only 2 accumulators.
357 Plus this this forces truncation to 32 bits and you lose the HW guard bits.
358 I think we can trust the compiler and let it vectorize and/or unroll itself.
359 spx_word32_t accum[4] = {0,0,0,0};
360 for(j=0;j<N;j+=4) {
361 accum[0] += MULT16_16(sinct[j], iptr[j]);
362 accum[1] += MULT16_16(sinct[j+1], iptr[j+1]);
363 accum[2] += MULT16_16(sinct[j+2], iptr[j+2]);
364 accum[3] += MULT16_16(sinct[j+3], iptr[j+3]);
365 }
366 sum = accum[0] + accum[1] + accum[2] + accum[3];
367*/
368 sum = SATURATE32PSHR(sum, 15, 32767);
369#else
370 sum = inner_product_single(sinct, iptr, N);
371#endif
372
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)
377 {
378 samp_frac_num -= den_rate;
379 last_sample++;
380 }
381 }
382
383 st->last_sample[channel_index] = last_sample;
384 st->samp_frac_num[channel_index] = samp_frac_num;
385 return out_sample;
386}
spx_int32_t spx_word32_t
Definition: arch.h:86
#define SATURATE32PSHR(x, shift, a)
Definition: fixed_generic.h:55
static float inner_product_single(const float *a, const float *b, unsigned int len)
Definition: resample_sse.h:40
spx_uint32_t den_rate
Definition: resample.c:120
spx_uint32_t * samp_frac_num
Definition: resample.c:136
spx_word16_t * sinc_table
Definition: resample.c:140
spx_uint32_t filt_len
Definition: resample.c:124
spx_int32_t * last_sample
Definition: resample.c:135
FILE * out
Definition: utils/frame.c:33
FILE * in
Definition: utils/frame.c:33

References SpeexResamplerState_::den_rate, SpeexResamplerState_::filt_len, SpeexResamplerState_::frac_advance, in, inner_product_single(), SpeexResamplerState_::int_advance, SpeexResamplerState_::last_sample, MULT16_16, out, SpeexResamplerState_::out_stride, SpeexResamplerState_::samp_frac_num, SATURATE32PSHR, and SpeexResamplerState_::sinc_table.

Referenced by update_filter().

◆ resampler_basic_interpolate_single()

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 
)
static

Definition at line 440 of file resample.c.

441{
442 const int N = st->filt_len;
443 int out_sample = 0;
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;
450 spx_word32_t sum;
451
452 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
453 {
454 const spx_word16_t *iptr = & in[last_sample];
455
456 const int offset = samp_frac_num*st->oversample/st->den_rate;
457#ifdef FIXED_POINT
458 const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);
459#else
460 const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;
461#endif
462 spx_word16_t interp[4];
463
464
465#ifndef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
466 int j;
467 spx_word32_t accum[4] = {0,0,0,0};
468
469 for(j=0;j<N;j++) {
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]);
475 }
476
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);
480#else
481 cubic_coef(frac, interp);
482 sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);
483#endif
484
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)
489 {
490 samp_frac_num -= den_rate;
491 last_sample++;
492 }
493 }
494
495 st->last_sample[channel_index] = last_sample;
496 st->samp_frac_num[channel_index] = samp_frac_num;
497 return out_sample;
498}
#define PDIV32(a, b)
#define SHL32(a, shift)
Definition: fixed_generic.h:48
#define MULT16_32_Q15(a, b)
Definition: fixed_generic.h:86
static void cubic_coef(spx_word16_t x, spx_word16_t interp[4])
Definition: resample.c:304
static float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac)
Definition: resample_sse.h:57
spx_uint32_t oversample
Definition: resample.c:130

References cubic_coef(), SpeexResamplerState_::den_rate, SpeexResamplerState_::filt_len, SpeexResamplerState_::frac_advance, in, SpeexResamplerState_::int_advance, interpolate_product_single(), SpeexResamplerState_::last_sample, MULT16_16, MULT16_32_Q15, out, SpeexResamplerState_::out_stride, SpeexResamplerState_::oversample, PDIV32, SpeexResamplerState_::samp_frac_num, SATURATE32PSHR, SHL32, SHR32, and SpeexResamplerState_::sinc_table.

Referenced by update_filter().

◆ resampler_basic_zero()

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 
)
static

Definition at line 567 of file resample.c.

568{
569 int out_sample = 0;
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;
576
577 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
578 {
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)
583 {
584 samp_frac_num -= den_rate;
585 last_sample++;
586 }
587 }
588
589 st->last_sample[channel_index] = last_sample;
590 st->samp_frac_num[channel_index] = samp_frac_num;
591 return out_sample;
592}

References SpeexResamplerState_::den_rate, SpeexResamplerState_::frac_advance, SpeexResamplerState_::int_advance, SpeexResamplerState_::last_sample, out, SpeexResamplerState_::out_stride, and SpeexResamplerState_::samp_frac_num.

Referenced by speex_resampler_process_float(), speex_resampler_process_int(), speex_resampler_process_interleaved_float(), speex_resampler_process_interleaved_int(), and update_filter().

◆ sinc()

static spx_word16_t sinc ( float  cutoff,
float  x,
int  N,
const struct FuncDef window_func 
)
static

Definition at line 277 of file resample.c.

278{
279 /*fprintf (stderr, "%f ", x);*/
280 float xx = x * cutoff;
281 if (fabs(x)<1e-6f)
282 return WORD2INT(32768.*cutoff);
283 else if (fabs(x) > .5f*N)
284 return 0;
285 /*FIXME: Can it really be any slower than this? */
286 return WORD2INT(32768.*cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func));
287}
static double compute_func(float x, const struct FuncDef *func)
Definition: resample.c:242
#define WORD2INT(x)
Definition: resample.c:87
#define M_PI
Definition: resample.c:83

References compute_func(), M_PI, QualityMapping::window_func, and WORD2INT.

Referenced by update_filter().

◆ speex_resampler_destroy()

EXPORT void speex_resampler_destroy ( SpeexResamplerState st)

Destroy a resampler state.

Parameters
stResampler state

Definition at line 849 of file resample.c.

850{
851 speex_free(st->mem);
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);
856 speex_free(st);
857}
spx_word16_t * mem
Definition: resample.c:139
spx_uint32_t * magic_samples
Definition: resample.c:137

References SpeexResamplerState_::last_sample, SpeexResamplerState_::magic_samples, SpeexResamplerState_::mem, SpeexResamplerState_::samp_frac_num, and SpeexResamplerState_::sinc_table.

Referenced by resamp_destroy(), and speex_resampler_init_frac().

◆ speex_resampler_get_input_latency()

EXPORT int speex_resampler_get_input_latency ( SpeexResamplerState st)

Get the latency in input samples introduced by the resampler.

Parameters
stResampler state

Definition at line 1159 of file resample.c.

1160{
1161 return st->filt_len / 2;
1162}

References SpeexResamplerState_::filt_len.

◆ speex_resampler_get_input_stride()

EXPORT void speex_resampler_get_input_stride ( SpeexResamplerState st,
spx_uint32_t *  stride 
)

Get the input stride.

Parameters
stResampler state
strideInput stride copied

Definition at line 1144 of file resample.c.

1145{
1146 *stride = st->in_stride;
1147}

References SpeexResamplerState_::in_stride.

◆ speex_resampler_get_output_latency()

EXPORT int speex_resampler_get_output_latency ( SpeexResamplerState st)

Get the latency in output samples introduced by the resampler.

Parameters
stResampler state

Definition at line 1164 of file resample.c.

1165{
1166 return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate;
1167}
spx_uint32_t num_rate
Definition: resample.c:119

References SpeexResamplerState_::den_rate, SpeexResamplerState_::filt_len, and SpeexResamplerState_::num_rate.

◆ speex_resampler_get_output_stride()

EXPORT void speex_resampler_get_output_stride ( SpeexResamplerState st,
spx_uint32_t *  stride 
)

Get the output stride.

Parameters
stResampler state copied
strideOutput stride

Definition at line 1154 of file resample.c.

1155{
1156 *stride = st->out_stride;
1157}

References SpeexResamplerState_::out_stride.

◆ speex_resampler_get_quality()

EXPORT void speex_resampler_get_quality ( SpeexResamplerState st,
int *  quality 
)

Get the conversion quality.

Parameters
stResampler state
qualityResampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality.

Definition at line 1134 of file resample.c.

1135{
1136 *quality = st->quality;
1137}
static int quality
Definition: codec_speex.c:62

References quality, and SpeexResamplerState_::quality.

◆ speex_resampler_get_rate()

EXPORT void speex_resampler_get_rate ( SpeexResamplerState st,
spx_uint32_t *  in_rate,
spx_uint32_t *  out_rate 
)

Get the current input/output sampling rates (integer value).

Parameters
stResampler state
in_rateInput sampling rate (integer number of Hz) copied.
out_rateOutput sampling rate (integer number of Hz) copied.

Definition at line 1071 of file resample.c.

1072{
1073 *in_rate = st->in_rate;
1074 *out_rate = st->out_rate;
1075}
spx_uint32_t out_rate
Definition: resample.c:118
spx_uint32_t in_rate
Definition: resample.c:117

References SpeexResamplerState_::in_rate, and SpeexResamplerState_::out_rate.

◆ speex_resampler_get_ratio()

EXPORT void speex_resampler_get_ratio ( SpeexResamplerState st,
spx_uint32_t *  ratio_num,
spx_uint32_t *  ratio_den 
)

Get the current resampling ratio. This will be reduced to the least common denominator.

Parameters
stResampler state
ratio_numNumerator of the sampling rate ratio copied
ratio_denDenominator of the sampling rate ratio copied

Definition at line 1116 of file resample.c.

1117{
1118 *ratio_num = st->num_rate;
1119 *ratio_den = st->den_rate;
1120}

References SpeexResamplerState_::den_rate, and SpeexResamplerState_::num_rate.

◆ speex_resampler_init()

EXPORT SpeexResamplerState * speex_resampler_init ( spx_uint32_t  nb_channels,
spx_uint32_t  in_rate,
spx_uint32_t  out_rate,
int  quality,
int *  err 
)

Create a new resampler with integer input and output rates.

Parameters
nb_channelsNumber of channels to be processed
in_rateInput sampling rate (integer number of Hz).
out_rateOutput sampling rate (integer number of Hz).
qualityResampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality.
err
Returns
Newly created resampler state
Return values
NULLError: not enough memory

Definition at line 783 of file resample.c.

784{
785 return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err);
786}
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)
Definition: resample.c:788

References quality, and speex_resampler_init_frac().

Referenced by resamp_new().

◆ speex_resampler_init_frac()

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 
)

Create a new resampler with fractional input/output rates. The sampling rate ratio is an arbitrary rational number with both the numerator and denominator being 32-bit integers.

Parameters
nb_channelsNumber of channels to be processed
ratio_numNumerator of the sampling rate ratio
ratio_denDenominator of the sampling rate ratio
in_rateInput sampling rate rounded to the nearest integer (in Hz).
out_rateOutput sampling rate rounded to the nearest integer (in Hz).
qualityResampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality.
err
Returns
Newly created resampler state
Return values
NULLError: not enough memory

Definition at line 788 of file resample.c.

789{
790 spx_uint32_t i;
792 int filter_err;
793
794 if (quality > 10 || quality < 0)
795 {
796 if (err)
798 return NULL;
799 }
800 st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState));
801 st->initialised = 0;
802 st->started = 0;
803 st->in_rate = 0;
804 st->out_rate = 0;
805 st->num_rate = 0;
806 st->den_rate = 0;
807 st->quality = -1;
808 st->sinc_table_length = 0;
809 st->mem_alloc_size = 0;
810 st->filt_len = 0;
811 st->mem = 0;
812 st->resampler_ptr = 0;
813
814 st->cutoff = 1.f;
815 st->nb_channels = nb_channels;
816 st->in_stride = 1;
817 st->out_stride = 1;
818
819 st->buffer_size = 160;
820
821 /* Per channel data */
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++)
826 {
827 st->last_sample[i] = 0;
828 st->magic_samples[i] = 0;
829 st->samp_frac_num[i] = 0;
830 }
831
833 speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate);
834
835 filter_err = update_filter(st);
836 if (filter_err == RESAMPLER_ERR_SUCCESS)
837 {
838 st->initialised = 1;
839 } else {
841 st = NULL;
842 }
843 if (err)
844 *err = filter_err;
845
846 return st;
847}
#define NULL
Definition: resample.c:96
EXPORT void speex_resampler_destroy(SpeexResamplerState *st)
Definition: resample.c:849
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)
Definition: resample.c:1077
static int update_filter(SpeexResamplerState *st)
Definition: resample.c:594
EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality)
Definition: resample.c:1122
@ RESAMPLER_ERR_INVALID_ARG
@ RESAMPLER_ERR_SUCCESS
resampler_basic_func resampler_ptr
Definition: resample.c:142
spx_uint32_t nb_channels
Definition: resample.c:123
spx_uint32_t sinc_table_length
Definition: resample.c:141
spx_uint32_t buffer_size
Definition: resample.c:126
spx_uint32_t mem_alloc_size
Definition: resample.c:125

References SpeexResamplerState_::buffer_size, SpeexResamplerState_::cutoff, SpeexResamplerState_::den_rate, SpeexResamplerState_::filt_len, SpeexResamplerState_::in_rate, SpeexResamplerState_::in_stride, SpeexResamplerState_::initialised, SpeexResamplerState_::last_sample, SpeexResamplerState_::magic_samples, SpeexResamplerState_::mem, SpeexResamplerState_::mem_alloc_size, SpeexResamplerState_::nb_channels, NULL, SpeexResamplerState_::num_rate, SpeexResamplerState_::out_rate, SpeexResamplerState_::out_stride, quality, SpeexResamplerState_::quality, RESAMPLER_ERR_INVALID_ARG, RESAMPLER_ERR_SUCCESS, SpeexResamplerState_::resampler_ptr, SpeexResamplerState_::samp_frac_num, SpeexResamplerState_::sinc_table_length, speex_resampler_destroy(), speex_resampler_set_quality(), speex_resampler_set_rate_frac(), SpeexResamplerState_::started, and update_filter().

Referenced by speex_resampler_init().

◆ speex_resampler_magic()

static int speex_resampler_magic ( SpeexResamplerState st,
spx_uint32_t  channel_index,
spx_word16_t **  out,
spx_uint32_t  out_len 
)
static

Definition at line 885 of file resample.c.

885 {
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;
889
890 speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len);
891
892 st->magic_samples[channel_index] -= tmp_in_len;
893
894 /* If we couldn't process all "magic" input samples, save the rest for next time */
895 if (st->magic_samples[channel_index])
896 {
897 spx_uint32_t i;
898 for (i=0;i<st->magic_samples[channel_index];i++)
899 mem[N-1+i]=mem[N-1+i+tmp_in_len];
900 }
901 *out += out_len*st->out_stride;
902 return out_len;
903}
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)
Definition: resample.c:859

References SpeexResamplerState_::filt_len, SpeexResamplerState_::magic_samples, SpeexResamplerState_::mem, SpeexResamplerState_::mem_alloc_size, out, SpeexResamplerState_::out_stride, and speex_resampler_process_native().

Referenced by speex_resampler_process_float(), and speex_resampler_process_int().

◆ speex_resampler_process_float()

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 
)

Resample a float array. The input and output buffers must not overlap.

Parameters
stResampler state
channel_indexIndex of the channel to process for the multi-channel base (0 otherwise)
inInput buffer
in_lenNumber of input samples in the input buffer. Returns the number of samples processed
outOutput buffer
out_lenSize of the output buffer. Returns the number of samples written

Definition at line 947 of file resample.c.

951{
952 int j;
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);
959#ifdef VAR_ARRAYS
960 const unsigned int ylen = (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC;
961 VARDECL(spx_word16_t *ystack);
962 ALLOC(ystack, ylen, spx_word16_t);
963#else
964 const unsigned int ylen = FIXED_STACK_ALLOC;
966#endif
967
968 st->out_stride = 1;
969
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;
975
976 if (st->magic_samples[channel_index]) {
977 omagic = speex_resampler_magic(st, channel_index, &y, ochunk);
978 ochunk -= omagic;
979 olen -= omagic;
980 }
981 if (! st->magic_samples[channel_index]) {
982 if (in) {
983 for(j=0;j<ichunk;++j)
984#ifdef FIXED_POINT
985 x[j+st->filt_len-1]=WORD2INT(in[j*istride_save]);
986#else
987 x[j+st->filt_len-1]=in[j*istride_save];
988#endif
989 } else {
990 for(j=0;j<ichunk;++j)
991 x[j+st->filt_len-1]=0;
992 }
993
994 speex_resampler_process_native(st, channel_index, &ichunk, y, &ochunk);
995 } else {
996 ichunk = 0;
997 ochunk = 0;
998 }
999
1000 for (j=0;j<ochunk+omagic;++j)
1001#ifdef FIXED_POINT
1002 out[j*ostride_save] = ystack[j];
1003#else
1004 out[j*ostride_save] = WORD2INT(ystack[j]);
1005#endif
1006
1007 ilen -= ichunk;
1008 olen -= ochunk;
1009 out += (ochunk+omagic) * ostride_save;
1010 if (in)
1011 in += ichunk * istride_save;
1012 }
1013 st->out_stride = ostride_save;
1014 *in_len -= ilen;
1015 *out_len -= olen;
1016
1018}
#define FIXED_POINT
Definition: arch.h:38
#define FIXED_STACK_ALLOC
Definition: resample.c:111
static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_index, spx_word16_t **out, spx_uint32_t out_len)
Definition: resample.c:885
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)
Definition: resample.c:567
@ RESAMPLER_ERR_ALLOC_FAILED
#define VARDECL(var)
Definition: stack_alloc.h:110
#define ALLOC(var, size, type)
Definition: stack_alloc.h:111

References ALLOC, SpeexResamplerState_::filt_len, FIXED_POINT, FIXED_STACK_ALLOC, in, SpeexResamplerState_::in_stride, SpeexResamplerState_::magic_samples, SpeexResamplerState_::mem, SpeexResamplerState_::mem_alloc_size, out, SpeexResamplerState_::out_stride, resampler_basic_zero(), RESAMPLER_ERR_ALLOC_FAILED, RESAMPLER_ERR_SUCCESS, SpeexResamplerState_::resampler_ptr, speex_resampler_magic(), speex_resampler_process_native(), VARDECL, and WORD2INT.

Referenced by speex_resampler_process_interleaved_float().

◆ speex_resampler_process_int()

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 
)

Resample an int array. The input and output buffers must not overlap.

Parameters
stResampler state
channel_indexIndex of the channel to process for the multi-channel base (0 otherwise)
inInput buffer
in_lenNumber of input samples in the input buffer. Returns the number of samples processed
outOutput buffer
out_lenSize of the output buffer. Returns the number of samples written

Definition at line 906 of file resample.c.

910{
911 int j;
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;
918
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;
925
926 if (in) {
927 for(j=0;j<ichunk;++j)
928 x[j+filt_offs]=in[j*istride];
929 } else {
930 for(j=0;j<ichunk;++j)
931 x[j+filt_offs]=0;
932 }
933 speex_resampler_process_native(st, channel_index, &ichunk, out, &ochunk);
934 ilen -= ichunk;
935 olen -= ochunk;
936 out += ochunk * st->out_stride;
937 if (in)
938 in += ichunk * istride;
939 }
940 }
941 *in_len -= ilen;
942 *out_len -= olen;
944}

References SpeexResamplerState_::filt_len, in, SpeexResamplerState_::in_stride, SpeexResamplerState_::magic_samples, SpeexResamplerState_::mem, SpeexResamplerState_::mem_alloc_size, out, SpeexResamplerState_::out_stride, resampler_basic_zero(), RESAMPLER_ERR_ALLOC_FAILED, RESAMPLER_ERR_SUCCESS, SpeexResamplerState_::resampler_ptr, speex_resampler_magic(), and speex_resampler_process_native().

Referenced by resamp_framein(), and speex_resampler_process_interleaved_int().

◆ speex_resampler_process_interleaved_float()

EXPORT int speex_resampler_process_interleaved_float ( SpeexResamplerState st,
const float *  in,
spx_uint32_t *  in_len,
float *  out,
spx_uint32_t *  out_len 
)

Resample an interleaved float array. The input and output buffers must not overlap.

Parameters
stResampler state
inInput buffer
in_lenNumber of input samples in the input buffer. Returns the number of samples processed. This is all per-channel.
outOutput buffer
out_lenSize of the output buffer. Returns the number of samples written. This is all per-channel.

Definition at line 1020 of file resample.c.

1021{
1022 spx_uint32_t i;
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++)
1030 {
1031 *out_len = bak_out_len;
1032 *in_len = bak_in_len;
1033 if (in != NULL)
1034 speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len);
1035 else
1036 speex_resampler_process_float(st, i, NULL, in_len, out+i, out_len);
1037 }
1038 st->in_stride = istride_save;
1039 st->out_stride = ostride_save;
1041}
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)
Definition: resample.c:947

References in, SpeexResamplerState_::in_stride, SpeexResamplerState_::nb_channels, NULL, out, SpeexResamplerState_::out_stride, resampler_basic_zero(), RESAMPLER_ERR_ALLOC_FAILED, RESAMPLER_ERR_SUCCESS, SpeexResamplerState_::resampler_ptr, and speex_resampler_process_float().

◆ speex_resampler_process_interleaved_int()

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 
)

Resample an interleaved int array. The input and output buffers must not overlap.

Parameters
stResampler state
inInput buffer
in_lenNumber of input samples in the input buffer. Returns the number of samples processed. This is all per-channel.
outOutput buffer
out_lenSize of the output buffer. Returns the number of samples written. This is all per-channel.

Definition at line 1043 of file resample.c.

1044{
1045 spx_uint32_t i;
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++)
1053 {
1054 *out_len = bak_out_len;
1055 *in_len = bak_in_len;
1056 if (in != NULL)
1057 speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len);
1058 else
1059 speex_resampler_process_int(st, i, NULL, in_len, out+i, out_len);
1060 }
1061 st->in_stride = istride_save;
1062 st->out_stride = ostride_save;
1064}
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)
Definition: resample.c:906

References in, SpeexResamplerState_::in_stride, SpeexResamplerState_::nb_channels, NULL, out, SpeexResamplerState_::out_stride, resampler_basic_zero(), RESAMPLER_ERR_ALLOC_FAILED, RESAMPLER_ERR_SUCCESS, SpeexResamplerState_::resampler_ptr, and speex_resampler_process_int().

◆ speex_resampler_process_native()

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 
)
static

Definition at line 859 of file resample.c.

860{
861 int j=0;
862 const int N = st->filt_len;
863 int out_sample = 0;
864 spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
865 spx_uint32_t ilen;
866
867 st->started = 1;
868
869 /* Call the right resampler through the function ptr */
870 out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len);
871
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;
876
877 ilen = *in_len;
878
879 for(j=0;j<N-1;++j)
880 mem[j] = mem[j+ilen];
881
883}

References SpeexResamplerState_::filt_len, SpeexResamplerState_::last_sample, SpeexResamplerState_::mem, SpeexResamplerState_::mem_alloc_size, out, RESAMPLER_ERR_SUCCESS, SpeexResamplerState_::resampler_ptr, and SpeexResamplerState_::started.

Referenced by speex_resampler_magic(), speex_resampler_process_float(), and speex_resampler_process_int().

◆ speex_resampler_reset_mem()

EXPORT int speex_resampler_reset_mem ( SpeexResamplerState st)

Reset a resampler so a new (unrelated) stream can be processed.

Parameters
stResampler state

Definition at line 1177 of file resample.c.

1178{
1179 spx_uint32_t i;
1180 for (i=0;i<st->nb_channels;i++)
1181 {
1182 st->last_sample[i] = 0;
1183 st->magic_samples[i] = 0;
1184 st->samp_frac_num[i] = 0;
1185 }
1186 for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
1187 st->mem[i] = 0;
1188 return RESAMPLER_ERR_SUCCESS;
1189}

References SpeexResamplerState_::filt_len, SpeexResamplerState_::last_sample, SpeexResamplerState_::magic_samples, SpeexResamplerState_::mem, SpeexResamplerState_::nb_channels, RESAMPLER_ERR_SUCCESS, and SpeexResamplerState_::samp_frac_num.

◆ speex_resampler_set_input_stride()

EXPORT void speex_resampler_set_input_stride ( SpeexResamplerState st,
spx_uint32_t  stride 
)

Set (change) the input stride.

Parameters
stResampler state
strideInput stride

Definition at line 1139 of file resample.c.

1140{
1141 st->in_stride = stride;
1142}

References SpeexResamplerState_::in_stride.

◆ speex_resampler_set_output_stride()

EXPORT void speex_resampler_set_output_stride ( SpeexResamplerState st,
spx_uint32_t  stride 
)

Set (change) the output stride.

Parameters
stResampler state
strideOutput stride

Definition at line 1149 of file resample.c.

1150{
1151 st->out_stride = stride;
1152}

References SpeexResamplerState_::out_stride.

◆ speex_resampler_set_quality()

EXPORT int speex_resampler_set_quality ( SpeexResamplerState st,
int  quality 
)

Set (change) the conversion quality.

Parameters
stResampler state
qualityResampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality.

Definition at line 1122 of file resample.c.

1123{
1124 if (quality > 10 || quality < 0)
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;
1132}

References SpeexResamplerState_::initialised, quality, SpeexResamplerState_::quality, RESAMPLER_ERR_INVALID_ARG, RESAMPLER_ERR_SUCCESS, and update_filter().

Referenced by speex_resampler_init_frac().

◆ speex_resampler_set_rate()

EXPORT int speex_resampler_set_rate ( SpeexResamplerState st,
spx_uint32_t  in_rate,
spx_uint32_t  out_rate 
)

Set (change) the input/output sampling rates (integer value).

Parameters
stResampler state
in_rateInput sampling rate (integer number of Hz).
out_rateOutput sampling rate (integer number of Hz).

Definition at line 1066 of file resample.c.

1067{
1068 return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);
1069}

References speex_resampler_set_rate_frac().

◆ speex_resampler_set_rate_frac()

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 
)

Set (change) the input/output sampling rates and resampling ratio (fractional values in Hz supported).

Parameters
stResampler state
ratio_numNumerator of the sampling rate ratio
ratio_denDenominator of the sampling rate ratio
in_rateInput sampling rate rounded to the nearest integer (in Hz).
out_rateOutput sampling rate rounded to the nearest integer (in Hz).

Definition at line 1077 of file resample.c.

1078{
1079 spx_uint32_t fact;
1080 spx_uint32_t old_den;
1081 spx_uint32_t i;
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;
1084
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;
1090 /* FIXME: This is terribly inefficient, but who cares (at least for now)? */
1091 for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++)
1092 {
1093 while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))
1094 {
1095 st->num_rate /= fact;
1096 st->den_rate /= fact;
1097 }
1098 }
1099
1100 if (old_den > 0)
1101 {
1102 for (i=0;i<st->nb_channels;i++)
1103 {
1104 st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den;
1105 /* Safety net */
1106 if (st->samp_frac_num[i] >= st->den_rate)
1107 st->samp_frac_num[i] = st->den_rate-1;
1108 }
1109 }
1110
1111 if (st->initialised)
1112 return update_filter(st);
1113 return RESAMPLER_ERR_SUCCESS;
1114}
#define IMIN(a, b)
Definition: resample.c:93

References SpeexResamplerState_::den_rate, IMIN, SpeexResamplerState_::in_rate, SpeexResamplerState_::initialised, SpeexResamplerState_::nb_channels, SpeexResamplerState_::num_rate, SpeexResamplerState_::out_rate, RESAMPLER_ERR_SUCCESS, SpeexResamplerState_::samp_frac_num, and update_filter().

Referenced by speex_resampler_init_frac(), and speex_resampler_set_rate().

◆ speex_resampler_skip_zeros()

EXPORT int speex_resampler_skip_zeros ( SpeexResamplerState st)

Make sure that the first samples to go out of the resamplers don't have leading zeros. This is only useful before starting to use a newly created resampler. It is recommended to use that when resampling an audio file, as it will generate a file with the same length. For real-time processing, it is probably easier not to use this call (so that the output duration is the same for the first frame).

Parameters
stResampler state

Definition at line 1169 of file resample.c.

1170{
1171 spx_uint32_t i;
1172 for (i=0;i<st->nb_channels;i++)
1173 st->last_sample[i] = st->filt_len/2;
1174 return RESAMPLER_ERR_SUCCESS;
1175}

References SpeexResamplerState_::filt_len, SpeexResamplerState_::last_sample, SpeexResamplerState_::nb_channels, and RESAMPLER_ERR_SUCCESS.

◆ speex_resampler_strerror()

EXPORT const char * speex_resampler_strerror ( int  err)

Returns the English meaning for an error code

Parameters
errError code
Returns
English string

Definition at line 1191 of file resample.c.

1192{
1193 switch (err)
1194 {
1196 return "Success.";
1198 return "Memory allocation failed.";
1200 return "Bad resampler state.";
1202 return "Invalid argument.";
1204 return "Input and output buffers overlap.";
1205 default:
1206 return "Unknown error. Bad error code or strange version mismatch.";
1207 }
1208}
@ RESAMPLER_ERR_BAD_STATE
@ RESAMPLER_ERR_PTR_OVERLAP

References RESAMPLER_ERR_ALLOC_FAILED, RESAMPLER_ERR_BAD_STATE, RESAMPLER_ERR_INVALID_ARG, RESAMPLER_ERR_PTR_OVERLAP, and RESAMPLER_ERR_SUCCESS.

◆ update_filter()

static int update_filter ( SpeexResamplerState st)
static

Definition at line 594 of file resample.c.

595{
596 spx_uint32_t old_length = st->filt_len;
597 spx_uint32_t old_alloc_size = st->mem_alloc_size;
598 int use_direct;
599 spx_uint32_t min_sinc_table_length;
600 spx_uint32_t min_alloc_size;
601
602 st->int_advance = st->num_rate/st->den_rate;
603 st->frac_advance = st->num_rate%st->den_rate;
606
607 if (st->num_rate > st->den_rate)
608 {
609 /* down-sampling */
611 /* FIXME: divide the numerator and denominator by a certain amount if they're too large */
612 st->filt_len = st->filt_len*st->num_rate / st->den_rate;
613 /* Round up to make sure we have a multiple of 8 for SSE */
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)
624 st->oversample = 1;
625 } else {
626 /* up-sampling */
628 }
629
630 /* Choose the resampling type that requires the least amount of memory */
631#ifdef RESAMPLE_FULL_SINC_TABLE
632 use_direct = 1;
633 if (INT_MAX/sizeof(spx_word16_t)/st->den_rate < st->filt_len)
634 goto fail;
635#else
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;
638#endif
639 if (use_direct)
640 {
641 min_sinc_table_length = st->filt_len*st->den_rate;
642 } else {
643 if ((INT_MAX/sizeof(spx_word16_t)-8)/st->oversample < st->filt_len)
644 goto fail;
645
646 min_sinc_table_length = st->filt_len*st->oversample+8;
647 }
648 if (st->sinc_table_length < min_sinc_table_length)
649 {
650 spx_word16_t *sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,min_sinc_table_length*sizeof(spx_word16_t));
651 if (!sinc_table)
652 goto fail;
653
654 st->sinc_table = sinc_table;
655 st->sinc_table_length = min_sinc_table_length;
656 }
657 if (use_direct)
658 {
659 spx_uint32_t i;
660 for (i=0;i<st->den_rate;i++)
661 {
662 spx_int32_t j;
663 for (j=0;j<st->filt_len;j++)
664 {
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);
666 }
667 }
668#ifdef FIXED_POINT
670#else
671 if (st->quality>8)
672 st->resampler_ptr = resampler_basic_direct_double;
673 else
675#endif
676 /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/
677 } else {
678 spx_int32_t i;
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);
681#ifdef FIXED_POINT
683#else
684 if (st->quality>8)
685 st->resampler_ptr = resampler_basic_interpolate_double;
686 else
688#endif
689 /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/
690 }
691
692 /* Here's the place where we update the filter memory to take into account
693 the change in filter length. It's probably the messiest part of the code
694 due to handling of lots of corner cases. */
695
696 /* Adding buffer_size to filt_len won't overflow here because filt_len
697 could be multiplied by sizeof(spx_word16_t) above. */
698 min_alloc_size = st->filt_len-1 + st->buffer_size;
699 if (min_alloc_size > st->mem_alloc_size)
700 {
701 spx_word16_t *mem;
702 if (INT_MAX/sizeof(spx_word16_t)/st->nb_channels < min_alloc_size)
703 goto fail;
704 else if (!(mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*min_alloc_size * sizeof(*mem))))
705 goto fail;
706
707 st->mem = mem;
708 st->mem_alloc_size = min_alloc_size;
709 }
710 if (!st->started)
711 {
712 spx_uint32_t i;
713 for (i=0;i<st->nb_channels*st->mem_alloc_size;i++)
714 st->mem[i] = 0;
715 /*speex_warning("reinit filter");*/
716 } else if (st->filt_len > old_length)
717 {
718 spx_uint32_t i;
719 /* Increase the filter length */
720 /*speex_warning("increase filter size");*/
721 for (i=st->nb_channels;i--;)
722 {
723 spx_uint32_t j;
724 spx_uint32_t olen = old_length;
725 /*if (st->magic_samples[i])*/
726 {
727 /* Try and remove the magic samples as if nothing had happened */
728
729 /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */
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;
736 }
737 if (st->filt_len > olen)
738 {
739 /* If the new filter length is still bigger than the "augmented" length */
740 /* Copy data going backward */
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)];
743 /* Then put zeros for lack of anything better */
744 for (;j<st->filt_len-1;j++)
745 st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0;
746 /* Adjust last_sample */
747 st->last_sample[i] += (st->filt_len - olen)/2;
748 } else {
749 /* Put back some of the magic! */
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]];
753 }
754 }
755 } else if (st->filt_len < old_length)
756 {
757 spx_uint32_t i;
758 /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic"
759 samples so they can be used directly as input the next time(s) */
760 for (i=0;i<st->nb_channels;i++)
761 {
762 spx_uint32_t j;
763 spx_uint32_t old_magic = st->magic_samples[i];
764 st->magic_samples[i] = (old_length - st->filt_len)/2;
765 /* We must copy some of the memory that's no longer used */
766 /* Copy data going backward */
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;
770 }
771 }
773
774fail:
776 /* st->mem may still contain consumed input samples for the filter.
777 Restore filt_len so that filt_len - 1 still points to the position after
778 the last of these samples. */
779 st->filt_len = old_length;
781}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
static const struct QualityMapping quality_map[11]
Definition: resample.c:228
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)
Definition: resample.c:440
static spx_word16_t sinc(float cutoff, float x, int N, const struct FuncDef *window_func)
Definition: resample.c:277
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)
Definition: resample.c:333
float downsample_bandwidth
Definition: resample.c:213
float upsample_bandwidth
Definition: resample.c:214
const struct FuncDef * window_func
Definition: resample.c:215

References QualityMapping::base_length, SpeexResamplerState_::buffer_size, SpeexResamplerState_::cutoff, SpeexResamplerState_::den_rate, QualityMapping::downsample_bandwidth, SpeexResamplerState_::filt_len, SpeexResamplerState_::frac_advance, if(), SpeexResamplerState_::int_advance, SpeexResamplerState_::last_sample, SpeexResamplerState_::magic_samples, SpeexResamplerState_::mem, SpeexResamplerState_::mem_alloc_size, SpeexResamplerState_::nb_channels, SpeexResamplerState_::num_rate, SpeexResamplerState_::oversample, QualityMapping::oversample, SpeexResamplerState_::quality, quality_map, resampler_basic_direct_single(), resampler_basic_interpolate_single(), resampler_basic_zero(), RESAMPLER_ERR_ALLOC_FAILED, RESAMPLER_ERR_SUCCESS, SpeexResamplerState_::resampler_ptr, sinc(), SpeexResamplerState_::sinc_table, SpeexResamplerState_::sinc_table_length, SpeexResamplerState_::started, QualityMapping::upsample_bandwidth, and QualityMapping::window_func.

Referenced by speex_resampler_init_frac(), speex_resampler_set_quality(), and speex_resampler_set_rate_frac().

Variable Documentation

◆ _KAISER10

const struct FuncDef _KAISER10 = {kaiser10_table, 32}
static

Definition at line 203 of file resample.c.

◆ _KAISER12

const struct FuncDef _KAISER12 = {kaiser12_table, 64}
static

Definition at line 199 of file resample.c.

◆ _KAISER6

const struct FuncDef _KAISER6 = {kaiser6_table, 32}
static

Definition at line 207 of file resample.c.

◆ _KAISER8

const struct FuncDef _KAISER8 = {kaiser8_table, 32}
static

Definition at line 205 of file resample.c.

◆ kaiser10_table

const double kaiser10_table[36]
static

Definition at line 170 of file resample.c.

◆ kaiser12_table

const double kaiser12_table[68]
static

Definition at line 148 of file resample.c.

◆ kaiser6_table

const double kaiser6_table[36]
static

Definition at line 186 of file resample.c.

◆ kaiser8_table

const double kaiser8_table[36]
static

Definition at line 178 of file resample.c.

◆ quality_map

const struct QualityMapping quality_map[11]
static

Definition at line 228 of file resample.c.

Referenced by update_filter().