Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/speexdsp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>2007-11-26 06:47:00 +0300
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>2008-05-19 09:24:16 +0400
commit622aadef4c06d7a49ca8ef8f5a0f3fad2690daf5 (patch)
tree3bd5b75baf91876991903e6300eb406ff7c0c303 /libspeex
parent3d7a6f0bd0a60145d8ac3a2f4037da623f407fba (diff)
parent37657c2b0b228b26ebecf31e36c69327489e66f1 (diff)
More changes merged from single channel case, renamed back to speex_*
Merge commit '37657c2b0b228b26ebecf31e36c69327489e66f1' into stereo Conflicts: include/speex/speex_echo.h libspeex/mdf.c libspeex/testecho.c
Diffstat (limited to 'libspeex')
-rw-r--r--libspeex/Makefile.am41
-rw-r--r--libspeex/_kiss_fft_guts.h2
-rw-r--r--libspeex/arch.h50
-rw-r--r--libspeex/bits.c17
-rw-r--r--libspeex/buffer.c176
-rw-r--r--libspeex/cb_search.c11
-rw-r--r--libspeex/cb_search.h2
-rw-r--r--libspeex/fftwrap.c3
-rw-r--r--libspeex/fftwrap.h2
-rw-r--r--libspeex/filterbank.c5
-rw-r--r--libspeex/filterbank.h2
-rw-r--r--libspeex/filters.c4
-rw-r--r--libspeex/filters.h4
-rw-r--r--libspeex/filters_arm4.h3
-rw-r--r--libspeex/jitter.c862
-rw-r--r--libspeex/kiss_fft.c9
-rw-r--r--libspeex/kiss_fft.h4
-rw-r--r--libspeex/kiss_fftr.c9
-rw-r--r--libspeex/lbr_48k_tables.c678
-rw-r--r--libspeex/lpc.h2
-rw-r--r--libspeex/lsp.h2
-rw-r--r--libspeex/ltp.h2
-rw-r--r--libspeex/math_approx.c291
-rw-r--r--libspeex/math_approx.h298
-rw-r--r--libspeex/mdf.c47
-rw-r--r--libspeex/medfilter.c6
-rw-r--r--libspeex/misc.c170
-rw-r--r--libspeex/misc.h130
-rw-r--r--libspeex/modes.c308
-rw-r--r--libspeex/modes.h13
-rw-r--r--libspeex/modes_wb.c300
-rw-r--r--libspeex/nb_celp.c343
-rw-r--r--libspeex/nb_celp.h24
-rw-r--r--libspeex/os_support.h162
-rw-r--r--libspeex/preprocess.c38
-rw-r--r--libspeex/pseudofloat.h3
-rw-r--r--libspeex/quant_lsp.c70
-rw-r--r--libspeex/quant_lsp.h11
-rw-r--r--libspeex/resample.c125
-rw-r--r--libspeex/sb_celp.c65
-rw-r--r--libspeex/sb_celp.h10
-rw-r--r--libspeex/smallft.c3
-rw-r--r--libspeex/speex.c28
-rw-r--r--libspeex/speex_callbacks.c8
-rw-r--r--libspeex/speex_header.c19
-rw-r--r--libspeex/stack_alloc.h14
-rw-r--r--libspeex/stereo.c240
-rw-r--r--libspeex/testecho.c36
-rw-r--r--libspeex/testenc.c30
-rw-r--r--libspeex/testenc_uwb.c10
-rw-r--r--libspeex/testenc_wb.c13
-rw-r--r--libspeex/vbr.c15
-rw-r--r--libspeex/vbr.h2
-rw-r--r--libspeex/vorbis_psy.c2
-rw-r--r--libspeex/vorbis_psy.h2
-rw-r--r--libspeex/vq.c25
-rw-r--r--libspeex/vq.h3
-rw-r--r--libspeex/window.c10
58 files changed, 2160 insertions, 2604 deletions
diff --git a/libspeex/Makefile.am b/libspeex/Makefile.am
index ff6d4bc..8dec1b5 100644
--- a/libspeex/Makefile.am
+++ b/libspeex/Makefile.am
@@ -6,28 +6,31 @@ EXTRA_DIST=echo_diagnostic.m
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) @OGG_CFLAGS@
-lib_LTLIBRARIES = libspeex.la
+lib_LTLIBRARIES = libspeex.la libspeexdsp.la
# Sources for compilation in the library
-libspeex_la_SOURCES = nb_celp.c sb_celp.c lpc.c ltp.c lsp.c quant_lsp.c \
- lsp_tables_nb.c gain_table.c gain_table_lbr.c cb_search.c filters.c bits.c \
- modes.c speex.c vq.c high_lsp_tables.c vbr.c hexc_table.c \
- exc_5_256_table.c exc_5_64_table.c exc_8_128_table.c exc_10_32_table.c \
- exc_10_16_table.c exc_20_32_table.c hexc_10_32_table.c misc.c speex_header.c \
- speex_callbacks.c math_approx.c stereo.c preprocess.c smallft.c lbr_48k_tables.c \
- jitter.c mdf.c vorbis_psy.c fftwrap.c kiss_fft.c _kiss_fft_guts.h kiss_fft.h \
- kiss_fftr.c kiss_fftr.h window.c filterbank.c resample.c
-
-noinst_HEADERS = lsp.h nb_celp.h lpc.h lpc_bfin.h ltp.h quant_lsp.h \
- cb_search.h filters.h stack_alloc.h vq.h vq_sse.h vq_arm4.h vq_bfin.h \
- modes.h sb_celp.h vbr.h misc.h misc_bfin.h ltp_sse.h ltp_arm4.h \
- ltp_bfin.h filters_sse.h filters_arm4.h filters_bfin.h math_approx.h \
- smallft.h arch.h fixed_arm4.h fixed_arm5e.h fixed_bfin.h fixed_debug.h \
- fixed_generic.h cb_search_sse.h cb_search_arm4.h cb_search_bfin.h vorbis_psy.h \
- fftwrap.h pseudofloat.h lsp_bfin.h quant_lsp_bfin.h filterbank.h
+libspeex_la_SOURCES = cb_search.c exc_10_32_table.c exc_8_128_table.c \
+ filters.c gain_table.c hexc_table.c high_lsp_tables.c lsp.c \
+ ltp.c speex.c stereo.c vbr.c vq.c bits.c exc_10_16_table.c \
+ exc_20_32_table.c exc_5_256_table.c exc_5_64_table.c gain_table_lbr.c hexc_10_32_table.c \
+ lpc.c lsp_tables_nb.c modes.c modes_wb.c nb_celp.c quant_lsp.c sb_celp.c \
+ speex_callbacks.c speex_header.c window.c
+
+libspeexdsp_la_SOURCES = preprocess.c smallft.c \
+ jitter.c mdf.c fftwrap.c kiss_fft.c _kiss_fft_guts.h kiss_fft.h \
+ kiss_fftr.c kiss_fftr.h filterbank.c resample.c buffer.c
+
+noinst_HEADERS = arch.h cb_search_arm4.h cb_search_bfin.h cb_search_sse.h \
+ filters.h filters_arm4.h filters_bfin.h filters_sse.h fixed_arm4.h \
+ fixed_arm5e.h fixed_bfin.h fixed_debug.h lpc.h lpc_bfin.h ltp.h ltp_arm4.h \
+ ltp_sse.h math_approx.h misc_bfin.h nb_celp.h quant_lsp.h sb_celp.h \
+ stack_alloc.h vbr.h vq.h vq_arm4.h vq_bfin.h vq_sse.h cb_search.h fftwrap.h \
+ filterbank.h fixed_generic.h lsp.h lsp_bfin.h ltp_bfin.h modes.h os_support.h \
+ pseudofloat.h quant_lsp_bfin.h smallft.h vorbis_psy.h
libspeex_la_LDFLAGS = -no-undefined -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@
+libspeexdsp_la_LDFLAGS = -no-undefined -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@
noinst_PROGRAMS = testenc testenc_wb testenc_uwb testdenoise testecho
testenc_SOURCES = testenc.c
@@ -37,6 +40,6 @@ testenc_wb_LDADD = libspeex.la
testenc_uwb_SOURCES = testenc_uwb.c
testenc_uwb_LDADD = libspeex.la
testdenoise_SOURCES = testdenoise.c
-testdenoise_LDADD = libspeex.la
+testdenoise_LDADD = libspeexdsp.la
testecho_SOURCES = testecho.c
-testecho_LDADD = libspeex.la
+testecho_LDADD = libspeexdsp.la
diff --git a/libspeex/_kiss_fft_guts.h b/libspeex/_kiss_fft_guts.h
index 526a73b..6571e79 100644
--- a/libspeex/_kiss_fft_guts.h
+++ b/libspeex/_kiss_fft_guts.h
@@ -45,7 +45,7 @@ struct kiss_fft_state{
C_ADDTO( res , a) : res += a
* */
#ifdef FIXED_POINT
-#include "misc.h"
+#include "arch.h"
# define FRACBITS 15
# define SAMPPROD spx_int32_t
#define SAMP_MAX 32767
diff --git a/libspeex/arch.h b/libspeex/arch.h
index e2d731a..7679aea 100644
--- a/libspeex/arch.h
+++ b/libspeex/arch.h
@@ -35,6 +35,45 @@
#ifndef ARCH_H
#define ARCH_H
+#ifndef SPEEX_VERSION
+#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */
+#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */
+#define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */
+#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */
+#define SPEEX_VERSION "speex-1.2beta3" /**< Speex version string. */
+#endif
+
+/* A couple test to catch stupid option combinations */
+#ifdef FIXED_POINT
+
+#ifdef FLOATING_POINT
+#error You cannot compile as floating point and fixed point at the same time
+#endif
+#ifdef _USE_SSE
+#error SSE is only for floating-point
+#endif
+#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))
+#error Make up your mind. What CPU do you have?
+#endif
+#ifdef VORBIS_PSYCHO
+#error Vorbis-psy model currently not implemented in fixed-point
+#endif
+
+#else
+
+#ifndef FLOATING_POINT
+#error You now need to define either FIXED_POINT or FLOATING_POINT
+#endif
+#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
+#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?
+#endif
+#ifdef FIXED_POINT_DEBUG
+#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?"
+#endif
+
+
+#endif
+
#ifndef OUTSIDE_SPEEX
#include "speex/speex_types.h"
#endif
@@ -68,6 +107,7 @@ typedef spx_word32_t spx_sig_t;
#define LPC_SHIFT 13
#define LSP_SHIFT 13
#define SIG_SHIFT 14
+#define GAIN_SHIFT 6
#define VERY_SMALL 0
#define VERY_LARGE32 ((spx_word32_t)2147483647)
@@ -111,9 +151,6 @@ typedef float spx_word32_t;
#define GAIN_SCALING 1.f
#define GAIN_SCALING_1 1.f
-#define LPC_SHIFT 0
-#define LSP_SHIFT 0
-#define SIG_SHIFT 0
#define VERY_SMALL 1e-15f
#define VERY_LARGE32 1e15f
@@ -194,4 +231,11 @@ typedef float spx_word32_t;
#endif
+
+
+#ifdef FIXED_DEBUG
+long long spx_mips=0;
+#endif
+
+
#endif
diff --git a/libspeex/bits.c b/libspeex/bits.c
index 5c4cb0e..311e812 100644
--- a/libspeex/bits.c
+++ b/libspeex/bits.c
@@ -37,7 +37,8 @@
#endif
#include <speex/speex_bits.h>
-#include "misc.h"
+#include "arch.h"
+#include "os_support.h"
/* Maximum size of the bit-stream (for fixed-size allocation) */
#ifndef MAX_CHARS_PER_FRAME
@@ -67,6 +68,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)
diff --git a/libspeex/buffer.c b/libspeex/buffer.c
new file mode 100644
index 0000000..2f94430
--- /dev/null
+++ b/libspeex/buffer.c
@@ -0,0 +1,176 @@
+/* Copyright (C) 2007 Jean-Marc Valin
+
+ File: buffer.c
+ This is a very simple ring buffer implementation. It is not thread-safe
+ so you need to do your own locking.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "os_support.h"
+#include "arch.h"
+#include <speex/speex_buffer.h>
+
+struct SpeexBuffer_ {
+ char *data;
+ int size;
+ int read_ptr;
+ int write_ptr;
+ int available;
+};
+
+SpeexBuffer *speex_buffer_init(int size)
+{
+ SpeexBuffer *st = speex_alloc(sizeof(SpeexBuffer));
+ st->data = speex_alloc(size);
+ st->size = size;
+ st->read_ptr = 0;
+ st->write_ptr = 0;
+ st->available = 0;
+ return st;
+}
+
+void speex_buffer_destroy(SpeexBuffer *st)
+{
+ speex_free(st->data);
+ speex_free(st);
+}
+
+int speex_buffer_write(SpeexBuffer *st, void *_data, int len)
+{
+ int end;
+ int end1;
+ char *data = _data;
+ if (len > st->size)
+ {
+ data += len-st->size;
+ len = st->size;
+ }
+ end = st->write_ptr + len;
+ end1 = end;
+ if (end1 > st->size)
+ end1 = st->size;
+ speex_move(st->data + st->write_ptr, data, end1 - st->write_ptr);
+ if (end > st->size)
+ {
+ end -= st->size;
+ speex_move(st->data, data+end1 - st->write_ptr, end);
+ }
+ st->available += len;
+ if (st->available > st->size)
+ {
+ st->available = st->size;
+ st->read_ptr = st->write_ptr;
+ }
+ st->write_ptr += len;
+ if (st->write_ptr > st->size)
+ st->write_ptr -= st->size;
+ return len;
+}
+
+int speex_buffer_writezeros(SpeexBuffer *st, int len)
+{
+ /* This is almost the same as for speex_buffer_write() but using
+ speex_memset() instead of speex_move(). Update accordingly. */
+ int end;
+ int end1;
+ if (len > st->size)
+ {
+ len = st->size;
+ }
+ end = st->write_ptr + len;
+ end1 = end;
+ if (end1 > st->size)
+ end1 = st->size;
+ speex_memset(st->data + st->write_ptr, 0, end1 - st->write_ptr);
+ if (end > st->size)
+ {
+ end -= st->size;
+ speex_memset(st->data, 0, end);
+ }
+ st->available += len;
+ if (st->available > st->size)
+ {
+ st->available = st->size;
+ st->read_ptr = st->write_ptr;
+ }
+ st->write_ptr += len;
+ if (st->write_ptr > st->size)
+ st->write_ptr -= st->size;
+ return len;
+}
+
+int speex_buffer_read(SpeexBuffer *st, void *_data, int len)
+{
+ int end, end1;
+ char *data = _data;
+ if (len > st->available)
+ {
+ speex_memset(data+st->available, 0, st->size-st->available);
+ len = st->available;
+ }
+ end = st->read_ptr + len;
+ end1 = end;
+ if (end1 > st->size)
+ end1 = st->size;
+ speex_move(data, st->data + st->read_ptr, end1 - st->read_ptr);
+
+ if (end > st->size)
+ {
+ end -= st->size;
+ speex_move(data+end1 - st->read_ptr, st->data, end);
+ }
+ st->available -= len;
+ st->read_ptr += len;
+ if (st->read_ptr > st->size)
+ st->read_ptr -= st->size;
+ return len;
+}
+
+int speex_buffer_get_available(SpeexBuffer *st)
+{
+ return st->available;
+}
+
+int speex_buffer_resize(SpeexBuffer *st, int len)
+{
+ int old_len = st->size;
+ if (len > old_len)
+ {
+ st->data = speex_realloc(st->data, len);
+ /* FIXME: move data/pointers properly for growing the buffer */
+ } else {
+ /* FIXME: move data/pointers properly for shrinking the buffer */
+ st->data = speex_realloc(st->data, len);
+ }
+ return len;
+}
diff --git a/libspeex/cb_search.c b/libspeex/cb_search.c
index cab2b71..0d9f295 100644
--- a/libspeex/cb_search.c
+++ b/libspeex/cb_search.c
@@ -37,7 +37,9 @@
#include "filters.h"
#include "stack_alloc.h"
#include "vq.h"
-#include "misc.h"
+#include "arch.h"
+#include "math_approx.h"
+#include "os_support.h"
#ifdef _USE_SSE
#include "cb_search_sse.h"
@@ -359,7 +361,11 @@ int update_target
/*"erase" nbest list*/
for (j=0;j<N;j++)
ndist[j]=VERY_LARGE32;
-
+ /* This is not strictly necessary, but it provides an additonal safety
+ to prevent crashes in case something goes wrong in the previous
+ steps (e.g. NaNs) */
+ for (j=0;j<N;j++)
+ best_nind[j] = best_ntarget[j] = 0;
/*For all n-bests of previous subvector*/
for (j=0;j<N;j++)
{
@@ -397,6 +403,7 @@ int update_target
best_nind[n] = best_nind[n-1];
best_ntarget[n] = best_ntarget[n-1];
}
+ /* n is equal to m here, so they're interchangeable */
ndist[m] = err;
best_nind[n] = best_index[k];
best_ntarget[n] = j;
diff --git a/libspeex/cb_search.h b/libspeex/cb_search.h
index fd5c110..7687b45 100644
--- a/libspeex/cb_search.h
+++ b/libspeex/cb_search.h
@@ -36,7 +36,7 @@
#define CB_SEARCH_H
#include <speex/speex_bits.h>
-#include "misc.h"
+#include "arch.h"
/** Split codebook parameters. */
typedef struct split_cb_params {
diff --git a/libspeex/fftwrap.c b/libspeex/fftwrap.c
index 35e2d05..0b462c2 100644
--- a/libspeex/fftwrap.c
+++ b/libspeex/fftwrap.c
@@ -40,7 +40,8 @@
#define USE_KISS_FFT
-#include "misc.h"
+#include "arch.h"
+#include "os_support.h"
#define MAX_FFT_SIZE 2048
diff --git a/libspeex/fftwrap.h b/libspeex/fftwrap.h
index 826b38e..dfaf489 100644
--- a/libspeex/fftwrap.h
+++ b/libspeex/fftwrap.h
@@ -35,7 +35,7 @@
#ifndef FFTWRAP_H
#define FFTWRAP_H
-#include "misc.h"
+#include "arch.h"
/** Compute tables for an FFT */
void *spx_fft_init(int size);
diff --git a/libspeex/filterbank.c b/libspeex/filterbank.c
index 187d5ee..e2fb71d 100644
--- a/libspeex/filterbank.c
+++ b/libspeex/filterbank.c
@@ -36,9 +36,10 @@
#endif
#include "filterbank.h"
-#include "misc.h"
+#include "arch.h"
#include <math.h>
#include "math_approx.h"
+#include "os_support.h"
#ifdef FIXED_POINT
@@ -59,7 +60,7 @@ FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type)
int id1;
int id2;
df = DIV32(SHL32(sampling,15),MULT16_16(2,len));
- max_mel = toBARK(EXTRACT16(MULT16_16_Q15(QCONST16(.5f,15),sampling)));
+ max_mel = toBARK(EXTRACT16(sampling/2));
mel_interval = PDIV32(max_mel,banks-1);
bank = (FilterBank*)speex_alloc(sizeof(FilterBank));
diff --git a/libspeex/filterbank.h b/libspeex/filterbank.h
index 5ded6b9..3e889a2 100644
--- a/libspeex/filterbank.h
+++ b/libspeex/filterbank.h
@@ -34,7 +34,7 @@
#ifndef FILTERBANK_H
#define FILTERBANK_H
-#include "misc.h"
+#include "arch.h"
typedef struct {
int *bank_left;
diff --git a/libspeex/filters.c b/libspeex/filters.c
index 48b4753..36ef4f6 100644
--- a/libspeex/filters.c
+++ b/libspeex/filters.c
@@ -36,7 +36,7 @@
#include "filters.h"
#include "stack_alloc.h"
-#include "misc.h"
+#include "arch.h"
#include "math_approx.h"
#include "ltp.h"
#include <math.h>
@@ -474,7 +474,7 @@ void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *y1
}
/* Re-synthesised a signal from the QMF low-band and high-band signals */
-void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word32_t *mem1, spx_word32_t *mem2, char *stack)
+void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack)
/* assumptions:
all odd x[i] are zero -- well, actually they are left out of the array now
N and M are multiples of 4 */
diff --git a/libspeex/filters.h b/libspeex/filters.h
index b363a9a..e3a5980 100644
--- a/libspeex/filters.h
+++ b/libspeex/filters.h
@@ -35,7 +35,7 @@
#ifndef FILTERS_H
#define FILTERS_H
-#include "misc.h"
+#include "arch.h"
spx_word16_t compute_rms(const spx_sig_t *x, int len);
spx_word16_t compute_rms16(const spx_word16_t *x, int len);
@@ -59,7 +59,7 @@ void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_m
void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack);
-void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word32_t *mem1, spx_word32_t *mem2, char *stack);
+void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack);
void filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);
void iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);
diff --git a/libspeex/filters_arm4.h b/libspeex/filters_arm4.h
index 9138610..886caed 100644
--- a/libspeex/filters_arm4.h
+++ b/libspeex/filters_arm4.h
@@ -33,9 +33,8 @@
*/
#define OVERRIDE_NORMALIZE16
-int normalize16(const spx_sig_t *x, spx_word16_t *y, int max_scale, int len)
+int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t 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/libspeex/jitter.c b/libspeex/jitter.c
index 2b64453..0bf609b 100644
--- a/libspeex/jitter.c
+++ b/libspeex/jitter.c
@@ -32,66 +32,260 @@
*/
+/*
+TODO:
+- Add short-term estimate
+- Defensive programming
+ + warn when last returned < last desired (begative buffering)
+ + warn if update_delay not called between get() and tick() or is called twice in a row
+- Linked list structure for holding the packets instead of the current fixed-size array
+ + return memory to a pool
+ + allow pre-allocation of the pool
+ + optional max number of elements
+- Statistics
+ + drift
+ + loss
+ + late
+ + jitter
+ + buffering delay
+*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include "misc.h"
+#include "arch.h"
#include <speex/speex.h>
#include <speex/speex_bits.h>
#include <speex/speex_jitter.h>
+#include "os_support.h"
#ifndef NULL
#define NULL 0
#endif
-#define LATE_BINS 15
-#define MAX_MARGIN 30 /**< Number of bins in margin histogram */
-
#define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */
-
+#define TSUB(a,b) ((spx_int32_t)((a)-(b)))
#define GT32(a,b) (((spx_int32_t)((a)-(b)))>0)
#define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0)
#define LT32(a,b) (((spx_int32_t)((a)-(b)))<0)
#define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0)
+#define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step))
+
+#define MAX_TIMINGS 20
+#define MAX_BUFFERS 3
+#define TOP_DELAY 20
+
+/** Buffer that keeps the time of arrival of the latest packets */
+struct TimingBuffer {
+ int filled; /**< Number of entries occupied in "timing" and "counts"*/
+ int curr_count; /**< Number of packet timings we got (including those we discarded) */
+ spx_int16_t timing[MAX_TIMINGS]; /**< Sorted list of all timings ("latest" packets first) */
+ spx_int16_t counts[MAX_TIMINGS]; /**< Order the packets were put in (will be used for short-term estimate) */
+};
+
+static void tb_init(struct TimingBuffer *tb)
+{
+ tb->filled = 0;
+ tb->curr_count = 0;
+}
+
+/* Add the timing of a new packet to the TimingBuffer */
+static void tb_add(struct TimingBuffer *tb, spx_int16_t timing)
+{
+ int pos;
+ /* Discard packet that won't make it into the list because they're too early */
+ if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1])
+ {
+ tb->curr_count++;
+ return;
+ }
+
+ /* Find where the timing info goes in the sorted list */
+ pos = 0;
+ /* FIXME: Do bisection instead of linear search */
+ while (pos<tb->filled && timing >= tb->timing[pos])
+ {
+ pos++;
+ }
+
+ speex_assert(pos <= tb->filled && pos < MAX_TIMINGS);
+
+ /* Shift everything so we can perform the insertion */
+ if (pos < tb->filled)
+ {
+ int move_size = tb->filled-pos;
+ if (tb->filled == MAX_TIMINGS)
+ move_size -= 1;
+ speex_move(&tb->timing[pos+1], &tb->timing[pos], move_size*sizeof(tb->timing[0]));
+ speex_move(&tb->counts[pos+1], &tb->counts[pos], move_size*sizeof(tb->counts[0]));
+ }
+ /* Insert */
+ tb->timing[pos] = timing;
+ tb->counts[pos] = tb->curr_count;
+
+ tb->curr_count++;
+ if (tb->filled<MAX_TIMINGS)
+ tb->filled++;
+}
+
+
+
/** Jitter buffer structure */
struct JitterBuffer_ {
- spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */
- spx_uint32_t current_timestamp; /**< Timestamp of the local clock (what we will *play* next) */
-
- char *buf[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Buffer of packets (NULL if slot is free) */
- spx_uint32_t timestamp[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Timestamp of packet */
- int span[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Timestamp of packet */
- int len[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Number of bytes in packet */
-
- int tick_size; /**< Output granularity */
- int reset_state; /**< True if state was just reset */
- int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */
- int late_cutoff; /**< How late must a packet be for it not to be considered at all */
- int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */
-
- int lost_count; /**< Number of consecutive lost packets */
- float shortterm_margin[MAX_MARGIN]; /**< Short term margin histogram */
- float longterm_margin[MAX_MARGIN]; /**< Long term margin histogram */
- float loss_rate; /**< Average loss rate */
+ spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */
+ spx_uint32_t last_returned_timestamp; /**< Useful for getting the next packet with the same timestamp (for fragmented media) */
+ spx_uint32_t next_stop; /**< Estimated time the next get() will be called */
+
+ spx_int32_t buffered; /**< Amount of data we think is still buffered by the application (timestamp units)*/
+
+ JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */
+ spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */
+
+ void (*destroy) (void *); /**< Callback for destroying a packet */
+
+ spx_int32_t delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */
+ spx_int32_t concealment_size; /**< Size of the packet loss concealment "units" */
+ int reset_state; /**< True if state was just reset */
+ int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */
+ int late_cutoff; /**< How late must a packet be for it not to be considered at all */
+ int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */
+
+ struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */
+ struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */
+ int window_size; /**< Total window over which the late frames are counted */
+ int subwindow_size; /**< Sub-window size for faster computation */
+ int max_late_rate; /**< Absolute maximum amount of late packets tolerable (in percent) */
+ int latency_tradeoff; /**< Latency equivalent of losing one percent of packets */
+ int auto_tradeoff; /**< Latency equivalent of losing one percent of packets (automatic default) */
+
+ int lost_count; /**< Number of consecutive lost packets */
};
+/** Based on available data, this computes the optimal delay for the jitter buffer.
+ The optimised function is in timestamp units and is:
+ cost = delay + late_factor*[number of frames that would be late if we used that delay]
+ @param tb Array of buffers
+ @param late_factor Equivalent cost of a late frame (in timestamp units)
+ */
+static spx_int16_t compute_opt_delay(JitterBuffer *jitter)
+{
+ int i;
+ spx_int16_t opt=0;
+ spx_int32_t best_cost=0x7fffffff;
+ int late = 0;
+ int pos[MAX_BUFFERS];
+ int tot_count;
+ float late_factor;
+ int penalty_taken = 0;
+ int best = 0;
+ int worst = 0;
+ spx_int32_t deltaT;
+ struct TimingBuffer *tb;
+
+ tb = jitter->_tb;
+
+ /* Number of packet timings we have received (including those we didn't keep) */
+ tot_count = 0;
+ for (i=0;i<MAX_BUFFERS;i++)
+ tot_count += tb[i].curr_count;
+ if (tot_count==0)
+ return 0;
+
+ /* Compute cost for one lost packet */
+ if (jitter->latency_tradeoff != 0)
+ late_factor = jitter->latency_tradeoff * 100.0f / tot_count;
+ else
+ late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count;
+
+ /*fprintf(stderr, "late_factor = %f\n", late_factor);*/
+ for (i=0;i<MAX_BUFFERS;i++)
+ pos[i] = 0;
+
+ /* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late
+ for the current settings) */
+ for (i=0;i<TOP_DELAY;i++)
+ {
+ int j;
+ int next=-1;
+ int latest = 32767;
+ /* Pick latest amoung all sub-windows */
+ for (j=0;j<MAX_BUFFERS;j++)
+ {
+ if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest)
+ {
+ next = j;
+ latest = tb[j].timing[pos[j]];
+ }
+ }
+ if (next != -1)
+ {
+ spx_int32_t cost;
+
+ if (i==0)
+ worst = latest;
+ best = latest;
+ latest = ROUND_DOWN(latest, jitter->delay_step);
+ pos[next]++;
+
+ /* Actual cost function that tells us how bad using this delay would be */
+ cost = -latest + late_factor*late;
+ /*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/
+ if (cost < best_cost)
+ {
+ best_cost = cost;
+ opt = latest;
+ }
+ } else {
+ break;
+ }
+
+ /* For the next timing we will consider, there will be one more late packet to count */
+ late++;
+ /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */
+ if (latest >= 0 && !penalty_taken)
+ {
+ penalty_taken = 1;
+ late+=2;
+ }
+ }
+
+ deltaT = best-worst;
+ /* This is a default "automatic latency tradeoff" when none is provided */
+ jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY;
+ /*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/
+
+ /* FIXME: Compute a short-term estimate too and combine with the long-term one */
+
+ /* Prevents reducing the buffer size when we haven't really had much data */
+ if (tot_count < TOP_DELAY && opt > 0)
+ return 0;
+ return opt;
+}
+
+
/** Initialise jitter buffer */
-JitterBuffer *jitter_buffer_init(int tick)
+JitterBuffer *jitter_buffer_init(void)
{
JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer));
if (jitter)
{
int i;
+ spx_int32_t tmp;
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
- jitter->buf[i]=NULL;
- jitter->tick_size = tick;
- jitter->buffer_margin = 1;
+ jitter->packets[i].data=NULL;
+ jitter->delay_step = 1;
+ jitter->concealment_size = 1;
+ /*FIXME: Should this be 0 or 1?*/
+ jitter->buffer_margin = 0;
jitter->late_cutoff = 50;
+ jitter->destroy = NULL;
+ jitter->latency_tradeoff = 0;
+ tmp = 4;
+ jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
jitter_buffer_reset(jitter);
}
return jitter;
@@ -103,22 +297,27 @@ void jitter_buffer_reset(JitterBuffer *jitter)
int i;
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
{
- if (jitter->buf[i])
+ if (jitter->packets[i].data)
{
- speex_free(jitter->buf[i]);
- jitter->buf[i] = NULL;
+ if (jitter->destroy)
+ jitter->destroy(jitter->packets[i].data);
+ else
+ speex_free(jitter->packets[i].data);
+ jitter->packets[i].data = NULL;
}
}
/* Timestamp is actually undefined at this point */
jitter->pointer_timestamp = 0;
- jitter->current_timestamp = 0;
+ jitter->next_stop = 0;
jitter->reset_state = 1;
jitter->lost_count = 0;
- jitter->loss_rate = 0;
- for (i=0;i<MAX_MARGIN;i++)
+ jitter->buffered = 0;
+ jitter->auto_tradeoff = 32000;
+
+ for (i=0;i<MAX_BUFFERS;i++)
{
- jitter->shortterm_margin[i] = 0;
- jitter->longterm_margin[i] = 0;
+ tb_init(&jitter->_tb[i]);
+ jitter->timeBuffers[i] = &jitter->_tb[i];
}
/*fprintf (stderr, "reset\n");*/
}
@@ -130,17 +329,52 @@ void jitter_buffer_destroy(JitterBuffer *jitter)
speex_free(jitter);
}
+/** Take the following timing into consideration for future calculations */
+static void update_timings(JitterBuffer *jitter, spx_int32_t timing)
+{
+ if (timing < -32767)
+ timing = -32767;
+ if (timing > 32767)
+ timing = 32767;
+ /* If the current sub-window is full, perform a rotation and discard oldest sub-widow */
+ if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size)
+ {
+ int i;
+ /*fprintf(stderr, "Rotate buffer\n");*/
+ struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1];
+ for (i=MAX_BUFFERS-1;i>=1;i--)
+ jitter->timeBuffers[i] = jitter->timeBuffers[i-1];
+ jitter->timeBuffers[0] = tmp;
+ tb_init(jitter->timeBuffers[0]);
+ }
+ tb_add(jitter->timeBuffers[0], timing);
+}
+
+/** Compensate all timings when we do an adjustment of the buffering */
+static void shift_timings(JitterBuffer *jitter, spx_int16_t amount)
+{
+ int i, j;
+ for (i=0;i<MAX_BUFFERS;i++)
+ {
+ for (j=0;j<jitter->timeBuffers[i]->filled;j++)
+ jitter->timeBuffers[i]->timing[j] += amount;
+ }
+}
+
+
/** Put one packet into the jitter buffer */
void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
{
int i,j;
- spx_int32_t arrival_margin;
+ int late;
/*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/
+
+ /* Syncing on the first packet to arrive */
if (jitter->reset_state)
{
jitter->reset_state=0;
jitter->pointer_timestamp = packet->timestamp;
- jitter->current_timestamp = packet->timestamp;
+ jitter->next_stop = packet->timestamp;
/*fprintf(stderr, "reset to %d\n", timestamp);*/
}
@@ -148,167 +382,120 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
{
/* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */
- if (jitter->buf[i] && LE32(jitter->timestamp[i] + jitter->span[i], jitter->pointer_timestamp))
+ if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp))
{
/*fprintf (stderr, "cleaned (not played)\n");*/
- speex_free(jitter->buf[i]);
- jitter->buf[i] = NULL;
+ if (jitter->destroy)
+ jitter->destroy(jitter->packets[i].data);
+ else
+ speex_free(jitter->packets[i].data);
+ jitter->packets[i].data = NULL;
}
}
- /*Find an empty slot in the buffer*/
- for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
+ /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/
+ /* Check if packet is late (could still be useful though) */
+ if (LT32(packet->timestamp, jitter->next_stop))
{
- if (jitter->buf[i]==NULL)
- break;
+ update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin);
+ late = 1;
+ } else {
+ late = 0;
}
-
- /*fprintf(stderr, "%d %d %f\n", timestamp, jitter->pointer_timestamp, jitter->drift_average);*/
- /*No place left in the buffer*/
- if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
+
+ /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */
+ if (GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp))
{
- int earliest=jitter->timestamp[0];
- i=0;
- for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
+
+ /*Find an empty slot in the buffer*/
+ for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
{
- if (!jitter->buf[i] || LT32(jitter->timestamp[j],earliest))
+ if (jitter->packets[i].data==NULL)
+ break;
+ }
+
+ /*No place left in the buffer, need to make room for it by discarding the oldest packet */
+ if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
+ {
+ int earliest=jitter->packets[0].timestamp;
+ i=0;
+ for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
{
- earliest = jitter->timestamp[j];
- i=j;
+ if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest))
+ {
+ earliest = jitter->packets[j].timestamp;
+ i=j;
+ }
}
+ if (jitter->destroy)
+ jitter->destroy(jitter->packets[i].data);
+ else
+ speex_free(jitter->packets[i].data);
+ jitter->packets[i].data=NULL;
+ if (jitter->lost_count>20)
+ {
+ jitter_buffer_reset(jitter);
+ }
+ /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/
}
- speex_free(jitter->buf[i]);
- jitter->buf[i]=NULL;
- if (jitter->lost_count>20)
+
+ /* Copy packet in buffer */
+ if (jitter->destroy)
{
- jitter_buffer_reset(jitter);
+ jitter->packets[i].data = packet->data;
+ } else {
+ jitter->packets[i].data=(char*)speex_alloc(packet->len);
+ for (j=0;j<packet->len;j++)
+ jitter->packets[i].data[j]=packet->data[j];
}
- /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/
+ jitter->packets[i].timestamp=packet->timestamp;
+ jitter->packets[i].span=packet->span;
+ jitter->packets[i].len=packet->len;
+ jitter->packets[i].user_data=packet->user_data;
+ if (late)
+ jitter->arrival[i] = 0;
+ else
+ jitter->arrival[i] = jitter->next_stop;
}
- /* Copy packet in buffer */
- jitter->buf[i]=(char*)speex_alloc(packet->len);
- for (j=0;j<packet->len;j++)
- jitter->buf[i][j]=packet->data[j];
- jitter->timestamp[i]=packet->timestamp;
- jitter->span[i]=packet->span;
- jitter->len[i]=packet->len;
-
- /* Adjust the buffer size depending on network conditions.
- The arrival margin is how much in advance (or late) the packet it */
- 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)
- {
- /* Here we compute the histogram based on the time of arrival of the packet.
- This is based on a (first-order) recursive average. We keep both a short-term
- histogram and a long-term histogram */
- spx_int32_t int_margin;
- /* First, apply the "damping" of the recursive average to all bins */
- for (i=0;i<MAX_MARGIN;i++)
- {
- jitter->shortterm_margin[i] *= .98;
- jitter->longterm_margin[i] *= .995;
- }
- /* What histogram bin the packet should be counted in */
- int_margin = LATE_BINS + arrival_margin;
- if (int_margin>MAX_MARGIN-1)
- int_margin = MAX_MARGIN-1;
- if (int_margin<0)
- int_margin = 0;
- /* Add the packet to the right bin */
- jitter->shortterm_margin[int_margin] += .02;
- jitter->longterm_margin[int_margin] += .005;
- } else {
- /* Packet has arrived *way* too late, we pretty much consider it lost and not take it into account in the histogram */
- /*fprintf (stderr, "way too late = %d\n", arrival_margin);*/
- if (jitter->lost_count>20)
- {
- jitter_buffer_reset(jitter);
- }
- }
-#if 0 /* Enable to check how much is being buffered */
- if (rand()%1000==0)
- {
- int count = 0;
- for (j=0;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
- {
- if (jitter->buf[j])
- count++;
- }
- fprintf (stderr, "buffer_size = %d\n", count);
- }
-#endif
}
/** Get one packet from the jitter buffer */
-int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
+int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset)
{
int i;
unsigned int j;
- float late_ratio_short;
- float late_ratio_long;
- float ontime_ratio_short;
- float ontime_ratio_long;
- float early_ratio_short;
- float early_ratio_long;
- int chunk_size;
int incomplete = 0;
+ spx_int16_t opt;
- if (jitter->interp_requested)
+ jitter->last_returned_timestamp = jitter->pointer_timestamp;
+
+ if (jitter->interp_requested != 0)
{
- jitter->interp_requested = 0;
if (start_offset)
*start_offset = 0;
packet->timestamp = jitter->pointer_timestamp;
- packet->span = jitter->tick_size;
- jitter->pointer_timestamp += jitter->tick_size;
+ packet->span = jitter->interp_requested;
+
+ /* Increment the pointer because it got decremented in the delay update */
+ jitter->pointer_timestamp += jitter->interp_requested;
packet->len = 0;
- return JITTER_BUFFER_MISSING;
- }
- if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp))
- {
- jitter->current_timestamp = jitter->pointer_timestamp;
- speex_warning("did you forget to call jitter_buffer_tick() by any chance?");
- }
- /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/
+ /*fprintf (stderr, "Deferred interpolate\n");*/
+
+ jitter->interp_requested = 0;
+
+ jitter->buffered = packet->span - desired_span;
- /* FIXME: This should be only what remaining of the current tick */
- chunk_size = jitter->tick_size;
-
- /* Compiling arrival statistics */
-
- late_ratio_short = 0;
- late_ratio_long = 0;
- /* Count the proportion of packets that are late */
- for (i=0;i<LATE_BINS;i++)
- {
- late_ratio_short += jitter->shortterm_margin[i];
- late_ratio_long += jitter->longterm_margin[i];
- }
- /* Count the proportion of packets that are just on time */
- ontime_ratio_short = jitter->shortterm_margin[LATE_BINS];
- ontime_ratio_long = jitter->longterm_margin[LATE_BINS];
- early_ratio_short = early_ratio_long = 0;
- /* Count the proportion of packets that are early */
- for (i=LATE_BINS+1;i<MAX_MARGIN;i++)
- {
- early_ratio_short += jitter->shortterm_margin[i];
- early_ratio_long += jitter->longterm_margin[i];
- }
- if (0&&jitter->pointer_timestamp%1000==0)
- {
- /*fprintf (stderr, "%f %f %f %f %f %f\n", early_ratio_short, early_ratio_long, ontime_ratio_short, ontime_ratio_long, late_ratio_short, late_ratio_long);*/
- /*fprintf (stderr, "%f %f\n", early_ratio_short + ontime_ratio_short + late_ratio_short, early_ratio_long + ontime_ratio_long + late_ratio_long);*/
+ return JITTER_BUFFER_MISSING;
}
-
/* Searching for the packet that fits best */
/* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
{
- if (jitter->buf[i] && jitter->timestamp[i]==jitter->pointer_timestamp && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size))
+ if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->pointer_timestamp && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span))
break;
}
@@ -317,7 +504,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
{
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
{
- if (jitter->buf[i] && LE32(jitter->timestamp[i], jitter->pointer_timestamp) && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size))
+ if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span))
break;
}
}
@@ -327,7 +514,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
{
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
{
- if (jitter->buf[i] && LE32(jitter->timestamp[i], jitter->pointer_timestamp) && GT32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp))
+ if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GT32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp))
break;
}
}
@@ -342,12 +529,12 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
{
/* check if packet starts within current chunk */
- if (jitter->buf[i] && LT32(jitter->timestamp[i],jitter->pointer_timestamp+chunk_size) && GE32(jitter->timestamp[i],jitter->pointer_timestamp))
+ if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp))
{
- if (!found || LT32(jitter->timestamp[i],best_time) || (jitter->timestamp[i]==best_time && GT32(jitter->span[i],best_span)))
+ if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span)))
{
- best_time = jitter->timestamp[i];
- best_span = jitter->span[i];
+ best_time = jitter->packets[i].timestamp;
+ best_span = jitter->packets[i].span;
besti = i;
found = 1;
}
@@ -357,31 +544,52 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
{
i=besti;
incomplete = 1;
- /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->timestamp[i], jitter->pointer_timestamp, chunk_size, jitter->span[i]);*/
+ /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/
}
}
/* If we find something */
if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
{
+
+
/* We (obviously) haven't lost this packet */
jitter->lost_count = 0;
- jitter->loss_rate = .999*jitter->loss_rate;
- /* Check for potential overflow */
- packet->len = jitter->len[i];
+
+ /* In this case, 0 isn't as a valid timestamp */
+ if (jitter->arrival[i] != 0)
+ {
+ update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin);
+ }
+
+
+ /* FIXME: Check for potential overflow */
+ packet->len = jitter->packets[i].len;
/* Copy packet */
- for (j=0;j<packet->len;j++)
- packet->data[j] = jitter->buf[i][j];
- /* Remove packet */
- speex_free(jitter->buf[i]);
- jitter->buf[i] = NULL;
+ if (jitter->destroy)
+ {
+ packet->data = jitter->packets[i].data;
+ } else {
+ for (j=0;j<packet->len;j++)
+ packet->data[j] = jitter->packets[i].data[j];
+ /* Remove packet */
+ speex_free(jitter->packets[i].data);
+ }
+ jitter->packets[i].data = NULL;
/* Set timestamp and span (if requested) */
if (start_offset)
- *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 */
- jitter->pointer_timestamp = jitter->timestamp[i]+jitter->span[i];
+ *start_offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp;
+
+ packet->timestamp = jitter->packets[i].timestamp;
+ jitter->last_returned_timestamp = packet->timestamp;
+
+ packet->span = jitter->packets[i].span;
+ packet->user_data = jitter->packets[i].user_data;
+ /* Point to the end of the current packet */
+ jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span;
+
+ jitter->buffered = *start_offset + packet->span - desired_span;
+
if (incomplete)
return JITTER_BUFFER_INCOMPLETE;
else
@@ -390,41 +598,81 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
/* If we haven't found anything worth returning */
+
/*fprintf (stderr, "not found\n");*/
jitter->lost_count++;
/*fprintf (stderr, "m");*/
/*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/
- jitter->loss_rate = .999*jitter->loss_rate + .001;
if (start_offset)
*start_offset = 0;
- packet->timestamp = jitter->pointer_timestamp;
- packet->span = jitter->tick_size;
- jitter->pointer_timestamp += chunk_size;
- packet->len = 0;
- /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */
- if (late_ratio_short > .1 || late_ratio_long > .03)
+ opt = compute_opt_delay(jitter);
+
+ /* Should we force an increase in the buffer or just do normal interpolation? */
+ if (opt < 0)
{
- /* If too many packets are arriving late */
- jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2];
- jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2];
- for (i=MAX_MARGIN-3;i>=0;i--)
- {
- jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i];
- jitter->longterm_margin[i+1] = jitter->longterm_margin[i];
- }
- jitter->shortterm_margin[0] = 0;
- jitter->longterm_margin[0] = 0;
- jitter->pointer_timestamp -= jitter->tick_size;
- jitter->current_timestamp -= jitter->tick_size;
- /*fprintf (stderr, "i");*/
- /*fprintf (stderr, "interpolate (getting some slack)\n");*/
+ /* Need to increase buffering */
+
+ /* Shift histogram to compensate */
+ shift_timings(jitter, -opt);
+
+ packet->timestamp = jitter->pointer_timestamp;
+ packet->span = -opt;
+ /* Don't move the pointer_timestamp forward */
+ packet->len = 0;
+
+ /*jitter->pointer_timestamp -= jitter->delay_step;*/
+ /*fprintf (stderr, "Forced to interpolate\n");*/
+ } else {
+ /* Normal packet loss */
+ packet->timestamp = jitter->pointer_timestamp;
+
+ desired_span = ROUND_DOWN(desired_span, jitter->concealment_size);
+ packet->span = desired_span;
+ jitter->pointer_timestamp += desired_span;
+ packet->len = 0;
+ /*fprintf (stderr, "Normal loss\n");*/
}
+ jitter->buffered = packet->span - desired_span;
return JITTER_BUFFER_MISSING;
}
+int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet)
+{
+ int i, j;
+ for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
+ {
+ if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp)
+ break;
+ }
+ if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
+ {
+ /* Copy packet */
+ packet->len = jitter->packets[i].len;
+ if (jitter->destroy)
+ {
+ packet->data = jitter->packets[i].data;
+ } else {
+ for (j=0;j<packet->len;j++)
+ packet->data[j] = jitter->packets[i].data[j];
+ /* Remove packet */
+ speex_free(jitter->packets[i].data);
+ }
+ jitter->packets[i].data = NULL;
+ packet->timestamp = jitter->packets[i].timestamp;
+ packet->span = jitter->packets[i].span;
+ packet->user_data = jitter->packets[i].user_data;
+ return JITTER_BUFFER_OK;
+ } else {
+ packet->data = NULL;
+ packet->len = 0;
+ packet->span = 0;
+ return JITTER_BUFFER_MISSING;
+ }
+}
+
/** Get pointer timestamp of jitter buffer */
int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
{
@@ -433,85 +681,44 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
void jitter_buffer_tick(JitterBuffer *jitter)
{
- jitter->current_timestamp += jitter->tick_size;
+ if (jitter->buffered >= 0)
+ {
+ jitter->next_stop = jitter->pointer_timestamp - jitter->buffered;
+ } else {
+ jitter->next_stop = jitter->pointer_timestamp;
+ speex_warning_int("jitter buffer sees negative buffering, you code might be broken. Value is ", jitter->buffered);
+ }
+ jitter->buffered = 0;
+}
+
+void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem)
+{
+ if (jitter->buffered < 0)
+ speex_warning_int("jitter buffer sees negative buffering, you code might be broken. Value is ", jitter->buffered);
+ jitter->next_stop = jitter->pointer_timestamp - rem;
}
/* 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_int32_t *start_offset)
{
- int i;
- float late_ratio_short;
- float late_ratio_long;
- float ontime_ratio_short;
- float ontime_ratio_long;
- float early_ratio_short;
- float early_ratio_long;
-
- if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp))
- {
- jitter->current_timestamp = jitter->pointer_timestamp;
- speex_warning("did you forget to call jitter_buffer_tick() by any chance?");
- }
- /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/
-
- /* FIXME: This should be only what remaining of the current tick */
- late_ratio_short = 0;
- late_ratio_long = 0;
- /* Count the proportion of packets that are late */
- for (i=0;i<LATE_BINS;i++)
- {
- late_ratio_short += jitter->shortterm_margin[i];
- late_ratio_long += jitter->longterm_margin[i];
- }
- /* Count the proportion of packets that are just on time */
- ontime_ratio_short = jitter->shortterm_margin[LATE_BINS];
- ontime_ratio_long = jitter->longterm_margin[LATE_BINS];
- early_ratio_short = early_ratio_long = 0;
- /* Count the proportion of packets that are early */
- for (i=LATE_BINS+1;i<MAX_MARGIN;i++)
- {
- early_ratio_short += jitter->shortterm_margin[i];
- early_ratio_long += jitter->longterm_margin[i];
- }
+ spx_int16_t opt = compute_opt_delay(jitter);
+ /*fprintf(stderr, "opt adjustment is %d ", opt);*/
- /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */
- if (late_ratio_short > .1 || late_ratio_long > .03)
+ if (opt < 0)
{
- /* If too many packets are arriving late */
- jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2];
- jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2];
- for (i=MAX_MARGIN-3;i>=0;i--)
- {
- jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i];
- jitter->longterm_margin[i+1] = jitter->longterm_margin[i];
- }
- jitter->shortterm_margin[0] = 0;
- jitter->longterm_margin[0] = 0;
- jitter->pointer_timestamp -= jitter->tick_size;
- jitter->current_timestamp -= jitter->tick_size;
- jitter->interp_requested = 1;
- return JITTER_BUFFER_ADJUST_INTERPOLATE;
-
- } else if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8)
+ shift_timings(jitter, -opt);
+
+ jitter->pointer_timestamp += opt;
+ jitter->interp_requested = -opt;
+ /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/
+ } else if (opt > 0)
{
- /* Many frames arriving early */
- jitter->shortterm_margin[0] += jitter->shortterm_margin[1];
- jitter->longterm_margin[0] += jitter->longterm_margin[1];
- for (i=1;i<MAX_MARGIN-1;i++)
- {
- jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1];
- jitter->longterm_margin[i] = jitter->longterm_margin[i+1];
- }
- jitter->shortterm_margin[MAX_MARGIN-1] = 0;
- jitter->longterm_margin[MAX_MARGIN-1] = 0;
- /*fprintf (stderr, "drop frame\n");*/
- /*fprintf (stderr, "d");*/
- jitter->pointer_timestamp += jitter->tick_size;
- jitter->current_timestamp += jitter->tick_size;
- return JITTER_BUFFER_ADJUST_DROP;
+ shift_timings(jitter, -opt);
+ jitter->pointer_timestamp += opt;
+ /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/
}
- return JITTER_BUFFER_ADJUST_OK;
+ return opt;
}
/* Used like the ioctl function to control the jitter buffer parameters */
@@ -530,13 +737,45 @@ int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr)
count = 0;
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
{
- if (jitter->buf[i] && LE32(jitter->pointer_timestamp, jitter->timestamp[i]))
+ if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp))
{
count++;
}
}
*(spx_int32_t*)ptr = count;
break;
+ case JITTER_BUFFER_SET_DESTROY_CALLBACK:
+ jitter->destroy = (void (*) (void *))ptr;
+ break;
+ case JITTER_BUFFER_GET_DESTROY_CALLBACK:
+ *(void (**) (void *))ptr = jitter->destroy;
+ break;
+ case JITTER_BUFFER_SET_DELAY_STEP:
+ jitter->delay_step = *(spx_int32_t*)ptr;
+ break;
+ case JITTER_BUFFER_GET_DELAY_STEP:
+ *(spx_int32_t*)ptr = jitter->delay_step;
+ break;
+ case JITTER_BUFFER_SET_CONCEALMENT_SIZE:
+ jitter->concealment_size = *(spx_int32_t*)ptr;
+ break;
+ case JITTER_BUFFER_GET_CONCEALMENT_SIZE:
+ *(spx_int32_t*)ptr = jitter->concealment_size;
+ break;
+ case JITTER_BUFFER_SET_MAX_LATE_RATE:
+ jitter->max_late_rate = *(spx_int32_t*)ptr;
+ jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate;
+ jitter->subwindow_size = jitter->window_size/MAX_BUFFERS;
+ break;
+ case JITTER_BUFFER_GET_MAX_LATE_RATE:
+ *(spx_int32_t*)ptr = jitter->max_late_rate;
+ break;
+ case JITTER_BUFFER_SET_LATE_COST:
+ jitter->latency_tradeoff = *(spx_int32_t*)ptr;
+ break;
+ case JITTER_BUFFER_GET_LATE_COST:
+ *(spx_int32_t*)ptr = jitter->latency_tradeoff;
+ break;
default:
speex_warning_int("Unknown jitter_buffer_ctl request: ", request);
return -1;
@@ -544,84 +783,3 @@ int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr)
return 0;
}
-
-
-void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate)
-{
- jitter->dec = decoder;
- speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size);
-
- jitter->packets = jitter_buffer_init(jitter->frame_size);
-
- speex_bits_init(&jitter->current_packet);
- jitter->valid_bits = 0;
-
-}
-
-void speex_jitter_destroy(SpeexJitter *jitter)
-{
- jitter_buffer_destroy(jitter->packets);
- speex_bits_destroy(&jitter->current_packet);
-}
-
-void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp)
-{
- JitterBufferPacket p;
- p.data = packet;
- p.len = len;
- p.timestamp = timestamp;
- p.span = jitter->frame_size;
- jitter_buffer_put(jitter->packets, &p);
-}
-
-void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp)
-{
- int i;
- int ret;
- char data[2048];
- JitterBufferPacket packet;
- packet.data = data;
-
- if (jitter->valid_bits)
- {
- /* Try decoding last received packet */
- ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
- if (ret == 0)
- {
- jitter_buffer_tick(jitter->packets);
- return;
- } else {
- jitter->valid_bits = 0;
- }
- }
-
- ret = jitter_buffer_get(jitter->packets, &packet, NULL);
-
- if (ret != JITTER_BUFFER_OK)
- {
- /* No packet found */
-
- /*fprintf (stderr, "lost/late frame\n");*/
- /*Packet is late or lost*/
- speex_decode_int(jitter->dec, NULL, out);
- } else {
- speex_bits_read_from(&jitter->current_packet, packet.data, packet.len);
- /* Decode packet */
- ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
- if (ret == 0)
- {
- jitter->valid_bits = 1;
- } else {
- /* Error while decoding */
- for (i=0;i<jitter->frame_size;i++)
- out[i]=0;
- }
- }
- jitter_buffer_update_delay(jitter->packets, &packet, NULL);
- jitter_buffer_tick(jitter->packets);
-}
-
-int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter)
-{
- return jitter_buffer_get_pointer_timestamp(jitter->packets);
-}
diff --git a/libspeex/kiss_fft.c b/libspeex/kiss_fft.c
index 775a257..62904cd 100644
--- a/libspeex/kiss_fft.c
+++ b/libspeex/kiss_fft.c
@@ -19,7 +19,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#endif
#include "_kiss_fft_guts.h"
-#include "misc.h"
+#include "arch.h"
+#include "os_support.h"
/* The guts header contains all the multiplication and addition macros that are defined for
fixed or floating point complex numbers. It also delares the kf_ internal functions.
@@ -86,7 +87,7 @@ static void kf_bfly4(
kiss_fft_cpx * Fout,
const size_t fstride,
const kiss_fft_cfg st,
- const size_t m,
+ int m,
int N,
int mm
)
@@ -290,7 +291,7 @@ static void kf_bfly_generic(
/*CHECKBUF(scratchbuf,nscratchbuf,p);*/
if (p>17)
- speex_error("KissFFT: max radix supported is 17");
+ speex_fatal("KissFFT: max radix supported is 17");
for ( u=0; u<m; ++u ) {
k=u;
@@ -505,7 +506,7 @@ void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,
{
if (fin == fout)
{
- speex_error("In-place FFT not supported");
+ speex_fatal("In-place FFT not supported");
/*CHECKBUF(tmpbuf,ntmpbuf,st->nfft);
kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
speex_move(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);*/
diff --git a/libspeex/kiss_fft.h b/libspeex/kiss_fft.h
index 54627e7..fa3f2c6 100644
--- a/libspeex/kiss_fft.h
+++ b/libspeex/kiss_fft.h
@@ -3,7 +3,7 @@
#include <stdlib.h>
#include <math.h>
-#include "misc.h"
+#include "arch.h"
#ifdef __cplusplus
extern "C" {
@@ -32,7 +32,7 @@ extern "C" {
#ifdef FIXED_POINT
-#include "misc.h"
+#include "arch.h"
# define kiss_fft_scalar spx_int16_t
#else
# ifndef kiss_fft_scalar
diff --git a/libspeex/kiss_fftr.c b/libspeex/kiss_fftr.c
index 392945c..f6275b8 100644
--- a/libspeex/kiss_fftr.c
+++ b/libspeex/kiss_fftr.c
@@ -16,6 +16,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#include "config.h"
#endif
+#include "os_support.h"
#include "kiss_fftr.h"
#include "_kiss_fft_guts.h"
@@ -84,7 +85,7 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr
kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
if ( st->substate->inverse) {
- speex_error("kiss fft usage error: improper alloc\n");
+ speex_fatal("kiss fft usage error: improper alloc\n");
}
ncfft = st->substate->nfft;
@@ -138,7 +139,7 @@ void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata, kiss_fft_scalar *
int k, ncfft;
if (st->substate->inverse == 0) {
- speex_error ("kiss fft usage error: improper alloc\n");
+ speex_fatal("kiss fft usage error: improper alloc\n");
}
ncfft = st->substate->nfft;
@@ -177,7 +178,7 @@ void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar
spx_word32_t f1kr, f1ki, twr, twi;
if ( st->substate->inverse) {
- speex_error("kiss fft usage error: improper alloc\n");
+ speex_fatal("kiss fft usage error: improper alloc\n");
}
ncfft = st->substate->nfft;
@@ -263,7 +264,7 @@ void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scala
int k, ncfft;
if (st->substate->inverse == 0) {
- speex_error ("kiss fft usage error: improper alloc\n");
+ speex_fatal ("kiss fft usage error: improper alloc\n");
}
ncfft = st->substate->nfft;
diff --git a/libspeex/lbr_48k_tables.c b/libspeex/lbr_48k_tables.c
deleted file mode 100644
index d4d80dc..0000000
--- a/libspeex/lbr_48k_tables.c
+++ /dev/null
@@ -1,678 +0,0 @@
-/* Copyright (C) 2002 Jean-Marc Valin
- File: lbr_48k_tables.c
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- - Neither the name of the Xiph.org Foundation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- 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 FOUNDATION 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.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-
-const int dummy_epic_48k_variable=0;
-#ifdef EPIC_48K
-
-const signed char gain_cdbk_ulbr[256] = {
--31, -48, -30, 10,
--19, -10, -18, 25,
--33, -22, -45, 12,
--5, -56, -43, 31,
--30, -56, -3, 28,
--59, -17, -52, 31,
--41, -60, -58, 32,
--64, -47, -22, 29,
--30, -31, -31, 2,
--29, -14, -31, 11,
--22, -37, -58, 21,
--31, -44, 13, 29,
--37, 0, 1, 35,
--46, -55, -35, 20,
--56, -14, -53, 32,
--8, 1, -36, 31,
--29, -15, -27, 13,
--29, -39, -28, 7,
--43, -5, 3, 37,
--51, -27, -54, 23,
-10, -46, -36, 30,
-3, -3, -42, 37,
--27, 16, -22, 32,
--34, -52, 13, 34,
--31, -21, -28, 8,
--34, -45, -40, 12,
--20, -48, 4, 32,
--40, -27, 16, 31,
--6, 11, -44, 41,
--35, 12, -5, 37,
-19, -33, -37, 29,
--29, 18, -32, 27,
--29, -23, -19, 13,
-16, -47, -28, 34,
--34, -30, 17, 27,
--20, 2, -26, 26,
--38, -40, -36, 9,
-15, -14, -40, 37,
--39, 14, -9, 38,
--15, 25, -39, 41,
--26, 19, -32, 29,
--39, 17, -14, 37,
-10, -36, -26, 26,
-14, -13, -40, 37,
--29, -21, -12, 17,
--8, 19, -39, 41,
--36, -18, 15, 33,
--32, -38, -38, 6,
--19, 4, -23, 29,
--38, -7, 11, 37,
-9, -10, -39, 35,
--37, 24, -19, 37,
--34, -5, -8, 27,
--20, 23, -41, 38,
--4, 17, -31, 39,
--17, -26, -26, 14,
--24, 28, -36, 36,
--7, 15, -39, 40,
--42, 16, -11, 40,
--29, 14, -6, 38,
--36, 28, -27, 35,
--21, 5, -26, 27,
-11, -9, -39, 37,
--38, -7, 13, 38
-};
-
-
-const signed char exc_12_32_table[384] = {
-34, 55, 9, 55, 4, 44, -2, 25, 4, -6, 13, -22,
-20, 26, -13, -56, -37, 18, 5, 28, 4, 10, 6, -7,
-37, -24, -31, 22, 12, -6, -4, -7, 2, 0, -3, -2,
--16, -13, -1, 9, -2, 4, 6, 5, -3, 3, 8, -1,
--1, -6, -2, -1, 8, 24, 19, 33, -73, -53, 6, -18,
-14, 7, 11, 8, -33, -94, -5, 7, 0, 44, 1, 19,
--9, -7, -34, -16, 8, 2, 5, 0, 3, 1, -2, 3,
--22, 6, -2, 12, 16, 30, 39, 25, 25, 2, 10, -2,
--1, -40, -6, -51, -5, -48, -9, -33, -14, -1, -24, 15,
-104, 39, 12, -9, -20, -12, -30, -10, -31, -7, -30, -8,
--71, -53, -4, -11, 9, -10, 7, -10, 10, -1, 11, 8,
-24, 14, 6, -3, 10, 8, 8, 11, -6, 11, 0, -2,
--6, -2, 1, -1, -3, 8, -41, 27, 57, -7, 11, -16,
--61, 50, 10, -10, 4, -13, 14, -7, 1, 5, -4, 4,
-0, 2, -1, -2, -1, 1, 1, 0, -1, -1, -2, -3,
--3, -15, 69, 60, 10, -10, -10, -29, -21, -7, -16, 2,
-24, -32, 24, -18, -14, -2, -11, 11, -6, 10, 1, 3,
-24, -10, 14, 18, -13, 17, -16, 4, -3, -21, -3, -11,
--19, 12, -14, 26, 20, -9, 24, -15, 18, 1, -32, -2,
--1, 8, -3, 4, 11, -47, 7, 46, -4, -10, -10, -2,
--24, 29, -33, 6, -20, -3, 0, -12, 5, -30, 8, -13,
-28, 9, 5, -11, 0, -14, -13, -22, -12, -8, -4, 1,
--6, 28, 45, -18, -31, -5, 1, 2, 1, 5, 0, -3,
--19, -10, 10, 27, 8, -16, -28, -9, 2, -5, 8, -1,
-100, -49, 4, -43, 25, -7, 1, 9, -13, 13, -18, 13,
--1, -1, 0, 2, -2, -8, 9, -46, -7, 70, 23, 7,
--103, 20, 8, 42, -5, 21, -4, 4, 1, -8, 16, -8,
-3, 3, 8, 4, 7, -3, -3, -4, 9, 6, 2, 13,
-6, 3, -15, 11, -43, 31, 40, -13, 12, -21, -2, -3,
--10, -9, 16, -35, 31, -3, -12, 8, -34, 7, 12, 22,
--3, -4, -7, -12, 24, 53, -19, -43, 4, -3, -4, 6,
--18, -30, -58, -17, -11, 17, 23, 34, 30, 28, 28, 15,
-};
-
-
-const signed char cdbk_lsp_vlbr[5120]={
-23, 34, 108, 100, 102, 82, 69, 48, 52, 25,
-0, -37, -55, -78, -111, -79, 58, 57, 45, 32,
-27, -9, -12, -14, -41, -29, -17, -41, 44, 35,
--24, -68, -72, 61, 100, 73, 100, 80, 70, 37,
-12, -5, 22, 11, -10, -40, -33, -17, 19, 12,
--20, -57, -94, -92, 56, 71, 48, 31, 22, -5,
-41, 28, 6, -6, -12, -39, -18, -16, -30, -23,
-65, 54, 41, 28, 23, 9, 26, 18, 22, 6,
-17, -16, -33, -54, -87, -79, 8, -8, 44, 35,
--20, -62, -78, 22, 78, 47, 44, 33, 26, 14,
-8, 1, 45, 47, 72, 68, 55, 31, 36, 17,
--27, -68, -86, -65, -10, 23, 8, -22, -31, 25,
--4, -38, -55, -68, -96, -118, -39, 30, 28, 31,
--21, -66, -47, 99, 91, 68, 78, 56, 64, 36,
-33, 22, 13, -13, -36, -22, 44, 37, 54, 33,
--31, -76, -106, -100, -5, 21, 7, -17, 13, 48,
--26, -65, -84, -84, -46, 67, 97, 66, 58, 31,
--20, -52, -32, -20, 3, 16, 27, 40, 54, 29,
--6, -35, -56, -64, -8, -31, -36, 21, 26, -3,
-32, 23, 1, -23, -19, -44, -45, -7, 10, -10,
--24, -55, 2, 67, 72, 85, 90, 74, 77, 45,
--21, -58, -45, -49, 16, 34, 13, -15, -16, 16,
-8, -31, -34, -61, -83, 10, 24, 8, 56, 25,
--8, -49, -74, -95, -123, -77, 6, 40, 46, 42,
--21, -60, -59, -34, -12, 27, 8, -19, -48, -17,
--25, -66, -78, -73, -81, -16, 14, 0, -2, 33,
-78, 79, 69, 49, 44, 32, 50, 44, 46, 22,
-24, 9, -4, -18, -37, -56, 22, 34, 22, 11,
--19, -59, -85, -41, 46, 72, 60, 33, 29, -3,
--21, -66, -70, 65, 92, 57, 61, 41, 40, 23,
--4, -41, -60, -72, -102, -106, 4, 56, 57, 31,
--5, -48, -62, -91, -109, 1, 76, 54, 72, 39,
--21, -61, -86, -46, -34, -39, 42, 25, 15, 12,
-5, -16, -36, -56, 5, 18, 11, 13, 52, 23,
-12, -6, 30, 40, 59, 40, 27, 8, 19, 6,
-25, 8, -9, -19, -25, -53, -40, -38, -46, -4,
--17, -59, -83, 2, 58, 29, 18, -2, -17, -5,
--35, -80, -111, -117, -41, -9, 14, 23, 36, 56,
-48, 67, 93, 71, 77, 91, 110, 95, 83, 47,
--25, -62, -97, -93, 76, 96, 73, 52, 61, 28,
--9, -55, -46, 49, 33, 8, 1, -25, 28, 23,
--10, -47, -60, -45, -62, -58, 56, 57, 48, 28,
-34, 12, -9, 0, 34, 4, 6, 11, 3, -18,
-21, -9, -16, -13, -39, -41, 14, -8, 33, 28,
--7, -49, -61, 15, 34, 3, 2, -13, -28, -17,
--14, -50, -46, -65, -76, -13, -10, -29, -30, 22,
--28, -68, -97, -98, -8, 38, 36, 26, 25, 15,
-6, -33, -9, 1, -28, -11, -19, -24, 61, 36,
--15, -60, -19, 81, 58, 52, 42, 28, 66, 36,
--15, -52, -71, -15, 11, -13, 38, 28, 11, -4,
-34, 1, -9, -27, -57, -19, 36, 6, 14, 0,
--1, -43, -14, 16, -12, -5, -14, -29, -33, -32,
--13, -57, -75, -100, -111, 1, 2, 13, 48, 33,
-12, 16, 100, 85, 69, 49, 40, 29, 46, 23,
--4, -26, -41, -44, -7, -26, -39, -27, 18, 0,
--4, -47, -51, 17, 7, -19, 13, -10, -16, 9,
--24, -63, -93, -53, 25, 14, 73, 51, 35, 8,
--34, -77, -106, -83, -51, -47, 2, 12, 41, 53,
--13, -47, -67, -44, 42, 20, 24, 33, 21, -3,
-11, -15, -29, -51, -79, -88, 22, 56, 43, 20,
-11, -22, -37, -1, 61, 40, 28, 24, 22, -6,
--3, -33, -50, -66, -93, -100, -16, -16, 3, 41,
--18, -58, -82, -5, 95, 78, 56, 39, 30, 1,
--6, -47, -28, -26, -36, 49, 55, 51, 71, 35,
--6, -50, -42, -4, -32, -1, -1, -18, 67, 40,
--23, -63, -56, -48, -32, 0, -14, -43, -46, 25,
--17, -61, -63, 13, -1, 28, 23, 10, 67, 36,
-45, 92, 124, 111, 108, 86, 77, 56, 57, 28,
-50, 35, 13, 3, -2, -32, 3, 14, 6, -8,
-12, -17, -24, -42, -67, -23, 67, 49, 64, 38,
--21, -60, -90, -45, 32, 6, 7, -3, -15, 9,
--16, -62, -73, 50, 46, 18, 7, -13, 63, 39,
-19, -16, -19, 20, 5, -15, 16, -9, 5, 8,
--11, -46, -42, -39, -55, -68, -62, -27, -18, 23,
--23, -61, -67, -71, -29, 44, 32, 10, -15, -12,
--6, -45, -43, -40, -67, -22, 42, 19, 61, 38,
-9, -13, -38, -37, 40, 30, 15, 9, 11, -16,
-0, -18, -29, -34, -17, -44, -50, -3, 47, 15,
--3, -46, -26, 20, -10, 16, 20, -2, 43, 18,
--23, -46, 46, 91, 99, 100, 99, 79, 72, 42,
--1, -44, -33, -36, -56, 22, 17, 4, 71, 37,
-0, -38, -49, 0, -1, -30, -21, -35, -44, -6,
--32, -74, -101, -98, -14, -21, -23, 7, 26, 45,
-8, -28, -44, -63, -96, -84, 34, 21, 13, 23,
-10, -24, -38, -17, -29, -53, -16, -41, -14, 23,
--19, -61, -76, -12, 97, 99, 79, 60, 59, 25,
-5, -11, -26, -54, -26, -8, -13, 3, 25, 4,
-17, 16, 4, -24, -1, 42, 60, 63, 70, 37,
-10, -27, -22, -43, -62, -7, -16, 10, 75, 40,
--26, -64, -96, -106, -3, 73, 73, 46, 55, 29,
--2, -45, -43, 45, 46, 17, 37, 10, 30, 32,
-21, -2, -18, -28, -47, -63, -38, -56, -3, 27,
--17, -48, -9, 9, 3, 28, 50, 58, 73, 44,
-8, -14, -32, -56, -81, -106, -35, 41, 53, 26,
-1, -38, -51, -66, -100, -61, 32, 17, 66, 42,
-17, 5, -6, -21, -26, -52, -36, 23, 56, 22,
-6, -20, -31, -22, -19, -48, 16, 38, 22, -2,
--25, -67, -93, -51, 82, 62, 71, 69, 63, 35,
--12, -51, -71, -60, -76, -91, -14, 41, 35, 20,
--16, -31, 22, 32, 55, 80, 98, 91, 85, 49,
--21, -63, -92, -6, 57, 27, 36, 11, 60, 39,
--7, -45, -67, -81, -114, -110, 0, 24, 23, 45,
--18, -55, -61, -56, -60, -64, -32, -2, 58, 36,
--3, -33, -51, -24, 19, -10, -19, 4, 14, -15,
--19, -59, -81, -12, 7, -12, 36, 16, 48, 36,
-17, -13, -32, -49, -78, -95, -1, -3, -10, 25,
-15, 5, 41, 59, 108, 101, 103, 81, 70, 35,
--14, -52, -37, 15, 93, 83, 66, 50, 47, 15,
--3, -31, -49, -52, -9, -31, -10, 37, 62, 27,
--15, -56, -82, -17, 75, 56, 36, 22, 7, -16,
--24, -63, -93, -84, 25, 94, 98, 65, 60, 31,
--2, -45, -39, -61, -61, 48, 35, 32, 54, 18,
--19, -51, -45, -57, -28, -8, 10, 14, 38, 26,
--2, -46, -38, 45, 26, 22, 48, 21, 63, 40,
--22, -61, -73, -75, -67, -31, 13, 18, 51, 34,
--12, -2, -1, -17, -3, -27, -3, 6, -1, -15,
--16, -59, -78, 10, 36, 9, 4, -18, 33, 22,
--25, -62, -97, -107, 39, 87, 69, 46, 42, 12,
-11, -7, -30, -36, 19, 2, -10, -7, -4, -24,
-11, -8, 25, 28, 28, 5, -4, -10, 5, -2,
--10, -48, -37, -17, -38, -9, -2, -19, -30, -22,
--23, -61, -79, -81, -2, 15, -4, 17, 20, 2,
-25, -14, -3, -10, -38, 1, 14, -14, -9, -27,
-2, -18, -38, -36, -11, -39, -36, -28, -36, -11,
-32, 59, 127, 124, 127, 108, 91, 68, 64, 34,
-3, -32, -37, -10, -25, -46, 12, 1, -17, -24,
--29, -69, -102, -100, 2, -7, 11, 14, 1, 31,
-30, -6, -4, -16, -44, -5, 3, -9, 66, 40,
--9, -45, -52, -5, 37, 19, 26, 6, 51, 32,
--31, -73, -96, -45, -25, -37, -15, -16, 32, 39,
-3, -15, 18, 21, 28, 33, 58, 58, 69, 42,
--31, -73, -99, -99, -48, 14, 21, 5, 2, 39,
-7, -35, -20, 29, 2, -8, -8, -28, 38, 26,
--5, -39, -64, -36, 15, -15, -11, -21, -23, 5,
--8, -51, -56, 15, -1, -14, -8, -31, 36, 22,
--8, -53, -68, -98, -101, 42, 49, 38, 41, 12,
-10, -27, -22, 4, -23, -21, 30, -1, 22, 26,
--13, -56, -42, 31, 9, -1, -10, -2, 22, -4,
-15, 8, 56, 57, 45, 55, 57, 46, 72, 44,
--7, -53, -26, 53, 21, 17, 0, 0, 74, 41,
-3, -18, -2, 0, 19, 17, 42, 36, 47, 26,
-24, -7, -23, -34, -62, -60, 6, -22, 18, 25,
--11, -42, -46, -61, -83, -99, -67, -11, 28, 39,
-30, -3, -10, -1, -24, -30, -1, -28, 15, 18,
-19, -15, -10, -6, -35, -26, 33, 10, 56, 39,
--13, -53, -82, -42, 53, 37, 18, 10, -3, -21,
--21, -60, -89, -46, 89, 94, 71, 46, 42, 9,
--2, -34, -44, -46, -64, -84, -1, 37, 16, 0,
--17, -51, -65, -64, -7, -17, -29, -11, 52, 27,
-22, -15, -16, -39, -55, 26, 36, 21, 62, 28,
--2, -26, -38, -49, -55, -80, -75, 8, 20, 9,
--6, -47, -61, -82, -103, -17, -15, -25, 53, 40,
--8, -47, -66, -18, 56, 43, 25, 29, 39, 3,
--27, -66, -86, -69, -50, -59, -34, -1, 19, 42,
-3, -20, 2, 21, 72, 57, 52, 36, 31, 7,
--12, -49, -61, -13, -1, -33, 5, 37, 26, 2,
--27, -69, -92, -62, 2, 43, 88, 67, 64, 36,
-0, -40, -4, -6, -20, 43, 33, 25, 50, 20,
-14, -20, -30, -44, -73, -37, -24, -47, 26, 20,
-31, 53, 111, 118, 127, 126, 121, 99, 85, 46,
--14, -45, -51, -39, 24, 5, -6, 17, 46, 14,
--4, -43, -45, -70, -63, 8, 14, 58, 78, 39,
--8, -47, -66, -84, -114, -55, 10, -8, 32, 40,
-28, 22, 42, 26, 8, -21, -16, -6, 22, 10,
-24, 10, 34, 31, 35, 31, 46, 39, 59, 36,
--4, -43, -62, -10, 20, -14, 2, 14, -6, -19,
--21, -62, -89, -22, 62, 33, 30, 16, 15, 15,
-0, -22, -31, -45, -58, -80, -66, 13, 68, 34,
--16, -45, -6, 7, -6, -17, -14, -15, 2, 2,
-10, -5, -22, -38, -40, -70, -60, -15, -23, 0,
-22, -11, -22, -39, -67, -25, 30, 5, 58, 37,
--21, -47, 6, 43, 37, 45, 65, 66, 73, 43,
-2, -25, -40, -53, -72, -94, -35, 24, 9, 8,
--3, 0, -3, -9, 4, -23, -10, 20, 43, 14,
--2, -41, -60, -9, 57, 32, 17, 16, 6, -19,
-1, -31, -36, -36, -54, -68, -77, -75, 21, 37,
--19, -32, 79, 90, 92, 81, 67, 47, 52, 28,
--6, -36, -57, -62, 27, 40, 21, 11, 9, -19,
--10, -47, -49, -59, -74, -18, -14, -30, 25, 18,
--23, -69, -82, 60, 66, 40, 75, 54, 65, 38,
--19, -57, -92, -68, 66, 58, 34, 18, 1, -16,
--29, -68, -99, -88, -37, -38, 13, 8, 5, 40,
--22, -63, -75, 14, 15, 7, 75, 58, 59, 34,
--23, -62, -82, -39, -31, -53, -27, 5, -3, 20,
-13, -26, -20, 22, 2, -3, 35, 13, 54, 39,
-32, 5, -13, -22, -45, -58, -1, -20, -19, 7,
-30, 46, 70, 55, 89, 88, 91, 67, 56, 28,
--13, -50, -63, -25, -28, -50, -23, -32, -34, 19,
--13, -54, -65, -9, -20, -37, 29, 6, 11, 25,
-0, -40, -55, -78, -107, -25, 47, 20, 34, 16,
--20, -58, -96, -103, 38, 43, 27, 30, 15, -1,
--16, -49, -52, -66, -80, -57, -44, -39, 6, 38,
-0, -38, 5, 13, -8, 23, 24, 1, 7, -9,
--18, -56, -64, -7, 38, 13, 11, 32, 28, 0,
-14, -3, -20, -17, 4, -26, -34, -8, 19, -9,
--23, -60, -83, -38, -8, -32, 11, 19, -1, -5,
--5, -47, -12, 56, 38, 22, 18, -8, -5, -8,
-18, -4, -24, -16, 27, 2, -6, 5, 25, -5,
-13, 0, -19, -35, -23, -45, -59, -30, 19, 3,
-19, -12, -23, 1, -7, -35, -14, -32, -23, 4,
--23, -64, -67, -22, -27, -5, -5, -20, 20, 5,
-20, 11, 83, 92, 85, 89, 69, 53, 80, 48,
-15, -2, -21, -29, -18, -48, -52, -12, -11, -21,
--6, -38, -55, -68, -9, 33, 22, 19, 25, -1,
--8, -46, -49, -67, -64, 16, 8, -6, 32, 15,
-3, -25, -46, -46, 39, 50, 34, 21, 46, 14,
-8, -33, -37, -68, -82, 31, 34, 13, 19, -6,
-33, 0, 5, -7, -32, 2, 22, -3, 35, 17,
--23, -62, -91, -64, 6, 3, 36, 26, 7, -3,
--12, -54, -60, 26, 46, 16, 30, 22, 8, -4,
--23, -61, -40, 31, 58, 73, 88, 77, 74, 41,
--2, -42, -49, 13, 5, -15, 22, -4, 26, 27,
--13, -54, -39, 18, 2, -8, -12, 34, 56, 23,
--20, -31, 27, 23, 24, 28, 39, 33, 47, 27,
-36, 17, -4, -20, -30, -61, -8, 20, 0, -15,
--10, -51, -72, -82, -111, -73, 34, 25, 19, 38,
--10, -45, -63, -55, -46, -75, -45, 34, 34, 12,
-6, -18, 29, 26, 7, -9, 0, 5, 38, 22,
--7, -52, -16, 69, 43, 26, 23, 2, 51, 34,
--12, -51, -59, -78, -88, 15, 20, 0, -14, 12,
--3, -36, -59, -45, 60, 49, 28, 20, 16, -13,
--28, -70, -90, 9, 67, 48, 90, 77, 70, 38,
--10, -39, -58, -54, 15, -12, 3, 35, 27, -3,
-12, -1, 28, 29, 55, 53, 80, 65, 51, 23,
--17, -61, -39, 74, 56, 43, 75, 51, 58, 36,
--30, -71, -93, -43, -29, -26, 4, -19, -14, 37,
-3, -13, -31, -38, 11, -5, -22, -11, 43, 14,
--25, -65, -80, -79, -71, 3, 37, 32, 20, 9,
--20, -60, -77, -26, 18, 43, 44, 24, 22, -3,
--4, -42, -22, -19, -45, -32, -35, -39, -46, 1,
--25, -59, -27, -10, -7, -4, 7, 13, 25, 12,
-8, -25, -32, -47, -74, -32, 27, 6, 25, 7,
-41, 40, 62, 64, 64, 50, 54, 42, 49, 25,
--21, -63, -88, -21, 16, -3, -4, -26, 57, 38,
-8, -25, -34, 2, -8, -28, 2, -22, 12, 23,
--19, -49, 10, 71, 84, 71, 66, 48, 42, 22,
--20, -58, -89, -57, 62, 44, 33, 36, 25, -1,
--22, -55, -27, 1, 43, 37, 46, 50, 51, 26,
-1, -38, -46, 22, 34, 4, 20, -2, 3, 9,
--4, -42, -49, -75, -89, -24, -25, 19, 71, 39,
-5, -28, -45, -43, -63, -75, -17, -38, 14, 30,
--4, -36, -62, -59, -29, -43, -4, -16, 11, 23,
--19, -57, -82, -39, 26, 2, -2, 20, 11, -10,
--28, -68, -92, -70, 9, -1, -15, -30, 11, 31,
-1, -22, -41, -49, -30, -58, -48, 8, 4, -9,
-38, 41, 108, 115, 96, 98, 103, 84, 86, 51,
-15, 1, 58, 46, 26, 6, 16, 18, 41, 24,
-4, -34, -14, -27, -42, 20, 18, 2, 23, 1,
--22, -59, -83, -70, -22, -42, -26, 29, 29, 15,
--14, -34, 11, -1, -21, -35, -3, 1, 29, 16,
--16, -57, -78, -7, 17, -13, 8, -13, -6, 22,
--22, -32, -21, -20, 20, -4, 10, 13, 12, -4,
-8, -30, -30, -46, -71, -4, 3, -11, 4, -11,
-16, 5, -15, -21, 3, -23, -25, -19, -28, -32,
--28, -68, -98, -101, -34, 19, 71, 52, 49, 30,
--18, -57, -82, -56, -56, -66, 15, 12, 1, 29,
--21, -62, -76, -27, -33, -38, 18, 30, 54, 32,
-3, -36, -10, -17, -34, -3, -8, 32, 63, 27,
-1, -30, -44, -20, -13, -49, -25, 3, -14, -18,
--26, -68, -80, -46, -28, 17, 42, 37, 58, 34,
-30, 26, 57, 55, 49, 25, 16, 3, 24, 11,
-35, 35, 67, 57, 60, 82, 114, 103, 93, 55,
-18, -8, -23, -32, -53, -68, 15, 11, -6, -7,
--2, -43, -29, 0, -28, -5, -5, -15, 25, -1,
-4, -13, -35, -45, 14, -6, -2, 19, 16, -9,
--30, -72, -93, -93, -73, -10, -15, 6, 30, 45,
--23, -58, -50, -55, -74, -60, -23, 0, 6, 21,
--4, -40, -63, -24, 7, -19, 4, -18, 27, 28,
--12, 1, 88, 76, 74, 88, 93, 90, 80, 44,
--13, -59, -43, 52, 27, 21, 15, 12, 42, 11,
-22, -14, -17, -33, -57, -4, 5, -18, 40, 18,
--3, -23, -43, -44, 8, -16, -14, -4, -20, -29,
-35, 45, 75, 82, 111, 117, 125, 105, 89, 51,
--3, -38, -57, -30, 79, 71, 48, 33, 33, 0,
--17, -62, -57, 66, 67, 35, 29, 5, 22, 17,
-3, -31, -34, -21, -44, -49, 42, 23, 24, 26,
--23, -62, -74, -49, -30, -30, -37, -50, 9, 35,
--17, -57, -71, -81, -45, 61, 58, 37, 31, 9,
-3, -7, 28, 14, -2, 0, 40, 41, 58, 33,
--11, -51, -74, -17, 40, 12, 8, 13, -4, -22,
--16, -46, -31, -35, -49, -49, -26, -9, -7, -7,
-17, -9, -24, -41, -68, -73, 38, 33, 19, 16,
--15, -50, -47, -16, -24, -21, 59, 56, 53, 30,
--14, -54, -57, 2, -17, -33, -34, -21, 4, -4,
--23, -62, -93, -72, 48, 31, 21, 6, 3, 17,
--18, -63, -79, 44, 68, 36, 45, 20, 57, 37,
--29, -72, -99, -111, -86, -31, 7, 25, 39, 55,
--14, -49, -53, -63, -80, -31, 24, 13, 1, -1,
--9, -45, -55, -27, -31, -63, -23, 25, 13, -5,
--20, -61, -80, 7, 44, 16, 54, 40, 32, 17,
-24, 7, -8, -43, -62, -54, -11, 7, 35, 27,
--12, -55, -59, -48, -69, -4, -1, -12, 68, 39,
--12, -31, 52, 63, 53, 34, 29, 22, 36, 19,
--26, -66, -97, -79, 50, 41, 40, 48, 54, 28,
--2, -37, -41, -2, -11, -30, 29, 16, 4, -2,
-40, 49, 56, 37, 39, 40, 64, 59, 67, 39,
-11, -5, 20, 14, 25, 16, 25, 22, 37, 17,
--3, -43, -46, -10, -35, -38, -35, -39, 67, 43,
--7, -47, -33, -39, -60, -12, -18, 11, 43, 11,
--25, -65, -91, -76, -91, -81, 0, 13, 34, 50,
--9, -50, -52, 17, 0, -4, 43, 18, 63, 42,
--8, -15, 15, 41, 56, 35, 51, 45, 51, 29,
-0, -14, -24, -36, -43, -70, -39, 27, 33, 5,
--25, -62, -81, -66, -12, -26, -16, -4, -13, 21,
--29, -68, -60, -24, -3, 11, 18, 19, 30, 20,
-1, -35, -42, -30, -57, -51, 13, -17, 3, 22,
--8, -27, -12, -2, -7, -21, 36, 41, 34, 12,
--17, -56, -62, -72, -73, -17, -26, 9, 16, 13,
-11, -21, -37, -3, 16, -17, 1, -3, -18, -19,
-15, -20, -19, -22, -49, -30, -7, -29, 3, -2,
-17, -4, 11, 6, 51, 40, 36, 34, 48, 22,
--19, -55, -29, 37, 68, 49, 45, 33, 42, 23,
-7, -30, -22, 3, -22, -36, -36, -54, 20, 22,
-20, 2, -15, -39, -59, -85, -10, 37, 21, 2,
--15, -54, -77, -54, 74, 70, 48, 32, 51, 20,
--25, -64, -70, -75, -52, 17, 6, -20, -30, 26,
--13, -55, -15, 39, 16, 42, 30, 33, 62, 28,
--21, -56, -30, -35, 6, 13, -4, -29, 33, 27,
--17, -55, -75, -31, 3, -28, -26, 16, 18, -4,
--13, -44, -60, -52, -9, -36, -38, 1, -9, -9,
--12, -50, -77, -70, 43, 47, 28, 13, 43, 16,
--13, -57, -80, -104, -113, -30, 43, 45, 52, 39,
-3, -28, -42, -37, -58, -67, 23, 4, 38, 33,
--21, -64, -74, -22, 43, 83, 81, 56, 62, 32,
-34, 26, 23, 9, 14, 17, 26, 16, 37, 19,
--5, -48, -49, -75, -65, 9, -6, 41, 45, 15,
-32, 30, 63, 83, 90, 91, 100, 84, 85, 52,
--19, -54, -68, -71, 11, 30, 13, 1, 63, 37,
-44, 76, 99, 87, 117, 113, 103, 77, 64, 32,
--16, -45, -12, 30, 27, 15, 57, 49, 42, 22,
-9, -15, -31, -28, -36, -61, -13, -18, -33, -5,
--12, -55, -8, 82, 64, 47, 42, 21, 27, 9,
--15, -56, -74, -12, -19, -28, 7, -16, 53, 38,
--7, -45, -64, -55, -74, -80, 35, 45, 24, 15,
--25, -48, -34, -42, -6, -27, -9, 9, 13, -7,
--25, -65, -84, -35, 30, 14, 24, 39, 48, 28,
--22, -62, -86, -51, 64, 104, 94, 61, 62, 31,
-16, -15, -25, -28, -55, -56, -10, -23, 52, 36,
-10, -10, -22, -46, -71, -92, -45, -13, 16, 26,
--22, -65, -84, 17, 85, 55, 66, 48, 55, 31,
--1, -38, -33, -25, -49, -15, 18, -10, 41, 30,
--3, -24, -47, -60, -30, -46, -17, -13, -27, 1,
--7, -41, -61, -54, -50, -78, -28, 5, -2, 20,
-17, -12, -27, -4, 8, -27, -5, 23, 14, -12,
--36, -81, -111, -75, -17, -9, 9, 9, 39, 49,
--13, -59, -54, 68, 51, 32, 35, 14, 64, 38,
--11, -44, -69, -57, 11, -11, -5, 3, -16, -15,
-34, 36, 41, 16, -8, -24, 11, 23, 48, 28,
--17, -42, 8, 17, 45, 69, 71, 55, 49, 23,
-3, -30, -46, -64, -95, -109, 2, 39, 19, 19,
-25, -13, -7, 16, -11, -5, 8, -11, 52, 33,
--8, -37, -57, -60, 13, 7, -14, -4, 20, -7,
-7, -31, 9, 44, 20, 22, 29, 10, 52, 31,
-3, -22, -36, -53, -80, -77, -35, -41, 54, 41,
--21, -59, -87, -83, 12, 69, 57, 36, 32, 2,
-6, -14, -34, -42, -4, -32, -27, 10, 4, -20,
--11, -56, -59, 25, 8, -5, -9, -26, 68, 43,
-22, 13, 40, 39, 73, 81, 95, 88, 82, 45,
--18, -62, -79, 28, 60, 28, 29, 3, 23, 25,
-6, -31, -39, -55, -85, -32, 7, -17, 48, 30,
-7, -24, -42, -8, 39, 10, 7, 11, 1, -20,
--1, -36, -26, -30, -48, 2, 46, 26, 35, 14,
--17, -57, -56, -10, -4, 26, 22, 6, -4, -16,
--18, -55, -59, -67, -86, -50, 3, 29, 29, 16,
--25, -61, -33, 2, 26, 25, 23, 10, 24, 16,
-26, 15, -8, -20, 6, -21, -16, 3, 0, -22,
-13, -17, -26, -12, -31, -48, 15, -3, 1, 14,
-4, -27, -33, -21, -29, -53, -52, -64, -42, 22,
--11, -41, -42, -40, -42, -64, 0, 48, 50, 19,
--13, -47, -42, -56, -50, 10, 3, -9, -30, -16,
--4, -47, -12, 14, -13, 21, 13, 6, 73, 40,
--15, -50, -63, -41, -31, -55, -60, -13, 28, 15,
--6, -50, -56, -81, -95, 30, 29, 21, 71, 35,
--14, -58, -65, 37, 40, 9, 18, -10, -4, 20,
-31, 33, 79, 106, 119, 103, 100, 77, 64, 33,
-14, 7, 56, 81, 97, 85, 85, 61, 45, 20,
--24, -66, -74, -51, -17, 16, 5, -21, 22, 26,
--1, -25, -38, -24, -2, -35, -26, 21, 34, 1,
-20, 15, 75, 59, 39, 26, 48, 43, 50, 29,
-26, 1, -15, -4, -9, -38, 9, 2, -9, -8,
-20, 14, 19, 13, 2, -16, 24, 25, 19, 3,
--8, -41, -58, -78, -109, -106, -27, 9, 53, 46,
-17, 5, -13, -25, -24, -54, -20, 2, -21, -25,
--11, -50, -48, 19, 10, -7, 46, 26, 24, 17,
--28, -68, -69, -50, -49, -33, -7, 10, 20, 21,
-4, -36, -21, 38, 19, 1, 25, -3, 20, 22,
--18, -58, -87, -44, 82, 73, 49, 31, 19, -7,
--21, -61, -78, -44, -58, -66, -9, -23, 10, 40,
--25, -66, -76, -33, -33, 6, 16, -6, -21, 5,
--27, -69, -77, 5, -2, -7, 6, 9, 24, 6,
-1, -41, -41, -58, -79, 25, 69, 43, 68, 36,
--28, -67, -85, -71, -34, 0, 14, 12, -2, 4,
--2, -33, -55, -37, 37, 25, 6, 6, 29, -4,
--8, -25, -11, -9, 40, 23, 17, 25, 37, 12,
--21, -27, 52, 60, 47, 58, 76, 70, 69, 38,
-23, 15, 22, -8, -32, -50, -10, 3, 31, 21,
--10, -44, -67, -61, -29, -54, 8, 39, 21, 4,
-31, 18, 30, 36, 46, 28, 50, 42, 35, 13,
--21, -57, -24, -16, -15, 14, 3, -25, -17, 20,
-23, 6, 24, 35, 90, 72, 64, 55, 55, 23,
-7, -28, -42, -19, -36, -50, -15, -40, 29, 28,
--21, -59, -66, -59, -6, 85, 83, 53, 54, 26,
-2, -20, -42, -52, -27, -49, 5, 9, -9, -8,
--18, -56, -84, -72, 24, 51, 32, 20, 13, -10,
--13, -53, -64, -39, -63, -40, 24, 0, 34, 29,
-0, -31, -45, -63, -90, -53, 3, -18, -9, 24,
--13, -57, -71, 27, 19, -3, 25, -3, 45, 35,
-12, -9, -26, -40, -51, -78, -24, 11, -9, -6,
--12, -49, -45, -33, -50, -48, -46, -52, 2, 25,
--14, -56, -84, -108, -122, -50, 4, 22, 42, 53,
--6, -44, -54, -28, -41, -61, 19, 25, 6, 1,
--32, -75, -95, -38, -1, -15, 7, 14, 23, 23,
-11, 12, 37, 30, 38, 51, 80, 80, 82, 47,
--19, -56, -69, -82, -98, -64, -29, 2, 28, 42,
--18, -49, 3, 34, 41, 39, 32, 18, 21, 7,
--8, 23, 39, 30, 30, 27, 41, 36, 44, 23,
--16, -49, -69, -46, 1, -27, 41, 48, 35, 15,
-6, -32, -36, 5, -17, -30, 2, -16, 51, 35,
--23, -64, -91, -21, 71, 44, 52, 44, 40, 21,
--22, -55, -40, -20, 62, 52, 38, 29, 27, 5,
--27, -69, -75, -6, -8, 3, -2, -30, -42, 13,
-2, -29, -42, -10, 29, 2, 15, 30, 26, 0,
--27, -69, -85, -75, -54, -8, -14, -31, 16, 42,
--2, -44, -54, -75, -101, -6, 4, -3, 32, 13,
-7, -3, -22, -43, -14, -27, -24, -11, -14, -12,
--18, -57, -85, -66, 47, 86, 75, 45, 42, 10,
-18, 3, 39, 76, 80, 48, 48, 41, 44, 21,
--13, -51, -73, -22, -15, -41, 3, -4, -22, 3,
--10, -50, -63, -9, -23, -42, -6, -30, 11, 28,
-15, -11, -29, -39, -57, -71, -23, -40, -33, 20,
--2, -40, -48, -5, -21, -25, 31, 7, 53, 35,
--19, -63, -72, 39, 34, 16, 37, 17, 54, 31,
--18, -49, -28, -27, -40, -29, 4, 4, 19, 11,
--1, -43, -41, 24, 15, -12, -4, -31, -4, 23,
--11, -46, -79, -74, 34, 21, 9, 15, 3, -13,
--16, -51, -56, -55, 8, 62, 50, 30, 43, 14,
--1, -25, -27, -32, -46, -62, -66, -36, 53, 32,
--12, -49, -77, -50, 2, -21, 23, 6, 14, 21,
--5, -47, -58, -77, -105, -14, 30, 9, 73, 44,
--24, -52, -4, 10, 13, 13, 27, 27, 42, 24,
--10, -38, -27, -15, -24, -52, -53, 1, 14, -6,
--17, -45, -13, 2, 19, 53, 83, 79, 76, 43,
--21, -62, -86, -48, 40, 17, 14, -9, 40, 30,
--1, -32, -51, -33, -3, -35, 2, 17, -2, -12,
--21, -60, -85, -70, 33, 73, 58, 37, 67, 36,
--1, -45, -39, 37, 17, 3, 18, -8, 53, 35,
--8, -47, -65, -61, -87, -93, 9, 9, 2, 33,
--13, -55, -56, -19, -29, 14, 17, 6, 55, 28,
-5, 1, -7, -23, -26, -56, -39, 14, 11, -13,
--28, -69, -89, -74, -83, -45, 1, 0, 16, 45,
--3, 5, 91, 104, 119, 111, 97, 76, 72, 39,
-19, 5, -12, -34, -41, -72, -67, 14, 21, 1,
--17, -49, 15, 27, 13, 6, 2, 12, 27, 10,
--10, -30, 18, 36, 93, 87, 87, 69, 58, 26,
-37, 32, 64, 54, 53, 67, 78, 73, 80, 48,
-48, 46, 38, 9, -1, 8, 47, 44, 58, 33,
--23, -61, -88, -76, 27, 14, 9, 36, 36, 10,
--24, -66, -88, -97, -55, 20, 19, 16, 52, 31,
-4, -16, -1, -8, 2, 0, 15, 13, 29, 14,
--9, -44, -66, -72, 8, 32, 37, 38, 46, 16,
--22, -65, -62, 30, 22, 51, 57, 45, 68, 38,
--4, -42, -53, -33, -54, -53, -4, -18, 62, 40,
--5, -37, -61, -41, 35, 15, -2, -3, -12, -28,
--18, -65, -55, 90, 80, 49, 44, 21, 59, 36,
-5, -16, -31, -32, -37, -62, -19, -11, 9, 16,
--22, -60, -67, -51, -61, -35, -5, -18, -27, 24,
--18, -55, -39, -42, -40, 20, 25, 6, 6, 7,
-0, -25, -42, -50, -59, -84, -31, -13, -22, 17,
--32, -73, -100, -89, -21, -10, 18, 38, 31, 23,
--15, -54, -57, -13, -18, -41, -32, 17, 50, 21,
--16, -57, -71, -10, -8, -26, -38, -47, 42, 25,
--17, -58, -82, -7, 33, 3, 30, 11, 13, 24,
--23, -61, -97, -83, 82, 81, 57, 39, 31, 2,
-26, 32, 104, 86, 62, 55, 77, 70, 74, 43,
--8, -29, -33, -52, -74, -73, -17, 14, 39, 25,
--21, -60, -68, -22, 43, 37, 51, 54, 64, 36,
--5, -30, -50, -52, 22, 7, 10, 13, 0, -20,
--15, -53, -61, -34, -50, -25, 15, 6, 0, -14,
--10, -51, -60, 20, 77, 50, 34, 22, 8, -8,
--8, -45, -52, -59, -76, -35, -43, -49, 47, 40,
-41, 44, 53, 40, 41, 30, 38, 31, 46, 24,
-19, 3, -15, -26, -16, -45, -13, 24, 18, -5,
--3, -39, -54, -35, -49, -70, 2, -6, -19, 15,
--13, -53, -36, 6, -3, 45, 50, 30, 33, 10,
-15, -25, -16, -4, -32, 7, 23, 6, 67, 36,
--21, -58, -87, -71, 10, -12, -16, 19, 10, 0,
-9, -15, -6, 25, 31, 7, 30, 28, 20, 2,
-2, -28, -42, -50, -67, -75, 12, 12, -4, 8,
--17, -63, -58, 56, 49, 36, 60, 38, 37, 14,
--13, -48, -38, -29, -44, -25, -20, -33, 38, 20,
-2, -37, -42, -1, -18, -42, 3, -17, -19, 12,
--20, -60, -73, -7, 12, -13, -22, -38, 4, 10,
--8, -41, -63, -65, 42, 63, 45, 31, 31, 0,
--4, -46, -38, -9, -35, 15, 50, 27, 67, 39,
-3, -7, -13, -34, -51, -47, 9, 39, 54, 29,
--29, -71, -89, -52, -39, -6, 3, 2, 38, 28,
--14, -42, -13, -15, -19, 0, 20, 12, 37, 25,
-11, -26, -24, -40, -65, -11, -13, -27, 65, 37,
-0, -31, -46, -17, -21, -45, 11, -2, 25, 24,
-51, 91, 102, 87, 85, 63, 57, 42, 48, 23,
--4, -34, -56, -70, -10, -14, 4, 18, 3, -8,
--23, -59, -39, -44, -42, -14, -10, -23, -4, 17,
--2, 4, 35, 63, 69, 75, 82, 63, 78, 48,
--17, -55, -60, -3, -4, -19, 4, -4, -18, -29,
-2, -20, -36, -50, -32, -59, -16, 30, 16, -6,
--12, -47, 24, 68, 45, 46, 41, 32, 65, 37,
--4, -40, -54, -67, -96, -66, -9, -25, 42, 38,
--15, 13, 58, 58, 84, 104, 119, 104, 89, 51,
--15, -24, -9, -24, -27, -50, -7, 28, 29, 6,
--7, -33, -35, -49, -65, -53, -37, -10, 33, 14,
-31, 19, 46, 72, 67, 45, 83, 68, 63, 41,
--14, -53, -59, -17, 55, 79, 64, 39, 43, 10,
-};
-
-const signed char cdbk_lsp2_vlbr[160]={
--20, -30, -24, 17, 7, -13, -21, 61, 56, 16,
-12, 1, 10, 77, 32, 3, 7, 3, -25, -31,
--4, 2, -36, -83, 18, 5, -5, 5, 11, 23,
--2, -1, -11, -12, -20, -28, 68, 50, -17, -20,
-5, 2, 1, 20, 17, 4, -52, -66, 36, 24,
--4, -10, 7, -15, -32, 80, 37, 8, -13, -29,
-33, 37, 28, 15, 8, 14, 35, 18, 50, 36,
--4, -1, 4, -7, 3, 3, -11, -58, -75, 13,
-13, 21, 24, -11, -12, -38, -72, 33, 15, -12,
--44, -17, 83, 21, 2, 7, 0, 4, 0, -1,
--25, -42, -51, 33, 20, 15, 30, -13, 9, 32,
-6, 2, -8, 7, -38, -77, 6, -13, -7, 32,
-48, 57, 32, -12, -10, -4, 2, -15, -29, -29,
-2, 10, -9, -16, 79, 44, 7, 12, -5, -18,
--23, -29, -35, -3, -3, -18, -34, -3, -39, -50,
--5, -10, -8, -37, -76, 11, -4, -19, 30, 16,
-};
-
-#endif
diff --git a/libspeex/lpc.h b/libspeex/lpc.h
index d64df96..952ecdd 100644
--- a/libspeex/lpc.h
+++ b/libspeex/lpc.h
@@ -35,7 +35,7 @@
#ifndef LPC_H
#define LPC_H
-#include "misc.h"
+#include "arch.h"
void _spx_autocorr(
const spx_word16_t * x, /* in: [0...n-1] samples x */
diff --git a/libspeex/lsp.h b/libspeex/lsp.h
index 9d0345f..648652f 100644
--- a/libspeex/lsp.h
+++ b/libspeex/lsp.h
@@ -51,7 +51,7 @@ Modified by Jean-Marc Valin
#ifndef __AK2LSPD__
#define __AK2LSPD__
-#include "misc.h"
+#include "arch.h"
int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack);
void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack);
diff --git a/libspeex/ltp.h b/libspeex/ltp.h
index bc050c6..1e435bc 100644
--- a/libspeex/ltp.h
+++ b/libspeex/ltp.h
@@ -33,7 +33,7 @@
*/
#include <speex/speex_bits.h>
-#include "misc.h"
+#include "arch.h"
/** LTP parameters. */
typedef struct {
diff --git a/libspeex/math_approx.c b/libspeex/math_approx.c
deleted file mode 100644
index 21af766..0000000
--- a/libspeex/math_approx.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/* Copyright (C) 2002 Jean-Marc Valin
- File: math_approx.c
- Various math approximation functions for Speex
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- - Neither the name of the Xiph.org Foundation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- 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 FOUNDATION 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.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "math_approx.h"
-#include "misc.h"
-
-spx_int16_t spx_ilog2(spx_uint32_t x)
-{
- int r=0;
- if (x>=(spx_int32_t)65536)
- {
- x >>= 16;
- r += 16;
- }
- if (x>=256)
- {
- x >>= 8;
- r += 8;
- }
- if (x>=16)
- {
- x >>= 4;
- r += 4;
- }
- if (x>=4)
- {
- x >>= 2;
- r += 2;
- }
- if (x>=2)
- {
- r += 1;
- }
- return r;
-}
-
-spx_int16_t spx_ilog4(spx_uint32_t x)
-{
- int r=0;
- if (x>=(spx_int32_t)65536)
- {
- x >>= 16;
- r += 8;
- }
- if (x>=256)
- {
- x >>= 8;
- r += 4;
- }
- if (x>=16)
- {
- x >>= 4;
- r += 2;
- }
- if (x>=4)
- {
- r += 1;
- }
- return r;
-}
-
-#ifdef FIXED_POINT
-
-/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
-/*#define C0 3634
-#define C1 21173
-#define C2 -12627
-#define C3 4215*/
-
-/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */
-#define C0 3634
-#define C1 21173
-#define C2 -12627
-#define C3 4204
-
-spx_word16_t spx_sqrt(spx_word32_t x)
-{
- int k;
- spx_word32_t rt;
- k = spx_ilog4(x)-6;
- x = VSHR32(x, (k<<1));
- rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
- rt = VSHR32(rt,7-k);
- return rt;
-}
-
-/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
-
-
-#define A1 16469
-#define A2 2242
-#define A3 1486
-
-spx_word16_t spx_acos(spx_word16_t x)
-{
- int s=0;
- spx_word16_t ret;
- spx_word16_t sq;
- if (x<0)
- {
- s=1;
- x = NEG16(x);
- }
- x = SUB16(16384,x);
-
- x = x >> 1;
- sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
- ret = spx_sqrt(SHL32(EXTEND32(sq),13));
-
- /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
- if (s)
- ret = SUB16(25736,ret);
- return ret;
-}
-
-
-#define K1 8192
-#define K2 -4096
-#define K3 340
-#define K4 -10
-
-spx_word16_t spx_cos(spx_word16_t x)
-{
- spx_word16_t x2;
-
- if (x<12868)
- {
- x2 = MULT16_16_P13(x,x);
- return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
- } else {
- x = SUB16(25736,x);
- x2 = MULT16_16_P13(x,x);
- return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
- }
-}
-
-#define L1 32767
-#define L2 -7651
-#define L3 8277
-#define L4 -626
-
-static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x)
-{
- spx_word16_t x2;
-
- x2 = MULT16_16_P15(x,x);
- return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2))))))));
-}
-
-spx_word16_t spx_cos_norm(spx_word32_t x)
-{
- x = x&0x0001ffff;
- if (x>SHL32(EXTEND32(1), 16))
- x = SUB32(SHL32(EXTEND32(1), 17),x);
- if (x&0x00007fff)
- {
- if (x<SHL32(EXTEND32(1), 15))
- {
- return _spx_cos_pi_2(EXTRACT16(x));
- } else {
- return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x)));
- }
- } else {
- if (x&0x0000ffff)
- return 0;
- else if (x&0x0001ffff)
- return -32767;
- else
- return 32767;
- }
-}
-
-/*
- K0 = 1
- K1 = log(2)
- K2 = 3-4*log(2)
- K3 = 3*log(2) - 2
-*/
-#define D0 16384
-#define D1 11356
-#define D2 3726
-#define D3 1301
-/* Input in Q11 format, output in Q16 */
-static spx_word32_t spx_exp2(spx_word16_t x)
-{
- int integer;
- spx_word16_t frac;
- integer = SHR16(x,11);
- if (integer>14)
- return 0x7fffffff;
- else if (integer < -15)
- return 0;
- frac = SHL16(x-SHL16(integer,11),3);
- frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac))))));
- return VSHR32(EXTEND32(frac), -integer-2);
-}
-
-/* Input in Q11 format, output in Q16 */
-spx_word32_t spx_exp(spx_word16_t x)
-{
- if (x>21290)
- return 0x7fffffff;
- else if (x<-21290)
- return 0;
- else
- return spx_exp2(MULT16_16_P14(23637,x));
-}
-#define M1 32767
-#define M2 -21
-#define M3 -11943
-#define M4 4936
-
-static inline spx_word16_t spx_atan01(spx_word16_t x)
-{
- return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
-}
-
-/* Input in Q15, output in Q14 */
-spx_word16_t spx_atan(spx_word32_t x)
-{
- if (x <= 32767)
- {
- return SHR16(spx_atan01(x),1);
- } else {
- int e = spx_ilog2(x);
- if (e>=29)
- return 25736;
- x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14)));
- return SUB16(25736, SHR16(spx_atan01(x),1));
- }
-}
-#else
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846 /* pi */
-#endif
-
-#define C1 0.9999932946f
-#define C2 -0.4999124376f
-#define C3 0.0414877472f
-#define C4 -0.0012712095f
-
-
-#define SPX_PI_2 1.5707963268
-spx_word16_t spx_cos(spx_word16_t x)
-{
- if (x<SPX_PI_2)
- {
- x *= x;
- return C1 + x*(C2+x*(C3+C4*x));
- } else {
- x = M_PI-x;
- x *= x;
- return NEG16(C1 + x*(C2+x*(C3+C4*x)));
- }
-}
-
-#endif
diff --git a/libspeex/math_approx.h b/libspeex/math_approx.h
index 49cfda6..9ca8307 100644
--- a/libspeex/math_approx.h
+++ b/libspeex/math_approx.h
@@ -35,21 +35,9 @@
#ifndef MATH_APPROX_H
#define MATH_APPROX_H
-#include "misc.h"
+#include "arch.h"
-spx_word16_t spx_cos(spx_word16_t x);
-spx_int16_t spx_ilog2(spx_uint32_t x);
-spx_int16_t spx_ilog4(spx_uint32_t x);
-#ifdef FIXED_POINT
-spx_word16_t spx_sqrt(spx_word32_t x);
-spx_word16_t spx_acos(spx_word16_t x);
-spx_word32_t spx_exp(spx_word16_t x);
-spx_word16_t spx_cos_norm(spx_word32_t x);
-
-/* Input in Q15, output in Q14 */
-spx_word16_t spx_atan(spx_word32_t x);
-
-#else
+#ifndef FIXED_POINT
#define spx_sqrt sqrt
#define spx_acos acos
@@ -57,6 +45,288 @@ spx_word16_t spx_atan(spx_word32_t x);
#define spx_cos_norm(x) (cos((.5f*M_PI)*(x)))
#define spx_atan atan
+/** Generate a pseudo-random number */
+static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
+{
+ const unsigned int jflone = 0x3f800000;
+ const unsigned int jflmsk = 0x007fffff;
+ union {int i; float f;} ran;
+ *seed = 1664525 * *seed + 1013904223;
+ ran.i = jflone | (jflmsk & *seed);
+ ran.f -= 1.5;
+ return 3.4642*std*ran.f;
+}
+
+
#endif
+
+static inline spx_int16_t spx_ilog2(spx_uint32_t x)
+{
+ int r=0;
+ if (x>=(spx_int32_t)65536)
+ {
+ x >>= 16;
+ r += 16;
+ }
+ if (x>=256)
+ {
+ x >>= 8;
+ r += 8;
+ }
+ if (x>=16)
+ {
+ x >>= 4;
+ r += 4;
+ }
+ if (x>=4)
+ {
+ x >>= 2;
+ r += 2;
+ }
+ if (x>=2)
+ {
+ r += 1;
+ }
+ return r;
+}
+
+static inline spx_int16_t spx_ilog4(spx_uint32_t x)
+{
+ int r=0;
+ if (x>=(spx_int32_t)65536)
+ {
+ x >>= 16;
+ r += 8;
+ }
+ if (x>=256)
+ {
+ x >>= 8;
+ r += 4;
+ }
+ if (x>=16)
+ {
+ x >>= 4;
+ r += 2;
+ }
+ if (x>=4)
+ {
+ r += 1;
+ }
+ return r;
+}
+
+#ifdef FIXED_POINT
+
+/** Generate a pseudo-random number */
+static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
+{
+ spx_word32_t res;
+ *seed = 1664525 * *seed + 1013904223;
+ res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
+ return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14));
+}
+
+/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
+/*#define C0 3634
+#define C1 21173
+#define C2 -12627
+#define C3 4215*/
+
+/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */
+#define C0 3634
+#define C1 21173
+#define C2 -12627
+#define C3 4204
+
+static inline spx_word16_t spx_sqrt(spx_word32_t x)
+{
+ int k;
+ spx_word32_t rt;
+ k = spx_ilog4(x)-6;
+ x = VSHR32(x, (k<<1));
+ rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
+ rt = VSHR32(rt,7-k);
+ return rt;
+}
+
+/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
+
+
+#define A1 16469
+#define A2 2242
+#define A3 1486
+
+static inline spx_word16_t spx_acos(spx_word16_t x)
+{
+ int s=0;
+ spx_word16_t ret;
+ spx_word16_t sq;
+ if (x<0)
+ {
+ s=1;
+ x = NEG16(x);
+ }
+ x = SUB16(16384,x);
+
+ x = x >> 1;
+ sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
+ ret = spx_sqrt(SHL32(EXTEND32(sq),13));
+
+ /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
+ if (s)
+ ret = SUB16(25736,ret);
+ return ret;
+}
+
+
+#define K1 8192
+#define K2 -4096
+#define K3 340
+#define K4 -10
+
+static inline spx_word16_t spx_cos(spx_word16_t x)
+{
+ spx_word16_t x2;
+
+ if (x<12868)
+ {
+ x2 = MULT16_16_P13(x,x);
+ return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
+ } else {
+ x = SUB16(25736,x);
+ x2 = MULT16_16_P13(x,x);
+ return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
+ }
+}
+
+#define L1 32767
+#define L2 -7651
+#define L3 8277
+#define L4 -626
+
+static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x)
+{
+ spx_word16_t x2;
+
+ x2 = MULT16_16_P15(x,x);
+ return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2))))))));
+}
+
+static inline spx_word16_t spx_cos_norm(spx_word32_t x)
+{
+ x = x&0x0001ffff;
+ if (x>SHL32(EXTEND32(1), 16))
+ x = SUB32(SHL32(EXTEND32(1), 17),x);
+ if (x&0x00007fff)
+ {
+ if (x<SHL32(EXTEND32(1), 15))
+ {
+ return _spx_cos_pi_2(EXTRACT16(x));
+ } else {
+ return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x)));
+ }
+ } else {
+ if (x&0x0000ffff)
+ return 0;
+ else if (x&0x0001ffff)
+ return -32767;
+ else
+ return 32767;
+ }
+}
+
+/*
+ K0 = 1
+ K1 = log(2)
+ K2 = 3-4*log(2)
+ K3 = 3*log(2) - 2
+*/
+#define D0 16384
+#define D1 11356
+#define D2 3726
+#define D3 1301
+/* Input in Q11 format, output in Q16 */
+static inline spx_word32_t spx_exp2(spx_word16_t x)
+{
+ int integer;
+ spx_word16_t frac;
+ integer = SHR16(x,11);
+ if (integer>14)
+ return 0x7fffffff;
+ else if (integer < -15)
+ return 0;
+ frac = SHL16(x-SHL16(integer,11),3);
+ frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac))))));
+ return VSHR32(EXTEND32(frac), -integer-2);
+}
+
+/* Input in Q11 format, output in Q16 */
+static inline spx_word32_t spx_exp(spx_word16_t x)
+{
+ if (x>21290)
+ return 0x7fffffff;
+ else if (x<-21290)
+ return 0;
+ else
+ return spx_exp2(MULT16_16_P14(23637,x));
+}
+#define M1 32767
+#define M2 -21
+#define M3 -11943
+#define M4 4936
+
+static inline spx_word16_t spx_atan01(spx_word16_t x)
+{
+ return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
+}
+
+#undef M1
+#undef M2
+#undef M3
+#undef M4
+
+/* Input in Q15, output in Q14 */
+static inline spx_word16_t spx_atan(spx_word32_t x)
+{
+ if (x <= 32767)
+ {
+ return SHR16(spx_atan01(x),1);
+ } else {
+ int e = spx_ilog2(x);
+ if (e>=29)
+ return 25736;
+ x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14)));
+ return SUB16(25736, SHR16(spx_atan01(x),1));
+ }
+}
+#else
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846 /* pi */
+#endif
+
+#define C1 0.9999932946f
+#define C2 -0.4999124376f
+#define C3 0.0414877472f
+#define C4 -0.0012712095f
+
+
+#define SPX_PI_2 1.5707963268
+static inline spx_word16_t spx_cos(spx_word16_t x)
+{
+ if (x<SPX_PI_2)
+ {
+ x *= x;
+ return C1 + x*(C2+x*(C3+C4*x));
+ } else {
+ x = M_PI-x;
+ x *= x;
+ return NEG16(C1 + x*(C2+x*(C3+C4*x)));
+ }
+}
+
+#endif
+
+
#endif
diff --git a/libspeex/mdf.c b/libspeex/mdf.c
index 014ea25..d0262c7 100644
--- a/libspeex/mdf.c
+++ b/libspeex/mdf.c
@@ -69,11 +69,12 @@
#include "config.h"
#endif
-#include "misc.h"
+#include "arch.h"
#include "speex/speex_echo.h"
#include "fftwrap.h"
#include "pseudofloat.h"
#include "math_approx.h"
+#include "os_support.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
@@ -87,9 +88,6 @@
#define WEIGHT_SHIFT 0
#endif
-/* If enabled, the transition between blocks is smooth, so there isn't any blocking
-aftifact when adapting. The cost is an extra FFT and a matrix-vector multiply */
-#define SMOOTH_BLOCKS
/* If enabled, the AEC will use a foreground filter and a background filter to be more robust to double-talk
and difficult signals in general. The cost is an extra FFT and a matrix-vector multiply */
#define TWO_PATH
@@ -107,7 +105,7 @@ static const spx_float_t VAR_BACKTRACK = {16384, -12};
#else
-static const spx_float_t MIN_LEAK = .0032f;
+static const spx_float_t MIN_LEAK = .005f;
/* Constants for the two-path filter */
static const spx_float_t VAR1_SMOOTH = .36f;
@@ -367,7 +365,7 @@ static inline void mdf_adjust_prop(const spx_word32_t *W, int N, int M, int P, s
}
for (i=0;i<M;i++)
{
- prop[i] += MULT16_16_Q15(QCONST16(.03f,15),max_sum);
+ prop[i] += MULT16_16_Q15(QCONST16(.1f,15),max_sum);
prop_sum += EXTEND32(prop[i]);
}
for (i=0;i<M;i++)
@@ -386,7 +384,7 @@ static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const sp
{
if (!(rFile && pFile && oFile))
{
- speex_error("Dump files not open");
+ speex_fatal("Dump files not open");
}
fwrite(rec, sizeof(spx_int16_t), len, rFile);
fwrite(play, sizeof(spx_int16_t), len, pFile);
@@ -395,7 +393,7 @@ static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const sp
#endif
/** Creates a new echo canceller state */
-SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers)
+SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers)
{
int i,N,M, C, K;
SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState));
@@ -406,10 +404,10 @@ SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic
K=st->K;
#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");
+ speex_fatal("Opening dump files twice");
+ rFile = fopen("aec_rec.sw", "wb");
+ pFile = fopen("aec_play.sw", "wb");
+ oFile = fopen("aec_out.sw", "wb");
#endif
st->frame_size = frame_size;
@@ -486,7 +484,7 @@ SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic
}
for (i=M-1;i>=0;i--)
{
- st->prop[i] = DIV32(MULT16_16(QCONST16(.99f,15), st->prop[i]),sum);
+ st->prop[i] = DIV32(MULT16_16(QCONST16(.8f,15), st->prop[i]),sum);
}
}
@@ -577,7 +575,7 @@ void speex_echo_state_reset(SpeexEchoState *st)
}
/** Destroys an echo canceller state */
-void mc_echo_state_destroy(SpeexEchoState *st)
+void speex_echo_state_destroy(SpeexEchoState *st)
{
spx_fft_destroy(st->fft_table);
@@ -619,15 +617,14 @@ void mc_echo_state_destroy(SpeexEchoState *st)
#endif
}
-
-void mc_echo_capture2(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out)
+void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out)
{
int i;
/*speex_warning_int("capture with fill level ", st->play_buf_pos/st->frame_size);*/
st->play_buf_started = 1;
if (st->play_buf_pos>=st->frame_size)
{
- mc_echo_cancellation(st, rec, st->play_buf, out);
+ speex_echo_cancellation(st, rec, st->play_buf, out);
st->play_buf_pos -= st->frame_size;
for (i=0;i<st->play_buf_pos;i++)
st->play_buf[i] = st->play_buf[i+st->frame_size];
@@ -643,7 +640,7 @@ void mc_echo_capture2(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *o
}
}
-void mc_echo_playback(SpeexEchoState *st, const spx_int16_t *play)
+void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play)
{
/*speex_warning_int("playback with fill level ", st->play_buf_pos/st->frame_size);*/
if (!st->play_buf_started)
@@ -669,14 +666,14 @@ void mc_echo_playback(SpeexEchoState *st, const spx_int16_t *play)
}
}
-/** Performs echo cancellation on a frame */
-void mc_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout)
+/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */
+void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout)
{
- mc_echo_cancellation(st, in, far_end, out);
+ speex_echo_cancellation(st, in, far_end, out);
}
-/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */
-void mc_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out)
+/** Performs echo cancellation on a frame */
+void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out)
{
int i,j, chan, speak;
int N,M, C, K;
@@ -1120,7 +1117,7 @@ void mc_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_i
#endif
/* We consider that the filter has had minimal adaptation if the following is true*/
- if (!st->adapted && st->sum_adapt > QCONST32(M,15) && MULT16_32_Q15(st->leak_estimate,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy))
+ if (!st->adapted && st->sum_adapt > SHL32(EXTEND32(M),15) && MULT16_32_Q15(st->leak_estimate,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy))
{
st->adapted = 1;
}
@@ -1219,7 +1216,7 @@ void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *residual_echo, in
}
-int mc_echo_ctl(SpeexEchoState *st, int request, void *ptr)
+int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr)
{
switch(request)
{
diff --git a/libspeex/medfilter.c b/libspeex/medfilter.c
index 83872e5..c061ea3 100644
--- a/libspeex/medfilter.c
+++ b/libspeex/medfilter.c
@@ -32,8 +32,12 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "medfilter.h"
-#include "misc.h"
+#include "arch.h"
MedianFilter *median_filter_new(int N)
{
diff --git a/libspeex/misc.c b/libspeex/misc.c
deleted file mode 100644
index df44d86..0000000
--- a/libspeex/misc.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* Copyright (C) 2002-2005 Jean-Marc Valin
- File: misc.c
- Various utility routines for Speex
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- - Neither the name of the Xiph.org Foundation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- 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 FOUNDATION 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.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "misc.h"
-
-#ifdef USER_MISC
-#include "user_misc.h"
-#endif
-
-#ifdef BFIN_ASM
-#include "misc_bfin.h"
-#endif
-
-#ifndef RELEASE
-void print_vec(float *vec, int len, char *name)
-{
- int i;
- printf ("%s ", name);
- for (i=0;i<len;i++)
- printf (" %f", vec[i]);
- printf ("\n");
-}
-#endif
-
-#ifdef FIXED_DEBUG
-long long spx_mips=0;
-#endif
-
-
-#ifndef OVERRIDE_SPEEX_ALLOC
-void *speex_alloc (int size)
-{
- return calloc(size,1);
-}
-#endif
-
-#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH
-void *speex_alloc_scratch (int size)
-{
- return calloc(size,1);
-}
-#endif
-
-#ifndef OVERRIDE_SPEEX_REALLOC
-void *speex_realloc (void *ptr, int size)
-{
- return realloc(ptr, size);
-}
-#endif
-
-#ifndef OVERRIDE_SPEEX_FREE
-void speex_free (void *ptr)
-{
- free(ptr);
-}
-#endif
-
-#ifndef OVERRIDE_SPEEX_FREE_SCRATCH
-void speex_free_scratch (void *ptr)
-{
- free(ptr);
-}
-#endif
-
-#ifndef OVERRIDE_SPEEX_MOVE
-void *speex_move (void *dest, void *src, int n)
-{
- return memmove(dest,src,n);
-}
-#endif
-
-#ifndef OVERRIDE_SPEEX_ERROR
-void speex_error(const char *str)
-{
- fprintf (stderr, "Fatal (internal) error: %s\n", str);
- exit(1);
-}
-#endif
-
-#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
-
-#ifdef FIXED_POINT
-spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
-{
- spx_word32_t res;
- *seed = 1664525 * *seed + 1013904223;
- res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
- return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14));
-}
-#else
-spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
-{
- const unsigned int jflone = 0x3f800000;
- const unsigned int jflmsk = 0x007fffff;
- union {int i; float f;} ran;
- *seed = 1664525 * *seed + 1013904223;
- ran.i = jflone | (jflmsk & *seed);
- ran.f -= 1.5;
- return 3.4642*std*ran.f;
-}
-#endif
-
-#ifndef OVERRIDE_SPEEX_PUTC
-void _speex_putc(int ch, void *file)
-{
- FILE *f = (FILE *)file;
- fprintf(f, "%c", ch);
-}
-#endif
diff --git a/libspeex/misc.h b/libspeex/misc.h
deleted file mode 100644
index c6ea9e7..0000000
--- a/libspeex/misc.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* Copyright (C) 2002 Jean-Marc Valin */
-/**
- @file misc.h
- @brief Various compatibility routines for Speex
-*/
-/*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- - Neither the name of the Xiph.org Foundation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- 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 FOUNDATION 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.
-*/
-
-#ifndef MISC_H
-#define MISC_H
-
-#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_EXTRA_VERSION "" /**< Extra Speex version. */
-#define SPEEX_VERSION "speex-1.2beta1" /**< Speex version string. */
-#endif
-
-/* A couple test to catch stupid option combinations */
-#ifdef FIXED_POINT
-
-#ifdef _USE_SSE
-#error SSE is only for floating-point
-#endif
-#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))
-#error Make up your mind. What CPU do you have?
-#endif
-#ifdef VORBIS_PSYCHO
-#error Vorbis-psy model currently not implemented in fixed-point
-#endif
-
-#else
-
-#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
-#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?
-#endif
-#ifdef FIXED_POINT_DEBUG
-#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?"
-#endif
-
-
-#endif
-
-#include "arch.h"
-
-#ifndef RELEASE
-/** Print a named vector to stdout */
-void print_vec(float *vec, int len, char *name);
-#endif
-
-/** Convert little endian */
-static inline spx_int32_t le_int(spx_int32_t i)
-{
-#ifdef WORDS_BIGENDIAN
- 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);
-
-/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
-void *speex_alloc_scratch (int size);
-
-/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */
-void *speex_realloc (void *ptr, int size);
-
-/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */
-void speex_free (void *ptr);
-
-/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
-void speex_free_scratch (void *ptr);
-
-/** Speex wrapper for mem_move */
-void *speex_move (void *dest, void *src, int n);
-
-/** Abort with an error message to stderr (internal Speex error) */
-void speex_error(const char *str);
-
-/** 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);
-
-/** Speex wrapper for putc */
-void _speex_putc(int ch, void *file);
-
-#endif
diff --git a/libspeex/modes.c b/libspeex/modes.c
index 9a1fe9c..33e031e 100644
--- a/libspeex/modes.c
+++ b/libspeex/modes.c
@@ -43,28 +43,23 @@
#include "sb_celp.h"
#include "nb_celp.h"
#include "vbr.h"
-#include "misc.h"
+#include "arch.h"
#include <math.h>
#ifndef NULL
#define NULL 0
#endif
-#define MAX_IN_SAMPLES 640
-
-const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
/* Extern declarations for all codebooks we use here */
extern const signed char gain_cdbk_nb[];
extern const signed char gain_cdbk_lbr[];
-extern const signed char hexc_table[];
extern const signed char exc_5_256_table[];
extern const signed char exc_5_64_table[];
extern const signed char exc_8_128_table[];
extern const signed char exc_10_32_table[];
extern const signed char exc_10_16_table[];
extern const signed char exc_20_32_table[];
-extern const signed char hexc_10_32_table[];
/* Parameters for Long-Term Prediction (LTP)*/
@@ -150,29 +145,8 @@ static const split_cb_params split_cb_sb = {
0,
};
-#ifndef DISABLE_WIDEBAND
-
-/* Split-VQ innovation for high-band wideband */
-static const split_cb_params split_cb_high = {
- 8, /*subvect_size*/
- 5, /*nb_subvect*/
- hexc_table, /*shape_cb*/
- 7, /*shape_bits*/
- 1,
-};
-/* Split-VQ innovation for high-band wideband */
-static const split_cb_params split_cb_high_lbr = {
- 10, /*subvect_size*/
- 4, /*nb_subvect*/
- hexc_10_32_table, /*shape_cb*/
- 5, /*shape_bits*/
- 0,
-};
-
-#endif
-
/* 2150 bps "vocoder-like" mode for comfort noise */
static const SpeexSubmode nb_submode1 = {
0,
@@ -354,11 +328,7 @@ static const SpeexNBMode nb_mode = {
#else
0.9, 0.6, /* gamma1, gamma2 */
#endif
- .012, /*lag_factor*/
QCONST16(.0002,15), /*lpc_floor*/
-#ifdef EPIC_48K
- 0,
-#endif
{NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7,
&nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
5,
@@ -384,285 +354,9 @@ const SpeexMode speex_nb_mode = {
};
-/* Wideband part */
-
-static const SpeexSubmode wb_submode1 = {
- 0,
- 0,
- 1,
- 0,
- /*LSP quantization*/
- lsp_quant_high,
- lsp_unquant_high,
- /*Pitch quantization*/
- NULL,
- NULL,
- NULL,
- /*No innovation quantization*/
- NULL,
- NULL,
- NULL,
- -1,
- 36
-};
-
-
-static const SpeexSubmode wb_submode2 = {
- 0,
- 0,
- 1,
- 0,
- /*LSP quantization*/
- lsp_quant_high,
- lsp_unquant_high,
- /*Pitch quantization*/
- NULL,
- NULL,
- NULL,
- /*Innovation quantization*/
- split_cb_search_shape_sign,
- split_cb_shape_sign_unquant,
-#ifdef DISABLE_WIDEBAND
- NULL,
-#else
- &split_cb_high_lbr,
-#endif
- -1,
- 112
-};
-
-
-static const SpeexSubmode wb_submode3 = {
- 0,
- 0,
- 1,
- 0,
- /*LSP quantization*/
- lsp_quant_high,
- lsp_unquant_high,
- /*Pitch quantization*/
- NULL,
- NULL,
- NULL,
- /*Innovation quantization*/
- split_cb_search_shape_sign,
- split_cb_shape_sign_unquant,
-#ifdef DISABLE_WIDEBAND
- NULL,
-#else
- &split_cb_high,
-#endif
- -1,
- 192
-};
-
-static const SpeexSubmode wb_submode4 = {
- 0,
- 0,
- 1,
- 1,
- /*LSP quantization*/
- lsp_quant_high,
- lsp_unquant_high,
- /*Pitch quantization*/
- NULL,
- NULL,
- NULL,
- /*Innovation quantization*/
- split_cb_search_shape_sign,
- split_cb_shape_sign_unquant,
-#ifdef DISABLE_WIDEBAND
- NULL,
-#else
- &split_cb_high,
-#endif
- -1,
- 352
-};
-
-
-/* Split-band wideband CELP mode*/
-static const SpeexSBMode sb_wb_mode = {
- &speex_nb_mode,
- 160, /*frameSize*/
- 40, /*subframeSize*/
- 8, /*lpcSize*/
- 640, /*bufSize*/
-#ifdef FIXED_POINT
- 29491, 19661, /* gamma1, gamma2 */
-#else
- 0.9, 0.6, /* gamma1, gamma2 */
-#endif
- .012, /*lag_factor*/
- QCONST16(.0002,15), /*lpc_floor*/
- QCONST16(0.9f,15),
- {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
- 3,
- {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
- {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
- vbr_hb_thresh,
- 5
-};
-
-
-const SpeexMode speex_wb_mode = {
- &sb_wb_mode,
- wb_mode_query,
- "wideband (sub-band CELP)",
- 1,
- 4,
- &sb_encoder_init,
- &sb_encoder_destroy,
- &sb_encode,
- &sb_decoder_init,
- &sb_decoder_destroy,
- &sb_decode,
- &sb_encoder_ctl,
- &sb_decoder_ctl,
-};
-
-
-
-/* "Ultra-wideband" mode stuff */
-
-
-
-/* Split-band "ultra-wideband" (32 kbps) CELP mode*/
-static const SpeexSBMode sb_uwb_mode = {
- &speex_wb_mode,
- 320, /*frameSize*/
- 80, /*subframeSize*/
- 8, /*lpcSize*/
- 1280, /*bufSize*/
-#ifdef FIXED_POINT
- 29491, 19661, /* gamma1, gamma2 */
-#else
- 0.9, 0.6, /* gamma1, gamma2 */
-#endif
- .012, /*lag_factor*/
- QCONST16(.0002,15), /*lpc_floor*/
- QCONST16(0.7f,15),
- {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
- 1,
- {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
- {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
- vbr_uhb_thresh,
- 2
-};
-
-
-const SpeexMode speex_uwb_mode = {
- &sb_uwb_mode,
- wb_mode_query,
- "ultra-wideband (sub-band CELP)",
- 2,
- 4,
- &sb_encoder_init,
- &sb_encoder_destroy,
- &sb_encode,
- &sb_decoder_init,
- &sb_decoder_destroy,
- &sb_decode,
- &sb_encoder_ctl,
- &sb_decoder_ctl,
-};
-
-
-
-
-#ifdef EPIC_48K
-
-extern const signed char gain_cdbk_ulbr[];
-extern const signed char exc_12_32_table[];
-
-/* Parameters for Long-Term Prediction (LTP)*/
-static const ltp_params ltp_params_48k = {
- gain_cdbk_ulbr,
- 3,
- 0
-};
-
-static const split_cb_params split_cb_nb_48k = {
- 12, /*subvect_size*/
- 4, /*nb_subvect*/
- exc_12_32_table, /*shape_cb*/
- 5, /*shape_bits*/
- 0,
-};
-
-
-/* 4.8 kbps very low bit-rate mode */
-static const SpeexSubmode nb_48k_submode = {
- 0,
- 0,
- 0,
- 0,
- /*LSP quantization*/
- lsp_quant_48k,
- lsp_unquant_48k,
- /*No pitch quantization*/
- pitch_search_3tap,
- pitch_unquant_3tap,
- &ltp_params_48k,
- /*Innovation quantization*/
- split_cb_search_shape_sign,
- split_cb_shape_sign_unquant,
- &split_cb_nb_48k,
- QCONST16(.7,15),
- 144
-};
-
-
-/* Special, non-standard 4.8 kbps mode */
-static const SpeexNBMode nb_48k_mode = {
- 240, /*frameSize*/
- 48, /*subframeSize*/
- 10, /*lpcSize*/
- 17, /*pitchStart*/
- 144, /*pitchEnd*/
- 0.9, /*gamma1*/
- 0.6, /*gamma2*/
- .01, /*lag_factor*/
- QCONST16(.0003,15), /*lpc_floor*/
- 1,
- {NULL, NULL, &nb_48k_submode, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
- 2,
- {2,2,2,2,2,2,2,2,2,2,2}
-};
-
-
-/* Default mode for narrowband */
-const SpeexMode speex_nb_48k_mode = {
- &nb_48k_mode,
- nb_mode_query,
- "narrowband 4.8 kbps",
- 1000,
- 4,
- &nb_encoder_init,
- &nb_encoder_destroy,
- &nb_encode,
- &nb_decoder_init,
- &nb_decoder_destroy,
- &nb_decode,
- &nb_encoder_ctl,
- &nb_decoder_ctl,
-};
-
-
-#endif
int speex_mode_query(const SpeexMode *mode, int request, void *ptr)
{
return mode->query(mode->mode, request, ptr);
}
-const SpeexMode * speex_lib_get_mode (int mode)
-{
-#ifdef EPIC_48K
- if (mode == SPEEX_MODEID_NB_48K) return &speex_nb_48k_mode;
-#endif
-
- if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL;
-
- return speex_mode_list[mode];
-}
diff --git a/libspeex/modes.h b/libspeex/modes.h
index 5bf1971..26e2d86 100644
--- a/libspeex/modes.h
+++ b/libspeex/modes.h
@@ -38,7 +38,7 @@
#include <speex/speex.h>
#include <speex/speex_bits.h>
-#include "misc.h"
+#include "arch.h"
#define NB_SUBMODES 16
#define NB_SUBMODE_BITS 4
@@ -98,7 +98,7 @@ typedef struct SpeexSubmode {
lsp_quant_func lsp_quant; /**< LSP quantization function */
lsp_unquant_func lsp_unquant; /**< LSP unquantization function */
- /*Lont-term predictor functions*/
+ /*Long-term predictor functions*/
ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */
ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */
const void *ltp_params; /**< Pitch parameters (options) */
@@ -123,13 +123,8 @@ typedef struct SpeexNBMode {
spx_word16_t gamma1; /**< Perceptual filter parameter #1 */
spx_word16_t gamma2; /**< Perceptual filter parameter #2 */
- float lag_factor; /**< Lag-windowing parameter */
spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */
-#ifdef EPIC_48K
- int lbr48k; /**< 1 for the special 4.8 kbps mode */
-#endif
-
const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */
int defaultSubmode; /**< Default sub-mode to use when encoding */
int quality_map[11]; /**< Mode corresponding to each quality setting */
@@ -142,10 +137,8 @@ typedef struct SpeexSBMode {
int frameSize; /**< Size of frames used for encoding */
int subframeSize; /**< Size of sub-frames used for encoding */
int lpcSize; /**< Order of LPC filter */
- int bufSize; /**< Signal buffer size in encoder */
spx_word16_t gamma1; /**< Perceptual filter parameter #1 */
spx_word16_t gamma2; /**< Perceptual filter parameter #1 */
- float lag_factor; /**< Lag-windowing parameter */
spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */
spx_word16_t folding_gain;
@@ -153,7 +146,9 @@ typedef struct SpeexSBMode {
int defaultSubmode; /**< Default sub-mode to use when encoding */
int low_quality_map[11]; /**< Mode corresponding to each quality setting */
int quality_map[11]; /**< Mode corresponding to each quality setting */
+#ifndef DISABLE_VBR
const float (*vbr_thresh)[11];
+#endif
int nb_modes;
} SpeexSBMode;
diff --git a/libspeex/modes_wb.c b/libspeex/modes_wb.c
new file mode 100644
index 0000000..4b575b2
--- /dev/null
+++ b/libspeex/modes_wb.c
@@ -0,0 +1,300 @@
+/* Copyright (C) 2002-2007 Jean-Marc Valin
+ File: modes.c
+
+ Describes the wideband modes of the codec
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of the Xiph.org Foundation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ 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 FOUNDATION 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "modes.h"
+#include "ltp.h"
+#include "quant_lsp.h"
+#include "cb_search.h"
+#include "sb_celp.h"
+#include "nb_celp.h"
+#include "vbr.h"
+#include "arch.h"
+#include <math.h>
+#include "os_support.h"
+
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
+
+extern const signed char hexc_table[];
+extern const signed char hexc_10_32_table[];
+
+#ifndef DISABLE_WIDEBAND
+
+/* Split-VQ innovation for high-band wideband */
+static const split_cb_params split_cb_high = {
+ 8, /*subvect_size*/
+ 5, /*nb_subvect*/
+ hexc_table, /*shape_cb*/
+ 7, /*shape_bits*/
+ 1,
+};
+
+
+/* Split-VQ innovation for high-band wideband */
+static const split_cb_params split_cb_high_lbr = {
+ 10, /*subvect_size*/
+ 4, /*nb_subvect*/
+ hexc_10_32_table, /*shape_cb*/
+ 5, /*shape_bits*/
+ 0,
+};
+
+#endif
+
+
+static const SpeexSubmode wb_submode1 = {
+ 0,
+ 0,
+ 1,
+ 0,
+ /*LSP quantization*/
+ lsp_quant_high,
+ lsp_unquant_high,
+ /*Pitch quantization*/
+ NULL,
+ NULL,
+ NULL,
+ /*No innovation quantization*/
+ NULL,
+ NULL,
+ NULL,
+ -1,
+ 36
+};
+
+
+static const SpeexSubmode wb_submode2 = {
+ 0,
+ 0,
+ 1,
+ 0,
+ /*LSP quantization*/
+ lsp_quant_high,
+ lsp_unquant_high,
+ /*Pitch quantization*/
+ NULL,
+ NULL,
+ NULL,
+ /*Innovation quantization*/
+ split_cb_search_shape_sign,
+ split_cb_shape_sign_unquant,
+#ifdef DISABLE_WIDEBAND
+ NULL,
+#else
+ &split_cb_high_lbr,
+#endif
+ -1,
+ 112
+};
+
+
+static const SpeexSubmode wb_submode3 = {
+ 0,
+ 0,
+ 1,
+ 0,
+ /*LSP quantization*/
+ lsp_quant_high,
+ lsp_unquant_high,
+ /*Pitch quantization*/
+ NULL,
+ NULL,
+ NULL,
+ /*Innovation quantization*/
+ split_cb_search_shape_sign,
+ split_cb_shape_sign_unquant,
+#ifdef DISABLE_WIDEBAND
+ NULL,
+#else
+ &split_cb_high,
+#endif
+ -1,
+ 192
+};
+
+static const SpeexSubmode wb_submode4 = {
+ 0,
+ 0,
+ 1,
+ 1,
+ /*LSP quantization*/
+ lsp_quant_high,
+ lsp_unquant_high,
+ /*Pitch quantization*/
+ NULL,
+ NULL,
+ NULL,
+ /*Innovation quantization*/
+ split_cb_search_shape_sign,
+ split_cb_shape_sign_unquant,
+#ifdef DISABLE_WIDEBAND
+ NULL,
+#else
+ &split_cb_high,
+#endif
+ -1,
+ 352
+};
+
+
+/* Split-band wideband CELP mode*/
+static const SpeexSBMode sb_wb_mode = {
+ &speex_nb_mode,
+ 160, /*frameSize*/
+ 40, /*subframeSize*/
+ 8, /*lpcSize*/
+#ifdef FIXED_POINT
+ 29491, 19661, /* gamma1, gamma2 */
+#else
+ 0.9, 0.6, /* gamma1, gamma2 */
+#endif
+ QCONST16(.0002,15), /*lpc_floor*/
+ QCONST16(0.9f,15),
+ {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
+ 3,
+ {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
+ {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
+#ifndef DISABLE_VBR
+ vbr_hb_thresh,
+#endif
+ 5
+};
+
+
+const SpeexMode speex_wb_mode = {
+ &sb_wb_mode,
+ wb_mode_query,
+ "wideband (sub-band CELP)",
+ 1,
+ 4,
+ &sb_encoder_init,
+ &sb_encoder_destroy,
+ &sb_encode,
+ &sb_decoder_init,
+ &sb_decoder_destroy,
+ &sb_decode,
+ &sb_encoder_ctl,
+ &sb_decoder_ctl,
+};
+
+
+
+/* "Ultra-wideband" mode stuff */
+
+
+
+/* Split-band "ultra-wideband" (32 kbps) CELP mode*/
+static const SpeexSBMode sb_uwb_mode = {
+ &speex_wb_mode,
+ 320, /*frameSize*/
+ 80, /*subframeSize*/
+ 8, /*lpcSize*/
+#ifdef FIXED_POINT
+ 29491, 19661, /* gamma1, gamma2 */
+#else
+ 0.9, 0.6, /* gamma1, gamma2 */
+#endif
+ QCONST16(.0002,15), /*lpc_floor*/
+ QCONST16(0.7f,15),
+ {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
+ 1,
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
+ {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+#ifndef DISABLE_VBR
+ vbr_uhb_thresh,
+#endif
+ 2
+};
+
+int wb_mode_query(const void *mode, int request, void *ptr)
+{
+ const SpeexSBMode *m = (const SpeexSBMode*)mode;
+
+ switch (request)
+ {
+ case SPEEX_MODE_FRAME_SIZE:
+ *((int*)ptr)=2*m->frameSize;
+ break;
+ case SPEEX_SUBMODE_BITS_PER_FRAME:
+ if (*((int*)ptr)==0)
+ *((int*)ptr) = SB_SUBMODE_BITS+1;
+ else if (m->submodes[*((int*)ptr)]==NULL)
+ *((int*)ptr) = -1;
+ else
+ *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
+ break;
+ default:
+ speex_warning_int("Unknown wb_mode_query request: ", request);
+ return -1;
+ }
+ return 0;
+}
+
+
+const SpeexMode speex_uwb_mode = {
+ &sb_uwb_mode,
+ wb_mode_query,
+ "ultra-wideband (sub-band CELP)",
+ 2,
+ 4,
+ &sb_encoder_init,
+ &sb_encoder_destroy,
+ &sb_encode,
+ &sb_decoder_init,
+ &sb_decoder_destroy,
+ &sb_decode,
+ &sb_encoder_ctl,
+ &sb_decoder_ctl,
+};
+
+/* We have defined speex_lib_get_mode() as a macro in speex.h */
+#undef speex_lib_get_mode
+
+const SpeexMode * speex_lib_get_mode (int mode)
+{
+ if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL;
+
+ return speex_mode_list[mode];
+}
+
+
+
diff --git a/libspeex/nb_celp.c b/libspeex/nb_celp.c
index 1828aed..b1d8592 100644
--- a/libspeex/nb_celp.c
+++ b/libspeex/nb_celp.c
@@ -45,8 +45,9 @@
#include "vq.h"
#include <speex/speex_bits.h>
#include "vbr.h"
-#include "misc.h"
+#include "arch.h"
#include "math_approx.h"
+#include "os_support.h"
#include <speex/speex_callbacks.h>
#ifdef VORBIS_PSYCHO
@@ -107,6 +108,7 @@ const float exc_gain_quant_scal1[2]={0.70469f, 1.05127f};
#define sqr(x) ((x)*(x))
+extern const spx_word16_t lag_window[];
extern const spx_word16_t lpc_window[];
void *nb_encoder_init(const SpeexMode *m)
@@ -136,7 +138,6 @@ void *nb_encoder_init(const SpeexMode *m)
st->gamma2=mode->gamma2;
st->min_pitch=mode->pitchStart;
st->max_pitch=mode->pitchEnd;
- st->lag_factor=mode->lag_factor;
st->lpc_floor = mode->lpc_floor;
st->submodes=mode->submodes;
@@ -144,9 +145,6 @@ void *nb_encoder_init(const SpeexMode *m)
st->bounded_pitch = 1;
st->encode_submode = 1;
-#ifdef EPIC_48K
- st->lbr_48k=mode->lbr48k;
-#endif
#ifdef VORBIS_PSYCHO
st->psy = vorbis_psy_init(8000, 256);
@@ -168,17 +166,13 @@ void *nb_encoder_init(const SpeexMode *m)
st->window= lpc_window;
/* Create the window for autocorrelation (lag-windowing) */
- st->lagWindow = (spx_word16_t*)speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t));
- for (i=0;i<st->lpcSize+1;i++)
- st->lagWindow[i]=16384*exp(-.5*sqr(2*M_PI*st->lag_factor*i));
+ st->lagWindow = lag_window;
st->old_lsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
st->first = 1;
for (i=0;i<st->lpcSize;i++)
- {
- st->old_lsp[i]=LSP_SCALING*(M_PI*((float)(i+1)))/(st->lpcSize+1);
- }
+ st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
@@ -191,6 +185,7 @@ void *nb_encoder_init(const SpeexMode *m)
st->pitch = (int*)speex_alloc((st->nbSubframes)*sizeof(int));
+#ifndef DISABLE_VBR
st->vbr = (VBRState*)speex_alloc(sizeof(VBRState));
vbr_init(st->vbr);
st->vbr_quality = 8;
@@ -198,18 +193,21 @@ void *nb_encoder_init(const SpeexMode *m)
st->vbr_max = 0;
st->vad_enabled = 0;
st->dtx_enabled = 0;
+ st->dtx_count=0;
st->abr_enabled = 0;
st->abr_drift = 0;
+ st->abr_drift2 = 0;
+ st->abr_drift = 0;
+#endif /* #ifndef DISABLE_VBR */
st->plc_tuning = 2;
st->complexity=2;
st->sampling_rate=8000;
- st->dtx_count=0;
st->isWideband = 0;
st->highpass_enabled = 1;
#ifdef ENABLE_VALGRIND
- VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
+ VALGRIND_MAKE_READABLE(st, NB_ENC_STACK);
#endif
return st;
}
@@ -227,8 +225,6 @@ void nb_encoder_destroy(void *state)
speex_free (st->old_qlsp);
speex_free (st->swBuf);
- speex_free (st->lagWindow);
-
speex_free (st->old_lsp);
speex_free (st->mem_sp);
speex_free (st->mem_sw);
@@ -238,8 +234,10 @@ void nb_encoder_destroy(void *state)
speex_free (st->pi_gain);
speex_free (st->pitch);
+#ifndef DISABLE_VBR
vbr_destroy(st->vbr);
speex_free (st->vbr);
+#endif /* #ifndef DISABLE_VBR */
#ifdef VORBIS_PSYCHO
vorbis_psy_destroy(st->psy);
@@ -276,10 +274,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
char *stack;
VARDECL(spx_word16_t *syn_resp);
VARDECL(spx_word16_t *real_exc);
-#ifdef EPIC_48K
- int pitch_half[2];
- int ol_pitch_id=0;
-#endif
+
spx_word32_t ener=0;
spx_word16_t fine_gain;
spx_word16_t *in = (spx_word16_t*)vin;
@@ -355,8 +350,11 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
/*Open-loop pitch*/
- if (st->complexity>2 || !st->submodes[st->submodeID] || st->vbr_enabled || st->vad_enabled || SUBMODE(forced_pitch_gain) ||
- SUBMODE(lbr_pitch) != -1)
+ if (!st->submodes[st->submodeID] || (st->complexity>2 && SUBMODE(have_subframe_gain)<3) || SUBMODE(forced_pitch_gain) || SUBMODE(lbr_pitch) != -1
+#ifndef DISABLE_VBR
+ || st->vbr_enabled || st->vad_enabled
+#endif
+ )
{
int nol_pitch[6];
spx_word16_t nol_pitch_coef[6];
@@ -393,19 +391,6 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
ol_pitch/=2;*/
/*ol_pitch_coef = sqrt(ol_pitch_coef);*/
-#ifdef EPIC_48K
- if (st->lbr_48k)
- {
- if (ol_pitch < st->min_pitch+2)
- ol_pitch = st->min_pitch+2;
- if (ol_pitch > st->max_pitch-2)
- ol_pitch = st->max_pitch-2;
- open_loop_nbest_pitch(st->sw, ol_pitch-2, ol_pitch+2, st->frameSize>>1,
- &pitch_half[0], nol_pitch_coef, 1, stack);
- open_loop_nbest_pitch(st->sw+(st->frameSize>>1), pitch_half[0]-1, pitch_half[0]+2, st->frameSize>>1,
- &pitch_half[1], nol_pitch_coef, 1, stack);
- }
-#endif
} else {
ol_pitch=0;
ol_pitch_coef=0;
@@ -419,28 +404,9 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
fir_mem16(st->exc, interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc, stack);
/* Compute open-loop excitation gain */
-#ifdef EPIC_48K
- if (st->lbr_48k)
- {
- float ol1=0,ol2=0;
- float ol_gain2;
- ol1 = compute_rms16(st->exc, st->frameSize>>1);
- ol2 = compute_rms16(st->exc+(st->frameSize>>1), st->frameSize>>1);
- ol1 *= ol1*(st->frameSize>>1);
- ol2 *= ol2*(st->frameSize>>1);
-
- ol_gain2=ol1;
- if (ol2>ol1)
- ol_gain2=ol2;
- ol_gain2 = sqrt(2*ol_gain2*(ol1+ol2))*1.3*(1-.5*GAIN_SCALING_1*GAIN_SCALING_1*ol_pitch_coef*ol_pitch_coef);
-
- ol_gain=SHR32(sqrt(1+ol_gain2/st->frameSize),SIG_SHIFT);
-
- } else
-#endif
{
spx_word16_t g = compute_rms16(st->exc, st->frameSize);
- if (ol_pitch>0)
+ if (st->submodeID!=1 && ol_pitch>0)
ol_gain = MULT16_16(g, MULT16_16_Q14(QCONST16(1.1,14),
spx_sqrt(QCONST32(1.,28)-MULT16_32_Q15(QCONST16(.8,15),SHL32(MULT16_16(ol_pitch_coef,ol_pitch_coef),16)))));
else
@@ -461,6 +427,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
#endif
/*VBR stuff*/
+#ifndef DISABLE_VBR
if (st->vbr && (st->vbr_enabled||st->vad_enabled))
{
float lsp_dist=0;
@@ -572,22 +539,16 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
} else {
st->relative_quality = -1;
}
+#endif /* #ifndef DISABLE_VBR */
if (st->encode_submode)
{
-#ifdef EPIC_48K
- if (!st->lbr_48k) {
-#endif
+ /* First, transmit a zero for narrowband */
+ speex_bits_pack(bits, 0, 1);
- /* First, transmit a zero for narrowband */
- speex_bits_pack(bits, 0, 1);
+ /* Transmit the sub-mode we use for this frame */
+ speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);
- /* Transmit the sub-mode we use for this frame */
- speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);
-
-#ifdef EPIC_48K
- }
-#endif
}
/* If null mode (no transmission), just set a couple things to zero*/
@@ -626,35 +587,6 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
qlsp[i]=lsp[i];
#endif
-#ifdef EPIC_48K
- if (st->lbr_48k) {
- speex_bits_pack(bits, pitch_half[0]-st->min_pitch, 7);
- speex_bits_pack(bits, pitch_half[1]-pitch_half[0]+1, 2);
-
- {
- int quant = (int)floor(.5+7.4*GAIN_SCALING_1*ol_pitch_coef);
- if (quant>7)
- quant=7;
- if (quant<0)
- quant=0;
- ol_pitch_id=quant;
- speex_bits_pack(bits, quant, 3);
- ol_pitch_coef=GAIN_SCALING*0.13514*quant;
-
- }
- {
- int qe = (int)(floor(.5+2.1*log(ol_gain*1.0/SIG_SCALING)))-2;
- if (qe<0)
- qe=0;
- if (qe>15)
- qe=15;
- ol_gain = exp((qe+2)/2.1)*SIG_SCALING;
- speex_bits_pack(bits, qe, 4);
- }
-
- } else {
-#endif
-
/*If we use low bit-rate pitch mode, transmit open-loop pitch*/
if (SUBMODE(lbr_pitch)!=-1)
{
@@ -664,13 +596,19 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
if (SUBMODE(forced_pitch_gain))
{
int quant;
+ /* This just damps the pitch a bit, because it tends to be too aggressive when forced */
+ ol_pitch_coef = MULT16_16_Q15(QCONST16(.9,15), ol_pitch_coef);
+#ifdef FIXED_POINT
+ quant = PSHR16(MULT16_16_16(15, ol_pitch_coef),GAIN_SHIFT);
+#else
quant = (int)floor(.5+15*ol_pitch_coef*GAIN_SCALING_1);
+#endif
if (quant>15)
quant=15;
if (quant<0)
quant=0;
speex_bits_pack(bits, quant, 4);
- ol_pitch_coef=GAIN_SCALING*0.066667*quant;
+ ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT));
}
@@ -695,10 +633,6 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
#endif
-#ifdef EPIC_48K
- }
-#endif
-
/* Special case for first frame */
if (st->first)
@@ -724,15 +658,6 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
spx_word16_t *exc;
int pitch;
int response_bound = st->subframeSize;
-#ifdef EPIC_48K
- if (st->lbr_48k)
- {
- if (sub*2 < st->nbSubframes)
- ol_pitch = pitch_half[0];
- else
- ol_pitch = pitch_half[1];
- }
-#endif
/* Offset relative to start of frame */
offset = st->subframeSize*sub;
@@ -787,18 +712,15 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
/*print_vec(st->bw_lpc1, 10, "bw_lpc");*/
#endif
+ /*FIXME: This will break if we change the window size */
+ speex_assert(st->windowSize-st->frameSize == st->subframeSize);
+ if (sub==0)
{
- /*FIXME: This will break if we change the window size */
- if (st->windowSize-st->frameSize != st->subframeSize)
- speex_error("windowSize-frameSize != subframeSize");
- if (sub==0)
- {
- for (i=0;i<st->subframeSize;i++)
- real_exc[i] = sw[i] = st->winBuf[i];
- } else {
- for (i=0;i<st->subframeSize;i++)
- real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)];
- }
+ for (i=0;i<st->subframeSize;i++)
+ real_exc[i] = sw[i] = st->winBuf[i];
+ } else {
+ for (i=0;i<st->subframeSize;i++)
+ real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)];
}
fir_mem16(real_exc, interp_qlpc, real_exc, st->subframeSize, st->lpcSize, st->mem_exc2, stack);
@@ -845,7 +767,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
exc[i]=0;
/* If we have a long-term predictor (otherwise, something's wrong) */
- if (SUBMODE(ltp_quant))
+ speex_assert (SUBMODE(ltp_quant));
{
int pit_min, pit_max;
/* Long-term prediction */
@@ -874,30 +796,14 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
if (st->bounded_pitch && pit_max>offset)
pit_max=offset;
-#ifdef EPIC_48K
- if (st->lbr_48k)
- {
- pitch = SUBMODE(ltp_quant)(target, sw, interp_qlpc, bw_lpc1, bw_lpc2,
- exc32, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef,
- st->lpcSize, st->subframeSize, bits, stack,
- exc, syn_resp, st->complexity, ol_pitch_id, st->plc_tuning, &st->cumul_gain);
- } else {
-#endif
-
/* Perform pitch search */
pitch = SUBMODE(ltp_quant)(target, sw, interp_qlpc, bw_lpc1, bw_lpc2,
exc32, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef,
st->lpcSize, st->subframeSize, bits, stack,
exc, syn_resp, st->complexity, 0, st->plc_tuning, &st->cumul_gain);
-#ifdef EPIC_48K
- }
-#endif
st->pitch[sub]=pitch;
- } else {
- speex_error ("No pitch prediction, what's wrong");
}
-
/* Quantization of innovation */
for (i=0;i<st->subframeSize;i++)
innov[i]=0;
@@ -944,7 +850,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
signal_div(target, target, ener, st->subframeSize);
/* Quantize innovation */
- if (SUBMODE(innovation_quant))
+ speex_assert (SUBMODE(innovation_quant));
{
/* Codebook search */
SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2,
@@ -980,11 +886,8 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
{
st->innov_rms_save[sub] = compute_rms(innov, st->subframeSize);
}
- } else {
- speex_error("No fixed codebook");
}
-
for (i=0;i<st->subframeSize;i++)
sw[i] = exc[i];
/* Final signal synthesis from excitation */
@@ -1015,9 +918,11 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
if (st->submodeID==1)
{
+#ifndef DISABLE_VBR
if (st->dtx_count)
speex_bits_pack(bits, 15, 4);
else
+#endif
speex_bits_pack(bits, 0, 4);
}
@@ -1053,9 +958,6 @@ void *nb_decoder_init(const SpeexMode *m)
st->encode_submode = 1;
-#ifdef EPIC_48K
- st->lbr_48k=mode->lbr48k;
-#endif
st->first=1;
/* Codec parameters, should eventually have several "modes"*/
@@ -1101,7 +1003,7 @@ void *nb_decoder_init(const SpeexMode *m)
st->highpass_enabled = 1;
#ifdef ENABLE_VALGRIND
- VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
+ VALGRIND_MAKE_READABLE(st, NB_DEC_STACK);
#endif
return st;
}
@@ -1195,7 +1097,9 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
st->pitch_gain_buf_idx = 0;
}
-
+/* Just so we don't need to carry the complete wideband mode information */
+static const int wb_skip_table[8] = {0, 36, 112, 192, 352, 0, 0, 0};
+
int nb_decode(void *state, SpeexBits *bits, void *vout)
{
DecState *st;
@@ -1215,10 +1119,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
VARDECL(spx_coef_t *ak);
VARDECL(spx_lsp_t *qlsp);
spx_word16_t pitch_average=0;
-#ifdef EPIC_48K
- int pitch_half[2] = {0, 0};
- int ol_pitch_id=0;
-#endif
+
spx_word16_t *out = (spx_word16_t*)vout;
VARDECL(spx_lsp_t *interp_qlsp);
@@ -1240,9 +1141,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
if (st->encode_submode)
{
-#ifdef EPIC_48K
- if (!st->lbr_48k) {
-#endif
/* Search for next narrowband block (handle requests, skip wideband blocks) */
do {
@@ -1254,7 +1152,8 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
int submode;
int advance;
advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
- speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);
+ /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/
+ advance = wb_skip_table[submode];
if (advance < 0)
{
speex_notify("Invalid mode encountered. The stream is corrupted.");
@@ -1269,7 +1168,8 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
if (wideband)
{
advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
- speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);
+ /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/
+ advance = wb_skip_table[submode];
if (advance < 0)
{
speex_notify("Invalid mode encountered. The stream is corrupted.");
@@ -1313,9 +1213,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
/* Get the sub-mode that was used */
st->submodeID = m;
-#ifdef EPIC_48K
- }
-#endif
}
}
@@ -1330,10 +1227,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
ALLOC(lpc, st->lpcSize, spx_coef_t);
bw_lpc(QCONST16(0.93f,15), st->interp_qlpc, lpc, st->lpcSize);
{
- float innov_gain=0;
- float pgain=GAIN_SCALING_1*st->last_pitch_gain;
- if (pgain>.6)
- pgain=.6;
+ spx_word16_t innov_gain=0;
/* FIXME: This was innov, not exc */
innov_gain = compute_rms16(st->exc, st->frameSize);
for (i=0;i<st->frameSize;i++)
@@ -1381,23 +1275,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
st->old_qlsp[i] = qlsp[i];
}
-#ifdef EPIC_48K
- if (st->lbr_48k) {
- pitch_half[0] = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);
- pitch_half[1] = pitch_half[0]+speex_bits_unpack_unsigned(bits, 2)-1;
-
- ol_pitch_id = speex_bits_unpack_unsigned(bits, 3);
- ol_pitch_coef=GAIN_SCALING*0.13514*ol_pitch_id;
-
- {
- int qe;
- qe = speex_bits_unpack_unsigned(bits, 4);
- ol_gain = SIG_SCALING*exp((qe+2)/2.1),SIG_SHIFT;
- }
-
- } else {
-#endif
-
/* Get open-loop pitch estimation for low bit-rate pitch coding */
if (SUBMODE(lbr_pitch)!=-1)
{
@@ -1408,7 +1285,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
{
int quant;
quant = speex_bits_unpack_unsigned(bits, 4);
- ol_pitch_coef=GAIN_SCALING*0.066667*quant;
+ ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT));
}
/* Get global excitation gain */
@@ -1422,9 +1299,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
ol_gain = SIG_SCALING*exp(qe/3.5);
#endif
}
-#ifdef EPIC_48K
- }
-#endif
ALLOC(ak, st->lpcSize, spx_coef_t);
ALLOC(innov, st->subframeSize, spx_sig_t);
@@ -1452,16 +1326,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
spx_word16_t *innov_save = NULL;
spx_word16_t tmp;
-#ifdef EPIC_48K
- if (st->lbr_48k)
- {
- if (sub*2 < st->nbSubframes)
- ol_pitch = pitch_half[0];
- else
- ol_pitch = pitch_half[1];
- }
-#endif
-
/* Offset relative to start of frame */
offset = st->subframeSize*sub;
/* Excitation */
@@ -1477,7 +1341,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
exc[i]=0;
/*Adaptive codebook contribution*/
- if (SUBMODE(ltp_unquant))
+ speex_assert (SUBMODE(ltp_unquant));
{
int pit_min, pit_max;
/* Handle pitch constraints if any */
@@ -1510,22 +1374,11 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
}
-#ifdef EPIC_48K
- if (st->lbr_48k)
- {
- SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),
- st->subframeSize, &pitch, &pitch_gain[0], bits, stack,
- st->count_lost, offset, st->last_pitch_gain, ol_pitch_id);
- } else {
-#endif
- SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),
- st->subframeSize, &pitch, &pitch_gain[0], bits, stack,
- st->count_lost, offset, st->last_pitch_gain, 0);
+ SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),
+ st->subframeSize, &pitch, &pitch_gain[0], bits, stack,
+ st->count_lost, offset, st->last_pitch_gain, 0);
-#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. */
@@ -1542,8 +1395,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
if (tmp > best_pitch_gain)
best_pitch_gain = tmp;
}
- } else {
- speex_error("No pitch prediction, what's wrong");
}
/* Unquantize the innovation */
@@ -1567,16 +1418,14 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
ener = ol_gain;
}
- if (SUBMODE(innovation_unquant))
+ speex_assert (SUBMODE(innovation_unquant));
{
/*Fixed codebook contribution*/
SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);
/* De-normalize innovation and update excitation */
-#ifdef FIXED_POINT
- signal_mul(innov, innov, ener, st->subframeSize);
-#else
+
signal_mul(innov, innov, ener, st->subframeSize);
-#endif
+
/* Decode second codebook (only for some modes) */
if (SUBMODE(double_codebook))
{
@@ -1599,39 +1448,40 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
for (i=0;i<st->subframeSize;i++)
innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT));
}
- } else {
- speex_error("No fixed codebook");
}
/*Vocoder mode*/
if (st->submodeID==1)
{
- float g=ol_pitch_coef*GAIN_SCALING_1;
-
+ spx_word16_t g=ol_pitch_coef;
+ g=MULT16_16_P14(QCONST16(1.5f,14),(g-QCONST16(.2f,6)));
+ if (g<0)
+ g=0;
+ if (g>GAIN_SCALING)
+ g=GAIN_SCALING;
for (i=0;i<st->subframeSize;i++)
exc[i]=0;
while (st->voc_offset<st->subframeSize)
{
+ /* exc[st->voc_offset]= g*sqrt(2*ol_pitch)*ol_gain;
+ Not quite sure why we need the factor of two in the sqrt */
if (st->voc_offset>=0)
- exc[st->voc_offset]=sqrt(1.0*ol_pitch);
+ exc[st->voc_offset]=MULT16_16(spx_sqrt(MULT16_16_16(2,ol_pitch)),EXTRACT16(PSHR32(MULT16_16(g,PSHR32(ol_gain,SIG_SHIFT)),6)));
st->voc_offset+=ol_pitch;
}
st->voc_offset -= st->subframeSize;
-
- g=.5+2*(g-.6);
- if (g<0)
- g=0;
- if (g>1)
- g=1;
+
for (i=0;i<st->subframeSize;i++)
{
spx_word16_t exci=exc[i];
- /* FIXME: cleanup the innov[i]/SIG_SCALING */
- exc[i]=.8*g*exc[i]*PSHR32(ol_gain,SIG_SHIFT) + .6*g*st->voc_m1*PSHR32(ol_gain,SIG_SHIFT) + (1-.5*g)*PSHR32(innov[i],SIG_SHIFT) - .5*g*PSHR32(st->voc_m2,SIG_SHIFT);
+ exc[i]= ADD16(ADD16(MULT16_16_Q15(QCONST16(.7f,15),exc[i]) , MULT16_16_Q15(QCONST16(.3f,15),st->voc_m1)),
+ SUB16(MULT16_16_Q15(Q15_ONE-MULT16_16_16(QCONST16(.85f,9),g),EXTRACT16(PSHR32(innov[i],SIG_SHIFT))),
+ MULT16_16_Q15(MULT16_16_16(QCONST16(.15f,9),g),EXTRACT16(PSHR32(st->voc_m2,SIG_SHIFT)))
+ ));
st->voc_m1 = exci;
st->voc_m2=innov[i];
- st->voc_mean = .95*st->voc_mean + .05*exc[i];
+ st->voc_mean = EXTRACT16(PSHR32(ADD32(MULT16_16(QCONST16(.8f,15),st->voc_mean), MULT16_16(QCONST16(.2f,15),exc[i])), 15));
exc[i]-=st->voc_mean;
}
}
@@ -1720,6 +1570,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];
@@ -1759,7 +1617,8 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_MODE:
(*(spx_int32_t*)ptr) = st->submodeID;
break;
- case SPEEX_SET_VBR:
+#ifndef DISABLE_VBR
+ case SPEEX_SET_VBR:
st->vbr_enabled = (*(spx_int32_t*)ptr);
break;
case SPEEX_GET_VBR:
@@ -1807,12 +1666,15 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_ABR:
(*(spx_int32_t*)ptr) = st->abr_enabled;
break;
+#endif /* #ifndef DISABLE_VBR */
+#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
case SPEEX_SET_VBR_QUALITY:
st->vbr_quality = (*(float*)ptr);
break;
case SPEEX_GET_VBR_QUALITY:
(*(float*)ptr) = st->vbr_quality;
break;
+#endif /* !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
case SPEEX_SET_QUALITY:
{
int quality = (*(spx_int32_t*)ptr);
@@ -1864,7 +1726,7 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
st->bounded_pitch = 1;
st->first = 1;
for (i=0;i<st->lpcSize;i++)
- st->old_lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1);
+ st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
for (i=0;i<st->lpcSize;i++)
st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0;
for (i=0;i<st->frameSize+st->max_pitch+1;i++)
@@ -1890,12 +1752,14 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_PLC_TUNING:
(*(spx_int32_t*)ptr)=(st->plc_tuning);
break;
+#ifndef DISABLE_VBR
case SPEEX_SET_VBR_MAX_BITRATE:
st->vbr_max = (*(spx_int32_t*)ptr);
break;
case SPEEX_GET_VBR_MAX_BITRATE:
(*(spx_int32_t*)ptr) = st->vbr_max;
break;
+#endif /* #ifndef DISABLE_VBR */
case SPEEX_SET_HIGHPASS:
st->highpass_enabled = (*(spx_int32_t*)ptr);
break;
@@ -1919,9 +1783,11 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize);
}
break;
+#ifndef DISABLE_VBR
case SPEEX_GET_RELATIVE_QUALITY:
(*(float*)ptr)=st->relative_quality;
break;
+#endif /* #ifndef DISABLE_VBR */
case SPEEX_SET_INNOVATION_SAVE:
st->innov_rms_save = (spx_word16_t*)ptr;
break;
@@ -2013,7 +1879,22 @@ int nb_decoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_HIGHPASS:
(*(spx_int32_t*)ptr) = st->highpass_enabled;
break;
-
+ /* FIXME: Convert to fixed-point and re-enable even when float API is disabled */
+#ifndef DISABLE_FLOAT_API
+ 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;
+#endif
case SPEEX_GET_PI_GAIN:
{
int i;
diff --git a/libspeex/nb_celp.h b/libspeex/nb_celp.h
index 1ebf717..14c776f 100644
--- a/libspeex/nb_celp.h
+++ b/libspeex/nb_celp.h
@@ -64,10 +64,6 @@ typedef struct EncState {
int ol_voiced; /**< Open-loop voiced/non-voiced decision */
int *pitch;
-#ifdef EPIC_48K
- int lbr_48k;
-#endif
-
#ifdef VORBIS_PSYCHO
VorbisPsy *psy;
float *psy_window;
@@ -77,7 +73,6 @@ typedef struct EncState {
spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */
spx_word16_t gamma2; /**< Perceptual filter: A(z/gamma2) */
- float lag_factor; /**< Lag windowing Gaussian width */
spx_word16_t lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/
char *stack; /**< Pseudo-stack allocation for temporary memory */
spx_word16_t *winBuf; /**< Input buffer (original signal) */
@@ -86,7 +81,7 @@ typedef struct EncState {
spx_word16_t *swBuf; /**< Weighted signal buffer */
spx_word16_t *sw; /**< Start of weighted signal frame */
const spx_word16_t *window; /**< Temporary (Hanning) window */
- spx_word16_t *lagWindow; /**< Window applied to auto-correlation */
+ const spx_word16_t *lagWindow; /**< Window applied to auto-correlation */
spx_lsp_t *old_lsp; /**< LSPs for previous frame */
spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */
spx_mem_t *mem_sp; /**< Filter memory for signal synthesis */
@@ -97,7 +92,8 @@ typedef struct EncState {
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_rms_save; /**< If non-NULL, innovation RMS is copied here */
-
+
+#ifndef DISABLE_VBR
VBRState *vbr; /**< State of the VBR data */
float vbr_quality; /**< Quality setting for VBR encoding */
float relative_quality; /**< Relative quality that will be needed by VBR */
@@ -110,6 +106,8 @@ typedef struct EncState {
float abr_drift;
float abr_drift2;
float abr_count;
+#endif /* #ifndef DISABLE_VBR */
+
int complexity; /**< Complexity setting (0-10 from least complex to most complex) */
spx_int32_t sampling_rate;
int plc_tuning;
@@ -134,10 +132,6 @@ typedef struct DecState {
int max_pitch; /**< Maximum pitch value allowed */
spx_int32_t sampling_rate;
-#ifdef EPIC_48K
- int lbr_48k;
-#endif
-
spx_word16_t last_ol_gain; /**< Open-loop gain for previous frame */
char *stack; /**< Pseudo-stack allocation for temporary memory */
@@ -148,7 +142,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 */
@@ -168,7 +166,7 @@ typedef struct DecState {
/*Vocoder data*/
spx_word16_t voc_m1;
spx_word32_t voc_m2;
- float voc_mean;
+ spx_word16_t voc_mean;
int voc_offset;
int dtx_enabled;
diff --git a/libspeex/os_support.h b/libspeex/os_support.h
new file mode 100644
index 0000000..7703461
--- /dev/null
+++ b/libspeex/os_support.h
@@ -0,0 +1,162 @@
+/* Copyright (C) 2007 Jean-Marc Valin
+
+ File: os_support.h
+ This is the (tiny) OS abstraction layer. Aside from math.h, this is the
+ only place where system headers are allowed.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+#ifndef OS_SUPPORT_H
+#define OS_SUPPORT_H
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free
+ NOTE: speex_alloc needs to CLEAR THE MEMORY */
+#ifndef OVERRIDE_SPEEX_ALLOC
+static inline void *speex_alloc (int size)
+{
+ /* WARNING: this is not equivalent to malloc(). If you want to use malloc()
+ or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise
+ you will experience strange bugs */
+ return calloc(size,1);
+}
+#endif
+
+/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
+#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH
+static inline void *speex_alloc_scratch (int size)
+{
+ /* Scratch space doesn't need to be cleared */
+ return calloc(size,1);
+}
+#endif
+
+/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */
+#ifndef OVERRIDE_SPEEX_REALLOC
+static inline void *speex_realloc (void *ptr, int size)
+{
+ return realloc(ptr, size);
+}
+#endif
+
+/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */
+#ifndef OVERRIDE_SPEEX_FREE
+static inline void speex_free (void *ptr)
+{
+ free(ptr);
+}
+#endif
+
+/** Same as speex_free, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
+#ifndef OVERRIDE_SPEEX_FREE_SCRATCH
+static inline void speex_free_scratch (void *ptr)
+{
+ free(ptr);
+}
+#endif
+
+/** Print warning message with integer argument to stderr */
+#ifndef OVERRIDE_SPEEX_MOVE
+static inline void *speex_move (void *dest, void *src, int n)
+{
+ return memmove(dest,src,n);
+}
+#endif
+
+/** Print warning message with integer argument to stderr */
+#ifndef OVERRIDE_SPEEX_MOVE
+static inline void *speex_memset (void *s, int c, int n)
+{
+ return memset(s,c,n);
+}
+#endif
+
+
+#ifndef OVERRIDE_SPEEX_FATAL
+static inline void _speex_fatal(const char *str, const char *file, int line)
+{
+ fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
+ exit(1);
+}
+#endif
+
+#ifndef OVERRIDE_SPEEX_WARNING
+static inline void speex_warning(const char *str)
+{
+#ifndef DISABLE_WARNINGS
+ fprintf (stderr, "warning: %s\n", str);
+#endif
+}
+#endif
+
+#ifndef OVERRIDE_SPEEX_WARNING_INT
+static inline 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
+static inline void speex_notify(const char *str)
+{
+#ifndef DISABLE_NOTIFICATIONS
+ fprintf (stderr, "notification: %s\n", str);
+#endif
+}
+#endif
+
+#ifndef OVERRIDE_SPEEX_PUTC
+/** Speex wrapper for putc */
+static inline void _speex_putc(int ch, void *file)
+{
+ FILE *f = (FILE *)file;
+ fprintf(f, "%c", ch);
+}
+#endif
+
+#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__);
+#define speex_assert(cond) {if (!(cond)) {speex_fatal("assertion failed: " #cond);}}
+
+#ifndef RELEASE
+static inline void print_vec(float *vec, int len, char *name)
+{
+ int i;
+ printf ("%s ", name);
+ for (i=0;i<len;i++)
+ printf (" %f", vec[i]);
+ printf ("\n");
+}
+#endif
+
+#endif
+
diff --git a/libspeex/preprocess.c b/libspeex/preprocess.c
index b5caf4b..d94a75a 100644
--- a/libspeex/preprocess.c
+++ b/libspeex/preprocess.c
@@ -62,10 +62,11 @@
#include <math.h>
#include "speex/speex_preprocess.h"
#include "speex/speex_echo.h"
-#include "misc.h"
+#include "arch.h"
#include "fftwrap.h"
#include "filterbank.h"
#include "math_approx.h"
+#include "os_support.h"
#ifndef M_PI
#define M_PI 3.14159263
@@ -215,7 +216,7 @@ struct SpeexPreprocessState_ {
spx_word32_t *S; /**< Smoothed power spectrum */
spx_word32_t *Smin; /**< See Cohen paper */
spx_word32_t *Stmp; /**< See Cohen paper */
- int *update_prob; /**< Propability of speech presence for noise update */
+ int *update_prob; /**< Probability of speech presence for noise update */
spx_word16_t *zeta; /**< Smoothed a priori SNR */
spx_word32_t *echo_noise;
@@ -276,7 +277,7 @@ static void conj_window(spx_word16_t *w, int len)
x=QCONST16(2.f,13)-x+QCONST16(2.f,13); /* 4 - x */
}
x = MULT16_16_Q14(QCONST16(1.271903f,14), x);
- tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(QCONST32(x,2))));
+ tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(SHL32(EXTEND32(x),2))));
if (inv)
tmp=SUB16(Q15_ONE,tmp);
w[i]=spx_sqrt(SHL32(EXTEND32(tmp),15));
@@ -737,6 +738,8 @@ int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x)
spx_word16_t effective_echo_suppress;
st->nb_adapt++;
+ if (st->nb_adapt>20000)
+ st->nb_adapt = 20000;
st->min_count++;
beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt));
@@ -1064,14 +1067,14 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr)
break;
case SPEEX_PREPROCESS_SET_AGC_LEVEL:
- st->agc_level = (*(float*)ptr);
+ st->agc_level = (*(spx_int32_t*)ptr);
if (st->agc_level<1)
st->agc_level=1;
if (st->agc_level>32768)
st->agc_level=32768;
break;
case SPEEX_PREPROCESS_GET_AGC_LEVEL:
- (*(float*)ptr) = st->agc_level;
+ (*(spx_int32_t*)ptr) = st->agc_level;
break;
case SPEEX_PREPROCESS_SET_AGC_INCREMENT:
st->max_increase_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate);
@@ -1110,30 +1113,34 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr)
break;
case SPEEX_PREPROCESS_SET_DEREVERB_LEVEL:
- st->reverb_level = (*(float*)ptr);
+ /* FIXME: Re-enable when de-reverberation is actually enabled again */
+ /*st->reverb_level = (*(float*)ptr);*/
break;
case SPEEX_PREPROCESS_GET_DEREVERB_LEVEL:
- (*(float*)ptr) = st->reverb_level;
+ /* FIXME: Re-enable when de-reverberation is actually enabled again */
+ /*(*(float*)ptr) = st->reverb_level;*/
break;
case SPEEX_PREPROCESS_SET_DEREVERB_DECAY:
- st->reverb_decay = (*(float*)ptr);
+ /* FIXME: Re-enable when de-reverberation is actually enabled again */
+ /*st->reverb_decay = (*(float*)ptr);*/
break;
case SPEEX_PREPROCESS_GET_DEREVERB_DECAY:
- (*(float*)ptr) = st->reverb_decay;
+ /* FIXME: Re-enable when de-reverberation is actually enabled again */
+ /*(*(float*)ptr) = st->reverb_decay;*/
break;
case SPEEX_PREPROCESS_SET_PROB_START:
- *(spx_int32_t*)ptr = MIN32(Q15_ONE,MAX32(0, *(spx_int32_t*)ptr));
- st->speech_prob_start = DIV32_16(MULT16_16(32767,*(spx_int32_t*)ptr), 100);
+ *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr));
+ st->speech_prob_start = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100);
break;
case SPEEX_PREPROCESS_GET_PROB_START:
(*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100);
break;
case SPEEX_PREPROCESS_SET_PROB_CONTINUE:
- *(spx_int32_t*)ptr = MIN32(Q15_ONE,MAX32(0, *(spx_int32_t*)ptr));
- st->speech_prob_continue = DIV32_16(MULT16_16(32767,*(spx_int32_t*)ptr), 100);
+ *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr));
+ st->speech_prob_continue = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100);
break;
case SPEEX_PREPROCESS_GET_PROB_CONTINUE:
(*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_continue, 100);
@@ -1163,6 +1170,11 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr)
case SPEEX_PREPROCESS_GET_ECHO_STATE:
ptr = (void*)st->echo_state;
break;
+#ifndef FIXED_POINT
+ case SPEEX_PREPROCESS_GET_AGC_LOUDNESS:
+ (*(spx_int32_t*)ptr) = pow(st->loudness, 1.0/LOUDNESS_EXP);
+ break;
+#endif
default:
speex_warning_int("Unknown speex_preprocess_ctl request: ", request);
diff --git a/libspeex/pseudofloat.h b/libspeex/pseudofloat.h
index a6c4762..fa841a0 100644
--- a/libspeex/pseudofloat.h
+++ b/libspeex/pseudofloat.h
@@ -44,7 +44,8 @@
#ifndef PSEUDOFLOAT_H
#define PSEUDOFLOAT_H
-#include "misc.h"
+#include "arch.h"
+#include "os_support.h"
#include "math_approx.h"
#include <math.h>
diff --git a/libspeex/quant_lsp.c b/libspeex/quant_lsp.c
index d907b98..e624d1a 100644
--- a/libspeex/quant_lsp.c
+++ b/libspeex/quant_lsp.c
@@ -35,12 +35,13 @@
#endif
#include "quant_lsp.h"
+#include "os_support.h"
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
-#include "misc.h"
+#include "arch.h"
#ifdef BFIN_ASM
#include "quant_lsp_bfin.h"
@@ -304,11 +305,11 @@ void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)
#ifdef DISABLE_WIDEBAND
void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
{
- speex_error("Wideband and Ultra-wideband are disabled");
+ speex_fatal("Wideband and Ultra-wideband are disabled");
}
void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
{
- speex_error("Wideband and Ultra-wideband are disabled");
+ speex_fatal("Wideband and Ultra-wideband are disabled");
}
#else
extern const signed char high_lsp_cdbk[];
@@ -382,66 +383,3 @@ void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
#endif
-
-#ifdef EPIC_48K
-
-extern const signed char cdbk_lsp_vlbr[5120];
-extern const signed char cdbk_lsp2_vlbr[160];
-
-void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
-{
- int i;
- int id;
- spx_word16_t quant_weight[10];
-
- for (i=0;i<order;i++)
- qlsp[i]=lsp[i];
-
- compute_quant_weights(qlsp, quant_weight, order);
-
- for (i=0;i<order;i++)
- qlsp[i]=SUB16(qlsp[i],LSP_SCALING*(.25*i+.3125));
-#ifndef FIXED_POINT
- for (i=0;i<order;i++)
- qlsp[i] = qlsp[i]*LSP_SCALE;
-#endif
-
- id = lsp_quant(qlsp, cdbk_lsp_vlbr, 512, order);
- speex_bits_pack(bits, id, 9);
-
- for (i=0;i<order;i++)
- qlsp[i]*=4;
-
- id = lsp_weight_quant(qlsp, quant_weight, cdbk_lsp2_vlbr, 16, 10);
- speex_bits_pack(bits, id, 4);
-
-#ifdef FIXED_POINT
- for (i=0;i<order;i++)
- qlsp[i]=PSHR16(qlsp[i],2);
-#else
- for (i=0;i<order;i++)
- qlsp[i]=qlsp[i]*0.00097655;
-#endif
-
- for (i=0;i<order;i++)
- qlsp[i]=lsp[i]-qlsp[i];
-}
-
-void lsp_unquant_48k(spx_lsp_t *lsp, int order, SpeexBits *bits)
-{
- int i, id;
- for (i=0;i<order;i++)
- lsp[i]=LSP_SCALING*(.25*i+.3125);
-
-
- id=speex_bits_unpack_unsigned(bits, 9);
- for (i=0;i<10;i++)
- lsp[i] += LSP_SCALING*0.0039062*cdbk_lsp_vlbr[id*10+i];
-
- id=speex_bits_unpack_unsigned(bits, 4);
- for (i=0;i<10;i++)
- lsp[i] += LSP_SCALING*0.00097655*cdbk_lsp2_vlbr[id*10+i];
-
-}
-
-#endif
diff --git a/libspeex/quant_lsp.h b/libspeex/quant_lsp.h
index c6d5bb3..3bf4d40 100644
--- a/libspeex/quant_lsp.h
+++ b/libspeex/quant_lsp.h
@@ -36,7 +36,7 @@
#define QUANT_LSP_H
#include <speex/speex_bits.h>
-#include "misc.h"
+#include "arch.h"
#define MAX_LSP_SIZE 20
@@ -71,13 +71,4 @@ void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
/* Decodes high-band LSPs */
void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits);
-#ifdef EPIC_48K
-/* Quantizes narrowband LSPs with 14 bits */
-void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
-
-/* Decodes quantized narrowband LSPs (14 bits) */
-void lsp_unquant_48k(spx_lsp_t *lsp, int order, SpeexBits *bits);
-#endif
-
-
#endif
diff --git a/libspeex/resample.c b/libspeex/resample.c
index 7135a29..6ca7f2e 100644
--- a/libspeex/resample.c
+++ b/libspeex/resample.c
@@ -37,17 +37,23 @@
- Low memory requirement
- Good *perceptual* quality (and not best SNR)
- The code is working, but it's in a very early stage, so it may have
- artifacts, noise or subliminal messages from satan. Also, the API
- isn't stable and I can actually promise that I *will* change the API
- some time in the future.
+ Warning: This resampler is relatively new. Although I think I got rid of
+ all the major bugs and I don't expect the API to change anymore, there
+ may be something I've missed. So use with caution.
-TODO list:
- - Variable calculation resolution depending on quality setting
- - Single vs double in float mode
- - 16-bit vs 32-bit (sinc only) in fixed-point mode
- - Make sure the filter update works even when changing params
- after only a few samples procesed
+ This algorithm is based on this original resampling algorithm:
+ Smith, Julius O. Digital Audio Resampling Home Page
+ Center for Computer Research in Music and Acoustics (CCRMA),
+ Stanford University, 2007.
+ Web published at http://www-ccrma.stanford.edu/~jos/resample/.
+
+ There is one main difference, though. This resampler uses cubic
+ interpolation instead of linear interpolation in the above paper. This
+ makes the table much smaller and makes it possible to compute that table
+ on a per-stream basis. In turn, being able to tweak the table for each
+ stream makes it possible to both reduce complexity on simple ratios
+ (e.g. 2/3), and get rid of the rounding operations in the inner loop.
+ The latter both reduces CPU time and makes the algorithm more SIMD-friendly.
*/
#ifdef HAVE_CONFIG_H
@@ -64,7 +70,8 @@ static void speex_free (void *ptr) {free(ptr);}
#else /* OUTSIDE_SPEEX */
#include "speex/speex_resampler.h"
-#include "misc.h"
+#include "arch.h"
+#include "os_support.h"
#endif /* OUTSIDE_SPEEX */
#include <math.h>
@@ -84,6 +91,7 @@ static void speex_free (void *ptr) {free(ptr);}
#define OVERSAMPLE 8
#define IMAX(a,b) ((a) > (b) ? (a) : (b))
+#define IMIN(a,b) ((a) < (b) ? (a) : (b))
#ifndef NULL
#define NULL 0
@@ -576,10 +584,10 @@ static void update_filter(SpeexResamplerState *st)
}
for (i=0;i<st->den_rate;i++)
{
- spx_uint32_t j;
+ spx_int32_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);
+ st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func);
}
}
#ifdef FIXED_POINT
@@ -615,6 +623,10 @@ 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;
@@ -633,7 +645,7 @@ static void update_filter(SpeexResamplerState *st)
/*speex_warning("reinit filter");*/
} else if (st->filt_len > old_length)
{
- spx_uint32_t i;
+ spx_int32_t i;
/* Increase the filter length */
/*speex_warning("increase filter size");*/
int old_alloc_size = st->mem_alloc_size;
@@ -642,32 +654,55 @@ 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--)
{
- spx_uint32_t 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)
{
spx_uint32_t i;
- /* 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;*/
+ /* 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++)
{
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;
}
}
@@ -756,15 +791,19 @@ static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t
/* Handle the case where we have samples left from a reduction in filter length */
if (st->magic_samples[channel_index])
{
+ 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)
@@ -774,7 +813,8 @@ static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t
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 */
@@ -919,11 +959,13 @@ int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const flo
{
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;
@@ -931,15 +973,18 @@ int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const flo
return RESAMPLER_ERR_SUCCESS;
}
+
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)
{
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;
@@ -960,16 +1005,19 @@ void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, sp
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;
+ spx_uint32_t fact;
+ spx_uint32_t old_den;
+ spx_uint32_t i;
if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)
return RESAMPLER_ERR_SUCCESS;
+ old_den = st->den_rate;
st->in_rate = in_rate;
st->out_rate = out_rate;
st->num_rate = ratio_num;
st->den_rate = ratio_den;
/* FIXME: This is terribly inefficient, but who cares (at least for now)? */
- for (fact=2;fact<=sqrt(IMAX(in_rate, out_rate));fact++)
+ for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++)
{
while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))
{
@@ -978,6 +1026,17 @@ int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_nu
}
}
+ if (old_den > 0)
+ {
+ for (i=0;i<st->nb_channels;i++)
+ {
+ st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den;
+ /* Safety net */
+ if (st->samp_frac_num[i] >= st->den_rate)
+ st->samp_frac_num[i] = st->den_rate-1;
+ }
+ }
+
if (st->initialised)
update_filter(st);
return RESAMPLER_ERR_SUCCESS;
diff --git a/libspeex/sb_celp.c b/libspeex/sb_celp.c
index 50b9824..619512c 100644
--- a/libspeex/sb_celp.c
+++ b/libspeex/sb_celp.c
@@ -35,7 +35,6 @@
#include <math.h>
#include "sb_celp.h"
-#include "stdlib.h"
#include "filters.h"
#include "lpc.h"
#include "lsp.h"
@@ -44,8 +43,13 @@
#include "quant_lsp.h"
#include "vq.h"
#include "ltp.h"
-#include "misc.h"
+#include "arch.h"
#include "math_approx.h"
+#include "os_support.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
/* Default size for the encoder and decoder stack (can be changed at compile time).
This does not apply when using variable-size arrays or alloca. */
@@ -61,40 +65,40 @@
#ifdef DISABLE_WIDEBAND
void *sb_encoder_init(const SpeexMode *m)
{
- speex_error("Wideband and Ultra-wideband are disabled");
+ speex_fatal("Wideband and Ultra-wideband are disabled");
return NULL;
}
void sb_encoder_destroy(void *state)
{
- speex_error("Wideband and Ultra-wideband are disabled");
+ speex_fatal("Wideband and Ultra-wideband are disabled");
}
int sb_encode(void *state, void *vin, SpeexBits *bits)
{
- speex_error("Wideband and Ultra-wideband are disabled");
+ speex_fatal("Wideband and Ultra-wideband are disabled");
return -2;
}
void *sb_decoder_init(const SpeexMode *m)
{
- speex_error("Wideband and Ultra-wideband are disabled");
+ speex_fatal("Wideband and Ultra-wideband are disabled");
return NULL;
}
void sb_decoder_destroy(void *state)
{
- speex_error("Wideband and Ultra-wideband are disabled");
+ speex_fatal("Wideband and Ultra-wideband are disabled");
}
int sb_decode(void *state, SpeexBits *bits, void *vout)
{
- speex_error("Wideband and Ultra-wideband are disabled");
+ speex_fatal("Wideband and Ultra-wideband are disabled");
return -2;
}
int sb_encoder_ctl(void *state, int request, void *ptr)
{
- speex_error("Wideband and Ultra-wideband are disabled");
+ speex_fatal("Wideband and Ultra-wideband are disabled");
return -2;
}
int sb_decoder_ctl(void *state, int request, void *ptr)
{
- speex_error("Wideband and Ultra-wideband are disabled");
+ speex_fatal("Wideband and Ultra-wideband are disabled");
return -2;
}
#else
@@ -179,6 +183,7 @@ static const float h0[64] = {
#endif
+extern const spx_word16_t lag_window[];
extern const spx_word16_t lpc_window[];
@@ -210,7 +215,6 @@ void *sb_encoder_init(const SpeexMode *m)
st->nbSubframes = mode->frameSize/mode->subframeSize;
st->windowSize = st->frame_size+st->subframeSize;
st->lpcSize=mode->lpcSize;
- st->bufSize=mode->bufSize;
st->encode_submode = 1;
st->submodes=mode->submodes;
@@ -221,7 +225,6 @@ void *sb_encoder_init(const SpeexMode *m)
tmp=1;
speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp);
- st->lag_factor = mode->lag_factor;
st->lpc_floor = mode->lpc_floor;
st->gamma1=mode->gamma1;
st->gamma2=mode->gamma2;
@@ -234,9 +237,7 @@ void *sb_encoder_init(const SpeexMode *m)
st->window= lpc_window;
- st->lagWindow = (spx_word16_t*)speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t));
- for (i=0;i<st->lpcSize+1;i++)
- st->lagWindow[i]=16384*exp(-.5*sqr(2*M_PI*st->lag_factor*i));
+ st->lagWindow = lag_window;
st->old_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
@@ -250,10 +251,9 @@ void *sb_encoder_init(const SpeexMode *m)
st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
for (i=0;i<st->lpcSize;i++)
- {
- st->old_lsp[i]=LSP_SCALING*(M_PI*((float)(i+1)))/(st->lpcSize+1);
- }
+ st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
+#ifndef DISABLE_VBR
st->vbr_quality = 8;
st->vbr_enabled = 0;
st->vbr_max = 0;
@@ -261,6 +261,7 @@ void *sb_encoder_init(const SpeexMode *m)
st->vad_enabled = 0;
st->abr_enabled = 0;
st->relative_quality=0;
+#endif /* #ifndef DISABLE_VBR */
st->complexity=2;
speex_encoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
@@ -285,8 +286,6 @@ void sb_encoder_destroy(void *state)
speex_free(st->h0_mem);
speex_free(st->h1_mem);
- speex_free(st->lagWindow);
-
speex_free(st->old_lsp);
speex_free(st->old_qlsp);
speex_free(st->interp_qlpc);
@@ -339,6 +338,7 @@ int sb_encode(void *state, void *vin, SpeexBits *bits)
/* Compute the two sub-bands by filtering with QMF h0*/
qmf_decomp(in, h0, low, high, st->full_frame_size, QMF_ORDER, st->h0_mem, stack);
+#ifndef DISABLE_VBR
if (st->vbr_enabled || st->vad_enabled)
{
/* Need to compute things here before the signal is trashed by the encoder */
@@ -346,6 +346,8 @@ int sb_encode(void *state, void *vin, SpeexBits *bits)
e_low = compute_rms16(low, st->frame_size);
e_high = compute_rms16(high, st->frame_size);
}
+#endif /* #ifndef DISABLE_VBR */
+
ALLOC(low_innov_rms, st->nbSubframes, spx_word16_t);
speex_encoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_rms);
/* Encode the narrowband part*/
@@ -421,6 +423,7 @@ int sb_encode(void *state, void *vin, SpeexBits *bits)
}
}
+#ifndef DISABLE_VBR
/* VBR code */
if ((st->vbr_enabled || st->vad_enabled) && !dtx)
{
@@ -497,6 +500,7 @@ int sb_encode(void *state, void *vin, SpeexBits *bits)
}
/*fprintf (stderr, "%f %f\n", ratio, low_qual);*/
}
+#endif /* #ifndef DISABLE_VBR */
if (st->encode_submode)
{
@@ -787,8 +791,8 @@ void *sb_decoder_init(const SpeexMode *m)
st->first=1;
- st->g0_mem = (spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t));
- st->g1_mem = (spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t));
+ st->g0_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
+ st->g1_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
st->excBuf = (spx_word16_t*)speex_alloc((st->subframeSize)*sizeof(spx_word16_t));
@@ -1130,6 +1134,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_SET_MODE:
speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr);
break;
+#ifndef DISABLE_VBR
case SPEEX_SET_VBR:
st->vbr_enabled = (*(spx_int32_t*)ptr);
speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr);
@@ -1144,6 +1149,8 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_VAD:
(*(spx_int32_t*)ptr) = st->vad_enabled;
break;
+#endif /* #ifndef DISABLE_VBR */
+#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
case SPEEX_SET_VBR_QUALITY:
{
spx_int32_t q;
@@ -1161,6 +1168,8 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_VBR_QUALITY:
(*(float*)ptr) = st->vbr_quality;
break;
+#endif /* #if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
+#ifndef DISABLE_VBR
case SPEEX_SET_ABR:
st->abr_enabled = (*(spx_int32_t*)ptr);
st->vbr_enabled = st->abr_enabled!=0;
@@ -1191,6 +1200,8 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_ABR:
(*(spx_int32_t*)ptr) = st->abr_enabled;
break;
+#endif /* #ifndef DISABLE_VBR */
+
case SPEEX_SET_QUALITY:
{
spx_int32_t nb_qual;
@@ -1253,7 +1264,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
int i;
st->first = 1;
for (i=0;i<st->lpcSize;i++)
- st->old_lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1);
+ st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
for (i=0;i<st->lpcSize;i++)
st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0;
for (i=0;i<QMF_ORDER;i++)
@@ -1277,6 +1288,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_PLC_TUNING:
speex_encoder_ctl(st->st_low, SPEEX_GET_PLC_TUNING, ptr);
break;
+#ifndef DISABLE_VBR
case SPEEX_SET_VBR_MAX_BITRATE:
{
st->vbr_max = (*(spx_int32_t*)ptr);
@@ -1308,6 +1320,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_VBR_MAX_BITRATE:
(*(spx_int32_t*)ptr) = st->vbr_max;
break;
+#endif /* #ifndef DISABLE_VBR */
case SPEEX_SET_HIGHPASS:
speex_encoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);
break;
@@ -1332,9 +1345,11 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
((spx_word16_t*)ptr)[i] = st->exc_rms[i];
}
break;
+#ifndef DISABLE_VBR
case SPEEX_GET_RELATIVE_QUALITY:
(*(float*)ptr)=st->relative_quality;
break;
+#endif /* #ifndef DISABLE_VBR */
case SPEEX_SET_INNOVATION_SAVE:
st->innov_rms_save = (spx_word16_t*)ptr;
break;
@@ -1441,7 +1456,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;
diff --git a/libspeex/sb_celp.h b/libspeex/sb_celp.h
index a0dc3af..e8c3761 100644
--- a/libspeex/sb_celp.h
+++ b/libspeex/sb_celp.h
@@ -50,9 +50,7 @@ typedef struct SBEncState {
int nbSubframes; /**< Number of high-band sub-frames*/
int windowSize; /**< Length of high-band LPC window*/
int lpcSize; /**< Order of high-band LPC analysis */
- int bufSize; /**< Buffer size */
int first; /**< First frame? */
- float lag_factor; /**< Lag-windowing control parameter */
spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */
spx_word16_t gamma1; /**< Perceptual weighting coef 1 */
spx_word16_t gamma2; /**< Perceptual weighting coef 2 */
@@ -62,7 +60,7 @@ typedef struct SBEncState {
spx_word16_t *h0_mem, *h1_mem;
const spx_word16_t *window; /**< LPC analysis window */
- spx_word16_t *lagWindow; /**< Auto-correlation window */
+ const spx_word16_t *lagWindow; /**< Auto-correlation window */
spx_lsp_t *old_lsp; /**< LSPs of previous frame */
spx_lsp_t *old_qlsp; /**< Quantized LSPs of previous frame */
spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */
@@ -74,6 +72,7 @@ typedef struct SBEncState {
spx_word16_t *exc_rms;
spx_word16_t *innov_rms_save; /**< If non-NULL, innovation is copied here */
+#ifndef DISABLE_VBR
float vbr_quality; /**< Quality setting for VBR encoding */
int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */
spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode (total) */
@@ -84,7 +83,8 @@ typedef struct SBEncState {
float abr_count;
int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */
float relative_quality;
-
+#endif /* #ifndef DISABLE_VBR */
+
int encode_submode;
const SpeexSubmode * const *submodes;
int submodeID;
@@ -109,7 +109,7 @@ typedef struct SBDecState {
int lpc_enh_enabled;
char *stack;
- spx_word32_t *g0_mem, *g1_mem;
+ spx_word16_t *g0_mem, *g1_mem;
spx_word16_t *excBuf;
spx_lsp_t *old_qlsp;
diff --git a/libspeex/smallft.c b/libspeex/smallft.c
index 269549d..5c26d01 100644
--- a/libspeex/smallft.c
+++ b/libspeex/smallft.c
@@ -34,7 +34,8 @@
#include <math.h>
#include "smallft.h"
-#include "misc.h"
+#include "arch.h"
+#include "os_support.h"
static void drfti1(int n, float *wa, int *ifac){
static int ntryh[4] = { 4,2,3,5 };
diff --git a/libspeex/speex.c b/libspeex/speex.c
index 846e021..78e1a7a 100644
--- a/libspeex/speex.c
+++ b/libspeex/speex.c
@@ -38,6 +38,7 @@
#include "modes.h"
#include <math.h>
+#include "os_support.h"
#ifndef NULL
#define NULL 0
@@ -83,6 +84,7 @@ int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out)
#ifdef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
int speex_encode(void *state, float *in, SpeexBits *bits)
{
int i;
@@ -100,6 +102,7 @@ int speex_encode(void *state, float *in, SpeexBits *bits)
}
return (*((SpeexMode**)state))->enc(state, short_in, bits);
}
+#endif /* #ifndef DISABLE_FLOAT_API */
int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
{
@@ -108,6 +111,7 @@ int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
return (mode)->enc(state, in, bits);
}
+#ifndef DISABLE_FLOAT_API
int speex_decode(void *state, SpeexBits *bits, float *out)
{
int i, ret;
@@ -119,6 +123,7 @@ int speex_decode(void *state, SpeexBits *bits, float *out)
out[i] = short_out[i];
return ret;
}
+#endif /* #ifndef DISABLE_FLOAT_API */
int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
{
@@ -208,29 +213,6 @@ int nb_mode_query(const void *mode, int request, void *ptr)
return 0;
}
-int wb_mode_query(const void *mode, int request, void *ptr)
-{
- const SpeexSBMode *m = (const SpeexSBMode*)mode;
-
- switch (request)
- {
- case SPEEX_MODE_FRAME_SIZE:
- *((int*)ptr)=2*m->frameSize;
- break;
- case SPEEX_SUBMODE_BITS_PER_FRAME:
- if (*((int*)ptr)==0)
- *((int*)ptr) = SB_SUBMODE_BITS+1;
- else if (m->submodes[*((int*)ptr)]==NULL)
- *((int*)ptr) = -1;
- else
- *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
- break;
- default:
- speex_warning_int("Unknown wb_mode_query request: ", request);
- return -1;
- }
- return 0;
-}
int speex_lib_ctl(int request, void *ptr)
diff --git a/libspeex/speex_callbacks.c b/libspeex/speex_callbacks.c
index 682322e..d1158b2 100644
--- a/libspeex/speex_callbacks.c
+++ b/libspeex/speex_callbacks.c
@@ -37,7 +37,8 @@
#endif
#include <speex/speex_callbacks.h>
-#include "misc.h"
+#include "arch.h"
+#include "os_support.h"
int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state)
{
@@ -95,6 +96,7 @@ int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data
return 0;
}
+#ifndef DISABLE_VBR
int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
{
spx_int32_t vbr;
@@ -102,6 +104,7 @@ int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr);
return 0;
}
+#endif /* #ifndef DISABLE_VBR */
int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
{
@@ -111,6 +114,7 @@ int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
return 0;
}
+#ifndef DISABLE_VBR
int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data)
{
float qual;
@@ -118,7 +122,7 @@ int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *da
speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual);
return 0;
}
-
+#endif /* #ifndef DISABLE_VBR */
int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
{
diff --git a/libspeex/speex_header.c b/libspeex/speex_header.c
index 8e10851..2efb3e3 100644
--- a/libspeex/speex_header.c
+++ b/libspeex/speex_header.c
@@ -35,14 +35,31 @@
#include "config.h"
#endif
-#include "misc.h"
+#include "arch.h"
#include <speex/speex_header.h>
#include <speex/speex.h>
+#include "os_support.h"
#ifndef NULL
#define NULL 0
#endif
+/** Convert little endian */
+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
+}
+
#define ENDIAN_SWITCH(x) {x=le_int(x);}
diff --git a/libspeex/stack_alloc.h b/libspeex/stack_alloc.h
index cb048fa..f9056b4 100644
--- a/libspeex/stack_alloc.h
+++ b/libspeex/stack_alloc.h
@@ -36,11 +36,15 @@
#define STACK_ALLOC_H
#ifdef USE_ALLOCA
-#ifdef WIN32
-#include <malloc.h>
-#else
-#include <alloca.h>
-#endif
+# ifdef WIN32
+# include <malloc.h>
+# else
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# include <stdlib.h>
+# endif
+# endif
#endif
/**
diff --git a/libspeex/stereo.c b/libspeex/stereo.c
index f18387e..bc6e1ba 100644
--- a/libspeex/stereo.c
+++ b/libspeex/stereo.c
@@ -35,12 +35,76 @@
#include <speex/speex_stereo.h>
#include <speex/speex_callbacks.h>
+#include "math_approx.h"
#include "vq.h"
#include <math.h>
+#include "os_support.h"
+
+typedef struct RealSpeexStereoState {
+ spx_word32_t balance; /**< Left/right balance info */
+ spx_word32_t e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */
+ spx_word32_t smooth_left; /**< Smoothed left channel gain */
+ spx_word32_t smooth_right; /**< Smoothed right channel gain */
+ spx_uint32_t reserved1; /**< Reserved for future use */
+ spx_int32_t reserved2; /**< Reserved for future use */
+} RealSpeexStereoState;
+
/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/
+#ifndef FIXED_POINT
static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f};
+static const float e_ratio_quant_bounds[3] = {0.2825f, 0.356f, 0.4485f};
+#else
+static const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384};
+static const spx_word16_t e_ratio_quant_bounds[3] = {9257, 11665, 14696};
+static const spx_word16_t balance_bounds[31] = {18, 23, 30, 38, 49, 63, 81, 104,
+ 134, 172, 221, 284, 364, 468, 600, 771,
+ 990, 1271, 1632, 2096, 2691, 3455, 4436, 5696,
+ 7314, 9392, 12059, 15484, 19882, 25529, 32766};
+#endif
+
+/* This is an ugly compatibility hack that properly resets the stereo state
+ In case it it compiled in fixed-point, but initialised with the deprecated
+ floating point static initialiser */
+#ifdef FIXED_POINT
+#define COMPATIBILITY_HACK(s) do {if ((s)->reserved1 != 0xdeadbeef) speex_stereo_state_reset((SpeexStereoState*)s); } while (0);
+#else
+#define COMPATIBILITY_HACK(s)
+#endif
+SpeexStereoState *speex_stereo_state_init()
+{
+ SpeexStereoState *stereo = speex_alloc(sizeof(SpeexStereoState));
+ speex_stereo_state_reset(stereo);
+ return stereo;
+}
+
+void speex_stereo_state_reset(SpeexStereoState *_stereo)
+{
+ RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
+#ifdef FIXED_POINT
+ stereo->balance = 65536;
+ stereo->e_ratio = 16384;
+ stereo->smooth_left = 16384;
+ stereo->smooth_right = 16384;
+ stereo->reserved1 = 0xdeadbeef;
+ stereo->reserved2 = 0;
+#else
+ stereo->balance = 1.0f;
+ stereo->e_ratio = .5f;
+ stereo->smooth_left = 1.f;
+ stereo->smooth_right = 1.f;
+ stereo->reserved1 = 0;
+ stereo->reserved2 = 0;
+#endif
+}
+
+void speex_stereo_state_destroy(SpeexStereoState *stereo)
+{
+ speex_free(stereo);
+}
+
+#ifndef DISABLE_FLOAT_API
void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
{
int i, tmp;
@@ -73,118 +137,158 @@ void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
speex_bits_pack(bits, (int)balance, 5);
- /*Quantize energy ratio*/
- tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4);
+ /* FIXME: this is a hack */
+ tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 4);
speex_bits_pack(bits, tmp, 2);
}
+#endif /* #ifndef DISABLE_FLOAT_API */
void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits)
{
int i, tmp;
- float e_left=0, e_right=0, e_tot=0;
- float balance, e_ratio;
+ spx_word32_t e_left=0, e_right=0, e_tot=0;
+ spx_word32_t balance, e_ratio;
+ spx_word32_t largest, smallest;
+ int balance_id;
+#ifdef FIXED_POINT
+ int shift;
+#endif
+
+ /* In band marker */
+ speex_bits_pack(bits, 14, 5);
+ /* Stereo marker */
+ speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
+
for (i=0;i<frame_size;i++)
{
- e_left += ((float)data[2*i])*data[2*i];
- e_right += ((float)data[2*i+1])*data[2*i+1];
+ e_left += SHR32(MULT16_16(data[2*i],data[2*i]),8);
+ e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),8);
+#ifdef FIXED_POINT
+ /* I think this is actually unbiased */
+ data[i] = SHR16(data[2*i],1)+PSHR16(data[2*i+1],1);
+#else
data[i] = .5*(((float)data[2*i])+data[2*i+1]);
- e_tot += ((float)data[i])*data[i];
+#endif
+ e_tot += SHR32(MULT16_16(data[i],data[i]),8);
}
- balance=(e_left+1)/(e_right+1);
- e_ratio = e_tot/(1+e_left+e_right);
-
- /*Quantization*/
- speex_bits_pack(bits, 14, 5);
- speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
-
- balance=4*log(balance);
-
- /*Pack sign*/
- if (balance>0)
+ if (e_left > e_right)
+ {
speex_bits_pack(bits, 0, 1);
- else
+ largest = e_left;
+ smallest = e_right;
+ } else {
speex_bits_pack(bits, 1, 1);
- balance=floor(.5+fabs(balance));
- if (balance>30)
- balance=31;
+ largest = e_right;
+ smallest = e_left;
+ }
+
+ /* Balance quantization */
+#ifdef FIXED_POINT
+ shift = spx_ilog2(largest)-15;
+ largest = VSHR32(largest, shift-4);
+ smallest = VSHR32(smallest, shift);
+ balance = DIV32(largest, ADD32(smallest, 1));
+ if (balance > 32767)
+ balance = 32767;
+ balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32);
+#else
+ balance=(largest+1.)/(smallest+1.);
+ balance=4*log(balance);
+ balance_id=floor(.5+fabs(balance));
+ if (balance_id>30)
+ balance_id=31;
+#endif
- speex_bits_pack(bits, (int)balance, 5);
+ speex_bits_pack(bits, balance_id, 5);
+
+ /* "coherence" quantisation */
+#ifdef FIXED_POINT
+ shift = spx_ilog2(e_tot);
+ e_tot = VSHR32(e_tot, shift-25);
+ e_left = VSHR32(e_left, shift-10);
+ e_right = VSHR32(e_right, shift-10);
+ e_ratio = DIV32(e_tot, e_left+e_right+1);
+#else
+ e_ratio = e_tot/(1.+e_left+e_right);
+#endif
- /*Quantize energy ratio*/
- tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4);
+ tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4);
+ /*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio);*/
speex_bits_pack(bits, tmp, 2);
}
-void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo)
+#ifndef DISABLE_FLOAT_API
+void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo)
{
- float balance, e_ratio;
int i;
- float e_tot=0, e_left, e_right, e_sum;
-
+ spx_word32_t balance;
+ spx_word16_t e_left, e_right, e_ratio;
+ RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
+
+ COMPATIBILITY_HACK(stereo);
+
balance=stereo->balance;
e_ratio=stereo->e_ratio;
- for (i=frame_size-1;i>=0;i--)
- {
- e_tot += ((float)data[i])*data[i];
- }
- e_sum=e_tot/e_ratio;
- e_left = e_sum*balance / (1+balance);
- e_right = e_sum-e_left;
-
- e_left = sqrt(e_left/(e_tot+.01));
- e_right = sqrt(e_right/(e_tot+.01));
+
+ /* These two are Q14, with max value just below 2. */
+ e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));
+ e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);
for (i=frame_size-1;i>=0;i--)
{
- float ftmp=data[i];
- stereo->smooth_left = .98*stereo->smooth_left + .02*e_left;
- stereo->smooth_right = .98*stereo->smooth_right + .02*e_right;
- data[2*i] = stereo->smooth_left*ftmp;
- data[2*i+1] = stereo->smooth_right*ftmp;
+ spx_word16_t tmp=data[i];
+ stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));
+ stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));
+ data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp);
+ data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp);
}
}
+#endif /* #ifndef DISABLE_FLOAT_API */
-void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo)
+void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo)
{
- float balance, e_ratio;
int i;
- float e_tot=0, e_left, e_right, e_sum;
+ spx_word32_t balance;
+ spx_word16_t e_left, e_right, e_ratio;
+ RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
+ COMPATIBILITY_HACK(stereo);
+
balance=stereo->balance;
e_ratio=stereo->e_ratio;
- for (i=frame_size-1;i>=0;i--)
- {
- e_tot += ((float)data[i])*data[i];
- }
- e_sum=e_tot/e_ratio;
- e_left = e_sum*balance / (1+balance);
- e_right = e_sum-e_left;
-
- e_left = sqrt(e_left/(e_tot+.01));
- e_right = sqrt(e_right/(e_tot+.01));
+
+ /* These two are Q14, with max value just below 2. */
+ e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));
+ e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);
for (i=frame_size-1;i>=0;i--)
{
- float ftmp=data[i];
- stereo->smooth_left = .98*stereo->smooth_left + .02*e_left;
- stereo->smooth_right = .98*stereo->smooth_right + .02*e_right;
- data[2*i] = stereo->smooth_left*ftmp;
- data[2*i+1] = stereo->smooth_right*ftmp;
+ spx_int16_t tmp=data[i];
+ stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));
+ stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));
+ data[2*i] = (spx_int16_t)MULT16_16_P14(stereo->smooth_left, tmp);
+ data[2*i+1] = (spx_int16_t)MULT16_16_P14(stereo->smooth_right, tmp);
}
}
int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
{
- SpeexStereoState *stereo;
- float sign=1;
+ RealSpeexStereoState *stereo;
+ spx_word16_t sign=1, dexp;
int tmp;
- stereo = (SpeexStereoState*)data;
+ stereo = (RealSpeexStereoState*)data;
+
+ COMPATIBILITY_HACK(stereo);
+
if (speex_bits_unpack_unsigned(bits, 1))
sign=-1;
- tmp = speex_bits_unpack_unsigned(bits, 5);
- stereo->balance = exp(sign*.25*tmp);
-
+ dexp = speex_bits_unpack_unsigned(bits, 5);
+#ifndef FIXED_POINT
+ stereo->balance = exp(sign*.25*dexp);
+#else
+ stereo->balance = spx_exp(MULT16_16(sign, SHL16(dexp, 9)));
+#endif
tmp = speex_bits_unpack_unsigned(bits, 2);
stereo->e_ratio = e_ratio_quant[tmp];
diff --git a/libspeex/testecho.c b/libspeex/testecho.c
index 60d76d5..01b4539 100644
--- a/libspeex/testecho.c
+++ b/libspeex/testecho.c
@@ -7,7 +7,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <unistd.h>
#include "speex/speex_echo.h"
#include "speex/speex_preprocess.h"
@@ -17,37 +16,38 @@
int main(int argc, char **argv)
{
- int echo_fd, ref_fd, e_fd;
+ FILE *echo_fd, *ref_fd, *e_fd;
short echo_buf[NN], ref_buf[NN], e_buf[NN];
SpeexEchoState *st;
SpeexPreprocessState *den;
+ int sampleRate = 8000;
if (argc != 4)
{
- fprintf (stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n");
+ fprintf(stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n");
exit(1);
}
- echo_fd = open (argv[2], O_RDONLY);
- ref_fd = open (argv[1], O_RDONLY);
- e_fd = open (argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ echo_fd = fopen(argv[2], "rb");
+ ref_fd = fopen(argv[1], "rb");
+ e_fd = fopen(argv[3], "wb");
- st = mc_echo_state_init(NN, TAIL, 1, 1);
- den = speex_preprocess_state_init(NN, 8000);
- int tmp = 8000;
- mc_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp);
+ st = speex_echo_state_init(NN, TAIL, 1, 1);
+ den = speex_preprocess_state_init(NN, sampleRate);
+ speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st);
- while (read(ref_fd, ref_buf, NN*2))
+ while (!feof(ref_fd) && !feof(echo_fd))
{
- read(echo_fd, echo_buf, NN*2);
- mc_echo_cancellation(st, ref_buf, echo_buf, e_buf);
+ fread(ref_buf, sizeof(short), NN, ref_fd);
+ fread(echo_buf, sizeof(short), NN, echo_fd);
+ speex_echo_cancellation(st, ref_buf, echo_buf, e_buf);
speex_preprocess_run(den, e_buf);
- write(e_fd, e_buf, NN*2);
+ fwrite(e_buf, sizeof(short), NN, e_fd);
}
- mc_echo_state_destroy(st);
+ speex_echo_state_destroy(st);
speex_preprocess_state_destroy(den);
- close(e_fd);
- close(echo_fd);
- close(ref_fd);
+ fclose(e_fd);
+ fclose(echo_fd);
+ fclose(ref_fd);
return 0;
}
diff --git a/libspeex/testenc.c b/libspeex/testenc.c
index eabd02c..44c132f 100644
--- a/libspeex/testenc.c
+++ b/libspeex/testenc.c
@@ -19,7 +19,6 @@ int main(int argc, char **argv)
FILE *fin, *fout, *fbits=NULL;
short in_short[FRAME_SIZE];
short out_short[FRAME_SIZE];
- float sigpow,errpow,snr, seg_snr=0;
int snr_frames = 0;
char cbits[200];
int nbBits;
@@ -32,11 +31,8 @@ int main(int argc, char **argv)
spx_int32_t skip_group_delay;
SpeexCallback callback;
- sigpow = 0;
- errpow = 0;
-
- st = speex_encoder_init(&speex_nb_mode);
- dec = speex_decoder_init(&speex_nb_mode);
+ st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
+ dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
/* BEGIN: You probably don't need the following in a real application */
callback.callback_id = SPEEX_INBAND_CHAR;
@@ -74,13 +70,13 @@ int main(int argc, char **argv)
exit(1);
}
inFile = argv[1];
- fin = fopen(inFile, "r");
+ fin = fopen(inFile, "rb");
outFile = argv[2];
- fout = fopen(outFile, "w+");
+ fout = fopen(outFile, "wb+");
if (argc==4)
{
bitsFile = argv[3];
- fbits = fopen(bitsFile, "w");
+ fbits = fopen(bitsFile, "wb");
}
speex_bits_init(&bits);
while (!feof(fin))
@@ -109,6 +105,12 @@ int main(int argc, char **argv)
speex_decoder_destroy(dec);
speex_bits_destroy(&bits);
+#ifndef DISABLE_FLOAT_API
+ {
+ float sigpow,errpow,snr, seg_snr=0;
+ sigpow = 0;
+ errpow = 0;
+
/* This code just computes SNR, so you don't need it either */
rewind(fin);
rewind(fout);
@@ -127,9 +129,6 @@ int main(int argc, char **argv)
errpow += e;
snr_frames++;
}
- fclose(fin);
- fclose(fout);
-
snr = 10 * log10( sigpow / errpow );
seg_snr /= snr_frames;
fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
@@ -137,6 +136,11 @@ int main(int argc, char **argv)
#ifdef FIXED_DEBUG
printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
#endif
-
+ }
+#endif
+
+ fclose(fin);
+ fclose(fout);
+
return 0;
}
diff --git a/libspeex/testenc_uwb.c b/libspeex/testenc_uwb.c
index e9bf18a..503b64d 100644
--- a/libspeex/testenc_uwb.c
+++ b/libspeex/testenc_uwb.c
@@ -36,8 +36,8 @@ int main(int argc, char **argv)
sigpow = 0;
errpow = 0;
- st = speex_encoder_init(&speex_uwb_mode);
- dec = speex_decoder_init(&speex_uwb_mode);
+ st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));
+ dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));
callback.callback_id = SPEEX_INBAND_CHAR;
callback.func = speex_std_char_handler;
@@ -69,13 +69,13 @@ int main(int argc, char **argv)
exit(1);
}
inFile = argv[1];
- fin = fopen(inFile, "r");
+ fin = fopen(inFile, "rb");
outFile = argv[2];
- fout = fopen(outFile, "w+");
+ fout = fopen(outFile, "wb+");
if (argc==4)
{
bitsFile = argv[3];
- fbits = fopen(bitsFile, "w");
+ fbits = fopen(bitsFile, "wb");
}
speex_bits_init(&bits);
while (!feof(fin))
diff --git a/libspeex/testenc_wb.c b/libspeex/testenc_wb.c
index 8e515cb..3f13184 100644
--- a/libspeex/testenc_wb.c
+++ b/libspeex/testenc_wb.c
@@ -19,7 +19,6 @@ int main(int argc, char **argv)
FILE *fin, *fout, *fbits=NULL;
short in_short[FRAME_SIZE];
short out_short[FRAME_SIZE];
- float in_float[FRAME_SIZE];
float sigpow,errpow,snr, seg_snr=0;
int snr_frames = 0;
char cbits[200];
@@ -36,8 +35,8 @@ int main(int argc, char **argv)
sigpow = 0;
errpow = 0;
- st = speex_encoder_init(&speex_wb_mode);
- dec = speex_decoder_init(&speex_wb_mode);
+ st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));
+ dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));
callback.callback_id = SPEEX_INBAND_CHAR;
callback.func = speex_std_char_handler;
@@ -74,13 +73,13 @@ int main(int argc, char **argv)
exit(1);
}
inFile = argv[1];
- fin = fopen(inFile, "r");
+ fin = fopen(inFile, "rb");
outFile = argv[2];
- fout = fopen(outFile, "w+");
+ fout = fopen(outFile, "wb+");
if (argc==4)
{
bitsFile = argv[3];
- fbits = fopen(bitsFile, "w");
+ fbits = fopen(bitsFile, "wb");
}
speex_bits_init(&bits);
while (!feof(fin))
@@ -88,8 +87,6 @@ int main(int argc, char **argv)
fread(in_short, sizeof(short), FRAME_SIZE, fin);
if (feof(fin))
break;
- for (i=0;i<FRAME_SIZE;i++)
- in_float[i]=in_short[i];
speex_bits_reset(&bits);
speex_encode_int(st, in_short, &bits);
diff --git a/libspeex/vbr.c b/libspeex/vbr.c
index d24ec0f..5b7dd9b 100644
--- a/libspeex/vbr.c
+++ b/libspeex/vbr.c
@@ -45,17 +45,18 @@
#define MIN_ENERGY 6000
#define NOISE_POW .3
+#ifndef DISABLE_VBR
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 */
};
@@ -270,3 +271,5 @@ float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float p
void vbr_destroy(VBRState *vbr)
{
}
+
+#endif /* #ifndef DISABLE_VBR */
diff --git a/libspeex/vbr.h b/libspeex/vbr.h
index 34e1d4c..ff1e3e4 100644
--- a/libspeex/vbr.h
+++ b/libspeex/vbr.h
@@ -37,7 +37,7 @@
#ifndef VBR_H
#define VBR_H
-#include "misc.h"
+#include "arch.h"
#define VBR_MEMORY_SIZE 5
diff --git a/libspeex/vorbis_psy.c b/libspeex/vorbis_psy.c
index 6aac56f..ec32c6e 100644
--- a/libspeex/vorbis_psy.c
+++ b/libspeex/vorbis_psy.c
@@ -35,7 +35,7 @@
#ifdef VORBIS_PSYCHO
-#include "misc.h"
+#include "arch.h"
#include "smallft.h"
#include "lpc.h"
#include "vorbis_psy.h"
diff --git a/libspeex/vorbis_psy.h b/libspeex/vorbis_psy.h
index fbdb7c5..6871057 100644
--- a/libspeex/vorbis_psy.h
+++ b/libspeex/vorbis_psy.h
@@ -39,7 +39,7 @@
#define NOISE_COMPAND_LEVELS 40
-#define todB(x) ((x)==0?-400.f:log((x)*(x))*4.34294480f)
+#define todB(x) ((x)>1e-13?log((x)*(x))*4.34294480f:-30)
#define fromdB(x) (exp((x)*.11512925f))
/* The bark scale equations are approximations, since the original
diff --git a/libspeex/vq.c b/libspeex/vq.c
index d40133f..609f124 100644
--- a/libspeex/vq.c
+++ b/libspeex/vq.c
@@ -36,7 +36,7 @@
#include "vq.h"
#include "stack_alloc.h"
-#include "misc.h"
+#include "arch.h"
#ifdef _USE_SSE
#include <xmmintrin.h>
@@ -70,29 +70,6 @@ int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries)
return i;
}
-/*Finds the index of the entry in a codebook that best matches the input*/
-int vq_index(float *in, const float *codebook, int len, int entries)
-{
- int i,j;
- float min_dist=0;
- int best_index=0;
- for (i=0;i<entries;i++)
- {
- float dist=0;
- for (j=0;j<len;j++)
- {
- float tmp = in[j]-*codebook++;
- dist += tmp*tmp;
- }
- if (i==0 || dist<min_dist)
- {
- min_dist=dist;
- best_index=i;
- }
- }
- return best_index;
-}
-
#ifndef OVERRIDE_VQ_NBEST
/*Finds the indices of the n-best entries in a codebook*/
diff --git a/libspeex/vq.h b/libspeex/vq.h
index 7ca8197..5a4ced2 100644
--- a/libspeex/vq.h
+++ b/libspeex/vq.h
@@ -35,12 +35,11 @@
#ifndef VQ_H
#define VQ_H
-#include "misc.h"
+#include "arch.h"
int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries);
int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries);
-int vq_index(float *in, const float *codebook, int len, int entries);
#ifdef _USE_SSE
#include <xmmintrin.h>
void vq_nbest(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
diff --git a/libspeex/window.c b/libspeex/window.c
index 65b1917..ac042d4 100644
--- a/libspeex/window.c
+++ b/libspeex/window.c
@@ -33,9 +33,13 @@
#include "config.h"
#endif
-#include "misc.h"
+#include "arch.h"
#ifdef FIXED_POINT
+const spx_word16_t lag_window[11] = {
+ 16384, 16337, 16199, 15970, 15656, 15260, 14790, 14254, 13659, 13015, 12330
+};
+
const spx_word16_t lpc_window[200] = {
1310, 1313, 1321, 1333, 1352, 1375, 1403, 1436,
1475, 1518, 1567, 1621, 1679, 1743, 1811, 1884,
@@ -64,6 +68,10 @@ const spx_word16_t lpc_window[200] = {
6797, 6028, 5251, 4470, 3695, 2943, 2248, 1696
};
#else
+const spx_word16_t lag_window[11] = {
+ 1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998, 0.83367, 0.79434, 0.75258
+};
+
const spx_word16_t lpc_window[200] = {
0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f,
0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f,