Newer
Older
David Vossel
committed
#ifdef FIXED_POINT
out[j*ostride_save] = ystack[j];
#else
out[j*ostride_save] = WORD2INT(ystack[j]);
#endif
David Vossel
committed
ilen -= ichunk;
olen -= ochunk;
out += (ochunk+omagic) * ostride_save;
if (in)
in += ichunk * istride_save;
}
st->out_stride = ostride_save;
*in_len -= ilen;
*out_len -= olen;
return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
David Vossel
committed
}
EXPORT int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
David Vossel
committed
{
spx_uint32_t i;
int istride_save, ostride_save;
spx_uint32_t bak_out_len = *out_len;
spx_uint32_t bak_in_len = *in_len;
David Vossel
committed
istride_save = st->in_stride;
ostride_save = st->out_stride;
st->in_stride = st->out_stride = st->nb_channels;
for (i=0;i<st->nb_channels;i++)
{
*out_len = bak_out_len;
*in_len = bak_in_len;
David Vossel
committed
if (in != NULL)
speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len);
else
speex_resampler_process_float(st, i, NULL, in_len, out+i, out_len);
}
st->in_stride = istride_save;
st->out_stride = ostride_save;
return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
David Vossel
committed
}
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)
David Vossel
committed
{
spx_uint32_t i;
int istride_save, ostride_save;
spx_uint32_t bak_out_len = *out_len;
spx_uint32_t bak_in_len = *in_len;
David Vossel
committed
istride_save = st->in_stride;
ostride_save = st->out_stride;
st->in_stride = st->out_stride = st->nb_channels;
for (i=0;i<st->nb_channels;i++)
{
*out_len = bak_out_len;
*in_len = bak_in_len;
David Vossel
committed
if (in != NULL)
speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len);
else
speex_resampler_process_int(st, i, NULL, in_len, out+i, out_len);
}
st->in_stride = istride_save;
st->out_stride = ostride_save;
return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
David Vossel
committed
}
EXPORT int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate)
David Vossel
committed
{
return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);
}
EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate)
David Vossel
committed
{
*in_rate = st->in_rate;
*out_rate = st->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)
David Vossel
committed
{
spx_uint32_t fact;
spx_uint32_t old_den;
spx_uint32_t i;
if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)
return RESAMPLER_ERR_SUCCESS;
David Vossel
committed
old_den = st->den_rate;
st->in_rate = in_rate;
st->out_rate = out_rate;
st->num_rate = ratio_num;
st->den_rate = ratio_den;
/* FIXME: This is terribly inefficient, but who cares (at least for now)? */
for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++)
{
while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))
{
st->num_rate /= fact;
st->den_rate /= fact;
}
}
David Vossel
committed
if (old_den > 0)
{
for (i=0;i<st->nb_channels;i++)
{
st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den;
/* Safety net */
if (st->samp_frac_num[i] >= st->den_rate)
st->samp_frac_num[i] = st->den_rate-1;
}
}
David Vossel
committed
if (st->initialised)
return update_filter(st);
David Vossel
committed
return RESAMPLER_ERR_SUCCESS;
}
EXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den)
David Vossel
committed
{
*ratio_num = st->num_rate;
*ratio_den = st->den_rate;
}
EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality)
David Vossel
committed
{
if (quality > 10 || quality < 0)
return RESAMPLER_ERR_INVALID_ARG;
if (st->quality == quality)
return RESAMPLER_ERR_SUCCESS;
st->quality = quality;
if (st->initialised)
return update_filter(st);
David Vossel
committed
return RESAMPLER_ERR_SUCCESS;
}
EXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality)
David Vossel
committed
{
*quality = st->quality;
}
EXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride)
David Vossel
committed
{
st->in_stride = stride;
}
EXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride)
David Vossel
committed
{
*stride = st->in_stride;
}
EXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride)
David Vossel
committed
{
st->out_stride = stride;
}
EXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride)
David Vossel
committed
{
*stride = st->out_stride;
}
EXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st)
David Vossel
committed
{
return st->filt_len / 2;
}
EXPORT int speex_resampler_get_output_latency(SpeexResamplerState *st)
David Vossel
committed
{
return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate;
}
EXPORT int speex_resampler_skip_zeros(SpeexResamplerState *st)
David Vossel
committed
{
spx_uint32_t i;
for (i=0;i<st->nb_channels;i++)
st->last_sample[i] = st->filt_len/2;
return RESAMPLER_ERR_SUCCESS;
}
EXPORT int speex_resampler_reset_mem(SpeexResamplerState *st)
David Vossel
committed
{
spx_uint32_t i;
for (i=0;i<st->nb_channels;i++)
{
st->last_sample[i] = 0;
st->magic_samples[i] = 0;
st->samp_frac_num[i] = 0;
}
David Vossel
committed
for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
st->mem[i] = 0;
return RESAMPLER_ERR_SUCCESS;
}
EXPORT const char *speex_resampler_strerror(int err)
David Vossel
committed
{
switch (err)
{
case RESAMPLER_ERR_SUCCESS:
return "Success.";
case RESAMPLER_ERR_ALLOC_FAILED:
return "Memory allocation failed.";
case RESAMPLER_ERR_BAD_STATE:
return "Bad resampler state.";
case RESAMPLER_ERR_INVALID_ARG:
return "Invalid argument.";
case RESAMPLER_ERR_PTR_OVERLAP:
return "Input and output buffers overlap.";
default:
return "Unknown error. Bad error code or strange version mismatch.";
}
}