summaryrefslogtreecommitdiffstats
path: root/apps/codecs
diff options
context:
space:
mode:
authorDan Everton <dan@iocaine.org>2007-05-22 09:50:31 +0000
committerDan Everton <dan@iocaine.org>2007-05-22 09:50:31 +0000
commitdf6f2f9a3c88a7a4a8ad0382ee4ee7c9a3ee3256 (patch)
treed9862e5d04f4014def5911bb4ff8206c85636fb7 /apps/codecs
parent8970055ec107a2387eedbb373889d0f540745121 (diff)
downloadrockbox-df6f2f9a3c88a7a4a8ad0382ee4ee7c9a3ee3256.tar.gz
rockbox-df6f2f9a3c88a7a4a8ad0382ee4ee7c9a3ee3256.zip
Upgrade to libspeex 1.2beta2. Very minor performance increase (0.6% on coldfire).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13461 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/libspeex/README.rockbox2
-rw-r--r--apps/codecs/libspeex/_kiss_fft_guts.h1
-rw-r--r--apps/codecs/libspeex/arch.h2
-rw-r--r--apps/codecs/libspeex/bits.c24
-rw-r--r--apps/codecs/libspeex/cb_search.c2
-rw-r--r--apps/codecs/libspeex/config-speex.h1
-rw-r--r--apps/codecs/libspeex/filters.c21
-rw-r--r--apps/codecs/libspeex/filters.h1
-rw-r--r--apps/codecs/libspeex/filters_arm4.h1
-rw-r--r--apps/codecs/libspeex/jitter.c13
-rw-r--r--apps/codecs/libspeex/ltp_arm4.h2
-rw-r--r--apps/codecs/libspeex/ltp_bfin.h10
-rw-r--r--apps/codecs/libspeex/mdf.c57
-rw-r--r--apps/codecs/libspeex/medfilter.c4
-rw-r--r--apps/codecs/libspeex/misc.c39
-rw-r--r--apps/codecs/libspeex/misc.h28
-rw-r--r--apps/codecs/libspeex/modes.c2
-rw-r--r--apps/codecs/libspeex/modes.h3
-rw-r--r--apps/codecs/libspeex/nb_celp.c44
-rw-r--r--apps/codecs/libspeex/nb_celp.h6
-rw-r--r--apps/codecs/libspeex/preprocess.c22
-rw-r--r--apps/codecs/libspeex/resample.c380
-rw-r--r--apps/codecs/libspeex/rockbox.c5
-rw-r--r--apps/codecs/libspeex/sb_celp.c64
-rw-r--r--apps/codecs/libspeex/speex/speex.h14
-rw-r--r--apps/codecs/libspeex/speex/speex_bits.h3
-rw-r--r--apps/codecs/libspeex/speex/speex_jitter.h4
-rw-r--r--apps/codecs/libspeex/speex/speex_resampler.h133
-rw-r--r--apps/codecs/libspeex/speex_header.c4
-rw-r--r--apps/codecs/libspeex/testdenoise.c2
-rw-r--r--apps/codecs/libspeex/testecho.c2
-rw-r--r--apps/codecs/libspeex/testenc.c2
-rw-r--r--apps/codecs/libspeex/testenc_uwb.c2
-rw-r--r--apps/codecs/libspeex/testenc_wb.c2
-rw-r--r--apps/codecs/libspeex/testresample.c14
-rw-r--r--apps/codecs/libspeex/vbr.c12
36 files changed, 626 insertions, 302 deletions
diff --git a/apps/codecs/libspeex/README.rockbox b/apps/codecs/libspeex/README.rockbox
index 6aeda714ab..a526420b91 100644
--- a/apps/codecs/libspeex/README.rockbox
+++ b/apps/codecs/libspeex/README.rockbox
@@ -1,4 +1,4 @@
-Library: libspeex-1.2beta1 (SVN version 12735)
+Library: libspeex-1.2beta2 (SVN version 12966)
Imported: 2007-03-12 by Dan Everton
diff --git a/apps/codecs/libspeex/_kiss_fft_guts.h b/apps/codecs/libspeex/_kiss_fft_guts.h
index 322299c197..6eb9bd312b 100644
--- a/apps/codecs/libspeex/_kiss_fft_guts.h
+++ b/apps/codecs/libspeex/_kiss_fft_guts.h
@@ -12,6 +12,7 @@ Redistribution and use in source and binary forms, with or without modification,
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
/* kiss_fft.h
defines kiss_fft_scalar as either short or a float type
and defines
diff --git a/apps/codecs/libspeex/arch.h b/apps/codecs/libspeex/arch.h
index 2bc5061b29..e2d731acc0 100644
--- a/apps/codecs/libspeex/arch.h
+++ b/apps/codecs/libspeex/arch.h
@@ -35,7 +35,9 @@
#ifndef ARCH_H
#define ARCH_H
+#ifndef OUTSIDE_SPEEX
#include "speex/speex_types.h"
+#endif
#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */
diff --git a/apps/codecs/libspeex/bits.c b/apps/codecs/libspeex/bits.c
index 6173246380..379fe748d4 100644
--- a/apps/codecs/libspeex/bits.c
+++ b/apps/codecs/libspeex/bits.c
@@ -67,6 +67,20 @@ void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
speex_bits_reset(bits);
}
+void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size)
+{
+ bits->chars = (char*)buff;
+ bits->buf_size = buf_size;
+
+ bits->owner=0;
+
+ bits->nbBits=buf_size<<LOG2_BITS_PER_CHAR;
+ bits->charPtr=0;
+ bits->bitPtr=0;
+ bits->overflow=0;
+
+}
+
void speex_bits_destroy(SpeexBits *bits)
{
if (bits->owner)
@@ -97,7 +111,7 @@ void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
int nchars = len / BYTES_PER_CHAR;
if (nchars > bits->buf_size)
{
- speex_warning_int("Packet is larger than allocated buffer: ", len);
+ speex_notify("Packet is larger than allocated buffer");
if (bits->owner)
{
char *tmp = (char*)speex_realloc(bits->chars, nchars);
@@ -110,7 +124,7 @@ void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
speex_warning("Could not resize input buffer: truncating input");
}
} else {
- speex_warning("Do not own input buffer: truncating input");
+ speex_warning("Do not own input buffer: truncating oversize input");
nchars=bits->buf_size;
}
}
@@ -159,10 +173,10 @@ void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
bits->chars=tmp;
} else {
nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;
- speex_warning("Could not resize input buffer: truncating input");
+ speex_warning("Could not resize input buffer: truncating oversize input");
}
} else {
- speex_warning("Do not own input buffer: truncating input");
+ speex_warning("Do not own input buffer: truncating oversize input");
nchars=bits->buf_size;
}
}
@@ -223,7 +237,7 @@ void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
{
- speex_warning("Buffer too small to pack bits");
+ speex_notify("Buffer too small to pack bits");
if (bits->owner)
{
int new_nchars = ((bits->buf_size+5)*3)>>1;
diff --git a/apps/codecs/libspeex/cb_search.c b/apps/codecs/libspeex/cb_search.c
index ce7ae7e8ce..1090af0e08 100644
--- a/apps/codecs/libspeex/cb_search.c
+++ b/apps/codecs/libspeex/cb_search.c
@@ -181,7 +181,7 @@ int update_target
t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]);
#ifdef FIXED_POINT
- if (sign)
+ if (sign==1)
{
for (j=0;j<subvect_size;j++)
e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
diff --git a/apps/codecs/libspeex/config-speex.h b/apps/codecs/libspeex/config-speex.h
index efdb7dbb54..461873945f 100644
--- a/apps/codecs/libspeex/config-speex.h
+++ b/apps/codecs/libspeex/config-speex.h
@@ -163,5 +163,6 @@
#define OVERRIDE_SPEEX_ERROR 1
#define OVERRIDE_SPEEX_WARNING 1
#define OVERRIDE_SPEEX_WARNING_INT 1
+#define OVERRIDE_SPEEX_NOTIFY 1
#define OVERRIDE_SPEEX_PUTC 1
diff --git a/apps/codecs/libspeex/filters.c b/apps/codecs/libspeex/filters.c
index 1ae6854d51..3d9d118cb6 100644
--- a/apps/codecs/libspeex/filters.c
+++ b/apps/codecs/libspeex/filters.c
@@ -34,6 +34,7 @@
#include "config-speex.h"
#endif
+#include "filters.h"
#include "stack_alloc.h"
#include "misc.h"
#include "math_approx.h"
@@ -46,8 +47,6 @@
#include "filters_arm4.h"
#elif defined (BFIN_ASM)
#include "filters_bfin.h"
-#else
-#include "filters.h"
#endif
@@ -63,6 +62,24 @@ void bw_lpc(spx_word16_t gamma, const spx_coef_t *lpc_in, spx_coef_t *lpc_out, i
}
}
+void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len)
+{
+ int i;
+ for (i=0;i<len;i++)
+ {
+ /* It's important we do the test that way so we can catch NaNs, which are neither greater nor smaller */
+ if (!(vec[i]>=min_val && vec[i] <= max_val))
+ {
+ if (vec[i] < min_val)
+ vec[i] = min_val;
+ else if (vec[i] > max_val)
+ vec[i] = max_val;
+ else /* Has to be NaN */
+ vec[i] = 0;
+ }
+ }
+}
+
void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem)
{
int i;
diff --git a/apps/codecs/libspeex/filters.h b/apps/codecs/libspeex/filters.h
index fee68aba31..b363a9a683 100644
--- a/apps/codecs/libspeex/filters.h
+++ b/apps/codecs/libspeex/filters.h
@@ -67,6 +67,7 @@ void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, in
/* Apply bandwidth expansion on LPC coef */
void bw_lpc(spx_word16_t , const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order);
+void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len);
void syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
diff --git a/apps/codecs/libspeex/filters_arm4.h b/apps/codecs/libspeex/filters_arm4.h
index 6bdfe4797c..91386100a4 100644
--- a/apps/codecs/libspeex/filters_arm4.h
+++ b/apps/codecs/libspeex/filters_arm4.h
@@ -35,6 +35,7 @@
#define OVERRIDE_NORMALIZE16
int normalize16(const spx_sig_t *x, spx_word16_t *y, int max_scale, int len)
{
+ int i;
spx_sig_t max_val=1;
int sig_shift;
int dead1, dead2, dead3, dead4, dead5, dead6;
diff --git a/apps/codecs/libspeex/jitter.c b/apps/codecs/libspeex/jitter.c
index 02919e2135..81935e9195 100644
--- a/apps/codecs/libspeex/jitter.c
+++ b/apps/codecs/libspeex/jitter.c
@@ -197,7 +197,7 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
/* Adjust the buffer size depending on network conditions.
The arrival margin is how much in advance (or late) the packet it */
- arrival_margin = (packet->timestamp - jitter->current_timestamp)/jitter->tick_size - jitter->buffer_margin;
+ arrival_margin = (((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->current_timestamp))/jitter->tick_size - jitter->buffer_margin;
if (arrival_margin >= -jitter->late_cutoff)
{
@@ -243,7 +243,7 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
}
/** Get one packet from the jitter buffer */
-int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint32_t *start_offset)
+int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
{
int i;
unsigned int j;
@@ -378,7 +378,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint
jitter->buf[i] = NULL;
/* Set timestamp and span (if requested) */
if (start_offset)
- *start_offset = jitter->timestamp[i]-jitter->pointer_timestamp;
+ *start_offset = (spx_int32_t)jitter->timestamp[i]-(spx_int32_t)jitter->pointer_timestamp;
packet->timestamp = jitter->timestamp[i];
packet->span = jitter->span[i];
/* Point at the end of the current packet */
@@ -438,7 +438,7 @@ void jitter_buffer_tick(JitterBuffer *jitter)
}
/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
-int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint32_t *start_offset)
+int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
{
int i;
float late_ratio_short;
@@ -579,6 +579,7 @@ void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp)
{
int i;
int ret;
+ spx_int32_t activity;
char data[2048];
JitterBufferPacket packet;
packet.data = data;
@@ -618,7 +619,9 @@ void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp)
out[i]=0;
}
}
- jitter_buffer_update_delay(jitter->packets, &packet, NULL);
+ speex_decoder_ctl(jitter->dec, SPEEX_GET_ACTIVITY, &activity);
+ if (activity < 30)
+ jitter_buffer_update_delay(jitter->packets, &packet, NULL);
jitter_buffer_tick(jitter->packets);
}
diff --git a/apps/codecs/libspeex/ltp_arm4.h b/apps/codecs/libspeex/ltp_arm4.h
index 5f667cf41b..cdb94e603a 100644
--- a/apps/codecs/libspeex/ltp_arm4.h
+++ b/apps/codecs/libspeex/ltp_arm4.h
@@ -171,7 +171,7 @@ void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *c
"\tstr %7, %14 \n"
: "+r" (y0), "+r" (y1), "+r" (y2), "+r" (y3),
- "=r" (part1), "=r" (part2), "=r" (part3), "=r" (part4),
+ "=r" (part1), "=r" (part2), "=r" (part3), "=r" (part4),
"+r" (x), "+r" (y), "=r" (x0), "+m" (sum1),
"+m" (sum2), "+m" (sum3), "+m" (sum4), "=r" (dead1)
:
diff --git a/apps/codecs/libspeex/ltp_bfin.h b/apps/codecs/libspeex/ltp_bfin.h
index c4669022f1..b530f85986 100644
--- a/apps/codecs/libspeex/ltp_bfin.h
+++ b/apps/codecs/libspeex/ltp_bfin.h
@@ -330,7 +330,6 @@ static int pitch_gain_search_3tap_vq(
" %0 = 0;\n\t" /* %0: best_sum */
" %1 = 0;\n\t" /* %1: best_cbdk */
" P1 = 0;\n\t" /* P1: loop counter */
-" R5 = 64;\n\t" /* R5: pitch_control */
" LSETUP (pgs1, pgs2) LC1 = %4;\n\t"
"pgs1: R2 = B [P0++] (X);\n\t" /* R2: g[0] */
@@ -339,6 +338,7 @@ static int pitch_gain_search_3tap_vq(
" R2 += 32;\n\t"
" R3 += 32;\n\t"
" R4 += 32;\n\t"
+" R4.H = 64;\n\t" /* R4.H: pitch_control */
" R0 = B [P0++] (X);\n\t"
" B0 = R0;\n\t" /* BO: gain_sum */
@@ -349,13 +349,13 @@ static int pitch_gain_search_3tap_vq(
" A0 = 0;\n\t"
" R0.L = W[I1++];\n\t"
-" R1.L = R2.L*R5.L (IS);\n\t"
+" R1.L = R2.L*R4.H (IS);\n\t"
" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
-" R1.L = R3.L*R5.L (IS);\n\t"
+" R1.L = R3.L*R4.H (IS);\n\t"
" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
-" R1.L = R4.L*R5.L (IS);\n\t"
+" R1.L = R4.L*R4.H (IS);\n\t"
" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
" R1.L = R2.L*R3.L (IS);\n\t"
@@ -406,7 +406,7 @@ static int pitch_gain_search_3tap_vq(
: "=&d" (best_sum), "=&d" (best_cdbk)
: "a" (gain_cdbk), "a" (C16), "a" (gain_cdbk_size), "a" (max_gain),
"b" (-VERY_LARGE32)
- : "R0", "R1", "R2", "R3", "R4", "R5", "P0",
+ : "R0", "R1", "R2", "R3", "R4", "P0",
"P1", "I1", "L1", "A0", "B0"
#if (__GNUC__ == 4)
, "LC1"
diff --git a/apps/codecs/libspeex/mdf.c b/apps/codecs/libspeex/mdf.c
index d67c36d6dc..2fe3bd08fd 100644
--- a/apps/codecs/libspeex/mdf.c
+++ b/apps/codecs/libspeex/mdf.c
@@ -41,8 +41,8 @@
double-talk is achieved using a variable learning rate as described in:
Valin, J.-M., On Adjusting the Learning Rate in Frequency Domain Echo
- Cancellation With Double-Talk. To appear in IEEE Transactions on Audio,
- Speech and Language Processing, 2006.
+ Cancellation With Double-Talk. IEEE Transactions on Audio,
+ Speech and Language Processing, Vol. 15, No. 3, pp. 1030-1034, 2007.
http://people.xiph.org/~jm/papers/valin_taslp2006.pdf
There is no explicit double-talk detection, but a continuous variation
@@ -360,12 +360,36 @@ static inline void mdf_adjust_prop(const spx_word32_t *W, int N, int M, spx_word
/*printf ("\n");*/
}
+#ifdef DUMP_ECHO_CANCEL_DATA
+#include <stdio.h>
+static FILE *rFile=NULL, *pFile=NULL, *oFile=NULL;
+
+static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const spx_int16_t *out, int len)
+{
+ if (!(rFile && pFile && oFile))
+ {
+ speex_error("Dump files not open");
+ }
+ fwrite(rec, sizeof(spx_int16_t), len, rFile);
+ fwrite(play, sizeof(spx_int16_t), len, pFile);
+ fwrite(out, sizeof(spx_int16_t), len, oFile);
+}
+#endif
+
/** Creates a new echo canceller state */
SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length)
{
int i,N,M;
SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState));
+#ifdef DUMP_ECHO_CANCEL_DATA
+ if (rFile || pFile || oFile)
+ speex_error("Opening dump files twice");
+ rFile = fopen("aec_rec.sw", "w");
+ pFile = fopen("aec_play.sw", "w");
+ oFile = fopen("aec_out.sw", "w");
+#endif
+
st->frame_size = frame_size;
st->window_size = 2*frame_size;
N = st->window_size;
@@ -553,6 +577,13 @@ void speex_echo_state_destroy(SpeexEchoState *st)
#endif
speex_free(st->play_buf);
speex_free(st);
+
+#ifdef DUMP_ECHO_CANCEL_DATA
+ fclose(rFile);
+ fclose(pFile);
+ fclose(oFile);
+ rFile = pFile = oFile = NULL;
+#endif
}
void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out)
@@ -701,8 +732,8 @@ void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const sp
spectral_mul_accum16(st->X, st->foreground, st->Y, N, M);
spx_ifft(st->fft_table, st->Y, st->e);
for (i=0;i<st->frame_size;i++)
- st->x[i+st->frame_size] = SUB16(st->input[i], st->e[i+st->frame_size]);
- Sff = mdf_inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size);
+ st->e[i] = SUB16(st->input[i], st->e[i+st->frame_size]);
+ Sff = mdf_inner_prod(st->e, st->e, st->frame_size);
#endif
/* Adjust proportional adaption rate */
@@ -762,13 +793,13 @@ void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const sp
#ifdef TWO_PATH
/* Difference in response, this is used to estimate the variance of our residual power estimate */
for (i=0;i<st->frame_size;i++)
- st->x[i+st->frame_size] = SUB16(st->e[i+st->frame_size], st->y[i+st->frame_size]);
- Dbf = 10+mdf_inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size);
+ st->e[i] = SUB16(st->e[i+st->frame_size], st->y[i+st->frame_size]);
+ Dbf = 10+mdf_inner_prod(st->e, st->e, st->frame_size);
#endif
for (i=0;i<st->frame_size;i++)
- st->x[i+st->frame_size] = SUB16(st->input[i], st->y[i+st->frame_size]);
- See = mdf_inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size);
+ st->e[i] = SUB16(st->input[i], st->y[i+st->frame_size]);
+ See = mdf_inner_prod(st->e, st->e, st->frame_size);
#ifndef TWO_PATH
Sff = See;
#endif
@@ -828,7 +859,7 @@ void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const sp
for (i=0;i<st->frame_size;i++)
st->y[i+st->frame_size] = st->e[i+st->frame_size];
for (i=0;i<st->frame_size;i++)
- st->x[i+st->frame_size] = SUB16(st->input[i], st->y[i+st->frame_size]);
+ st->e[i] = SUB16(st->input[i], st->y[i+st->frame_size]);
See = Sff;
st->Davg1 = st->Davg2 = 0;
st->Dvar1 = st->Dvar2 = FLOAT_ZERO;
@@ -861,12 +892,16 @@ void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const sp
out[i] = (spx_int16_t)tmp_out;
st->memE = tmp_out;
}
-
+
+#ifdef DUMP_ECHO_CANCEL_DATA
+ dump_audio(in, far_end, out, st->frame_size);
+#endif
+
/* Compute error signal (filter update version) */
for (i=0;i<st->frame_size;i++)
{
+ st->e[i+st->frame_size] = st->e[i];
st->e[i] = 0;
- st->e[i+st->frame_size] = st->x[i+st->frame_size];
}
/* Compute a bunch of correlations */
diff --git a/apps/codecs/libspeex/medfilter.c b/apps/codecs/libspeex/medfilter.c
index 83872e5474..e4bc1c6ce9 100644
--- a/apps/codecs/libspeex/medfilter.c
+++ b/apps/codecs/libspeex/medfilter.c
@@ -32,6 +32,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config-speex.h"
+#endif
+
#include "medfilter.h"
#include "misc.h"
diff --git a/apps/codecs/libspeex/misc.c b/apps/codecs/libspeex/misc.c
index a0a6e3da37..ae6869781d 100644
--- a/apps/codecs/libspeex/misc.c
+++ b/apps/codecs/libspeex/misc.c
@@ -63,30 +63,6 @@ long long spx_mips=0;
#endif
-spx_uint32_t be_int(spx_uint32_t i)
-{
- spx_uint32_t ret=i;
-#ifndef WORDS_BIGENDIAN
- ret = i>>24;
- ret += (i>>8)&0x0000ff00;
- ret += (i<<8)&0x00ff0000;
- ret += (i<<24);
-#endif
- return ret;
-}
-
-spx_uint32_t le_int(spx_uint32_t i)
-{
- spx_uint32_t ret=i;
-#ifdef WORDS_BIGENDIAN
- ret = i>>24;
- ret += (i>>8)&0x0000ff00;
- ret += (i<<8)&0x00ff0000;
- ret += (i<<24);
-#endif
- return ret;
-}
-
#ifndef OVERRIDE_SPEEX_ALLOC
void *speex_alloc (int size)
{
@@ -132,7 +108,7 @@ void *speex_move (void *dest, void *src, int n)
#ifndef OVERRIDE_SPEEX_ERROR
void speex_error(const char *str)
{
- fprintf (stderr, "Fatal error: %s\n", str);
+ fprintf (stderr, "Fatal (internal) error: %s\n", str);
exit(1);
}
#endif
@@ -140,14 +116,27 @@ void speex_error(const char *str)
#ifndef OVERRIDE_SPEEX_WARNING
void speex_warning(const char *str)
{
+#ifndef DISABLE_WARNINGS
fprintf (stderr, "warning: %s\n", str);
+#endif
}
#endif
#ifndef OVERRIDE_SPEEX_WARNING_INT
void speex_warning_int(const char *str, int val)
{
+#ifndef DISABLE_WARNINGS
fprintf (stderr, "warning: %s %d\n", str, val);
+#endif
+}
+#endif
+
+#ifndef OVERRIDE_SPEEX_NOTIFY
+void speex_notify(const char *str)
+{
+#ifndef DISABLE_NOTIFICATIONS
+ fprintf (stderr, "notification: %s\n", str);
+#endif
}
#endif
diff --git a/apps/codecs/libspeex/misc.h b/apps/codecs/libspeex/misc.h
index 1d6c6cb49f..1664aaed9d 100644
--- a/apps/codecs/libspeex/misc.h
+++ b/apps/codecs/libspeex/misc.h
@@ -38,9 +38,9 @@
#ifndef SPEEX_VERSION
#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */
#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */
-#define SPEEX_MICRO_VERSION 13 /**< Micro Speex version. */
+#define SPEEX_MICRO_VERSION 14 /**< Micro Speex version. */
#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */
-#define SPEEX_VERSION "speex-1.2beta1" /**< Speex version string. */
+#define SPEEX_VERSION "speex-1.2beta2" /**< Speex version string. */
#endif
/* A couple test to catch stupid option combinations */
@@ -75,10 +75,21 @@
void print_vec(float *vec, int len, char *name);
#endif
-/** Convert big endian */
-spx_uint32_t be_int(spx_uint32_t i);
/** Convert little endian */
-spx_uint32_t le_int(spx_uint32_t i);
+static inline spx_int32_t le_int(spx_int32_t i)
+{
+#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
+ spx_uint32_t ui, ret;
+ ui = i;
+ ret = ui>>24;
+ ret |= (ui>>8)&0x0000ff00;
+ ret |= (ui<<8)&0x00ff0000;
+ ret |= (ui<<24);
+ return ret;
+#else
+ return i;
+#endif
+}
/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free */
void *speex_alloc (int size);
@@ -98,15 +109,18 @@ void speex_free_scratch (void *ptr);
/** Speex wrapper for mem_move */
void *speex_move (void *dest, void *src, int n);
-/** Print error message to stderr */
+/** Abort with an error message to stderr (internal Speex error) */
void speex_error(const char *str);
-/** Print warning message to stderr */
+/** Print warning message to stderr (programming error) */
void speex_warning(const char *str);
/** Print warning message with integer argument to stderr */
void speex_warning_int(const char *str, int val);
+/** Print notification message to stderr */
+void speex_notify(const char *str);
+
/** Generate a random number */
spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed);
diff --git a/apps/codecs/libspeex/modes.c b/apps/codecs/libspeex/modes.c
index 652fcf9550..1d30ce4a15 100644
--- a/apps/codecs/libspeex/modes.c
+++ b/apps/codecs/libspeex/modes.c
@@ -662,7 +662,7 @@ const SpeexMode * speex_lib_get_mode (int mode)
if (mode == SPEEX_MODEID_NB_48K) return &speex_nb_48k_mode;
#endif
- if (mode < 0 || mode > SPEEX_NB_MODES) return NULL;
+ if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL;
return speex_mode_list[mode];
}
diff --git a/apps/codecs/libspeex/modes.h b/apps/codecs/libspeex/modes.h
index 385cec007d..5bf1971c21 100644
--- a/apps/codecs/libspeex/modes.h
+++ b/apps/codecs/libspeex/modes.h
@@ -60,6 +60,9 @@
/** Used internally*/
#define SPEEX_SET_WIDEBAND 105
+/** Used internally*/
+#define SPEEX_GET_STACK 106
+
/** Quantizes LSPs */
typedef void (*lsp_quant_func)(spx_lsp_t *, spx_lsp_t *, int, SpeexBits *);
diff --git a/apps/codecs/libspeex/nb_celp.c b/apps/codecs/libspeex/nb_celp.c
index 85e4ca015e..e41ad6e703 100644
--- a/apps/codecs/libspeex/nb_celp.c
+++ b/apps/codecs/libspeex/nb_celp.c
@@ -1257,7 +1257,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);
if (advance < 0)
{
- speex_warning ("Invalid wideband mode encountered. Corrupted stream?");
+ speex_notify("Invalid mode encountered. The stream is corrupted.");
return -2;
}
advance -= (SB_SUBMODE_BITS+1);
@@ -1272,7 +1272,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);
if (advance < 0)
{
- speex_warning ("Invalid wideband mode encountered: corrupted stream?");
+ speex_notify("Invalid mode encountered. The stream is corrupted.");
return -2;
}
advance -= (SB_SUBMODE_BITS+1);
@@ -1280,7 +1280,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
wideband = speex_bits_unpack_unsigned(bits, 1);
if (wideband)
{
- speex_warning ("More than two wideband layers found: corrupted stream?");
+ speex_notify("More than two wideband layers found. The stream is corrupted.");
return -2;
}
@@ -1305,7 +1305,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
return ret;
} else if (m>8) /* Invalid mode */
{
- speex_warning("Invalid mode encountered: corrupted stream?");
+ speex_notify("Invalid mode encountered. The stream is corrupted.");
return -2;
}
@@ -1526,7 +1526,11 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
#ifdef EPIC_48K
}
#endif
-
+ /* Ensuring that things aren't blowing up as would happen if e.g. an encoder is
+ crafting packets to make us produce NaNs and slow down the decoder (vague DoS threat).
+ We can probably be even more aggressive and limit to 15000 or so. */
+ sanitize_values32(exc32, NEG32(QCONST32(32000,SIG_SHIFT-1)), QCONST32(32000,SIG_SHIFT-1), st->subframeSize);
+
tmp = gain_3tap_to_1tap(pitch_gain);
pitch_average += tmp;
@@ -1698,7 +1702,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
for (i=0;i<st->lpcSize;i+=2)
{
/*pi_g += -st->interp_qlpc[i] + st->interp_qlpc[i+1];*/
- pi_g = ADD32(pi_g, SUB32(EXTEND32(st->interp_qlpc[i+1]),EXTEND32(st->interp_qlpc[i])));
+ pi_g = ADD32(pi_g, SUB32(EXTEND32(ak[i+1]),EXTEND32(ak[i])));
}
st->pi_gain[sub] = pi_g;
}
@@ -1716,6 +1720,14 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
/*for (i=0;i<st->frameSize;i++)
printf ("%d\n", (int)st->frame[i]);*/
+ /* Tracking output level */
+ st->level = 1+PSHR32(ol_gain,SIG_SHIFT);
+ st->max_level = MAX16(MULT16_16_Q15(QCONST16(.99f,15), st->max_level), st->level);
+ st->min_level = MIN16(ADD16(1,MULT16_16_Q14(QCONST16(1.01f,14), st->min_level)), st->level);
+ if (st->max_level < st->min_level+1)
+ st->max_level = st->min_level+1;
+ /*printf ("%f %f %f %d\n", og, st->min_level, st->max_level, update);*/
+
/* Store the LSPs for interpolation in the next frame */
for (i=0;i<st->lpcSize;i++)
st->old_qlsp[i] = qlsp[i];
@@ -1924,6 +1936,9 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_SET_WIDEBAND:
st->isWideband = *((spx_int32_t*)ptr);
break;
+ case SPEEX_GET_STACK:
+ *((char**)ptr) = st->stack;
+ break;
default:
speex_warning_int("Unknown nb_ctl request: ", request);
return -1;
@@ -2006,7 +2021,19 @@ int nb_decoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_HIGHPASS:
(*(spx_int32_t*)ptr) = st->highpass_enabled;
break;
-
+ case SPEEX_GET_ACTIVITY:
+ {
+ float ret;
+ ret = log(st->level/st->min_level)/log(st->max_level/st->min_level);
+ if (ret>1)
+ ret = 1;
+ /* Done in a strange way to catch NaNs as well */
+ if (!(ret > 0))
+ ret = 0;
+ /*printf ("%f %f %f %f\n", st->level, st->min_level, st->max_level, ret);*/
+ (*(spx_int32_t*)ptr) = (int)(100*ret);
+ }
+ break;
case SPEEX_GET_PI_GAIN:
{
int i;
@@ -2031,6 +2058,9 @@ int nb_decoder_ctl(void *state, int request, void *ptr)
case SPEEX_SET_WIDEBAND:
st->isWideband = *((spx_int32_t*)ptr);
break;
+ case SPEEX_GET_STACK:
+ *((char**)ptr) = st->stack;
+ break;
default:
speex_warning_int("Unknown nb_ctl request: ", request);
return -1;
diff --git a/apps/codecs/libspeex/nb_celp.h b/apps/codecs/libspeex/nb_celp.h
index 1ebf71754c..cc91b1c4fe 100644
--- a/apps/codecs/libspeex/nb_celp.h
+++ b/apps/codecs/libspeex/nb_celp.h
@@ -148,7 +148,11 @@ typedef struct DecState {
spx_mem_t *mem_sp; /**< Filter memory for synthesis signal */
spx_mem_t mem_hp[2]; /**< High-pass filter memory */
spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */
- spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */
+ spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */
+
+ spx_word16_t level;
+ spx_word16_t max_level;
+ spx_word16_t min_level;
/* This is used in packet loss concealment */
int last_pitch; /**< Pitch of last correctly decoded frame */
diff --git a/apps/codecs/libspeex/preprocess.c b/apps/codecs/libspeex/preprocess.c
index d030d3fcb2..7e7f106b55 100644
--- a/apps/codecs/libspeex/preprocess.c
+++ b/apps/codecs/libspeex/preprocess.c
@@ -229,6 +229,7 @@ struct SpeexPreprocessState_ {
#ifndef FIXED_POINT
int agc_enabled;
float agc_level;
+ float loudness_accum;
float *loudness_weight; /**< Perceptual loudness curve */
float loudness; /**< Loudness estimate */
float agc_gain; /**< Current AGC gain */
@@ -509,12 +510,13 @@ SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_r
st->loudness_weight[i]=.01f;
st->loudness_weight[i] *= st->loudness_weight[i];
}
- st->loudness = pow(AMP_SCALE*st->agc_level,LOUDNESS_EXP);
+ /*st->loudness = pow(AMP_SCALE*st->agc_level,LOUDNESS_EXP);*/
+ st->loudness = 1e-15;
st->agc_gain = 1;
st->nb_loudness_adapt = 0;
- st->max_gain = 10;
- st->max_increase_step = exp(0.11513f * 6.*st->frame_size / st->sampling_rate);
- st->max_decrease_step = exp(-0.11513f * 30.*st->frame_size / st->sampling_rate);
+ st->max_gain = 30;
+ st->max_increase_step = exp(0.11513f * 12.*st->frame_size / st->sampling_rate);
+ st->max_decrease_step = exp(-0.11513f * 40.*st->frame_size / st->sampling_rate);
st->prev_loudness = 1;
st->init_max = 1;
#endif
@@ -578,17 +580,19 @@ static void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx
loudness=sqrt(loudness);
/*if (loudness < 2*pow(st->loudness, 1.0/LOUDNESS_EXP) &&
loudness*2 > pow(st->loudness, 1.0/LOUDNESS_EXP))*/
- if (Pframe>.5f)
+ if (Pframe>.3f)
{
st->nb_loudness_adapt++;
- rate=2.0f*Pframe*Pframe/(1+st->nb_loudness_adapt);
+ /*rate=2.0f*Pframe*Pframe/(1+st->nb_loudness_adapt);*/
+ rate = .03*Pframe*Pframe;
st->loudness = (1-rate)*st->loudness + (rate)*pow(AMP_SCALE*loudness, LOUDNESS_EXP);
+ st->loudness_accum = (1-rate)*st->loudness_accum + rate;
if (st->init_max < st->max_gain && st->nb_adapt > 20)
- st->init_max *= 1.f + .05f*Pframe*Pframe;
+ st->init_max *= 1.f + .1f*Pframe*Pframe;
}
/*printf ("%f %f %f %f\n", Pframe, loudness, pow(st->loudness, 1.0f/LOUDNESS_EXP), st->loudness2);*/
- target_gain = AMP_SCALE*st->agc_level*pow(st->loudness, -1.0f/LOUDNESS_EXP);
+ target_gain = AMP_SCALE*st->agc_level*pow(st->loudness/(1e-4+st->loudness_accum), -1.0f/LOUDNESS_EXP);
if ((Pframe>.5 && st->nb_adapt > 20) || target_gain < st->agc_gain)
{
@@ -603,7 +607,7 @@ static void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx
st->agc_gain = target_gain;
}
- /*printf ("%f %f %f\n", loudness, (float)AMP_SCALE_1*pow(st->loudness, 1.0f/LOUDNESS_EXP), st->agc_gain);*/
+ /*fprintf (stderr, "%f %f %f\n", loudness, (float)AMP_SCALE_1*pow(st->loudness, 1.0f/LOUDNESS_EXP), st->agc_gain);*/
for (i=0;i<2*N;i++)
ft[i] *= st->agc_gain;
diff --git a/apps/codecs/libspeex/resample.c b/apps/codecs/libspeex/resample.c
index 22ed21c64a..2dfe2dd5f3 100644
--- a/apps/codecs/libspeex/resample.c
+++ b/apps/codecs/libspeex/resample.c
@@ -56,14 +56,16 @@ TODO list:
#ifdef OUTSIDE_SPEEX
#include <stdlib.h>
-void *speex_alloc (int size) {return calloc(size,1);}
-void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);}
-void speex_free (void *ptr) {free(ptr);}
+static void *speex_alloc (int size) {return calloc(size,1);}
+static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);}
+static void speex_free (void *ptr) {free(ptr);}
#include "speex_resampler.h"
-#else
+#include "arch.h"
+#else /* OUTSIDE_SPEEX */
+
#include "speex/speex_resampler.h"
#include "misc.h"
-#endif
+#endif /* OUTSIDE_SPEEX */
#include <math.h>
@@ -83,34 +85,37 @@ void speex_free (void *ptr) {free(ptr);}
#define IMAX(a,b) ((a) > (b) ? (a) : (b))
+#ifndef NULL
+#define NULL 0
+#endif
-typedef int (*resampler_basic_func)(SpeexResamplerState *, int , const spx_word16_t *, int *, spx_word16_t *, int *);
+typedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t , const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *);
struct SpeexResamplerState_ {
- int in_rate;
- int out_rate;
- int num_rate;
- int den_rate;
+ spx_uint32_t in_rate;
+ spx_uint32_t out_rate;
+ spx_uint32_t num_rate;
+ spx_uint32_t den_rate;
int quality;
- int nb_channels;
- int filt_len;
- int mem_alloc_size;
- int int_advance;
- int frac_advance;
+ spx_uint32_t nb_channels;
+ spx_uint32_t filt_len;
+ spx_uint32_t mem_alloc_size;
+ int int_advance;
+ int frac_advance;
float cutoff;
- int oversample;
- int initialised;
- int started;
+ spx_uint32_t oversample;
+ int initialised;
+ int started;
/* These are per-channel */
- int *last_sample;
- int *samp_frac_num;
- int *magic_samples;
+ spx_int32_t *last_sample;
+ spx_uint32_t *samp_frac_num;
+ spx_uint32_t *magic_samples;
spx_word16_t *mem;
spx_word16_t *sinc_table;
- int sinc_table_length;
+ spx_uint32_t sinc_table_length;
resampler_basic_func resampler_ptr;
int in_stride;
@@ -203,12 +208,12 @@ static const struct QualityMapping quality_map[11] = {
{ 32, 4, 0.882f, 0.910f, KAISER6 }, /* Q2 */ /* 82.3% cutoff ( ~60 dB stop) 6 */
{ 48, 8, 0.895f, 0.917f, KAISER8 }, /* Q3 */ /* 84.9% cutoff ( ~80 dB stop) 8 */
{ 64, 8, 0.921f, 0.940f, KAISER8 }, /* Q4 */ /* 88.7% cutoff ( ~80 dB stop) 8 */
- { 80, 8, 0.922f, 0.940f, KAISER10}, /* Q5 */ /* 89.1% cutoff (~100 dB stop) 10 */
- { 96, 8, 0.940f, 0.945f, KAISER10}, /* Q6 */ /* 91.5% cutoff (~100 dB stop) 10 */
+ { 80, 16, 0.922f, 0.940f, KAISER10}, /* Q5 */ /* 89.1% cutoff (~100 dB stop) 10 */
+ { 96, 16, 0.940f, 0.945f, KAISER10}, /* Q6 */ /* 91.5% cutoff (~100 dB stop) 10 */
{128, 16, 0.950f, 0.950f, KAISER10}, /* Q7 */ /* 93.1% cutoff (~100 dB stop) 10 */
{160, 16, 0.960f, 0.960f, KAISER10}, /* Q8 */ /* 94.5% cutoff (~100 dB stop) 10 */
- {192, 16, 0.968f, 0.968f, KAISER12}, /* Q9 */ /* 95.5% cutoff (~100 dB stop) 10 */
- {256, 16, 0.975f, 0.975f, KAISER12}, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */
+ {192, 32, 0.968f, 0.968f, KAISER12}, /* Q9 */ /* 95.5% cutoff (~100 dB stop) 10 */
+ {256, 32, 0.975f, 0.975f, KAISER12}, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */
};
/*8,24,40,56,80,104,128,160,200,256,320*/
static double compute_func(float x, struct FuncDef *func)
@@ -302,15 +307,15 @@ static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4])
}
#endif
-static int resampler_basic_direct_single(SpeexResamplerState *st, int channel_index, const spx_word16_t *in, int *in_len, spx_word16_t *out, int *out_len)
+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)
{
int N = st->filt_len;
int out_sample = 0;
spx_word16_t *mem;
int last_sample = st->last_sample[channel_index];
- int samp_frac_num = st->samp_frac_num[channel_index];
+ spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
mem = st->mem + channel_index * st->mem_alloc_size;
- while (!(last_sample >= *in_len || out_sample >= *out_len))
+ while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
{
int j;
spx_word32_t sum=0;
@@ -350,15 +355,15 @@ static int resampler_basic_direct_single(SpeexResamplerState *st, int channel_in
#ifdef FIXED_POINT
#else
/* This is the same as the previous function, except with a double-precision accumulator */
-static int resampler_basic_direct_double(SpeexResamplerState *st, int channel_index, const spx_word16_t *in, int *in_len, spx_word16_t *out, int *out_len)
+static int resampler_basic_direct_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
{
int N = st->filt_len;
int out_sample = 0;
spx_word16_t *mem;
int last_sample = st->last_sample[channel_index];
- int samp_frac_num = st->samp_frac_num[channel_index];
+ spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
mem = st->mem + channel_index * st->mem_alloc_size;
- while (!(last_sample >= *in_len || out_sample >= *out_len))
+ while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
{
int j;
double sum=0;
@@ -396,15 +401,15 @@ static int resampler_basic_direct_double(SpeexResamplerState *st, int channel_in
}
#endif
-static int resampler_basic_interpolate_single(SpeexResamplerState *st, int channel_index, const spx_word16_t *in, int *in_len, spx_word16_t *out, int *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)
{
int N = st->filt_len;
int out_sample = 0;
spx_word16_t *mem;
int last_sample = st->last_sample[channel_index];
- int samp_frac_num = st->samp_frac_num[channel_index];
+ spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
mem = st->mem + channel_index * st->mem_alloc_size;
- while (!(last_sample >= *in_len || out_sample >= *out_len))
+ while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
{
int j;
spx_word32_t sum=0;
@@ -465,15 +470,15 @@ static int resampler_basic_interpolate_single(SpeexResamplerState *st, int chann
#ifdef FIXED_POINT
#else
/* This is the same as the previous function, except with a double-precision accumulator */
-static int resampler_basic_interpolate_double(SpeexResamplerState *st, int channel_index, const spx_word16_t *in, int *in_len, spx_word16_t *out, int *out_len)
+static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
{
int N = st->filt_len;
int out_sample = 0;
spx_word16_t *mem;
int last_sample = st->last_sample[channel_index];
- int samp_frac_num = st->samp_frac_num[channel_index];
+ spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
mem = st->mem + channel_index * st->mem_alloc_size;
- while (!(last_sample >= *in_len || out_sample >= *out_len))
+ while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
{
int j;
spx_word32_t sum=0;
@@ -529,8 +534,7 @@ static int resampler_basic_interpolate_double(SpeexResamplerState *st, int chann
static void update_filter(SpeexResamplerState *st)
{
- int i;
- int old_length;
+ spx_uint32_t old_length;
old_length = st->filt_len;
st->oversample = quality_map[st->quality].oversample;
@@ -544,6 +548,16 @@ static void update_filter(SpeexResamplerState *st)
st->filt_len = st->filt_len*st->num_rate / st->den_rate;
/* Round down to make sure we have a multiple of 4 */
st->filt_len &= (~0x3);
+ if (2*st->den_rate < st->num_rate)
+ st->oversample >>= 1;
+ if (4*st->den_rate < st->num_rate)
+ st->oversample >>= 1;
+ if (8*st->den_rate < st->num_rate)
+ st->oversample >>= 1;
+ if (16*st->den_rate < st->num_rate)
+ st->oversample >>= 1;
+ if (st->oversample < 1)
+ st->oversample = 1;
} else {
/* up-sampling */
st->cutoff = quality_map[st->quality].upsample_bandwidth;
@@ -552,6 +566,7 @@ static void update_filter(SpeexResamplerState *st)
/* Choose the resampling type that requires the least amount of memory */
if (st->den_rate <= st->oversample)
{
+ spx_uint32_t i;
if (!st->sinc_table)
st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t));
else if (st->sinc_table_length < st->filt_len*st->den_rate)
@@ -561,7 +576,7 @@ static void update_filter(SpeexResamplerState *st)
}
for (i=0;i<st->den_rate;i++)
{
- int j;
+ spx_uint32_t j;
for (j=0;j<st->filt_len;j++)
{
st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func);
@@ -577,6 +592,7 @@ static void update_filter(SpeexResamplerState *st)
#endif
/*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/
} else {
+ spx_int32_t i;
if (!st->sinc_table)
st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t));
else if (st->sinc_table_length < st->filt_len*st->oversample+8)
@@ -584,7 +600,7 @@ static void update_filter(SpeexResamplerState *st)
st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t));
st->sinc_table_length = st->filt_len*st->oversample+8;
}
- for (i=-4;i<st->oversample*st->filt_len+4;i++)
+ for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++)
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);
#ifdef FIXED_POINT
st->resampler_ptr = resampler_basic_interpolate_single;
@@ -599,8 +615,13 @@ static void update_filter(SpeexResamplerState *st)
st->int_advance = st->num_rate/st->den_rate;
st->frac_advance = st->num_rate%st->den_rate;
+
+ /* Here's the place where we update the filter memory to take into account
+ the change in filter length. It's probably the messiest part of the code
+ due to handling of lots of corner cases. */
if (!st->mem)
{
+ spx_uint32_t i;
st->mem = (spx_word16_t*)speex_alloc(st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t));
for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
st->mem[i] = 0;
@@ -608,6 +629,7 @@ static void update_filter(SpeexResamplerState *st)
/*speex_warning("init filter");*/
} else if (!st->started)
{
+ spx_uint32_t i;
st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t));
for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
st->mem[i] = 0;
@@ -615,6 +637,7 @@ static void update_filter(SpeexResamplerState *st)
/*speex_warning("reinit filter");*/
} else if (st->filt_len > old_length)
{
+ spx_int32_t i;
/* Increase the filter length */
/*speex_warning("increase filter size");*/
int old_alloc_size = st->mem_alloc_size;
@@ -623,45 +646,76 @@ static void update_filter(SpeexResamplerState *st)
st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t));
st->mem_alloc_size = st->filt_len-1;
}
- for (i=0;i<st->nb_channels;i++)
+ for (i=st->nb_channels-1;i>=0;i--)
{
- int j;
- /* Copy data going backward */
- for (j=0;j<old_length-1;j++)
- st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*old_alloc_size+(old_length-2-j)];
- /* Then put zeros for lack of anything better */
- for (;j<st->filt_len-1;j++)
- st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0;
- /* Adjust last_sample */
- st->last_sample[i] += (st->filt_len - old_length)/2;
+ spx_int32_t j;
+ spx_uint32_t olen = old_length;
+ /*if (st->magic_samples[i])*/
+ {
+ /* Try and remove the magic samples as if nothing had happened */
+
+ /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */
+ olen = old_length + 2*st->magic_samples[i];
+ for (j=old_length-2+st->magic_samples[i];j>=0;j--)
+ st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j];
+ for (j=0;j<st->magic_samples[i];j++)
+ st->mem[i*st->mem_alloc_size+j] = 0;
+ st->magic_samples[i] = 0;
+ }
+ if (st->filt_len > olen)
+ {
+ /* If the new filter length is still bigger than the "augmented" length */
+ /* Copy data going backward */
+ for (j=0;j<olen-1;j++)
+ st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)];
+ /* Then put zeros for lack of anything better */
+ for (;j<st->filt_len-1;j++)
+ st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0;
+ /* Adjust last_sample */
+ st->last_sample[i] += (st->filt_len - olen)/2;
+ } else {
+ /* Put back some of the magic! */
+ st->magic_samples[i] = (olen - st->filt_len)/2;
+ for (j=0;j<st->filt_len-1+st->magic_samples[i];j++)
+ st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];
+ }
}
} else if (st->filt_len < old_length)
{
- /* Reduce filter length, this a bit tricky */
- /*speex_warning("decrease filter size (unimplemented)");*/
- /* Adjust last_sample (which will likely end up negative) */
- /*st->last_sample += (st->filt_len - old_length)/2;*/
+ spx_uint32_t i;
+ /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic"
+ samples so they can be used directly as input the next time(s) */
for (i=0;i<st->nb_channels;i++)
{
- int j;
+ spx_uint32_t j;
+ spx_uint32_t old_magic = st->magic_samples[i];
st->magic_samples[i] = (old_length - st->filt_len)/2;
+ /* We must copy some of the memory that's no longer used */
/* Copy data going backward */
- for (j=0;j<st->filt_len-1+st->magic_samples[i];j++)
+ for (j=0;j<st->filt_len-1+st->magic_samples[i]+old_magic;j++)
st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];
+ st->magic_samples[i] += old_magic;
}
}
}
-SpeexResamplerState *speex_resampler_init(int nb_channels, int in_rate, int out_rate, int quality)
+SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)
{
- return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality);
+ return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err);
}
-SpeexResamplerState *speex_resampler_init_frac(int nb_channels, int ratio_num, int ratio_den, int in_rate, int out_rate, int quality)
+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)
{
- int i;
- SpeexResamplerState *st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState));
+ spx_uint32_t i;
+ SpeexResamplerState *st;
+ if (quality > 10 || quality < 0)
+ {
+ if (err)
+ *err = RESAMPLER_ERR_INVALID_ARG;
+ return NULL;
+ }
+ st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState));
st->initialised = 0;
st->started = 0;
st->in_rate = 0;
@@ -681,9 +735,9 @@ SpeexResamplerState *speex_resampler_init_frac(int nb_channels, int ratio_num, i
st->out_stride = 1;
/* Per channel data */
- st->last_sample = (int*)speex_alloc(nb_channels*sizeof(int));
- st->magic_samples = (int*)speex_alloc(nb_channels*sizeof(int));
- st->samp_frac_num = (int*)speex_alloc(nb_channels*sizeof(int));
+ st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(int));
+ st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int));
+ st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int));
for (i=0;i<nb_channels;i++)
{
st->last_sample[i] = 0;
@@ -698,6 +752,9 @@ SpeexResamplerState *speex_resampler_init_frac(int nb_channels, int ratio_num, i
update_filter(st);
st->initialised = 1;
+ if (err)
+ *err = RESAMPLER_ERR_SUCCESS;
+
return st;
}
@@ -713,62 +770,75 @@ void speex_resampler_destroy(SpeexResamplerState *st)
-static void speex_resampler_process_native(SpeexResamplerState *st, int channel_index, const spx_word16_t *in, int *in_len, spx_word16_t *out, int *out_len)
+static int speex_resampler_process_native(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)
{
int j=0;
int N = st->filt_len;
int out_sample = 0;
spx_word16_t *mem;
- int tmp_out_len = 0;
+ spx_uint32_t tmp_out_len = 0;
mem = st->mem + channel_index * st->mem_alloc_size;
st->started = 1;
/* Handle the case where we have samples left from a reduction in filter length */
if (st->magic_samples[channel_index])
{
- int tmp_in_len;
- int tmp_magic;
+ int istride_save;
+ spx_uint32_t tmp_in_len;
+ spx_uint32_t tmp_magic;
+
+ istride_save = st->in_stride;
tmp_in_len = st->magic_samples[channel_index];
tmp_out_len = *out_len;
- /* FIXME: Need to handle the case where the out array is too small */
/* magic_samples needs to be set to zero to avoid infinite recursion */
tmp_magic = st->magic_samples[channel_index];
st->magic_samples[channel_index] = 0;
+ st->in_stride = 1;
speex_resampler_process_native(st, channel_index, mem+N-1, &tmp_in_len, out, &tmp_out_len);
+ st->in_stride = istride_save;
/*speex_warning_int("extra samples:", tmp_out_len);*/
/* If we couldn't process all "magic" input samples, save the rest for next time */
if (tmp_in_len < tmp_magic)
{
- int i;
+ spx_uint32_t i;
st->magic_samples[channel_index] = tmp_magic-tmp_in_len;
for (i=0;i<st->magic_samples[channel_index];i++)
mem[N-1+i]=mem[N-1+i+tmp_in_len];
}
- out += tmp_out_len;
+ out += tmp_out_len*st->out_stride;
+ *out_len -= tmp_out_len;
}
/* Call the right resampler through the function ptr */
out_sample = st->resampler_ptr(st, channel_index, in, in_len, out, out_len);
- if (st->last_sample[channel_index] < *in_len)
+ if (st->last_sample[channel_index] < (spx_int32_t)*in_len)
*in_len = st->last_sample[channel_index];
*out_len = out_sample+tmp_out_len;
st->last_sample[channel_index] -= *in_len;
- for (j=0;j<N-1-*in_len;j++)
+ for (j=0;j<N-1-(spx_int32_t)*in_len;j++)
mem[j] = mem[j+*in_len];
for (;j<N-1;j++)
mem[j] = in[st->in_stride*(j+*in_len-N+1)];
+ return RESAMPLER_ERR_SUCCESS;
}
+#define FIXED_STACK_ALLOC 1024
+
#ifdef FIXED_POINT
-void speex_resampler_process_float(SpeexResamplerState *st, int channel_index, const float *in, int *in_len, float *out, int *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)
{
- int i;
+ spx_uint32_t i;
int istride_save, ostride_save;
+#ifdef VAR_ARRAYS
spx_word16_t x[*in_len];
spx_word16_t y[*out_len];
+ /*VARDECL(spx_word16_t *x);
+ VARDECL(spx_word16_t *y);
+ ALLOC(x, *in_len, spx_word16_t);
+ ALLOC(y, *out_len, spx_word16_t);*/
istride_save = st->in_stride;
ostride_save = st->out_stride;
for (i=0;i<*in_len;i++)
@@ -779,22 +849,59 @@ void speex_resampler_process_float(SpeexResamplerState *st, int channel_index, c
st->out_stride = ostride_save;
for (i=0;i<*out_len;i++)
out[i*st->out_stride] = y[i];
+#else
+ spx_word16_t x[FIXED_STACK_ALLOC];
+ spx_word16_t y[FIXED_STACK_ALLOC];
+ spx_uint32_t ilen=*in_len, olen=*out_len;
+ istride_save = st->in_stride;
+ ostride_save = st->out_stride;
+ while (ilen && olen)
+ {
+ spx_uint32_t ichunk, ochunk;
+ ichunk = ilen;
+ ochunk = olen;
+ if (ichunk>FIXED_STACK_ALLOC)
+ ichunk=FIXED_STACK_ALLOC;
+ if (ochunk>FIXED_STACK_ALLOC)
+ ochunk=FIXED_STACK_ALLOC;
+ for (i=0;i<ichunk;i++)
+ x[i] = WORD2INT(in[i*st->in_stride]);
+ st->in_stride = st->out_stride = 1;
+ speex_resampler_process_native(st, channel_index, x, &ichunk, y, &ochunk);
+ st->in_stride = istride_save;
+ st->out_stride = ostride_save;
+ for (i=0;i<ochunk;i++)
+ out[i*st->out_stride] = y[i];
+ out += ochunk;
+ in += ichunk;
+ ilen -= ichunk;
+ olen -= ochunk;
+ }
+ *in_len -= ilen;
+ *out_len -= olen;
+#endif
+ return RESAMPLER_ERR_SUCCESS;
}
-void speex_resampler_process_int(SpeexResamplerState *st, int channel_index, const spx_int16_t *in, int *in_len, spx_int16_t *out, int *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)
{
- speex_resampler_process_native(st, channel_index, in, in_len, out, out_len);
+ return speex_resampler_process_native(st, channel_index, in, in_len, out, out_len);
}
#else
-void speex_resampler_process_float(SpeexResamplerState *st, int channel_index, const float *in, int *in_len, float *out, int *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)
{
- speex_resampler_process_native(st, channel_index, in, in_len, out, out_len);
+ return speex_resampler_process_native(st, channel_index, in, in_len, out, out_len);
}
-void speex_resampler_process_int(SpeexResamplerState *st, int channel_index, const spx_int16_t *in, int *in_len, spx_int16_t *out, int *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)
{
- int i;
+ spx_uint32_t i;
int istride_save, ostride_save;
+#ifdef VAR_ARRAYS
spx_word16_t x[*in_len];
spx_word16_t y[*out_len];
+ /*VARDECL(spx_word16_t *x);
+ VARDECL(spx_word16_t *y);
+ ALLOC(x, *in_len, spx_word16_t);
+ ALLOC(y, *out_len, spx_word16_t);*/
istride_save = st->in_stride;
ostride_save = st->out_stride;
for (i=0;i<*in_len;i++)
@@ -805,55 +912,94 @@ void speex_resampler_process_int(SpeexResamplerState *st, int channel_index, con
st->out_stride = ostride_save;
for (i=0;i<*out_len;i++)
out[i*st->out_stride] = WORD2INT(y[i]);
+#else
+ spx_word16_t x[FIXED_STACK_ALLOC];
+ spx_word16_t y[FIXED_STACK_ALLOC];
+ spx_uint32_t ilen=*in_len, olen=*out_len;
+ istride_save = st->in_stride;
+ ostride_save = st->out_stride;
+ while (ilen && olen)
+ {
+ spx_uint32_t ichunk, ochunk;
+ ichunk = ilen;
+ ochunk = olen;
+ if (ichunk>FIXED_STACK_ALLOC)
+ ichunk=FIXED_STACK_ALLOC;
+ if (ochunk>FIXED_STACK_ALLOC)
+ ochunk=FIXED_STACK_ALLOC;
+ for (i=0;i<ichunk;i++)
+ x[i] = in[i*st->in_stride];
+ st->in_stride = st->out_stride = 1;
+ speex_resampler_process_native(st, channel_index, x, &ichunk, y, &ochunk);
+ st->in_stride = istride_save;
+ st->out_stride = ostride_save;
+ for (i=0;i<ochunk;i++)
+ out[i*st->out_stride] = WORD2INT(y[i]);
+ out += ochunk;
+ in += ichunk;
+ ilen -= ichunk;
+ olen -= ochunk;
+ }
+ *in_len -= ilen;
+ *out_len -= olen;
+#endif
+ return RESAMPLER_ERR_SUCCESS;
}
#endif
-void speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, int *in_len, float *out, int *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)
{
- int i;
+ spx_uint32_t i;
int istride_save, ostride_save;
+ spx_uint32_t bak_len = *out_len;
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_len;
speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len);
}
st->in_stride = istride_save;
st->out_stride = ostride_save;
+ return RESAMPLER_ERR_SUCCESS;
}
-void speex_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, int *in_len, spx_int16_t *out, int *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)
{
- int i;
+ spx_uint32_t i;
int istride_save, ostride_save;
+ spx_uint32_t bak_len = *out_len;
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_len;
speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len);
}
st->in_stride = istride_save;
st->out_stride = ostride_save;
+ return RESAMPLER_ERR_SUCCESS;
}
-void speex_resampler_set_rate(SpeexResamplerState *st, int in_rate, int out_rate)
+int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate)
{
- speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);
+ return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);
}
-void speex_resampler_get_rate(SpeexResamplerState *st, int *in_rate, int *out_rate)
+void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate)
{
*in_rate = st->in_rate;
*out_rate = st->out_rate;
}
-void speex_resampler_set_rate_frac(SpeexResamplerState *st, int ratio_num, int ratio_den, int in_rate, int 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)
{
int fact;
if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)
- return;
+ return RESAMPLER_ERR_SUCCESS;
st->in_rate = in_rate;
st->out_rate = out_rate;
@@ -871,25 +1017,25 @@ void speex_resampler_set_rate_frac(SpeexResamplerState *st, int ratio_num, int r
if (st->initialised)
update_filter(st);
+ return RESAMPLER_ERR_SUCCESS;
}
-void speex_resampler_get_ratio(SpeexResamplerState *st, int *ratio_num, int *ratio_den)
+void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den)
{
*ratio_num = st->num_rate;
*ratio_den = st->den_rate;
}
-void speex_resampler_set_quality(SpeexResamplerState *st, int quality)
+int speex_resampler_set_quality(SpeexResamplerState *st, int quality)
{
- if (quality < 0)
- quality = 0;
- if (quality > 10)
- quality = 10;
+ if (quality > 10 || quality < 0)
+ return RESAMPLER_ERR_INVALID_ARG;
if (st->quality == quality)
- return;
+ return RESAMPLER_ERR_SUCCESS;
st->quality = quality;
if (st->initialised)
update_filter(st);
+ return RESAMPLER_ERR_SUCCESS;
}
void speex_resampler_get_quality(SpeexResamplerState *st, int *quality)
@@ -897,37 +1043,57 @@ void speex_resampler_get_quality(SpeexResamplerState *st, int *quality)
*quality = st->quality;
}
-void speex_resampler_set_input_stride(SpeexResamplerState *st, int stride)
+void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride)
{
st->in_stride = stride;
}
-void speex_resampler_get_input_stride(SpeexResamplerState *st, int *stride)
+void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride)
{
*stride = st->in_stride;
}
-void speex_resampler_set_output_stride(SpeexResamplerState *st, int stride)
+void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride)
{
st->out_stride = stride;
}
-void speex_resampler_get_output_stride(SpeexResamplerState *st, int *stride)
+void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride)
{
*stride = st->out_stride;
}
-void speex_resampler_skip_zeros(SpeexResamplerState *st)
+int speex_resampler_skip_zeros(SpeexResamplerState *st)
{
- int i;
+ spx_uint32_t i;
for (i=0;i<st->nb_channels;i++)
st->last_sample[i] = st->filt_len/2;
+ return RESAMPLER_ERR_SUCCESS;
}
-void speex_resampler_reset_mem(SpeexResamplerState *st)
+int speex_resampler_reset_mem(SpeexResamplerState *st)
{
- int i;
+ spx_uint32_t i;
for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
st->mem[i] = 0;
+ return RESAMPLER_ERR_SUCCESS;
}
+const char *speex_resampler_strerror(int err)
+{
+ 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.";
+ }
+}
diff --git a/apps/codecs/libspeex/rockbox.c b/apps/codecs/libspeex/rockbox.c
index ace2dfb63f..89af3cba5d 100644
--- a/apps/codecs/libspeex/rockbox.c
+++ b/apps/codecs/libspeex/rockbox.c
@@ -81,6 +81,11 @@ void speex_warning_int(const char *str, int val)
DEBUGF("warning: %s %d\n", str, val);
}
+void speex_notify(const char *str)
+{
+ DEBUGF("notice: %s\n", str);
+}
+
void _speex_putc(int ch, void *file)
{
//FILE *f = (FILE *)file;
diff --git a/apps/codecs/libspeex/sb_celp.c b/apps/codecs/libspeex/sb_celp.c
index 0b4b619e52..faabe24766 100644
--- a/apps/codecs/libspeex/sb_celp.c
+++ b/apps/codecs/libspeex/sb_celp.c
@@ -192,16 +192,18 @@ void *sb_encoder_init(const SpeexMode *m)
st = (SBEncState*)speex_alloc(sizeof(SBEncState));
if (!st)
return NULL;
-#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
- st->stack = NULL;
-#else
- st->stack = (char*)speex_alloc_scratch(SB_ENC_STACK);
-#endif
st->mode = m;
mode = (const SpeexSBMode*)m->mode;
st->st_low = speex_encoder_init(mode->nb_mode);
+#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
+ st->stack = NULL;
+#else
+ /*st->stack = (char*)speex_alloc_scratch(SB_ENC_STACK);*/
+ speex_encoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);
+#endif
+
st->full_frame_size = 2*mode->frameSize;
st->frame_size = mode->frameSize;
st->subframeSize = mode->subframeSize;
@@ -275,7 +277,7 @@ void sb_encoder_destroy(void *state)
speex_encoder_destroy(st->st_low);
#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
- speex_free_scratch(st->stack);
+ /*speex_free_scratch(st->stack);*/
#endif
speex_free(st->high);
@@ -629,7 +631,11 @@ int sb_encode(void *state, void *vin, SpeexBits *bits)
quant=31;
speex_bits_pack(bits, quant, 5);
}
-
+ if (st->innov_rms_save)
+ {
+ st->innov_rms_save[sub] = eh;
+ }
+ st->exc_rms[sub] = eh;
} else {
spx_word16_t gc; /*Q7*/
spx_word32_t scale; /*Q14*/
@@ -716,11 +722,11 @@ int sb_encode(void *state, void *vin, SpeexBits *bits)
{
st->innov_rms_save[sub] = MULT16_16_Q15(QCONST16(.70711f, 15), compute_rms(innov, st->subframeSize));
}
+ st->exc_rms[sub] = compute_rms16(exc, st->subframeSize);
}
- st->exc_rms[sub] = compute_rms16(exc, st->subframeSize);
/*Keep the previous memory*/
for (i=0;i<st->lpcSize;i++)
@@ -754,20 +760,18 @@ void *sb_decoder_init(const SpeexMode *m)
st = (SBDecState*)speex_alloc(sizeof(SBDecState));
if (!st)
return NULL;
-#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
- st->stack = NULL;
-#else
- st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK);
-#endif
st->mode = m;
mode=(const SpeexSBMode*)m->mode;
-
st->encode_submode = 1;
-
-
-
st->st_low = speex_decoder_init(mode->nb_mode);
+#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
+ st->stack = NULL;
+#else
+ /*st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK);*/
+ speex_decoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);
+#endif
+
st->full_frame_size = 2*mode->frameSize;
st->frame_size = mode->frameSize;
st->subframeSize = mode->subframeSize;
@@ -813,7 +817,7 @@ void sb_decoder_destroy(void *state)
st = (SBDecState*)state;
speex_decoder_destroy(st->st_low);
#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
- speex_free_scratch(st->stack);
+ /*speex_free_scratch(st->stack);*/
#endif
speex_free(st->g0_mem);
@@ -882,6 +886,8 @@ int sb_decode(void *state, SpeexBits *bits, void *vout)
const SpeexSBMode *mode;
spx_word16_t *out = (spx_word16_t*)vout;
spx_word16_t *low_innov_alias;
+ spx_word32_t exc_ener_sum = 0;
+
st = (SBDecState*)state;
stack=st->stack;
mode = (const SpeexSBMode*)(st->mode->mode);
@@ -925,7 +931,7 @@ int sb_decode(void *state, SpeexBits *bits, void *vout)
}
if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL)
{
- speex_warning("Invalid mode encountered: corrupted stream?");
+ speex_notify("Invalid mode encountered. The stream is corrupted.");
return -2;
}
}
@@ -1006,8 +1012,8 @@ int sb_decode(void *state, SpeexBits *bits, void *vout)
rh = LPC_SCALING;
for (i=0;i<st->lpcSize;i+=2)
{
- rh += st->interp_qlpc[i+1] - st->interp_qlpc[i];
- st->pi_gain[sub] += st->interp_qlpc[i] + st->interp_qlpc[i+1];
+ rh += ak[i+1] - ak[i];
+ st->pi_gain[sub] += ak[i] + ak[i+1];
}
rl = low_pi_gain[sub];
@@ -1083,9 +1089,9 @@ int sb_decode(void *state, SpeexBits *bits, void *vout)
for (i=0;i<st->lpcSize;i++)
st->interp_qlpc[i] = ak[i];
st->exc_rms[sub] = compute_rms16(st->excBuf, st->subframeSize);
-
+ exc_ener_sum = ADD32(exc_ener_sum, DIV32(MULT16_16(st->exc_rms[sub],st->exc_rms[sub]), st->nbSubframes));
}
- st->last_ener = compute_rms16(out+st->frame_size, st->frame_size);
+ st->last_ener = spx_sqrt(exc_ener_sum);
qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
for (i=0;i<st->lpcSize;i++)
@@ -1335,7 +1341,9 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_SET_WIDEBAND:
speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);
break;
-
+ case SPEEX_GET_STACK:
+ *((char**)ptr) = st->stack;
+ break;
default:
speex_warning_int("Unknown nb_ctl request: ", request);
return -1;
@@ -1433,7 +1441,9 @@ int sb_decoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_HIGHPASS:
speex_decoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);
break;
-
+ case SPEEX_GET_ACTIVITY:
+ speex_decoder_ctl(st->st_low, SPEEX_GET_ACTIVITY, ptr);
+ break;
case SPEEX_GET_PI_GAIN:
{
int i;
@@ -1458,7 +1468,9 @@ int sb_decoder_ctl(void *state, int request, void *ptr)
case SPEEX_SET_WIDEBAND:
speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);
break;
-
+ case SPEEX_GET_STACK:
+ *((char**)ptr) = st->stack;
+ break;
default:
speex_warning_int("Unknown nb_ctl request: ", request);
return -1;
diff --git a/apps/codecs/libspeex/speex/speex.h b/apps/codecs/libspeex/speex/speex.h
index 0ae1abad34..0ff4be135f 100644
--- a/apps/codecs/libspeex/speex/speex.h
+++ b/apps/codecs/libspeex/speex/speex.h
@@ -155,6 +155,10 @@ extern "C" {
/** Get status of input/output high-pass filtering */
#define SPEEX_GET_HIGHPASS 45
+/** Get "activity level" of the last decoded frame, i.e.
+ now much damage we cause if we remove the frame */
+#define SPEEX_GET_ACTIVITY 47
+
/* Preserving compatibility:*/
/** Equivalent to SPEEX_SET_ENH */
@@ -297,7 +301,7 @@ typedef struct SpeexMode {
* encode, you need one state per channel.
*
* @param mode The mode to use (either speex_nb_mode or speex_wb.mode)
- * @return A newly created encoder
+ * @return A newly created encoder state or NULL if state allocation fails
*/
void *speex_encoder_init(const SpeexMode *mode);
@@ -330,7 +334,7 @@ int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits);
* @param state Encoder state
* @param request ioctl-type request (one of the SPEEX_* macros)
* @param ptr Data exchanged to-from function
- * @return 0 if no error, -1 if request in unknown
+ * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
*/
int speex_encoder_ctl(void *state, int request, void *ptr);
@@ -341,7 +345,7 @@ int speex_encoder_ctl(void *state, int request, void *ptr);
* decode, you need one state per channel.
*
* @param mode Speex mode (one of speex_nb_mode or speex_wb_mode)
- * @return A newly created decoder state
+ * @return A newly created decoder state or NULL if state allocation fails
*/
void *speex_decoder_init(const SpeexMode *mode);
@@ -376,7 +380,7 @@ int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out);
* @param state Decoder state
* @param request ioctl-type request (one of the SPEEX_* macros)
* @param ptr Data exchanged to-from function
- * @return 0 if no error, -1 if request in unknown
+ * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
*/
int speex_decoder_ctl(void *state, int request, void *ptr);
@@ -386,12 +390,14 @@ int speex_decoder_ctl(void *state, int request, void *ptr);
* @param mode Speex mode
* @param request ioctl-type request (one of the SPEEX_* macros)
* @param ptr Data exchanged to-from function
+ * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
*/
int speex_mode_query(const SpeexMode *mode, int request, void *ptr);
/** Functions for controlling the behavior of libspeex
* @param request ioctl-type request (one of the SPEEX_LIB_* macros)
* @param ptr Data exchanged to-from function
+ * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
*/
int speex_lib_ctl(int request, void *ptr);
diff --git a/apps/codecs/libspeex/speex/speex_bits.h b/apps/codecs/libspeex/speex/speex_bits.h
index 88334c4214..a26fb4ce0c 100644
--- a/apps/codecs/libspeex/speex/speex_bits.h
+++ b/apps/codecs/libspeex/speex/speex_bits.h
@@ -64,6 +64,9 @@ void speex_bits_init(SpeexBits *bits);
/** Initializes SpeexBits struct using a pre-allocated buffer*/
void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size);
+/** Sets the bits in a SpeexBits struct to use data from an existing buffer (for decoding without copying data) */
+void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size);
+
/** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/
void speex_bits_destroy(SpeexBits *bits);
diff --git a/apps/codecs/libspeex/speex/speex_jitter.h b/apps/codecs/libspeex/speex/speex_jitter.h
index a5314d6e0a..570e22b1e2 100644
--- a/apps/codecs/libspeex/speex/speex_jitter.h
+++ b/apps/codecs/libspeex/speex/speex_jitter.h
@@ -121,7 +121,7 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet);
* @param packet Returned packet
* @param current_timestamp Timestamp for the returned packet
*/
-int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint32_t *current_timestamp);
+int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset);
/** Get pointer timestamp of jitter buffer
*
@@ -144,7 +144,7 @@ void jitter_buffer_tick(JitterBuffer *jitter);
*/
int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr);
-int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint32_t *start_offset);
+int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset);
/* @} */
diff --git a/apps/codecs/libspeex/speex/speex_resampler.h b/apps/codecs/libspeex/speex/speex_resampler.h
index 93642ced2f..c44fbcd0d1 100644
--- a/apps/codecs/libspeex/speex/speex_resampler.h
+++ b/apps/codecs/libspeex/speex/speex_resampler.h
@@ -69,29 +69,20 @@
#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality)
#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride)
#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride)
-#define speex_resample_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resample_set_output_stride)
-#define speex_resample_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resample_get_output_stride)
+#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride)
+#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride)
#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros)
#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
+#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
#define spx_int16_t short
-
-#ifdef FIXED_POINT
-#define spx_word16_t short
-#define spx_word32_t int
-
-#else /* FIXED_POINT */
-
-#define spx_word16_t float
-#define spx_word32_t float
-#define MULT16_16(a,b) ((a)*(b))
-#define MULT16_32_Q15(a,b) ((a)*(b))
-#define PSHR32(a,b) (a)
-#endif /* FIXED_POINT */
-
+#define spx_int32_t int
+#define spx_uint16_t unsigned short
+#define spx_uint32_t unsigned int
+
#else /* OUTSIDE_SPEEX */
-#include "speex_types.h"
+#include "speex/speex_types.h"
#endif /* OUTSIDE_SPEEX */
@@ -104,7 +95,17 @@ extern "C" {
#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
#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,
+ RESAMPLER_ERR_MAX_ERROR
+};
+
struct SpeexResamplerState_;
typedef struct SpeexResamplerState_ SpeexResamplerState;
@@ -117,10 +118,11 @@ typedef struct SpeexResamplerState_ SpeexResamplerState;
* @return Newly created resampler state
* @retval NULL Error: not enough memory
*/
-SpeexResamplerState *speex_resampler_init(int nb_channels,
- int in_rate,
- int out_rate,
- int quality);
+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
@@ -135,12 +137,13 @@ SpeexResamplerState *speex_resampler_init(int nb_channels,
* @return Newly created resampler state
* @retval NULL Error: not enough memory
*/
-SpeexResamplerState *speex_resampler_init_frac(int nb_channels,
- int ratio_num,
- int ratio_den,
- int in_rate,
- int out_rate,
- int quality);
+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
@@ -157,12 +160,12 @@ void speex_resampler_destroy(SpeexResamplerState *st);
* @param out Output buffer
* @param out_len Size of the output buffer. Returns the number of samples written
*/
-void speex_resampler_process_float(SpeexResamplerState *st,
- int channel_index,
+int speex_resampler_process_float(SpeexResamplerState *st,
+ spx_uint32_t channel_index,
const float *in,
- int *in_len,
+ spx_uint32_t *in_len,
float *out,
- int *out_len);
+ spx_uint32_t *out_len);
/** Resample an int array. The input and output buffers must *not* overlap.
* @param st Resampler state
@@ -174,12 +177,12 @@ void speex_resampler_process_float(SpeexResamplerState *st,
* @param out Output buffer
* @param out_len Size of the output buffer. Returns the number of samples written
*/
-void speex_resampler_process_int(SpeexResamplerState *st,
- int channel_index,
+int speex_resampler_process_int(SpeexResamplerState *st,
+ spx_uint32_t channel_index,
const spx_int16_t *in,
- int *in_len,
+ spx_uint32_t *in_len,
spx_int16_t *out,
- int *out_len);
+ spx_uint32_t *out_len);
/** Resample an interleaved float array. The input and output buffers must *not* overlap.
* @param st Resampler state
@@ -190,11 +193,11 @@ void speex_resampler_process_int(SpeexResamplerState *st,
* @param out_len Size of the output buffer. Returns the number of samples written.
* This is all per-channel.
*/
-void speex_resampler_process_interleaved_float(SpeexResamplerState *st,
+int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
const float *in,
- int *in_len,
+ spx_uint32_t *in_len,
float *out,
- int *out_len);
+ spx_uint32_t *out_len);
/** Resample an interleaved int array. The input and output buffers must *not* overlap.
* @param st Resampler state
@@ -205,20 +208,20 @@ void speex_resampler_process_interleaved_float(SpeexResamplerState *st,
* @param out_len Size of the output buffer. Returns the number of samples written.
* This is all per-channel.
*/
-void speex_resampler_process_interleaved_int(SpeexResamplerState *st,
+int speex_resampler_process_interleaved_int(SpeexResamplerState *st,
const spx_int16_t *in,
- int *in_len,
+ spx_uint32_t *in_len,
spx_int16_t *out,
- int *out_len);
+ 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).
*/
-void speex_resampler_set_rate(SpeexResamplerState *st,
- int in_rate,
- int 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
@@ -226,8 +229,8 @@ void speex_resampler_set_rate(SpeexResamplerState *st,
* @param out_rate Output sampling rate (integer number of Hz) copied.
*/
void speex_resampler_get_rate(SpeexResamplerState *st,
- int *in_rate,
- int *out_rate);
+ 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).
@@ -237,11 +240,11 @@ void speex_resampler_get_rate(SpeexResamplerState *st,
* @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).
*/
-void speex_resampler_set_rate_frac(SpeexResamplerState *st,
- int ratio_num,
- int ratio_den,
- int in_rate,
- int 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.
@@ -250,15 +253,15 @@ void speex_resampler_set_rate_frac(SpeexResamplerState *st,
* @param ratio_den Denominator of the sampling rate ratio copied
*/
void speex_resampler_get_ratio(SpeexResamplerState *st,
- int *ratio_num,
- int *ratio_den);
+ 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.
*/
-void speex_resampler_set_quality(SpeexResamplerState *st,
+int speex_resampler_set_quality(SpeexResamplerState *st,
int quality);
/** Get the conversion quality.
@@ -274,28 +277,28 @@ void speex_resampler_get_quality(SpeexResamplerState *st,
* @param stride Input stride
*/
void speex_resampler_set_input_stride(SpeexResamplerState *st,
- int stride);
+ 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,
- int *stride);
+ spx_uint32_t *stride);
/** Set (change) the output stride.
* @param st Resampler state
* @param stride Output stride
*/
-void speex_resample_set_output_stride(SpeexResamplerState *st,
- int 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_resample_get_output_stride(SpeexResamplerState *st,
- int *stride);
+void speex_resampler_get_output_stride(SpeexResamplerState *st,
+ spx_uint32_t *stride);
/** 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
@@ -305,12 +308,18 @@ void speex_resample_get_output_stride(SpeexResamplerState *st,
* is the same for the first frame).
* @param st Resampler state
*/
-void 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
*/
-void 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);
#ifdef __cplusplus
}
diff --git a/apps/codecs/libspeex/speex_header.c b/apps/codecs/libspeex/speex_header.c
index 13b114a3bc..5719eb1298 100644
--- a/apps/codecs/libspeex/speex_header.c
+++ b/apps/codecs/libspeex/speex_header.c
@@ -133,14 +133,14 @@ SpeexHeader *speex_packet_to_header(char *packet, int size)
for (i=0;i<8;i++)
if (packet[i]!=h[i])
{
- speex_warning ("This doesn't look like a Speex file");
+ speex_notify("This doesn't look like a Speex file");
return NULL;
}
/*FIXME: Do we allow larger headers?*/
if (size < (int)sizeof(SpeexHeader))
{
- speex_warning("Speex header too small");
+ speex_notify("Speex header too small");
return NULL;
}
diff --git a/apps/codecs/libspeex/testdenoise.c b/apps/codecs/libspeex/testdenoise.c
index 1b681866de..42644cb011 100644
--- a/apps/codecs/libspeex/testdenoise.c
+++ b/apps/codecs/libspeex/testdenoise.c
@@ -1,5 +1,5 @@
#ifdef HAVE_CONFIG_H
-#include "config-speex.h"
+#include "config.h"
#endif
#include <speex/speex_preprocess.h>
diff --git a/apps/codecs/libspeex/testecho.c b/apps/codecs/libspeex/testecho.c
index d59dbf94cf..7c32c8f60e 100644
--- a/apps/codecs/libspeex/testecho.c
+++ b/apps/codecs/libspeex/testecho.c
@@ -1,5 +1,5 @@
#ifdef HAVE_CONFIG_H
-#include "config-speex.h"
+#include "config.h"
#endif
#include <stdio.h>
diff --git a/apps/codecs/libspeex/testenc.c b/apps/codecs/libspeex/testenc.c
index 17141fa09e..eabd02cc76 100644
--- a/apps/codecs/libspeex/testenc.c
+++ b/apps/codecs/libspeex/testenc.c
@@ -1,5 +1,5 @@
#ifdef HAVE_CONFIG_H
-#include "config-speex.h"
+#include "config.h"
#endif
#include <speex/speex.h>
diff --git a/apps/codecs/libspeex/testenc_uwb.c b/apps/codecs/libspeex/testenc_uwb.c
index f6b943d46f..e9bf18a667 100644
--- a/apps/codecs/libspeex/testenc_uwb.c
+++ b/apps/codecs/libspeex/testenc_uwb.c
@@ -1,5 +1,5 @@
#ifdef HAVE_CONFIG_H
-#include "config-speex.h"
+#include "config.h"
#endif
#include <speex/speex.h>
diff --git a/apps/codecs/libspeex/testenc_wb.c b/apps/codecs/libspeex/testenc_wb.c
index f55dffaaba..8e515cb13c 100644
--- a/apps/codecs/libspeex/testenc_wb.c
+++ b/apps/codecs/libspeex/testenc_wb.c
@@ -1,5 +1,5 @@
#ifdef HAVE_CONFIG_H
-#include "config-speex.h"
+#include "config.h"
#endif
#include <speex/speex.h>
diff --git a/apps/codecs/libspeex/testresample.c b/apps/codecs/libspeex/testresample.c
index bb7ab74db0..71392cc011 100644
--- a/apps/codecs/libspeex/testresample.c
+++ b/apps/codecs/libspeex/testresample.c
@@ -31,7 +31,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config-speex.h"
+#include "config.h"
#endif
#include <stdio.h>
@@ -41,15 +41,15 @@
#define NN 256
-int main(int argc, char **argv)
+int main()
{
- int i;
+ spx_uint32_t i;
short *in;
short *out;
float *fin, *fout;
int count = 0;
- SpeexResamplerState *st = speex_resampler_init(1, 8000, 12000, 10);
- speex_resampler_set_rate(st, 8000, 15999);
+ SpeexResamplerState *st = speex_resampler_init(1, 8000, 12000, 10, NULL);
+ speex_resampler_set_rate(st, 96000, 44100);
speex_resampler_skip_zeros(st);
in = malloc(NN*sizeof(short));
@@ -58,8 +58,8 @@ int main(int argc, char **argv)
fout = malloc(2*NN*sizeof(float));
while (1)
{
- int in_len;
- int out_len;
+ spx_uint32_t in_len;
+ spx_uint32_t out_len;
fread(in, sizeof(short), NN, stdin);
if (feof(stdin))
break;
diff --git a/apps/codecs/libspeex/vbr.c b/apps/codecs/libspeex/vbr.c
index 405b7bd887..cc538b3fe9 100644
--- a/apps/codecs/libspeex/vbr.c
+++ b/apps/codecs/libspeex/vbr.c
@@ -48,14 +48,14 @@
const float vbr_nb_thresh[9][11]={
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* CNG */
- { 3.5f, 2.5f, 2.0f, 1.2f, 0.5f, 0.0f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /* 2 kbps */
+ { 4.0f, 2.5f, 2.0f, 1.2f, 0.5f, 0.0f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /* 2 kbps */
{10.0f, 6.5f, 5.2f, 4.5f, 3.9f, 3.5f, 3.0f, 2.5f, 2.3f, 1.8f, 1.0f}, /* 6 kbps */
{11.0f, 8.8f, 7.5f, 6.5f, 5.0f, 3.9f, 3.9f, 3.9f, 3.5f, 3.0f, 1.0f}, /* 8 kbps */
- {11.0f, 11.0f, 9.9f, 9.0f, 8.0f, 7.0f, 6.5f, 6.0f, 5.0f, 4.0f, 2.0f}, /* 11 kbps */
- {11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 9.0f, 8.0f, 7.0f, 6.5f, 5.0f, 3.0f}, /* 15 kbps */
- {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 8.0f, 6.5f, 4.0f}, /* 18 kbps */
- {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 7.5f, 5.5f}, /* 24 kbps */
- { 8.0f, 5.0f, 3.7f, 3.0f, 2.5f, 2.0f, 1.8f, 1.5f, 1.0f, 0.0f, 0.0f} /* 4 kbps */
+ {11.0f, 11.0f, 9.9f, 8.5f, 7.0f, 6.0f, 4.5f, 4.0f, 4.0f, 4.0f, 2.0f}, /* 11 kbps */
+ {11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 8.0f, 7.0f, 6.0f, 5.0f, 3.0f}, /* 15 kbps */
+ {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 7.0f, 6.0f, 5.0f}, /* 18 kbps */
+ {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 9.5f, 7.5f}, /* 24 kbps */
+ { 7.0f, 4.5f, 3.7f, 3.0f, 2.5f, 2.0f, 1.8f, 1.5f, 1.0f, 0.0f, 0.0f} /* 4 kbps */
};