audioresample: Update speex resampler to latest GIT

This commit is contained in:
Sebastian Dröge 2009-11-10 12:21:50 +01:00
parent 23f92ed8cd
commit 6723bf429f
9 changed files with 803 additions and 727 deletions

View file

@ -7,12 +7,13 @@
resample.c
speex_resampler.h
are taken from http://git.xiph.org/speex.git/ as of 2008-10-28.
are taken from http://git.xiph.org/speex.git/ as of 2009-11-10.
The only changes are:
--- arch.h 2008-11-28 09:57:15.000000000 +0100
+++ arch.h 2008-11-28 09:57:37.000000000 +0100
diff -Naur old/arch.h new/arch.h
--- old/arch.h 2009-11-10 12:18:29.000000000 +0100
+++ new/arch.h 2009-11-10 12:19:09.000000000 +0100
@@ -78,7 +78,10 @@
#include "../include/speex/speex_types.h"
#endif
@ -61,8 +62,9 @@ The only changes are:
#define QCONST16(x,bits) (x)
#define QCONST32(x,bits) (x)
--- resample.c 2008-11-28 09:56:42.000000000 +0100
+++ resample.c 2008-11-01 20:38:35.000000000 +0100
diff -Naur old/resample.c new/resample.c
--- old/resample.c 2009-11-10 12:18:51.000000000 +0100
+++ new/resample.c 2009-11-10 12:19:09.000000000 +0100
@@ -63,22 +63,27 @@
#ifdef OUTSIDE_SPEEX
@ -151,7 +153,7 @@ The only changes are:
static int
resampler_basic_direct_single (SpeexResamplerState * st,
spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
@@ -421,6 +441,7 @@
@@ -428,6 +448,7 @@
st->samp_frac_num[channel_index] = samp_frac_num;
return out_sample;
}
@ -159,7 +161,7 @@ The only changes are:
#ifdef FIXED_POINT
#else
@@ -476,6 +497,7 @@
@@ -483,6 +504,7 @@
}
#endif
@ -167,7 +169,7 @@ The only changes are:
static int
resampler_basic_interpolate_single (SpeexResamplerState * st,
spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
@@ -554,6 +576,7 @@
@@ -562,6 +584,7 @@
st->samp_frac_num[channel_index] = samp_frac_num;
return out_sample;
}
@ -175,7 +177,7 @@ The only changes are:
#ifdef FIXED_POINT
#else
@@ -584,10 +607,16 @@
@@ -592,10 +615,16 @@
PDIV32 (SHL32 ((samp_frac_num * st->oversample) % st->den_rate, 15),
st->den_rate);
#else
@ -192,7 +194,7 @@ The only changes are:
spx_word16_t interp[4];
@@ -688,20 +717,27 @@
@@ -696,20 +725,27 @@
spx_int32_t j;
for (j = 0; j < st->filt_len; j++) {
st->sinc_table[i * st->filt_len + j] =
@ -222,7 +224,7 @@ The only changes are:
/*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff); */
} else {
spx_int32_t i;
@@ -717,16 +753,24 @@
@@ -725,16 +761,24 @@
}
for (i = -4; i < (spx_int32_t) (st->oversample * st->filt_len + 4); i++)
st->sinc_table[i + 4] =
@ -247,7 +249,7 @@ The only changes are:
/*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff); */
}
st->int_advance = st->num_rate / st->den_rate;
@@ -956,11 +1000,18 @@
@@ -964,11 +1008,18 @@
spx_uint32_t channel_index, const spx_int16_t * in, spx_uint32_t * in_len,
spx_int16_t * out, spx_uint32_t * out_len)
#else
@ -266,7 +268,7 @@ The only changes are:
{
int j;
spx_uint32_t ilen = *in_len;
@@ -1078,9 +1129,16 @@
@@ -1086,9 +1137,16 @@
return RESAMPLER_ERR_SUCCESS;
}
@ -283,8 +285,9 @@ The only changes are:
{
spx_uint32_t i;
int istride_save, ostride_save;
--- speex_resampler.h 2008-11-28 09:57:15.000000000 +0100
+++ speex_resampler.h 2008-11-28 09:57:37.000000000 +0100
diff -Naur old/speex_resampler.h new/speex_resampler.h
--- old/speex_resampler.h 2009-11-10 12:18:09.000000000 +0100
+++ new/speex_resampler.h 2009-11-10 12:19:09.000000000 +0100
@@ -77,10 +77,10 @@
#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
@ -300,36 +303,44 @@ The only changes are:
#else /* OUTSIDE_SPEEX */
@@ -162,10 +162,17 @@
@@ -166,12 +166,21 @@
* @param out Output buffer
* @param out_len Size of the output buffer. Returns the number of samples written
*/
+#ifdef DOUBLE_PRECISION
+ int speex_resampler_process_float (SpeexResamplerState * st,
+ spx_uint32_t channel_index,
+ const double *in,
+ spx_uint32_t * in_len, double *out, spx_uint32_t * out_len);
+int speex_resampler_process_float(SpeexResamplerState *st,
+ spx_uint32_t channel_index,
+ const double *in,
+ spx_uint32_t *in_len,
+ double *out,
+ spx_uint32_t *out_len);
+#else
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);
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);
+#endif
/** Resample an int array. The input and output buffers must *not* overlap.
* @param st Resampler state
@@ -191,9 +198,15 @@
@@ -199,11 +208,19 @@
* @param out_len Size of the output buffer. Returns the number of samples written.
* This is all per-channel.
*/
+#ifdef DOUBLE_PRECISION
+ int speex_resampler_process_interleaved_float (SpeexResamplerState * st,
+ const double *in,
+ spx_uint32_t * in_len, double *out, spx_uint32_t * out_len);
+int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
+ const double *in,
+ spx_uint32_t *in_len,
+ double *out,
+ spx_uint32_t *out_len);
+#else
int speex_resampler_process_interleaved_float (SpeexResamplerState * st,
const float *in,
spx_uint32_t * in_len, float *out, spx_uint32_t * out_len);
int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
const float *in,
spx_uint32_t *in_len,
float *out,
spx_uint32_t *out_len);
+#endif
/** Resample an interleaved int array. The input and output buffers must *not* overlap.

View file

@ -36,94 +36,112 @@
#define FIXED_ARM4_H
#undef MULT16_32_Q14
static inline spx_word32_t
MULT16_32_Q14 (spx_word16_t x, spx_word32_t y)
{
static inline spx_word32_t MULT16_32_Q14(spx_word16_t x, spx_word32_t y) {
int res;
int dummy;
asm ("smull %0,%1,%2,%3 \n\t" "mov %0, %0, lsr #14 \n\t" "add %0, %0, %1, lsl #18 \n\t":"=&r" (res),
"=&r"
(dummy)
: "r" (y), "r" ((int) x));
return (res);
asm (
"smull %0,%1,%2,%3 \n\t"
"mov %0, %0, lsr #14 \n\t"
"add %0, %0, %1, lsl #18 \n\t"
: "=&r"(res), "=&r" (dummy)
: "r"(y),"r"((int)x));
return(res);
}
#undef MULT16_32_Q15
static inline spx_word32_t
MULT16_32_Q15 (spx_word16_t x, spx_word32_t y)
{
static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
int res;
int dummy;
asm ("smull %0,%1,%2,%3 \n\t" "mov %0, %0, lsr #15 \n\t" "add %0, %0, %1, lsl #17 \n\t":"=&r" (res),
"=&r"
(dummy)
: "r" (y), "r" ((int) x));
return (res);
asm (
"smull %0,%1,%2,%3 \n\t"
"mov %0, %0, lsr #15 \n\t"
"add %0, %0, %1, lsl #17 \n\t"
: "=&r"(res), "=&r" (dummy)
: "r"(y),"r"((int)x));
return(res);
}
#undef DIV32_16
static inline short
DIV32_16 (int a, int b)
static inline short DIV32_16(int a, int b)
{
int res = 0;
int dead1, dead2, dead3, dead4, dead5;
__asm__ __volatile__ ("\teor %5, %0, %1\n"
"\tmovs %4, %0\n"
"\trsbmi %0, %0, #0 \n"
"\tmovs %4, %1\n"
"\trsbmi %1, %1, #0 \n"
"\tmov %4, #1\n"
"\tsubs %3, %0, %1, asl #14 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #14 \n"
"\tsubs %3, %0, %1, asl #13 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #13 \n"
"\tsubs %3, %0, %1, asl #12 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #12 \n"
"\tsubs %3, %0, %1, asl #11 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #11 \n"
"\tsubs %3, %0, %1, asl #10 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #10 \n"
"\tsubs %3, %0, %1, asl #9 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #9 \n"
"\tsubs %3, %0, %1, asl #8 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #8 \n"
"\tsubs %3, %0, %1, asl #7 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #7 \n"
"\tsubs %3, %0, %1, asl #6 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #6 \n"
"\tsubs %3, %0, %1, asl #5 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #5 \n"
"\tsubs %3, %0, %1, asl #4 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #4 \n"
"\tsubs %3, %0, %1, asl #3 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #3 \n"
"\tsubs %3, %0, %1, asl #2 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #2 \n"
"\tsubs %3, %0, %1, asl #1 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #1 \n"
"\tsubs %3, %0, %1 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4 \n"
"\tmovs %5, %5, lsr #31 \n"
"\trsbne %2, %2, #0 \n":"=r" (dead1), "=r" (dead2), "=r" (res),
"=r" (dead3), "=r" (dead4), "=r" (dead5)
:"0" (a), "1" (b), "2" (res)
:"cc");
return res;
int res=0;
int dead1, dead2, dead3, dead4, dead5;
__asm__ __volatile__ (
"\teor %5, %0, %1\n"
"\tmovs %4, %0\n"
"\trsbmi %0, %0, #0 \n"
"\tmovs %4, %1\n"
"\trsbmi %1, %1, #0 \n"
"\tmov %4, #1\n"
"\tsubs %3, %0, %1, asl #14 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #14 \n"
"\tsubs %3, %0, %1, asl #13 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #13 \n"
"\tsubs %3, %0, %1, asl #12 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #12 \n"
"\tsubs %3, %0, %1, asl #11 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #11 \n"
"\tsubs %3, %0, %1, asl #10 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #10 \n"
"\tsubs %3, %0, %1, asl #9 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #9 \n"
"\tsubs %3, %0, %1, asl #8 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #8 \n"
"\tsubs %3, %0, %1, asl #7 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #7 \n"
"\tsubs %3, %0, %1, asl #6 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #6 \n"
"\tsubs %3, %0, %1, asl #5 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #5 \n"
"\tsubs %3, %0, %1, asl #4 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #4 \n"
"\tsubs %3, %0, %1, asl #3 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #3 \n"
"\tsubs %3, %0, %1, asl #2 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #2 \n"
"\tsubs %3, %0, %1, asl #1 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4, asl #1 \n"
"\tsubs %3, %0, %1 \n"
"\tmovpl %0, %3 \n"
"\torrpl %2, %2, %4 \n"
"\tmovs %5, %5, lsr #31 \n"
"\trsbne %2, %2, #0 \n"
: "=r" (dead1), "=r" (dead2), "=r" (res),
"=r" (dead3), "=r" (dead4), "=r" (dead5)
: "0" (a), "1" (b), "2" (res)
: "cc"
);
return res;
}

View file

@ -36,128 +36,140 @@
#define FIXED_ARM5E_H
#undef MULT16_16
static inline spx_word32_t
MULT16_16 (spx_word16_t x, spx_word16_t y)
{
static inline spx_word32_t MULT16_16(spx_word16_t x, spx_word16_t y) {
int res;
asm ("smulbb %0,%1,%2;\n":"=&r" (res)
: "%r" (x), "r" (y));
return (res);
asm ("smulbb %0,%1,%2;\n"
: "=&r"(res)
: "%r"(x),"r"(y));
return(res);
}
#undef MAC16_16
static inline spx_word32_t
MAC16_16 (spx_word32_t a, spx_word16_t x, spx_word32_t y)
{
static inline spx_word32_t MAC16_16(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
int res;
asm ("smlabb %0,%1,%2,%3;\n":"=&r" (res)
: "%r" (x), "r" (y), "r" (a));
return (res);
asm ("smlabb %0,%1,%2,%3;\n"
: "=&r"(res)
: "%r"(x),"r"(y),"r"(a));
return(res);
}
#undef MULT16_32_Q15
static inline spx_word32_t
MULT16_32_Q15 (spx_word16_t x, spx_word32_t y)
{
static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
int res;
asm ("smulwb %0,%1,%2;\n":"=&r" (res)
: "%r" (y << 1), "r" (x));
return (res);
asm ("smulwb %0,%1,%2;\n"
: "=&r"(res)
: "%r"(y<<1),"r"(x));
return(res);
}
#undef MAC16_32_Q15
static inline spx_word32_t
MAC16_32_Q15 (spx_word32_t a, spx_word16_t x, spx_word32_t y)
{
static inline spx_word32_t MAC16_32_Q15(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
int res;
asm ("smlawb %0,%1,%2,%3;\n":"=&r" (res)
: "%r" (y << 1), "r" (x), "r" (a));
return (res);
asm ("smlawb %0,%1,%2,%3;\n"
: "=&r"(res)
: "%r"(y<<1),"r"(x),"r"(a));
return(res);
}
#undef MULT16_32_Q11
static inline spx_word32_t
MULT16_32_Q11 (spx_word16_t x, spx_word32_t y)
{
static inline spx_word32_t MULT16_32_Q11(spx_word16_t x, spx_word32_t y) {
int res;
asm ("smulwb %0,%1,%2;\n":"=&r" (res)
: "%r" (y << 5), "r" (x));
return (res);
asm ("smulwb %0,%1,%2;\n"
: "=&r"(res)
: "%r"(y<<5),"r"(x));
return(res);
}
#undef MAC16_32_Q11
static inline spx_word32_t
MAC16_32_Q11 (spx_word32_t a, spx_word16_t x, spx_word32_t y)
{
static inline spx_word32_t MAC16_32_Q11(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
int res;
asm ("smlawb %0,%1,%2,%3;\n":"=&r" (res)
: "%r" (y << 5), "r" (x), "r" (a));
return (res);
asm ("smlawb %0,%1,%2,%3;\n"
: "=&r"(res)
: "%r"(y<<5),"r"(x),"r"(a));
return(res);
}
#undef DIV32_16
static inline short
DIV32_16 (int a, int b)
static inline short DIV32_16(int a, int b)
{
int res = 0;
int dead1, dead2, dead3, dead4, dead5;
__asm__ __volatile__ ("\teor %5, %0, %1\n"
"\tmovs %4, %0\n"
"\trsbmi %0, %0, #0 \n"
"\tmovs %4, %1\n"
"\trsbmi %1, %1, #0 \n"
"\tmov %4, #1\n"
"\tsubs %3, %0, %1, asl #14 \n"
"\torrpl %2, %2, %4, asl #14 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #13 \n"
"\torrpl %2, %2, %4, asl #13 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #12 \n"
"\torrpl %2, %2, %4, asl #12 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #11 \n"
"\torrpl %2, %2, %4, asl #11 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #10 \n"
"\torrpl %2, %2, %4, asl #10 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #9 \n"
"\torrpl %2, %2, %4, asl #9 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #8 \n"
"\torrpl %2, %2, %4, asl #8 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #7 \n"
"\torrpl %2, %2, %4, asl #7 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #6 \n"
"\torrpl %2, %2, %4, asl #6 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #5 \n"
"\torrpl %2, %2, %4, asl #5 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #4 \n"
"\torrpl %2, %2, %4, asl #4 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #3 \n"
"\torrpl %2, %2, %4, asl #3 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #2 \n"
"\torrpl %2, %2, %4, asl #2 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #1 \n"
"\torrpl %2, %2, %4, asl #1 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1 \n"
"\torrpl %2, %2, %4 \n"
"\tmovpl %0, %3 \n"
"\tmovs %5, %5, lsr #31 \n"
"\trsbne %2, %2, #0 \n":"=r" (dead1), "=r" (dead2), "=r" (res),
"=r" (dead3), "=r" (dead4), "=r" (dead5)
:"0" (a), "1" (b), "2" (res)
:"memory", "cc");
return res;
int res=0;
int dead1, dead2, dead3, dead4, dead5;
__asm__ __volatile__ (
"\teor %5, %0, %1\n"
"\tmovs %4, %0\n"
"\trsbmi %0, %0, #0 \n"
"\tmovs %4, %1\n"
"\trsbmi %1, %1, #0 \n"
"\tmov %4, #1\n"
"\tsubs %3, %0, %1, asl #14 \n"
"\torrpl %2, %2, %4, asl #14 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #13 \n"
"\torrpl %2, %2, %4, asl #13 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #12 \n"
"\torrpl %2, %2, %4, asl #12 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #11 \n"
"\torrpl %2, %2, %4, asl #11 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #10 \n"
"\torrpl %2, %2, %4, asl #10 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #9 \n"
"\torrpl %2, %2, %4, asl #9 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #8 \n"
"\torrpl %2, %2, %4, asl #8 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #7 \n"
"\torrpl %2, %2, %4, asl #7 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #6 \n"
"\torrpl %2, %2, %4, asl #6 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #5 \n"
"\torrpl %2, %2, %4, asl #5 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #4 \n"
"\torrpl %2, %2, %4, asl #4 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #3 \n"
"\torrpl %2, %2, %4, asl #3 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #2 \n"
"\torrpl %2, %2, %4, asl #2 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1, asl #1 \n"
"\torrpl %2, %2, %4, asl #1 \n"
"\tmovpl %0, %3 \n"
"\tsubs %3, %0, %1 \n"
"\torrpl %2, %2, %4 \n"
"\tmovpl %0, %3 \n"
"\tmovs %5, %5, lsr #31 \n"
"\trsbne %2, %2, #0 \n"
: "=r" (dead1), "=r" (dead2), "=r" (res),
"=r" (dead3), "=r" (dead4), "=r" (dead5)
: "0" (a), "1" (b), "2" (res)
: "memory", "cc"
);
return res;
}

View file

@ -36,99 +36,141 @@
#ifndef FIXED_BFIN_H
#define FIXED_BFIN_H
#include "bfin.h"
#undef PDIV32_16
static inline spx_word16_t
PDIV32_16 (spx_word32_t a, spx_word16_t b)
static inline spx_word16_t PDIV32_16(spx_word32_t a, spx_word16_t b)
{
spx_word32_t res, bb;
bb = b;
a += b >> 1;
__asm__ ("P0 = 15;\n\t" "R0 = %1;\n\t" "R1 = %2;\n\t"
//"R0 = R0 + R1;\n\t"
"R0 <<= 1;\n\t" "DIVS (R0, R1);\n\t" "LOOP divide%= LC0 = P0;\n\t" "LOOP_BEGIN divide%=;\n\t" "DIVQ (R0, R1);\n\t" "LOOP_END divide%=;\n\t" "R0 = R0.L;\n\t" "%0 = R0;\n\t":"=m"
(res)
: "m" (a), "m" (bb)
: "P0", "R0", "R1", "cc");
return res;
spx_word32_t res, bb;
bb = b;
a += b>>1;
__asm__ (
"P0 = 15;\n\t"
"R0 = %1;\n\t"
"R1 = %2;\n\t"
//"R0 = R0 + R1;\n\t"
"R0 <<= 1;\n\t"
"DIVS (R0, R1);\n\t"
"LOOP divide%= LC0 = P0;\n\t"
"LOOP_BEGIN divide%=;\n\t"
"DIVQ (R0, R1);\n\t"
"LOOP_END divide%=;\n\t"
"R0 = R0.L;\n\t"
"%0 = R0;\n\t"
: "=m" (res)
: "m" (a), "m" (bb)
: "P0", "R0", "R1", "ASTAT" BFIN_HWLOOP0_REGS);
return res;
}
#undef DIV32_16
static inline spx_word16_t
DIV32_16 (spx_word32_t a, spx_word16_t b)
static inline spx_word16_t DIV32_16(spx_word32_t a, spx_word16_t b)
{
spx_word32_t res, bb;
bb = b;
/* Make the roundinf consistent with the C version
(do we need to do that?) */
if (a < 0)
a += (b - 1);
__asm__ ("P0 = 15;\n\t" "R0 = %1;\n\t" "R1 = %2;\n\t" "R0 <<= 1;\n\t" "DIVS (R0, R1);\n\t" "LOOP divide%= LC0 = P0;\n\t" "LOOP_BEGIN divide%=;\n\t" "DIVQ (R0, R1);\n\t" "LOOP_END divide%=;\n\t" "R0 = R0.L;\n\t" "%0 = R0;\n\t":"=m" (res)
: "m" (a), "m" (bb)
: "P0", "R0", "R1", "cc");
return res;
spx_word32_t res, bb;
bb = b;
/* Make the roundinf consistent with the C version
(do we need to do that?)*/
if (a<0)
a += (b-1);
__asm__ (
"P0 = 15;\n\t"
"R0 = %1;\n\t"
"R1 = %2;\n\t"
"R0 <<= 1;\n\t"
"DIVS (R0, R1);\n\t"
"LOOP divide%= LC0 = P0;\n\t"
"LOOP_BEGIN divide%=;\n\t"
"DIVQ (R0, R1);\n\t"
"LOOP_END divide%=;\n\t"
"R0 = R0.L;\n\t"
"%0 = R0;\n\t"
: "=m" (res)
: "m" (a), "m" (bb)
: "P0", "R0", "R1", "ASTAT" BFIN_HWLOOP0_REGS);
return res;
}
#undef MAX16
static inline spx_word16_t
MAX16 (spx_word16_t a, spx_word16_t b)
static inline spx_word16_t MAX16(spx_word16_t a, spx_word16_t b)
{
spx_word32_t res;
__asm__ ("%1 = %1.L (X);\n\t" "%2 = %2.L (X);\n\t" "%0 = MAX(%1,%2);":"=d" (res)
: "%d" (a), "d" (b)
);
return res;
spx_word32_t res;
__asm__ (
"%1 = %1.L (X);\n\t"
"%2 = %2.L (X);\n\t"
"%0 = MAX(%1,%2);"
: "=d" (res)
: "%d" (a), "d" (b)
: "ASTAT"
);
return res;
}
#undef MULT16_32_Q15
static inline spx_word32_t
MULT16_32_Q15 (spx_word16_t a, spx_word32_t b)
static inline spx_word32_t MULT16_32_Q15(spx_word16_t a, spx_word32_t b)
{
spx_word32_t res;
__asm__ ("A1 = %2.L*%1.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %2.L*%1.H) ;\n\t":"=&W" (res),
"=&d"
(b)
: "d" (a), "1" (b)
: "A1");
return res;
spx_word32_t res;
__asm__
(
"A1 = %2.L*%1.L (M);\n\t"
"A1 = A1 >>> 15;\n\t"
"%0 = (A1 += %2.L*%1.H) ;\n\t"
: "=&W" (res), "=&d" (b)
: "d" (a), "1" (b)
: "A1", "ASTAT"
);
return res;
}
#undef MAC16_32_Q15
static inline spx_word32_t
MAC16_32_Q15 (spx_word32_t c, spx_word16_t a, spx_word32_t b)
static inline spx_word32_t MAC16_32_Q15(spx_word32_t c, spx_word16_t a, spx_word32_t b)
{
spx_word32_t res;
__asm__ ("A1 = %2.L*%1.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %2.L*%1.H);\n\t" "%0 = %0 + %4;\n\t":"=&W" (res),
"=&d"
(b)
: "d" (a), "1" (b), "d" (c)
: "A1");
return res;
spx_word32_t res;
__asm__
(
"A1 = %2.L*%1.L (M);\n\t"
"A1 = A1 >>> 15;\n\t"
"%0 = (A1 += %2.L*%1.H);\n\t"
"%0 = %0 + %4;\n\t"
: "=&W" (res), "=&d" (b)
: "d" (a), "1" (b), "d" (c)
: "A1", "ASTAT"
);
return res;
}
#undef MULT16_32_Q14
static inline spx_word32_t
MULT16_32_Q14 (spx_word16_t a, spx_word32_t b)
static inline spx_word32_t MULT16_32_Q14(spx_word16_t a, spx_word32_t b)
{
spx_word32_t res;
__asm__ ("%2 <<= 1;\n\t" "A1 = %1.L*%2.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %1.L*%2.H);\n\t":"=W" (res), "=d" (a),
"=d"
(b)
: "1" (a), "2" (b)
: "A1");
return res;
spx_word32_t res;
__asm__
(
"%2 <<= 1;\n\t"
"A1 = %1.L*%2.L (M);\n\t"
"A1 = A1 >>> 15;\n\t"
"%0 = (A1 += %1.L*%2.H);\n\t"
: "=W" (res), "=d" (a), "=d" (b)
: "1" (a), "2" (b)
: "A1", "ASTAT"
);
return res;
}
#undef MAC16_32_Q14
static inline spx_word32_t
MAC16_32_Q14 (spx_word32_t c, spx_word16_t a, spx_word32_t b)
static inline spx_word32_t MAC16_32_Q14(spx_word32_t c, spx_word16_t a, spx_word32_t b)
{
spx_word32_t res;
__asm__ ("%1 <<= 1;\n\t" "A1 = %2.L*%1.L (M);\n\t" "A1 = A1 >>> 15;\n\t" "%0 = (A1 += %2.L*%1.H);\n\t" "%0 = %0 + %4;\n\t":"=&W" (res),
"=&d"
(b)
: "d" (a), "1" (b), "d" (c)
: "A1");
return res;
spx_word32_t res;
__asm__
(
"%1 <<= 1;\n\t"
"A1 = %2.L*%1.L (M);\n\t"
"A1 = A1 >>> 15;\n\t"
"%0 = (A1 += %2.L*%1.H);\n\t"
"%0 = %0 + %4;\n\t"
: "=&W" (res), "=&d" (b)
: "d" (a), "1" (b), "d" (c)
: "A1", "ASTAT"
);
return res;
}
#endif

View file

@ -47,124 +47,117 @@ extern long long spx_mips;
#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
static inline short
NEG16 (int x)
static inline short NEG16(int x)
{
int res;
if (!VERIFY_SHORT (x)) {
fprintf (stderr, "NEG16: input is not short: %d\n", (int) x);
}
res = -x;
if (!VERIFY_SHORT (res))
fprintf (stderr, "NEG16: output is not short: %d\n", (int) res);
spx_mips++;
return res;
int res;
if (!VERIFY_SHORT(x))
{
fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
}
res = -x;
if (!VERIFY_SHORT(res))
fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
spx_mips++;
return res;
}
static inline int
NEG32 (long long x)
static inline int NEG32(long long x)
{
long long res;
if (!VERIFY_INT (x)) {
fprintf (stderr, "NEG16: input is not int: %d\n", (int) x);
}
res = -x;
if (!VERIFY_INT (res))
fprintf (stderr, "NEG16: output is not int: %d\n", (int) res);
spx_mips++;
return res;
long long res;
if (!VERIFY_INT(x))
{
fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
}
res = -x;
if (!VERIFY_INT(res))
fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
spx_mips++;
return res;
}
#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__)
static inline short
_EXTRACT16 (int x, char *file, int line)
static inline short _EXTRACT16(int x, char *file, int line)
{
int res;
if (!VERIFY_SHORT (x)) {
fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x,
file, line);
}
res = x;
spx_mips++;
return res;
int res;
if (!VERIFY_SHORT(x))
{
fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
}
res = x;
spx_mips++;
return res;
}
#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__)
static inline int
_EXTEND32 (int x, char *file, int line)
static inline int _EXTEND32(int x, char *file, int line)
{
int res;
if (!VERIFY_SHORT (x)) {
fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x,
file, line);
}
res = x;
spx_mips++;
return res;
int res;
if (!VERIFY_SHORT(x))
{
fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
}
res = x;
spx_mips++;
return res;
}
#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__)
static inline short
_SHR16 (int a, int shift, char *file, int line)
static inline short _SHR16(int a, int shift, char *file, int line)
{
int res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (shift)) {
fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n",
a, shift, file, line);
}
res = a >> shift;
if (!VERIFY_SHORT (res))
fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res,
file, line);
spx_mips++;
return res;
int res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
{
fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
}
res = a>>shift;
if (!VERIFY_SHORT(res))
fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
spx_mips++;
return res;
}
#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__)
static inline short
_SHL16 (int a, int shift, char *file, int line)
static inline short _SHL16(int a, int shift, char *file, int line)
{
int res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (shift)) {
fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a,
shift, file, line);
}
res = a << shift;
if (!VERIFY_SHORT (res))
fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res,
file, line);
spx_mips++;
return res;
int res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
{
fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
}
res = a<<shift;
if (!VERIFY_SHORT(res))
fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
spx_mips++;
return res;
}
static inline int
SHR32 (long long a, int shift)
static inline int SHR32(long long a, int shift)
{
long long res;
if (!VERIFY_INT (a) || !VERIFY_SHORT (shift)) {
fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int) a, shift);
}
res = a >> shift;
if (!VERIFY_INT (res)) {
fprintf (stderr, "SHR32: output is not int: %d\n", (int) res);
}
spx_mips++;
return res;
long long res;
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
{
fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
}
res = a>>shift;
if (!VERIFY_INT(res))
{
fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
}
spx_mips++;
return res;
}
static inline int
SHL32 (long long a, int shift)
static inline int SHL32(long long a, int shift)
{
long long res;
if (!VERIFY_INT (a) || !VERIFY_SHORT (shift)) {
fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int) a, shift);
}
res = a << shift;
if (!VERIFY_INT (res)) {
fprintf (stderr, "SHL32: output is not int: %d\n", (int) res);
}
spx_mips++;
return res;
long long res;
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
{
fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift);
}
res = a<<shift;
if (!VERIFY_INT(res))
{
fprintf (stderr, "SHL32: output is not int: %d\n", (int)res);
}
spx_mips++;
return res;
}
#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift))
@ -178,104 +171,98 @@ SHL32 (long long a, int shift)
//#define SHL(a,shift) ((a) << (shift))
#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__)
static inline short
_ADD16 (int a, int b, char *file, int line)
static inline short _ADD16(int a, int b, char *file, int line)
{
int res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a,
b, file, line);
}
res = a + b;
if (!VERIFY_SHORT (res)) {
fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,
b, res, file, line);
}
spx_mips++;
return res;
int res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
}
res = a+b;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
}
spx_mips++;
return res;
}
#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__)
static inline short
_SUB16 (int a, int b, char *file, int line)
static inline short _SUB16(int a, int b, char *file, int line)
{
int res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a,
b, file, line);
}
res = a - b;
if (!VERIFY_SHORT (res))
fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res,
file, line);
spx_mips++;
return res;
int res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
}
res = a-b;
if (!VERIFY_SHORT(res))
fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
spx_mips++;
return res;
}
#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__)
static inline int
_ADD32 (long long a, long long b, char *file, int line)
static inline int _ADD32(long long a, long long b, char *file, int line)
{
long long res;
if (!VERIFY_INT (a) || !VERIFY_INT (b)) {
fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n",
(int) a, (int) b, file, line);
}
res = a + b;
if (!VERIFY_INT (res)) {
fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int) res,
file, line);
}
spx_mips++;
return res;
long long res;
if (!VERIFY_INT(a) || !VERIFY_INT(b))
{
fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
}
res = a+b;
if (!VERIFY_INT(res))
{
fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
}
spx_mips++;
return res;
}
static inline int
SUB32 (long long a, long long b)
static inline int SUB32(long long a, long long b)
{
long long res;
if (!VERIFY_INT (a) || !VERIFY_INT (b)) {
fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int) a, (int) b);
}
res = a - b;
if (!VERIFY_INT (res))
fprintf (stderr, "SUB32: output is not int: %d\n", (int) res);
spx_mips++;
return res;
long long res;
if (!VERIFY_INT(a) || !VERIFY_INT(b))
{
fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b);
}
res = a-b;
if (!VERIFY_INT(res))
fprintf (stderr, "SUB32: output is not int: %d\n", (int)res);
spx_mips++;
return res;
}
#define ADD64(a,b) (MIPS_INC(a)+(b))
/* result fits in 16 bits */
static inline short
MULT16_16_16 (int a, int b)
static inline short MULT16_16_16(int a, int b)
{
int res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
}
res = a * b;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
spx_mips++;
return res;
int res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
}
res = a*b;
if (!VERIFY_SHORT(res))
fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
spx_mips++;
return res;
}
#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__)
static inline int
_MULT16_16 (int a, int b, char *file, int line)
static inline int _MULT16_16(int a, int b, char *file, int line)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n",
a, b, file, line);
}
res = ((long long) a) * b;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n",
(int) res, file, line);
spx_mips++;
return res;
long long res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
}
res = ((long long)a)*b;
if (!VERIFY_INT(res))
fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
spx_mips++;
return res;
}
#define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b))))
@ -285,45 +272,36 @@ _MULT16_16 (int a, int b, char *file, int line)
#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__)
static inline int
_MULT16_32_QX (int a, long long b, int Q, char *file, int line)
static inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_INT (b)) {
fprintf (stderr,
"MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q,
(int) a, (int) b, file, line);
}
if (ABS32 (b) >= (EXTEND32 (1) << (15 + Q)))
fprintf (stderr,
"MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q,
(int) a, (int) b, file, line);
res = (((long long) a) * (long long) b) >> Q;
if (!VERIFY_INT (res))
fprintf (stderr,
"MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q,
(int) a, (int) b, (int) res, file, line);
spx_mips += 5;
return res;
long long res;
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
{
fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
}
if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
res = (((long long)a)*(long long)b) >> Q;
if (!VERIFY_INT(res))
fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line);
spx_mips+=5;
return res;
}
static inline int
MULT16_32_PX (int a, long long b, int Q)
static inline int MULT16_32_PX(int a, long long b, int Q)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_INT (b)) {
fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q,
(int) a, (int) b);
}
if (ABS32 (b) >= (EXTEND32 (1) << (15 + Q)))
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q,
(int) a, (int) b);
res = ((((long long) a) * (long long) b) + ((EXTEND32 (1) << Q) >> 1)) >> Q;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int) a,
(int) b, (int) res);
spx_mips += 5;
return res;
long long res;
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
{
fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b);
}
if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b);
res = ((((long long)a)*(long long)b) + ((EXTEND32(1)<<Q)>>1))>> Q;
if (!VERIFY_INT(res))
fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res);
spx_mips+=5;
return res;
}
@ -336,189 +314,173 @@ MULT16_32_PX (int a, long long b, int Q)
#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15)
#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b)))
static inline int
SATURATE (int a, int b)
static inline int SATURATE(int a, int b)
{
if (a > b)
a = b;
if (a < -b)
a = -b;
return a;
if (a>b)
a=b;
if (a<-b)
a = -b;
return a;
}
static inline int
MULT16_16_Q11_32 (int a, int b)
static inline int MULT16_16_Q11_32(int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res >>= 11;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int) a,
(int) b, (int) res);
spx_mips += 3;
return res;
long long res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
}
res = ((long long)a)*b;
res >>= 11;
if (!VERIFY_INT(res))
fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
spx_mips+=3;
return res;
}
static inline short MULT16_16_Q13(int a, int b)
{
long long res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
}
res = ((long long)a)*b;
res >>= 13;
if (!VERIFY_SHORT(res))
fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
spx_mips+=3;
return res;
}
static inline short MULT16_16_Q14(int a, int b)
{
long long res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
}
res = ((long long)a)*b;
res >>= 14;
if (!VERIFY_SHORT(res))
fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
spx_mips+=3;
return res;
}
static inline short MULT16_16_Q15(int a, int b)
{
long long res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
}
res = ((long long)a)*b;
res >>= 15;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
}
spx_mips+=3;
return res;
}
static inline short
MULT16_16_Q13 (int a, int b)
static inline short MULT16_16_P13(int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res >>= 13;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b,
(int) res);
spx_mips += 3;
return res;
long long res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
}
res = ((long long)a)*b;
res += 4096;
if (!VERIFY_INT(res))
fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
res >>= 13;
if (!VERIFY_SHORT(res))
fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
spx_mips+=4;
return res;
}
static inline short
MULT16_16_Q14 (int a, int b)
static inline short MULT16_16_P14(int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res >>= 14;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int) res);
spx_mips += 3;
return res;
long long res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
}
res = ((long long)a)*b;
res += 8192;
if (!VERIFY_INT(res))
fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
res >>= 14;
if (!VERIFY_SHORT(res))
fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
spx_mips+=4;
return res;
}
static inline short
MULT16_16_Q15 (int a, int b)
static inline short MULT16_16_P15(int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res >>= 15;
if (!VERIFY_SHORT (res)) {
fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int) res);
}
spx_mips += 3;
return res;
}
static inline short
MULT16_16_P13 (int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res += 4096;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int) res);
res >>= 13;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b,
(int) res);
spx_mips += 4;
return res;
}
static inline short
MULT16_16_P14 (int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res += 8192;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int) res);
res >>= 14;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b,
(int) res);
spx_mips += 4;
return res;
}
static inline short
MULT16_16_P15 (int a, int b)
{
long long res;
if (!VERIFY_SHORT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
}
res = ((long long) a) * b;
res += 16384;
if (!VERIFY_INT (res))
fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int) res);
res >>= 15;
if (!VERIFY_SHORT (res))
fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b,
(int) res);
spx_mips += 4;
return res;
long long res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
}
res = ((long long)a)*b;
res += 16384;
if (!VERIFY_INT(res))
fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
res >>= 15;
if (!VERIFY_SHORT(res))
fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
spx_mips+=4;
return res;
}
#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__)
static inline int
_DIV32_16 (long long a, long long b, char *file, int line)
static inline int _DIV32_16(long long a, long long b, char *file, int line)
{
long long res;
if (b == 0) {
fprintf (stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n",
(int) a, (int) b, file, line);
return 0;
}
if (!VERIFY_INT (a) || !VERIFY_SHORT (b)) {
fprintf (stderr,
"DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int) a,
(int) b, file, line);
}
res = a / b;
if (!VERIFY_SHORT (res)) {
fprintf (stderr,
"DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int) a,
(int) b, (int) res, file, line);
if (res > 32767)
res = 32767;
if (res < -32768)
res = -32768;
}
spx_mips += 20;
return res;
long long res;
if (b==0)
{
fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
return 0;
}
if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
}
res = a/b;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
if (res>32767)
res = 32767;
if (res<-32768)
res = -32768;
}
spx_mips+=20;
return res;
}
#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__)
static inline int
_DIV32 (long long a, long long b, char *file, int line)
static inline int _DIV32(long long a, long long b, char *file, int line)
{
long long res;
if (b == 0) {
fprintf (stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int) a,
(int) b, file, line);
return 0;
}
long long res;
if (b==0)
{
fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
return 0;
}
if (!VERIFY_INT (a) || !VERIFY_INT (b)) {
fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n",
(int) a, (int) b, file, line);
}
res = a / b;
if (!VERIFY_INT (res))
fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int) res,
file, line);
spx_mips += 36;
return res;
if (!VERIFY_INT(a) || !VERIFY_INT(b))
{
fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
}
res = a/b;
if (!VERIFY_INT(res))
fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
spx_mips+=36;
return res;
}
#define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b)
#define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b)

View file

@ -415,20 +415,27 @@ resampler_basic_direct_single (SpeexResamplerState * st,
const spx_word16_t *iptr = &in[last_sample];
#ifndef OVERRIDE_INNER_PRODUCT_SINGLE
float accum[4] = { 0, 0, 0, 0 };
sum = 0;
for (j = 0; j < N; j++)
sum += MULT16_16 (sinc[j], iptr[j]);
for (j = 0; j < N; j += 4) {
accum[0] += sinc[j] * iptr[j];
accum[1] += sinc[j + 1] * iptr[j + 1];
accum[2] += sinc[j + 2] * iptr[j + 2];
accum[3] += sinc[j + 3] * iptr[j + 3];
}
sum = accum[0] + accum[1] + accum[2] + accum[3];
/* This code is slower on most DSPs which have only 2 accumulators.
Plus this this forces truncation to 32 bits and you lose the HW guard bits.
I think we can trust the compiler and let it vectorize and/or unroll itself.
spx_word32_t accum[4] = {0,0,0,0};
for(j=0;j<N;j+=4) {
accum[0] += MULT16_16(sinc[j], iptr[j]);
accum[1] += MULT16_16(sinc[j+1], iptr[j+1]);
accum[2] += MULT16_16(sinc[j+2], iptr[j+2]);
accum[3] += MULT16_16(sinc[j+3], iptr[j+3]);
}
sum = accum[0] + accum[1] + accum[2] + accum[3];
*/
#else
sum = inner_product_single (sinc, iptr, N);
#endif
out[out_stride * out_sample++] = PSHR32 (sum, 15);
out[out_stride * out_sample++] = SATURATE32 (PSHR32 (sum, 15), 32767);
last_sample += int_advance;
samp_frac_num += frac_advance;
if (samp_frac_num >= den_rate) {
@ -552,9 +559,10 @@ resampler_basic_interpolate_single (SpeexResamplerState * st,
cubic_coef (frac, interp);
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]);
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));
#else
cubic_coef (frac, interp);
sum =
@ -563,7 +571,7 @@ resampler_basic_interpolate_single (SpeexResamplerState * st,
interp);
#endif
out[out_stride * out_sample++] = PSHR32 (sum, 15);
out[out_stride * out_sample++] = SATURATE32 (PSHR32 (sum, 14), 32767);
last_sample += int_advance;
samp_frac_num += frac_advance;
if (samp_frac_num >= den_rate) {

View file

@ -91,7 +91,7 @@ static inline double inner_product_double(const float *a, const float *b, unsign
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
}
sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum));
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
_mm_store_sd(&ret, sum);
return ret;
}
@ -120,7 +120,7 @@ static inline double interpolate_product_double(const float *a, const float *b,
sum1 = _mm_mul_pd(f1, sum1);
sum2 = _mm_mul_pd(f2, sum2);
sum = _mm_add_pd(sum1, sum2);
sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum));
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
_mm_store_sd(&ret, sum);
return ret;
}

View file

@ -93,8 +93,7 @@
#endif /* OUTSIDE_SPEEX */
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#define SPEEX_RESAMPLER_QUALITY_MAX 10
@ -103,19 +102,18 @@ extern "C"
#define SPEEX_RESAMPLER_QUALITY_VOIP 3
#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
enum
{
RESAMPLER_ERR_SUCCESS = 0,
RESAMPLER_ERR_ALLOC_FAILED = 1,
RESAMPLER_ERR_BAD_STATE = 2,
RESAMPLER_ERR_INVALID_ARG = 3,
RESAMPLER_ERR_PTR_OVERLAP = 4,
enum {
RESAMPLER_ERR_SUCCESS = 0,
RESAMPLER_ERR_ALLOC_FAILED = 1,
RESAMPLER_ERR_BAD_STATE = 2,
RESAMPLER_ERR_INVALID_ARG = 3,
RESAMPLER_ERR_PTR_OVERLAP = 4,
RESAMPLER_ERR_MAX_ERROR
};
RESAMPLER_ERR_MAX_ERROR
};
struct SpeexResamplerState_;
typedef struct SpeexResamplerState_ SpeexResamplerState;
struct SpeexResamplerState_;
typedef struct SpeexResamplerState_ SpeexResamplerState;
/** Create a new resampler with integer input and output rates.
* @param nb_channels Number of channels to be processed
@ -126,8 +124,11 @@ extern "C"
* @return Newly created resampler state
* @retval NULL Error: not enough memory
*/
SpeexResamplerState *speex_resampler_init (spx_uint32_t nb_channels,
spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err);
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 fractional input/output rates. The sampling
* rate ratio is an arbitrary rational number with both the numerator and
@ -142,15 +143,18 @@ extern "C"
* @return Newly created resampler state
* @retval NULL Error: not enough memory
*/
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);
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);
/** Destroy a resampler state.
* @param st Resampler state
*/
void speex_resampler_destroy (SpeexResamplerState * st);
void speex_resampler_destroy(SpeexResamplerState *st);
/** Resample a float array. The input and output buffers must *not* overlap.
* @param st Resampler state
@ -163,15 +167,19 @@ extern "C"
* @param out_len Size of the output buffer. Returns the number of samples written
*/
#ifdef DOUBLE_PRECISION
int speex_resampler_process_float (SpeexResamplerState * st,
spx_uint32_t channel_index,
const double *in,
spx_uint32_t * in_len, double *out, spx_uint32_t * out_len);
int speex_resampler_process_float(SpeexResamplerState *st,
spx_uint32_t channel_index,
const double *in,
spx_uint32_t *in_len,
double *out,
spx_uint32_t *out_len);
#else
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);
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);
#endif
/** Resample an int array. The input and output buffers must *not* overlap.
@ -184,10 +192,12 @@ extern "C"
* @param out Output buffer
* @param out_len Size of the output buffer. Returns the number of samples written
*/
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);
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 interleaved float array. The input and output buffers must *not* overlap.
* @param st Resampler state
@ -199,13 +209,17 @@ extern "C"
* This is all per-channel.
*/
#ifdef DOUBLE_PRECISION
int speex_resampler_process_interleaved_float (SpeexResamplerState * st,
const double *in,
spx_uint32_t * in_len, double *out, spx_uint32_t * out_len);
int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
const double *in,
spx_uint32_t *in_len,
double *out,
spx_uint32_t *out_len);
#else
int speex_resampler_process_interleaved_float (SpeexResamplerState * st,
const float *in,
spx_uint32_t * in_len, float *out, spx_uint32_t * out_len);
int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
const float *in,
spx_uint32_t *in_len,
float *out,
spx_uint32_t *out_len);
#endif
/** Resample an interleaved int array. The input and output buffers must *not* overlap.
@ -217,25 +231,29 @@ extern "C"
* @param out_len Size of the output buffer. Returns the number of samples written.
* This is all per-channel.
*/
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);
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);
/** Set (change) the input/output sampling rates (integer value).
* @param st Resampler state
* @param in_rate Input sampling rate (integer number of Hz).
* @param out_rate Output sampling rate (integer number of Hz).
*/
int speex_resampler_set_rate (SpeexResamplerState * st,
spx_uint32_t in_rate, spx_uint32_t out_rate);
int speex_resampler_set_rate(SpeexResamplerState *st,
spx_uint32_t in_rate,
spx_uint32_t out_rate);
/** Get the current input/output sampling rates (integer value).
* @param st Resampler state
* @param in_rate Input sampling rate (integer number of Hz) copied.
* @param out_rate Output sampling rate (integer number of Hz) copied.
*/
void speex_resampler_get_rate (SpeexResamplerState * st,
spx_uint32_t * in_rate, spx_uint32_t * out_rate);
void speex_resampler_get_rate(SpeexResamplerState *st,
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).
@ -245,9 +263,11 @@ extern "C"
* @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
* @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
*/
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);
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);
/** Get the current resampling ratio. This will be reduced to the least
* common denominator.
@ -255,60 +275,63 @@ extern "C"
* @param ratio_num Numerator of the sampling rate ratio copied
* @param ratio_den Denominator of the sampling rate ratio copied
*/
void speex_resampler_get_ratio (SpeexResamplerState * st,
spx_uint32_t * ratio_num, spx_uint32_t * ratio_den);
void speex_resampler_get_ratio(SpeexResamplerState *st,
spx_uint32_t *ratio_num,
spx_uint32_t *ratio_den);
/** Set (change) the conversion quality.
* @param st Resampler state
* @param quality Resampling quality between 0 and 10, where 0 has poor
* quality and 10 has very high quality.
*/
int speex_resampler_set_quality (SpeexResamplerState * st, int quality);
int speex_resampler_set_quality(SpeexResamplerState *st,
int quality);
/** Get the conversion quality.
* @param st Resampler state
* @param quality Resampling quality between 0 and 10, where 0 has poor
* quality and 10 has very high quality.
*/
void speex_resampler_get_quality (SpeexResamplerState * st, int *quality);
void speex_resampler_get_quality(SpeexResamplerState *st,
int *quality);
/** Set (change) the input stride.
* @param st Resampler state
* @param stride Input stride
*/
void speex_resampler_set_input_stride (SpeexResamplerState * st,
spx_uint32_t stride);
void speex_resampler_set_input_stride(SpeexResamplerState *st,
spx_uint32_t stride);
/** Get the input stride.
* @param st Resampler state
* @param stride Input stride copied
*/
void speex_resampler_get_input_stride (SpeexResamplerState * st,
spx_uint32_t * stride);
void speex_resampler_get_input_stride(SpeexResamplerState *st,
spx_uint32_t *stride);
/** Set (change) the output stride.
* @param st Resampler state
* @param stride Output stride
*/
void speex_resampler_set_output_stride (SpeexResamplerState * st,
spx_uint32_t stride);
void speex_resampler_set_output_stride(SpeexResamplerState *st,
spx_uint32_t stride);
/** Get the output stride.
* @param st Resampler state copied
* @param stride Output stride
*/
void speex_resampler_get_output_stride (SpeexResamplerState * st,
spx_uint32_t * stride);
void speex_resampler_get_output_stride(SpeexResamplerState *st,
spx_uint32_t *stride);
/** Get the latency in input samples introduced by the resampler.
/** Get the latency introduced by the resampler measured in input samples.
* @param st Resampler state
*/
int speex_resampler_get_input_latency (SpeexResamplerState * st);
int speex_resampler_get_input_latency(SpeexResamplerState *st);
/** Get the latency in output samples introduced by the resampler.
/** Get the latency introduced by the resampler measured in output samples.
* @param st Resampler state
*/
int speex_resampler_get_output_latency (SpeexResamplerState * st);
int speex_resampler_get_output_latency(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
@ -318,18 +341,18 @@ extern "C"
* is the same for the first frame).
* @param st Resampler state
*/
int speex_resampler_skip_zeros (SpeexResamplerState * st);
int speex_resampler_skip_zeros(SpeexResamplerState *st);
/** Reset a resampler so a new (unrelated) stream can be processed.
* @param st Resampler state
*/
int speex_resampler_reset_mem (SpeexResamplerState * st);
int speex_resampler_reset_mem(SpeexResamplerState *st);
/** Returns the English meaning for an error code
* @param err Error code
* @return English string
*/
const char *speex_resampler_strerror (int err);
const char *speex_resampler_strerror(int err);
#ifdef __cplusplus
}