summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libspeex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libspeex')
-rw-r--r--lib/rbcodec/codecs/libspeex/COPYING34
-rw-r--r--lib/rbcodec/codecs/libspeex/README.rockbox30
-rw-r--r--lib/rbcodec/codecs/libspeex/SOURCES45
-rw-r--r--lib/rbcodec/codecs/libspeex/_kiss_fft_guts.h166
-rw-r--r--lib/rbcodec/codecs/libspeex/arch.h242
-rw-r--r--lib/rbcodec/codecs/libspeex/bits.c399
-rw-r--r--lib/rbcodec/codecs/libspeex/cb_search.c621
-rw-r--r--lib/rbcodec/codecs/libspeex/cb_search.h103
-rw-r--r--lib/rbcodec/codecs/libspeex/cb_search_arm4.h137
-rw-r--r--lib/rbcodec/codecs/libspeex/cb_search_bfin.h112
-rw-r--r--lib/rbcodec/codecs/libspeex/cb_search_sse.h84
-rw-r--r--lib/rbcodec/codecs/libspeex/config-speex.h186
-rw-r--r--lib/rbcodec/codecs/libspeex/exc_10_16_table.c51
-rw-r--r--lib/rbcodec/codecs/libspeex/exc_10_32_table.c67
-rw-r--r--lib/rbcodec/codecs/libspeex/exc_20_32_table.c67
-rw-r--r--lib/rbcodec/codecs/libspeex/exc_5_256_table.c291
-rw-r--r--lib/rbcodec/codecs/libspeex/exc_5_64_table.c99
-rw-r--r--lib/rbcodec/codecs/libspeex/exc_8_128_table.c163
-rw-r--r--lib/rbcodec/codecs/libspeex/fftwrap.c288
-rw-r--r--lib/rbcodec/codecs/libspeex/fftwrap.h58
-rw-r--r--lib/rbcodec/codecs/libspeex/filterbank.c227
-rw-r--r--lib/rbcodec/codecs/libspeex/filterbank.h66
-rw-r--r--lib/rbcodec/codecs/libspeex/filters.c845
-rw-r--r--lib/rbcodec/codecs/libspeex/filters.h90
-rw-r--r--lib/rbcodec/codecs/libspeex/filters_arm4.S328
-rw-r--r--lib/rbcodec/codecs/libspeex/filters_arm4.h96
-rw-r--r--lib/rbcodec/codecs/libspeex/filters_bfin.h515
-rw-r--r--lib/rbcodec/codecs/libspeex/filters_cf.S356
-rw-r--r--lib/rbcodec/codecs/libspeex/filters_sse.h336
-rw-r--r--lib/rbcodec/codecs/libspeex/fixed_arm4.h148
-rw-r--r--lib/rbcodec/codecs/libspeex/fixed_arm5e.h178
-rw-r--r--lib/rbcodec/codecs/libspeex/fixed_bfin.h173
-rw-r--r--lib/rbcodec/codecs/libspeex/fixed_debug.h487
-rw-r--r--lib/rbcodec/codecs/libspeex/fixed_generic.h106
-rw-r--r--lib/rbcodec/codecs/libspeex/gain_table.c162
-rw-r--r--lib/rbcodec/codecs/libspeex/gain_table_lbr.c66
-rw-r--r--lib/rbcodec/codecs/libspeex/hexc_10_32_table.c68
-rw-r--r--lib/rbcodec/codecs/libspeex/hexc_table.c164
-rw-r--r--lib/rbcodec/codecs/libspeex/high_lsp_tables.c165
-rw-r--r--lib/rbcodec/codecs/libspeex/jitter.c839
-rw-r--r--lib/rbcodec/codecs/libspeex/kiss_fft.c523
-rw-r--r--lib/rbcodec/codecs/libspeex/kiss_fft.h108
-rw-r--r--lib/rbcodec/codecs/libspeex/kiss_fftr.c297
-rw-r--r--lib/rbcodec/codecs/libspeex/kiss_fftr.h51
-rw-r--r--lib/rbcodec/codecs/libspeex/libspeex.make66
-rw-r--r--lib/rbcodec/codecs/libspeex/lpc.c201
-rw-r--r--lib/rbcodec/codecs/libspeex/lpc.h53
-rw-r--r--lib/rbcodec/codecs/libspeex/lpc_bfin.h131
-rw-r--r--lib/rbcodec/codecs/libspeex/lsp.c661
-rw-r--r--lib/rbcodec/codecs/libspeex/lsp.h64
-rw-r--r--lib/rbcodec/codecs/libspeex/lsp_bfin.h89
-rw-r--r--lib/rbcodec/codecs/libspeex/lsp_tables_nb.c362
-rw-r--r--lib/rbcodec/codecs/libspeex/ltp.c856
-rw-r--r--lib/rbcodec/codecs/libspeex/ltp.h141
-rw-r--r--lib/rbcodec/codecs/libspeex/ltp_arm4.h188
-rw-r--r--lib/rbcodec/codecs/libspeex/ltp_bfin.h419
-rw-r--r--lib/rbcodec/codecs/libspeex/ltp_cf.S85
-rw-r--r--lib/rbcodec/codecs/libspeex/ltp_sse.h92
-rw-r--r--lib/rbcodec/codecs/libspeex/math_approx.h332
-rw-r--r--lib/rbcodec/codecs/libspeex/mdf.c1177
-rw-r--r--lib/rbcodec/codecs/libspeex/misc_bfin.h54
-rw-r--r--lib/rbcodec/codecs/libspeex/modes.c484
-rw-r--r--lib/rbcodec/codecs/libspeex/modes.h161
-rw-r--r--lib/rbcodec/codecs/libspeex/modes_wb.c374
-rw-r--r--lib/rbcodec/codecs/libspeex/nb_celp.c1917
-rw-r--r--lib/rbcodec/codecs/libspeex/nb_celp.h205
-rw-r--r--lib/rbcodec/codecs/libspeex/oggframing.c909
-rw-r--r--lib/rbcodec/codecs/libspeex/os_support.h165
-rw-r--r--lib/rbcodec/codecs/libspeex/preprocess.c1185
-rw-r--r--lib/rbcodec/codecs/libspeex/pseudofloat.h382
-rw-r--r--lib/rbcodec/codecs/libspeex/quant_lsp.c391
-rw-r--r--lib/rbcodec/codecs/libspeex/quant_lsp.h74
-rw-r--r--lib/rbcodec/codecs/libspeex/quant_lsp_bfin.h165
-rw-r--r--lib/rbcodec/codecs/libspeex/resample.c1140
-rw-r--r--lib/rbcodec/codecs/libspeex/rockbox.h119
-rw-r--r--lib/rbcodec/codecs/libspeex/sb_celp.c1510
-rw-r--r--lib/rbcodec/codecs/libspeex/sb_celp.h160
-rw-r--r--lib/rbcodec/codecs/libspeex/smallft.c1261
-rw-r--r--lib/rbcodec/codecs/libspeex/smallft.h46
-rw-r--r--lib/rbcodec/codecs/libspeex/speex.c252
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/ogg.h216
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex.h428
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex_bits.h184
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex_callbacks.h134
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex_config_types.h13
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex_echo.h123
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex_header.h91
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex_jitter.h197
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex_preprocess.h190
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex_resampler.h328
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex_stereo.h91
-rw-r--r--lib/rbcodec/codecs/libspeex/speex/speex_types.h126
-rw-r--r--lib/rbcodec/codecs/libspeex/speex_callbacks.c160
-rw-r--r--lib/rbcodec/codecs/libspeex/speex_header.c188
-rw-r--r--lib/rbcodec/codecs/libspeex/stack_alloc.h130
-rw-r--r--lib/rbcodec/codecs/libspeex/stereo.c302
-rw-r--r--lib/rbcodec/codecs/libspeex/vbr.c275
-rw-r--r--lib/rbcodec/codecs/libspeex/vbr.h70
-rw-r--r--lib/rbcodec/codecs/libspeex/vorbis_psy.c508
-rw-r--r--lib/rbcodec/codecs/libspeex/vorbis_psy.h97
-rw-r--r--lib/rbcodec/codecs/libspeex/vq.c147
-rw-r--r--lib/rbcodec/codecs/libspeex/vq.h54
-rw-r--r--lib/rbcodec/codecs/libspeex/vq_arm4.h115
-rw-r--r--lib/rbcodec/codecs/libspeex/vq_bfin.h107
-rw-r--r--lib/rbcodec/codecs/libspeex/vq_sse.h120
-rw-r--r--lib/rbcodec/codecs/libspeex/window.c102
106 files changed, 30004 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libspeex/COPYING b/lib/rbcodec/codecs/libspeex/COPYING
new file mode 100644
index 0000000000..3b6b579cf3
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/COPYING
@@ -0,0 +1,34 @@
1Copyright 2002-2006
2 Xiph.org Foundation
3 Jean-Marc Valin
4 David Rowe
5 EpicGames
6 Analog Devices
7 Commonwealth Scientific and Industrial Research Organisation (CSIRO)
8
9Redistribution and use in source and binary forms, with or without
10modification, are permitted provided that the following conditions
11are met:
12
13- Redistributions of source code must retain the above copyright
14notice, this list of conditions and the following disclaimer.
15
16- Redistributions in binary form must reproduce the above copyright
17notice, this list of conditions and the following disclaimer in the
18documentation and/or other materials provided with the distribution.
19
20- Neither the name of the Xiph.org Foundation nor the names of its
21contributors may be used to endorse or promote products derived from
22this software without specific prior written permission.
23
24THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
28CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/lib/rbcodec/codecs/libspeex/README.rockbox b/lib/rbcodec/codecs/libspeex/README.rockbox
new file mode 100644
index 0000000000..84fff59b60
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/README.rockbox
@@ -0,0 +1,30 @@
1Library: libspeex-1.2beta3 (SVN version 14054)
2Imported: 2007-03-12 by Dan Everton
3
4
5This directory contains a local version of libspeex for decoding Ogg/Speex
6audio streams.
7
8
9LICENSING INFORMATION
10
11Speex is available under the terms of the Xiph.Org variant of the BSD
12license, which is both an open source and free software license. The
13license is described in the COPYING file in this directory.
14
15
16IMPORT DETAILS
17
18The .[ch] files from speex/libspeex/ and speex/include/ were imported
19into Rockbox. This includes the test files. Some hackery was done to
20the include files so that they #include properly when built in Rockbox.
21
22A simple config-speex.h file was added to enable libspeex's fixed-point
23integer-only mode and to specify the endianness of the target CPU. Also,
24ARM specific optimisations were enabled.
25
26Since some parts of Speex still rely on <math.h> functions, a simple
27include was created to get these parts to compile. Stub functions can be
28found in rockbox.c in this directory.
29
30
diff --git a/lib/rbcodec/codecs/libspeex/SOURCES b/lib/rbcodec/codecs/libspeex/SOURCES
new file mode 100644
index 0000000000..575bcb5bae
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/SOURCES
@@ -0,0 +1,45 @@
1bits.c
2cb_search.c
3exc_10_16_table.c
4exc_10_32_table.c
5exc_20_32_table.c
6exc_5_256_table.c
7exc_5_64_table.c
8exc_8_128_table.c
9filters.c
10gain_table.c
11gain_table_lbr.c
12hexc_10_32_table.c
13hexc_table.c
14high_lsp_tables.c
15lsp.c
16lsp_tables_nb.c
17ltp.c
18modes.c
19modes_wb.c
20nb_celp.c
21quant_lsp.c
22sb_celp.c
23speex.c
24speex_callbacks.c
25#ifndef ROCKBOX_VOICE_CODEC
26#ifndef ROCKBOX_VOICE_ENCODER
27oggframing.c
28#endif
29stereo.c
30speex_header.c
31#endif
32#ifdef ROCKBOX_VOICE_ENCODER
33lpc.c
34vbr.c
35vq.c
36window.c
37resample.c
38#else
39#ifdef CPU_COLDFIRE
40filters_cf.S
41ltp_cf.S
42#elif defined(CPU_ARM)
43filters_arm4.S
44#endif
45#endif
diff --git a/lib/rbcodec/codecs/libspeex/_kiss_fft_guts.h b/lib/rbcodec/codecs/libspeex/_kiss_fft_guts.h
new file mode 100644
index 0000000000..12c055040f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/_kiss_fft_guts.h
@@ -0,0 +1,166 @@
1/*
2Copyright (c) 2003-2004, Mark Borgerding
3
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 * 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.
10 * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
12THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*/
14
15#ifdef MIN
16#undef MIN
17#endif
18#define MIN(a,b) ((a)<(b) ? (a):(b))
19#ifdef MAX
20#undef MAX
21#endif
22#define MAX(a,b) ((a)>(b) ? (a):(b))
23
24/* kiss_fft.h
25 defines kiss_fft_scalar as either short or a float type
26 and defines
27 typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
28#include "kiss_fft.h"
29#include "math_approx.h"
30
31#define MAXFACTORS 32
32/* e.g. an fft of length 128 has 4 factors
33 as far as kissfft is concerned
34 4*4*4*2
35 */
36
37struct kiss_fft_state{
38 int nfft;
39 int inverse;
40 int factors[2*MAXFACTORS];
41 kiss_fft_cpx twiddles[1];
42};
43
44/*
45 Explanation of macros dealing with complex math:
46
47 C_MUL(m,a,b) : m = a*b
48 C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
49 C_SUB( res, a,b) : res = a - b
50 C_SUBFROM( res , a) : res -= a
51 C_ADDTO( res , a) : res += a
52 * */
53#ifdef FIXED_POINT
54#include "arch.h"
55# define FRACBITS 15
56# define SAMPPROD spx_int32_t
57#define SAMP_MAX 32767
58
59#define SAMP_MIN -SAMP_MAX
60
61#if defined(CHECK_OVERFLOW)
62# define CHECK_OVERFLOW_OP(a,op,b) \
63 if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
64 fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); }
65#endif
66
67
68# define smul(a,b) ( (SAMPPROD)(a)*(b) )
69# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
70
71# define S_MUL(a,b) sround( smul(a,b) )
72
73# define C_MUL(m,a,b) \
74 do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
75 (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
76
77# define C_MUL4(m,a,b) \
78 do{ (m).r = PSHR32( smul((a).r,(b).r) - smul((a).i,(b).i),17 ); \
79 (m).i = PSHR32( smul((a).r,(b).i) + smul((a).i,(b).r),17 ); }while(0)
80
81# define DIVSCALAR(x,k) \
82 (x) = sround( smul( x, SAMP_MAX/k ) )
83
84# define C_FIXDIV(c,div) \
85 do { DIVSCALAR( (c).r , div); \
86 DIVSCALAR( (c).i , div); }while (0)
87
88# define C_MULBYSCALAR( c, s ) \
89 do{ (c).r = sround( smul( (c).r , s ) ) ;\
90 (c).i = sround( smul( (c).i , s ) ) ; }while(0)
91
92#else /* not FIXED_POINT*/
93
94# define S_MUL(a,b) ( (a)*(b) )
95#define C_MUL(m,a,b) \
96 do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
97 (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
98
99#define C_MUL4(m,a,b) C_MUL(m,a,b)
100
101# define C_FIXDIV(c,div) /* NOOP */
102# define C_MULBYSCALAR( c, s ) \
103 do{ (c).r *= (s);\
104 (c).i *= (s); }while(0)
105#endif
106
107#ifndef CHECK_OVERFLOW_OP
108# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
109#endif
110
111#define C_ADD( res, a,b)\
112 do { \
113 CHECK_OVERFLOW_OP((a).r,+,(b).r)\
114 CHECK_OVERFLOW_OP((a).i,+,(b).i)\
115 (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
116 }while(0)
117#define C_SUB( res, a,b)\
118 do { \
119 CHECK_OVERFLOW_OP((a).r,-,(b).r)\
120 CHECK_OVERFLOW_OP((a).i,-,(b).i)\
121 (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
122 }while(0)
123#define C_ADDTO( res , a)\
124 do { \
125 CHECK_OVERFLOW_OP((res).r,+,(a).r)\
126 CHECK_OVERFLOW_OP((res).i,+,(a).i)\
127 (res).r += (a).r; (res).i += (a).i;\
128 }while(0)
129
130#define C_SUBFROM( res , a)\
131 do {\
132 CHECK_OVERFLOW_OP((res).r,-,(a).r)\
133 CHECK_OVERFLOW_OP((res).i,-,(a).i)\
134 (res).r -= (a).r; (res).i -= (a).i; \
135 }while(0)
136
137
138#ifdef FIXED_POINT
139# define KISS_FFT_COS(phase) floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase))))
140# define KISS_FFT_SIN(phase) floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))
141# define HALF_OF(x) ((x)>>1)
142#elif defined(USE_SIMD)
143# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
144# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
145# define HALF_OF(x) ((x)*_mm_set1_ps(.5))
146#else
147# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
148# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
149# define HALF_OF(x) ((x)*.5)
150#endif
151
152#define kf_cexp(x,phase) \
153 do{ \
154 (x)->r = KISS_FFT_COS(phase);\
155 (x)->i = KISS_FFT_SIN(phase);\
156 }while(0)
157#define kf_cexp2(x,phase) \
158 do{ \
159 (x)->r = spx_cos_norm((phase));\
160 (x)->i = spx_cos_norm((phase)-32768);\
161}while(0)
162
163
164/* a debugging function */
165#define pcpx(c)\
166 fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
diff --git a/lib/rbcodec/codecs/libspeex/arch.h b/lib/rbcodec/codecs/libspeex/arch.h
new file mode 100644
index 0000000000..35b5363837
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/arch.h
@@ -0,0 +1,242 @@
1/* Copyright (C) 2003 Jean-Marc Valin */
2/**
3 @file arch.h
4 @brief Various architecture definitions Speex
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef ARCH_H
36#define ARCH_H
37
38#include "config-speex.h"
39
40#ifndef SPEEX_VERSION
41#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */
42#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */
43#define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */
44#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */
45#define SPEEX_VERSION "speex-1.2beta4" /**< Speex version string. */
46#endif
47
48/* A couple test to catch stupid option combinations */
49#ifdef FIXED_POINT
50
51#ifdef FLOATING_POINT
52#error You cannot compile as floating point and fixed point at the same time
53#endif
54#ifdef _USE_SSE
55#error SSE is only for floating-point
56#endif
57#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))
58#error Make up your mind. What CPU do you have?
59#endif
60#ifdef VORBIS_PSYCHO
61#error Vorbis-psy model currently not implemented in fixed-point
62#endif
63
64#else
65
66#ifndef FLOATING_POINT
67#error You now need to define either FIXED_POINT or FLOATING_POINT
68#endif
69#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
70#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?
71#endif
72#ifdef FIXED_POINT_DEBUG
73#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?"
74#endif
75
76
77#endif
78
79#ifndef OUTSIDE_SPEEX
80#include "speex/speex_types.h"
81#endif
82
83#undef ABS
84#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
85#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */
86#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */
87#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
88#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */
89#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */
90#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
91
92#ifdef FIXED_POINT
93
94typedef spx_int16_t spx_word16_t;
95typedef spx_int32_t spx_word32_t;
96typedef spx_word32_t spx_mem_t;
97typedef spx_word16_t spx_coef_t;
98typedef spx_word16_t spx_lsp_t;
99typedef spx_word32_t spx_sig_t;
100
101#define Q15ONE 32767
102
103#define LPC_SCALING 8192
104#define SIG_SCALING 16384
105#define LSP_SCALING 8192.
106#define GAMMA_SCALING 32768.
107#define GAIN_SCALING 64
108#define GAIN_SCALING_1 0.015625
109
110#define LPC_SHIFT 13
111#define LSP_SHIFT 13
112#define SIG_SHIFT 14
113#define GAIN_SHIFT 6
114
115#define VERY_SMALL 0
116#define VERY_LARGE32 ((spx_word32_t)2147483647)
117#define VERY_LARGE16 ((spx_word16_t)32767)
118#define Q15_ONE ((spx_word16_t)32767)
119
120
121#ifdef FIXED_DEBUG
122#include "fixed_debug.h"
123#else
124
125#include "fixed_generic.h"
126
127#ifdef ARM5E_ASM
128#include "fixed_arm5e.h"
129#elif defined (ARM4_ASM)
130#include "fixed_arm4.h"
131#elif defined (BFIN_ASM)
132#include "fixed_bfin.h"
133#endif
134
135#endif
136
137
138#else
139
140typedef float spx_mem_t;
141typedef float spx_coef_t;
142typedef float spx_lsp_t;
143typedef float spx_sig_t;
144typedef float spx_word16_t;
145typedef float spx_word32_t;
146
147#define Q15ONE 1.0f
148#define LPC_SCALING 1.f
149#define SIG_SCALING 1.f
150#define LSP_SCALING 1.f
151#define GAMMA_SCALING 1.f
152#define GAIN_SCALING 1.f
153#define GAIN_SCALING_1 1.f
154
155
156#define VERY_SMALL 1e-15f
157#define VERY_LARGE32 1e15f
158#define VERY_LARGE16 1e15f
159#define Q15_ONE ((spx_word16_t)1.f)
160
161#define QCONST16(x,bits) (x)
162#define QCONST32(x,bits) (x)
163
164#define NEG16(x) (-(x))
165#define NEG32(x) (-(x))
166#define EXTRACT16(x) (x)
167#define EXTEND32(x) (x)
168#define SHR16(a,shift) (a)
169#define SHL16(a,shift) (a)
170#define SHR32(a,shift) (a)
171#define SHL32(a,shift) (a)
172#define PSHR16(a,shift) (a)
173#define PSHR32(a,shift) (a)
174#define VSHR32(a,shift) (a)
175#define SATURATE16(x,a) (x)
176#define SATURATE32(x,a) (x)
177
178#define PSHR(a,shift) (a)
179#define SHR(a,shift) (a)
180#define SHL(a,shift) (a)
181#define SATURATE(x,a) (x)
182
183#define ADD16(a,b) ((a)+(b))
184#define SUB16(a,b) ((a)-(b))
185#define ADD32(a,b) ((a)+(b))
186#define SUB32(a,b) ((a)-(b))
187#define MULT16_16_16(a,b) ((a)*(b))
188#define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b))
189#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b))
190
191#define MULT16_32_Q11(a,b) ((a)*(b))
192#define MULT16_32_Q13(a,b) ((a)*(b))
193#define MULT16_32_Q14(a,b) ((a)*(b))
194#define MULT16_32_Q15(a,b) ((a)*(b))
195#define MULT16_32_P15(a,b) ((a)*(b))
196
197#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b))
198#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
199
200#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b))
201#define MAC16_16_Q13(c,a,b) ((c)+(a)*(b))
202#define MAC16_16_P13(c,a,b) ((c)+(a)*(b))
203#define MULT16_16_Q11_32(a,b) ((a)*(b))
204#define MULT16_16_Q13(a,b) ((a)*(b))
205#define MULT16_16_Q14(a,b) ((a)*(b))
206#define MULT16_16_Q15(a,b) ((a)*(b))
207#define MULT16_16_P15(a,b) ((a)*(b))
208#define MULT16_16_P13(a,b) ((a)*(b))
209#define MULT16_16_P14(a,b) ((a)*(b))
210
211#define DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
212#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
213#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
214#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
215
216
217#endif
218
219
220#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
221
222/* 2 on TI C5x DSP */
223#define BYTES_PER_CHAR 2
224#define BITS_PER_CHAR 16
225#define LOG2_BITS_PER_CHAR 4
226
227#else
228
229#define BYTES_PER_CHAR 1
230#define BITS_PER_CHAR 8
231#define LOG2_BITS_PER_CHAR 3
232
233#endif
234
235
236
237#ifdef FIXED_DEBUG
238long long spx_mips=0;
239#endif
240
241
242#endif
diff --git a/lib/rbcodec/codecs/libspeex/bits.c b/lib/rbcodec/codecs/libspeex/bits.c
new file mode 100644
index 0000000000..c7a5c14ede
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/bits.c
@@ -0,0 +1,399 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: speex_bits.c
3
4 Handles bit packing/unpacking
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35#ifdef HAVE_CONFIG_H
36#include "config-speex.h"
37#endif
38
39#include "speex/speex_bits.h"
40#include "arch.h"
41#include "os_support.h"
42
43/* Maximum size of the bit-stream (for fixed-size allocation) */
44#ifndef MAX_CHARS_PER_FRAME
45#define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR)
46#endif
47
48#ifdef ROCKBOX_VOICE_ENCODER
49void speex_bits_init(SpeexBits *bits)
50{
51 bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);
52 if (!bits->chars)
53 return;
54
55 bits->buf_size = MAX_CHARS_PER_FRAME;
56
57 bits->owner=1;
58
59 speex_bits_reset(bits);
60}
61#endif
62
63#if 0
64/* Rockbox: unused */
65void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
66{
67 bits->chars = (char*)buff;
68 bits->buf_size = buf_size;
69
70 bits->owner=0;
71
72 speex_bits_reset(bits);
73}
74#endif
75
76void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size)
77{
78 bits->chars = (char*)buff;
79 bits->buf_size = buf_size;
80
81 bits->owner=0;
82
83 bits->nbBits=buf_size<<LOG2_BITS_PER_CHAR;
84 bits->charPtr=0;
85 bits->bitPtr=0;
86 bits->overflow=0;
87
88}
89
90#ifndef ROCKBOX_VOICE_CODEC
91void speex_bits_destroy(SpeexBits *bits)
92{
93 if (bits->owner)
94 speex_free(bits->chars);
95 /* Will do something once the allocation is dynamic */
96}
97#endif
98
99#ifdef ROCKBOX_VOICE_ENCODER
100void speex_bits_reset(SpeexBits *bits)
101{
102 /* We only need to clear the first byte now */
103 bits->chars[0]=0;
104 bits->nbBits=0;
105 bits->charPtr=0;
106 bits->bitPtr=0;
107 bits->overflow=0;
108}
109#endif
110
111#if 0
112/* Rockbox: unused */
113void speex_bits_rewind(SpeexBits *bits)
114{
115 bits->charPtr=0;
116 bits->bitPtr=0;
117 bits->overflow=0;
118}
119#endif
120
121#if !defined(SPEEX_VOICE_ENCODER) && !defined(ROCKBOX_VOICE_CODEC)
122void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
123{
124 int i;
125 int nchars = len / BYTES_PER_CHAR;
126 if (nchars > bits->buf_size)
127 {
128 speex_notify("Packet is larger than allocated buffer");
129 if (bits->owner)
130 {
131 char *tmp = (char*)speex_realloc(bits->chars, nchars);
132 if (tmp)
133 {
134 bits->buf_size=nchars;
135 bits->chars=tmp;
136 } else {
137 nchars=bits->buf_size;
138 speex_warning("Could not resize input buffer: truncating input");
139 }
140 } else {
141 speex_warning("Do not own input buffer: truncating oversize input");
142 nchars=bits->buf_size;
143 }
144 }
145#if (BYTES_PER_CHAR==2)
146/* Swap bytes to proper endian order (could be done externally) */
147#define HTOLS(A) ((((A) >> 8)&0xff)|(((A) & 0xff)<<8))
148#else
149#define HTOLS(A) (A)
150#endif
151 for (i=0;i<nchars;i++)
152 bits->chars[i]=HTOLS(chars[i]);
153
154 bits->nbBits=nchars<<LOG2_BITS_PER_CHAR;
155 bits->charPtr=0;
156 bits->bitPtr=0;
157 bits->overflow=0;
158}
159
160static void speex_bits_flush(SpeexBits *bits)
161{
162 int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
163 if (bits->charPtr>0)
164 SPEEX_MOVE(bits->chars, &bits->chars[bits->charPtr], nchars-bits->charPtr);
165 bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;
166 bits->charPtr=0;
167}
168
169void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
170{
171 int i,pos;
172 int nchars = nbytes/BYTES_PER_CHAR;
173
174 if (((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)+nchars > bits->buf_size)
175 {
176 /* Packet is larger than allocated buffer */
177 if (bits->owner)
178 {
179 char *tmp = (char*)speex_realloc(bits->chars, (bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1);
180 if (tmp)
181 {
182 bits->buf_size=(bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1;
183 bits->chars=tmp;
184 } else {
185 nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;
186 speex_warning("Could not resize input buffer: truncating oversize input");
187 }
188 } else {
189 speex_warning("Do not own input buffer: truncating oversize input");
190 nchars=bits->buf_size;
191 }
192 }
193
194 speex_bits_flush(bits);
195 pos=bits->nbBits>>LOG2_BITS_PER_CHAR;
196 for (i=0;i<nchars;i++)
197 bits->chars[pos+i]=HTOLS(chars[i]);
198 bits->nbBits+=nchars<<LOG2_BITS_PER_CHAR;
199}
200#endif
201
202#ifndef SPEEX_DISABLE_ENCODER
203int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
204{
205 int i;
206 int max_nchars = max_nbytes/BYTES_PER_CHAR;
207 int charPtr, bitPtr, nbBits;
208
209 /* Insert terminator, but save the data so we can put it back after */
210 bitPtr=bits->bitPtr;
211 charPtr=bits->charPtr;
212 nbBits=bits->nbBits;
213 speex_bits_insert_terminator(bits);
214 bits->bitPtr=bitPtr;
215 bits->charPtr=charPtr;
216 bits->nbBits=nbBits;
217
218 if (max_nchars > ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR))
219 max_nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
220
221 for (i=0;i<max_nchars;i++)
222 chars[i]=HTOLS(bits->chars[i]);
223 return max_nchars*BYTES_PER_CHAR;
224}
225
226int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)
227{
228 int max_nchars = max_nbytes/BYTES_PER_CHAR;
229 int i;
230 if (max_nchars > ((bits->nbBits)>>LOG2_BITS_PER_CHAR))
231 max_nchars = ((bits->nbBits)>>LOG2_BITS_PER_CHAR);
232 for (i=0;i<max_nchars;i++)
233 chars[i]=HTOLS(bits->chars[i]);
234
235 if (bits->bitPtr>0)
236 bits->chars[0]=bits->chars[max_nchars];
237 else
238 bits->chars[0]=0;
239 bits->charPtr=0;
240 bits->nbBits &= (BITS_PER_CHAR-1);
241 return max_nchars*BYTES_PER_CHAR;
242}
243
244void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
245{
246 unsigned int d=data;
247
248 if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
249 {
250 speex_notify("Buffer too small to pack bits");
251 if (bits->owner)
252 {
253 int new_nchars = ((bits->buf_size+5)*3)>>1;
254 char *tmp = (char*)speex_realloc(bits->chars, new_nchars);
255 if (tmp)
256 {
257 bits->buf_size=new_nchars;
258 bits->chars=tmp;
259 } else {
260 speex_warning("Could not resize input buffer: not packing");
261 return;
262 }
263 } else {
264 speex_warning("Do not own input buffer: not packing");
265 return;
266 }
267 }
268
269 while(nbBits)
270 {
271 int bit;
272 bit = (d>>(nbBits-1))&1;
273 bits->chars[bits->charPtr] |= bit<<(BITS_PER_CHAR-1-bits->bitPtr);
274 bits->bitPtr++;
275
276 if (bits->bitPtr==BITS_PER_CHAR)
277 {
278 bits->bitPtr=0;
279 bits->charPtr++;
280 bits->chars[bits->charPtr] = 0;
281 }
282 bits->nbBits++;
283 nbBits--;
284 }
285}
286#endif /* SPEEX_DISABLE_ENCODER */
287
288#if 0
289/* Rockbox: unused */
290int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
291{
292 unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
293 /* If number is negative */
294 if (d>>(nbBits-1))
295 {
296 d |= (-1)<<nbBits;
297 }
298 return d;
299}
300#endif
301
302unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
303{
304 unsigned int d=0;
305 if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
306 bits->overflow=1;
307 if (bits->overflow)
308 return 0;
309 while(nbBits)
310 {
311 d<<=1;
312 d |= (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
313 bits->bitPtr++;
314 if (bits->bitPtr==BITS_PER_CHAR)
315 {
316 bits->bitPtr=0;
317 bits->charPtr++;
318 }
319 nbBits--;
320 }
321 return d;
322}
323
324#if 0
325/* Rockbox: unused */
326unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
327{
328 unsigned int d=0;
329 int bitPtr, charPtr;
330 char *chars;
331
332 if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
333 bits->overflow=1;
334 if (bits->overflow)
335 return 0;
336
337 bitPtr=bits->bitPtr;
338 charPtr=bits->charPtr;
339 chars = bits->chars;
340 while(nbBits)
341 {
342 d<<=1;
343 d |= (chars[charPtr]>>(BITS_PER_CHAR-1 - bitPtr))&1;
344 bitPtr++;
345 if (bitPtr==BITS_PER_CHAR)
346 {
347 bitPtr=0;
348 charPtr++;
349 }
350 nbBits--;
351 }
352 return d;
353}
354#endif
355
356int speex_bits_peek(SpeexBits *bits)
357{
358 if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)
359 bits->overflow=1;
360 if (bits->overflow)
361 return 0;
362 return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
363}
364
365void speex_bits_advance(SpeexBits *bits, int n)
366{
367 if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
368 bits->overflow=1;
369 return;
370 }
371 bits->charPtr += (bits->bitPtr+n) >> LOG2_BITS_PER_CHAR; /* divide by BITS_PER_CHAR */
372 bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1); /* modulo by BITS_PER_CHAR */
373}
374
375int speex_bits_remaining(SpeexBits *bits)
376{
377 if (bits->overflow)
378 return -1;
379 else
380 return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);
381}
382
383#if 0
384/* Rockbox: unused */
385int speex_bits_nbytes(SpeexBits *bits)
386{
387 return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
388}
389#endif
390
391#ifndef SPEEX_DISABLE_ENCODER
392void speex_bits_insert_terminator(SpeexBits *bits)
393{
394 if (bits->bitPtr)
395 speex_bits_pack(bits, 0, 1);
396 while (bits->bitPtr)
397 speex_bits_pack(bits, 1, 1);
398}
399#endif /* SPEEX_DISABLE_ENCODER */
diff --git a/lib/rbcodec/codecs/libspeex/cb_search.c b/lib/rbcodec/codecs/libspeex/cb_search.c
new file mode 100644
index 0000000000..35fe3a2f67
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/cb_search.c
@@ -0,0 +1,621 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin
2 File: cb_search.c
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#ifdef HAVE_CONFIG_H
33#include "config-speex.h"
34#endif
35
36#include "cb_search.h"
37#include "filters.h"
38#include "stack_alloc.h"
39#include "vq.h"
40#include "arch.h"
41#include "math_approx.h"
42#include "os_support.h"
43
44#ifdef _USE_SSE
45#include "cb_search_sse.h"
46#elif defined(ARM4_ASM) || defined(ARM5E_ASM)
47#include "cb_search_arm4.h"
48#elif defined(BFIN_ASM)
49#include "cb_search_bfin.h"
50#endif
51
52#ifndef SPEEX_DISABLE_ENCODER
53#ifndef OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
54static void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
55{
56 int i, j, k;
57 VARDECL(spx_word16_t *shape);
58 ALLOC(shape, subvect_size, spx_word16_t);
59 for (i=0;i<shape_cb_size;i++)
60 {
61 spx_word16_t *res;
62
63 res = resp+i*subvect_size;
64 for (k=0;k<subvect_size;k++)
65 shape[k] = (spx_word16_t)shape_cb[i*subvect_size+k];
66 E[i]=0;
67
68 /* Compute codeword response using convolution with impulse response */
69 for(j=0;j<subvect_size;j++)
70 {
71 spx_word32_t resj=0;
72 spx_word16_t res16;
73 for (k=0;k<=j;k++)
74 resj = MAC16_16(resj,shape[k],r[j-k]);
75#ifdef FIXED_POINT
76 res16 = EXTRACT16(SHR32(resj, 13));
77#else
78 res16 = 0.03125f*resj;
79#endif
80 /* Compute codeword energy */
81 E[i]=MAC16_16(E[i],res16,res16);
82 res[j] = res16;
83 /*printf ("%d\n", (int)res[j]);*/
84 }
85 }
86
87}
88#endif
89
90#ifndef OVERRIDE_TARGET_UPDATE
91static inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len)
92{
93 int n;
94 for (n=0;n<len;n++)
95 t[n] = SUB16(t[n],PSHR32(MULT16_16(g,r[n]),13));
96}
97#endif
98
99
100
101static void split_cb_search_shape_sign_N1(
102spx_word16_t target[], /* target vector */
103spx_coef_t ak[], /* LPCs for this subframe */
104spx_coef_t awk1[], /* Weighted LPCs for this subframe */
105spx_coef_t awk2[], /* Weighted LPCs for this subframe */
106const void *par, /* Codebook/search parameters*/
107int p, /* number of LPC coeffs */
108int nsf, /* number of samples in subframe */
109spx_sig_t *exc,
110spx_word16_t *r,
111SpeexBits *bits,
112char *stack,
113int update_target
114)
115{
116 int i,j,m,q;
117 VARDECL(spx_word16_t *resp);
118#ifdef _USE_SSE
119 VARDECL(__m128 *resp2);
120 VARDECL(__m128 *E);
121#else
122 spx_word16_t *resp2;
123 VARDECL(spx_word32_t *E);
124#endif
125 VARDECL(spx_word16_t *t);
126 VARDECL(spx_sig_t *e);
127 const signed char *shape_cb;
128 int shape_cb_size, subvect_size, nb_subvect;
129 const split_cb_params *params;
130 int best_index;
131 spx_word32_t best_dist;
132 int have_sign;
133
134 params = (const split_cb_params *) par;
135 subvect_size = params->subvect_size;
136 nb_subvect = params->nb_subvect;
137 shape_cb_size = 1<<params->shape_bits;
138 shape_cb = params->shape_cb;
139 have_sign = params->have_sign;
140 ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);
141#ifdef _USE_SSE
142 ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);
143 ALLOC(E, shape_cb_size>>2, __m128);
144#else
145 resp2 = resp;
146 ALLOC(E, shape_cb_size, spx_word32_t);
147#endif
148 ALLOC(t, nsf, spx_word16_t);
149 ALLOC(e, nsf, spx_sig_t);
150
151 /* FIXME: Do we still need to copy the target? */
152 SPEEX_COPY(t, target, nsf);
153
154 compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
155
156 for (i=0;i<nb_subvect;i++)
157 {
158 spx_word16_t *x=t+subvect_size*i;
159 /*Find new n-best based on previous n-best j*/
160 if (have_sign)
161 vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
162 else
163 vq_nbest(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
164
165 speex_bits_pack(bits,best_index,params->shape_bits+have_sign);
166
167 {
168 int rind;
169 spx_word16_t *res;
170 spx_word16_t sign=1;
171 rind = best_index;
172 if (rind>=shape_cb_size)
173 {
174 sign=-1;
175 rind-=shape_cb_size;
176 }
177 res = resp+rind*subvect_size;
178 if (sign>0)
179 for (m=0;m<subvect_size;m++)
180 t[subvect_size*i+m] = SUB16(t[subvect_size*i+m], res[m]);
181 else
182 for (m=0;m<subvect_size;m++)
183 t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]);
184
185#ifdef FIXED_POINT
186 if (sign==1)
187 {
188 for (j=0;j<subvect_size;j++)
189 e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
190 } else {
191 for (j=0;j<subvect_size;j++)
192 e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));
193 }
194#else
195 for (j=0;j<subvect_size;j++)
196 e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
197#endif
198
199 }
200
201 for (m=0;m<subvect_size;m++)
202 {
203 spx_word16_t g;
204 int rind;
205 spx_word16_t sign=1;
206 rind = best_index;
207 if (rind>=shape_cb_size)
208 {
209 sign=-1;
210 rind-=shape_cb_size;
211 }
212
213 q=subvect_size-m;
214#ifdef FIXED_POINT
215 g=sign*shape_cb[rind*subvect_size+m];
216#else
217 g=sign*0.03125*shape_cb[rind*subvect_size+m];
218#endif
219 target_update(t+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));
220 }
221 }
222
223 /* Update excitation */
224 /* FIXME: We could update the excitation directly above */
225 for (j=0;j<nsf;j++)
226 exc[j]=ADD32(exc[j],e[j]);
227
228 /* Update target: only update target if necessary */
229 if (update_target)
230 {
231 VARDECL(spx_word16_t *r2);
232 ALLOC(r2, nsf, spx_word16_t);
233 for (j=0;j<nsf;j++)
234 r2[j] = EXTRACT16(PSHR32(e[j] ,6));
235 syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);
236 for (j=0;j<nsf;j++)
237 target[j]=SUB16(target[j],PSHR16(r2[j],2));
238 }
239}
240
241
242
243void split_cb_search_shape_sign(
244spx_word16_t target[], /* target vector */
245spx_coef_t ak[], /* LPCs for this subframe */
246spx_coef_t awk1[], /* Weighted LPCs for this subframe */
247spx_coef_t awk2[], /* Weighted LPCs for this subframe */
248const void *par, /* Codebook/search parameters*/
249int p, /* number of LPC coeffs */
250int nsf, /* number of samples in subframe */
251spx_sig_t *exc,
252spx_word16_t *r,
253SpeexBits *bits,
254char *stack,
255int complexity,
256int update_target
257)
258{
259 int i,j,k,m,n,q;
260 VARDECL(spx_word16_t *resp);
261#ifdef _USE_SSE
262 VARDECL(__m128 *resp2);
263 VARDECL(__m128 *E);
264#else
265 spx_word16_t *resp2;
266 VARDECL(spx_word32_t *E);
267#endif
268 VARDECL(spx_word16_t *t);
269 VARDECL(spx_sig_t *e);
270 VARDECL(spx_word16_t *tmp);
271 VARDECL(spx_word32_t *ndist);
272 VARDECL(spx_word32_t *odist);
273 VARDECL(int *itmp);
274 VARDECL(spx_word16_t **ot2);
275 VARDECL(spx_word16_t **nt2);
276 spx_word16_t **ot, **nt;
277 VARDECL(int **nind);
278 VARDECL(int **oind);
279 VARDECL(int *ind);
280 const signed char *shape_cb;
281 int shape_cb_size, subvect_size, nb_subvect;
282 const split_cb_params *params;
283 int N=2;
284 VARDECL(int *best_index);
285 VARDECL(spx_word32_t *best_dist);
286 VARDECL(int *best_nind);
287 VARDECL(int *best_ntarget);
288 int have_sign;
289 N=complexity;
290 if (N>10)
291 N=10;
292 /* Complexity isn't as important for the codebooks as it is for the pitch */
293 N=(2*N)/3;
294 if (N<1)
295 N=1;
296 if (N==1)
297 {
298 split_cb_search_shape_sign_N1(target,ak,awk1,awk2,par,p,nsf,exc,r,bits,stack,update_target);
299 return;
300 }
301 ALLOC(ot2, N, spx_word16_t*);
302 ALLOC(nt2, N, spx_word16_t*);
303 ALLOC(oind, N, int*);
304 ALLOC(nind, N, int*);
305
306 params = (const split_cb_params *) par;
307 subvect_size = params->subvect_size;
308 nb_subvect = params->nb_subvect;
309 shape_cb_size = 1<<params->shape_bits;
310 shape_cb = params->shape_cb;
311 have_sign = params->have_sign;
312 ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);
313#ifdef _USE_SSE
314 ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);
315 ALLOC(E, shape_cb_size>>2, __m128);
316#else
317 resp2 = resp;
318 ALLOC(E, shape_cb_size, spx_word32_t);
319#endif
320 ALLOC(t, nsf, spx_word16_t);
321 ALLOC(e, nsf, spx_sig_t);
322 ALLOC(ind, nb_subvect, int);
323
324 ALLOC(tmp, 2*N*nsf, spx_word16_t);
325 for (i=0;i<N;i++)
326 {
327 ot2[i]=tmp+2*i*nsf;
328 nt2[i]=tmp+(2*i+1)*nsf;
329 }
330 ot=ot2;
331 nt=nt2;
332 ALLOC(best_index, N, int);
333 ALLOC(best_dist, N, spx_word32_t);
334 ALLOC(best_nind, N, int);
335 ALLOC(best_ntarget, N, int);
336 ALLOC(ndist, N, spx_word32_t);
337 ALLOC(odist, N, spx_word32_t);
338
339 ALLOC(itmp, 2*N*nb_subvect, int);
340 for (i=0;i<N;i++)
341 {
342 nind[i]=itmp+2*i*nb_subvect;
343 oind[i]=itmp+(2*i+1)*nb_subvect;
344 }
345
346 SPEEX_COPY(t, target, nsf);
347
348 for (j=0;j<N;j++)
349 SPEEX_COPY(&ot[j][0], t, nsf);
350
351 /* Pre-compute codewords response and energy */
352 compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
353
354 for (j=0;j<N;j++)
355 odist[j]=0;
356
357 /*For all subvectors*/
358 for (i=0;i<nb_subvect;i++)
359 {
360 /*"erase" nbest list*/
361 for (j=0;j<N;j++)
362 ndist[j]=VERY_LARGE32;
363 /* This is not strictly necessary, but it provides an additonal safety
364 to prevent crashes in case something goes wrong in the previous
365 steps (e.g. NaNs) */
366 for (j=0;j<N;j++)
367 best_nind[j] = best_ntarget[j] = 0;
368 /*For all n-bests of previous subvector*/
369 for (j=0;j<N;j++)
370 {
371 spx_word16_t *x=ot[j]+subvect_size*i;
372 spx_word32_t tener = 0;
373 for (m=0;m<subvect_size;m++)
374 tener = MAC16_16(tener, x[m],x[m]);
375#ifdef FIXED_POINT
376 tener = SHR32(tener,1);
377#else
378 tener *= .5;
379#endif
380 /*Find new n-best based on previous n-best j*/
381 if (have_sign)
382 vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
383 else
384 vq_nbest(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
385
386 /*For all new n-bests*/
387 for (k=0;k<N;k++)
388 {
389 /* Compute total distance (including previous sub-vectors */
390 spx_word32_t err = ADD32(ADD32(odist[j],best_dist[k]),tener);
391
392 /*update n-best list*/
393 if (err<ndist[N-1])
394 {
395 for (m=0;m<N;m++)
396 {
397 if (err < ndist[m])
398 {
399 for (n=N-1;n>m;n--)
400 {
401 ndist[n] = ndist[n-1];
402 best_nind[n] = best_nind[n-1];
403 best_ntarget[n] = best_ntarget[n-1];
404 }
405 /* n is equal to m here, so they're interchangeable */
406 ndist[m] = err;
407 best_nind[n] = best_index[k];
408 best_ntarget[n] = j;
409 break;
410 }
411 }
412 }
413 }
414 if (i==0)
415 break;
416 }
417 for (j=0;j<N;j++)
418 {
419 /*previous target (we don't care what happened before*/
420 for (m=(i+1)*subvect_size;m<nsf;m++)
421 nt[j][m]=ot[best_ntarget[j]][m];
422
423 /* New code: update the rest of the target only if it's worth it */
424 for (m=0;m<subvect_size;m++)
425 {
426 spx_word16_t g;
427 int rind;
428 spx_word16_t sign=1;
429 rind = best_nind[j];
430 if (rind>=shape_cb_size)
431 {
432 sign=-1;
433 rind-=shape_cb_size;
434 }
435
436 q=subvect_size-m;
437#ifdef FIXED_POINT
438 g=sign*shape_cb[rind*subvect_size+m];
439#else
440 g=sign*0.03125*shape_cb[rind*subvect_size+m];
441#endif
442 target_update(nt[j]+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));
443 }
444
445 for (q=0;q<nb_subvect;q++)
446 nind[j][q]=oind[best_ntarget[j]][q];
447 nind[j][i]=best_nind[j];
448 }
449
450 /*update old-new data*/
451 /* just swap pointers instead of a long copy */
452 {
453 spx_word16_t **tmp2;
454 tmp2=ot;
455 ot=nt;
456 nt=tmp2;
457 }
458 for (j=0;j<N;j++)
459 for (m=0;m<nb_subvect;m++)
460 oind[j][m]=nind[j][m];
461 for (j=0;j<N;j++)
462 odist[j]=ndist[j];
463 }
464
465 /*save indices*/
466 for (i=0;i<nb_subvect;i++)
467 {
468 ind[i]=nind[0][i];
469 speex_bits_pack(bits,ind[i],params->shape_bits+have_sign);
470 }
471
472 /* Put everything back together */
473 for (i=0;i<nb_subvect;i++)
474 {
475 int rind;
476 spx_word16_t sign=1;
477 rind = ind[i];
478 if (rind>=shape_cb_size)
479 {
480 sign=-1;
481 rind-=shape_cb_size;
482 }
483#ifdef FIXED_POINT
484 if (sign==1)
485 {
486 for (j=0;j<subvect_size;j++)
487 e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
488 } else {
489 for (j=0;j<subvect_size;j++)
490 e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));
491 }
492#else
493 for (j=0;j<subvect_size;j++)
494 e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
495#endif
496 }
497 /* Update excitation */
498 for (j=0;j<nsf;j++)
499 exc[j]=ADD32(exc[j],e[j]);
500
501 /* Update target: only update target if necessary */
502 if (update_target)
503 {
504 VARDECL(spx_word16_t *r2);
505 ALLOC(r2, nsf, spx_word16_t);
506 for (j=0;j<nsf;j++)
507 r2[j] = EXTRACT16(PSHR32(e[j] ,6));
508 syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);
509 for (j=0;j<nsf;j++)
510 target[j]=SUB16(target[j],PSHR16(r2[j],2));
511 }
512}
513#endif /* SPEEX_DISABLE_ENCODER*/
514
515
516void split_cb_shape_sign_unquant(
517spx_sig_t *exc,
518const void *par, /* non-overlapping codebook */
519int nsf, /* number of samples in subframe */
520SpeexBits *bits,
521char *stack,
522spx_int32_t *seed
523)
524{
525 (void)nsf;
526 (void)stack;
527 (void)seed;
528 int i,j;
529 VARDECL(int *ind);
530 VARDECL(int *signs);
531 const signed char *shape_cb;
532 int subvect_size, nb_subvect;
533 const split_cb_params *params;
534 int have_sign;
535
536 params = (const split_cb_params *) par;
537 subvect_size = params->subvect_size;
538 nb_subvect = params->nb_subvect;
539 shape_cb = params->shape_cb;
540 have_sign = params->have_sign;
541
542 ALLOC(ind, nb_subvect, int);
543 ALLOC(signs, nb_subvect, int);
544
545 /* Decode codewords and gains */
546 for (i=0;i<nb_subvect;i++)
547 {
548 if (have_sign)
549 signs[i] = speex_bits_unpack_unsigned(bits, 1);
550 else
551 signs[i] = 0;
552 ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits);
553 }
554 /* Compute decoded excitation */
555 for (i=0;i<nb_subvect;i++)
556 {
557 spx_word16_t s=1;
558 if (signs[i])
559 s=-1;
560#ifdef FIXED_POINT
561 if (s==1)
562 {
563 for (j=0;j<subvect_size;j++)
564 exc[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5);
565 } else {
566 for (j=0;j<subvect_size;j++)
567 exc[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5));
568 }
569#else
570 for (j=0;j<subvect_size;j++)
571 exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j];
572#endif
573 }
574}
575
576#ifndef SPEEX_DISABLE_ENCODER
577void noise_codebook_quant(
578spx_word16_t target[], /* target vector */
579spx_coef_t ak[], /* LPCs for this subframe */
580spx_coef_t awk1[], /* Weighted LPCs for this subframe */
581spx_coef_t awk2[], /* Weighted LPCs for this subframe */
582const void *par, /* Codebook/search parameters*/
583int p, /* number of LPC coeffs */
584int nsf, /* number of samples in subframe */
585spx_sig_t *exc,
586spx_word16_t *r,
587SpeexBits *bits,
588char *stack,
589int complexity,
590int update_target
591)
592{
593 int i;
594 VARDECL(spx_word16_t *tmp);
595 ALLOC(tmp, nsf, spx_word16_t);
596 residue_percep_zero16(target, ak, awk1, awk2, tmp, nsf, p, stack);
597
598 for (i=0;i<nsf;i++)
599 exc[i]+=SHL32(EXTEND32(tmp[i]),8);
600 SPEEX_MEMSET(target, 0, nsf);
601}
602#endif /* SPEEX_DISABLE_ENCODER */
603
604
605void noise_codebook_unquant(
606spx_sig_t *exc,
607const void *par, /* non-overlapping codebook */
608int nsf, /* number of samples in subframe */
609SpeexBits *bits,
610char *stack,
611spx_int32_t *seed
612)
613{
614 (void)par;
615 (void)bits;
616 (void)stack;
617 int i;
618 /* FIXME: This is bad, but I don't think the function ever gets called anyway */
619 for (i=0;i<nsf;i++)
620 exc[i]=SHL32(EXTEND32(speex_rand(1, seed)),SIG_SHIFT);
621}
diff --git a/lib/rbcodec/codecs/libspeex/cb_search.h b/lib/rbcodec/codecs/libspeex/cb_search.h
new file mode 100644
index 0000000000..50b530a725
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/cb_search.h
@@ -0,0 +1,103 @@
1/* Copyright (C) 2002 Jean-Marc Valin & David Rowe */
2/**
3 @file cb_search.h
4 @brief Overlapped codebook search
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef CB_SEARCH_H
36#define CB_SEARCH_H
37
38#include "speex/speex_bits.h"
39#include "arch.h"
40
41/** Split codebook parameters. */
42typedef struct split_cb_params {
43 int subvect_size;
44 int nb_subvect;
45 const signed char *shape_cb;
46 int shape_bits;
47 int have_sign;
48} split_cb_params;
49
50
51void split_cb_search_shape_sign(
52spx_word16_t target[], /* target vector */
53spx_coef_t ak[], /* LPCs for this subframe */
54spx_coef_t awk1[], /* Weighted LPCs for this subframe */
55spx_coef_t awk2[], /* Weighted LPCs for this subframe */
56const void *par, /* Codebook/search parameters */
57int p, /* number of LPC coeffs */
58int nsf, /* number of samples in subframe */
59spx_sig_t *exc,
60spx_word16_t *r,
61SpeexBits *bits,
62char *stack,
63int complexity,
64int update_target
65);
66
67void split_cb_shape_sign_unquant(
68spx_sig_t *exc,
69const void *par, /* non-overlapping codebook */
70int nsf, /* number of samples in subframe */
71SpeexBits *bits,
72char *stack,
73spx_int32_t *seed
74);
75
76
77void noise_codebook_quant(
78spx_word16_t target[], /* target vector */
79spx_coef_t ak[], /* LPCs for this subframe */
80spx_coef_t awk1[], /* Weighted LPCs for this subframe */
81spx_coef_t awk2[], /* Weighted LPCs for this subframe */
82const void *par, /* Codebook/search parameters */
83int p, /* number of LPC coeffs */
84int nsf, /* number of samples in subframe */
85spx_sig_t *exc,
86spx_word16_t *r,
87SpeexBits *bits,
88char *stack,
89int complexity,
90int update_target
91);
92
93
94void noise_codebook_unquant(
95spx_sig_t *exc,
96const void *par, /* non-overlapping codebook */
97int nsf, /* number of samples in subframe */
98SpeexBits *bits,
99char *stack,
100spx_int32_t *seed
101);
102
103#endif
diff --git a/lib/rbcodec/codecs/libspeex/cb_search_arm4.h b/lib/rbcodec/codecs/libspeex/cb_search_arm4.h
new file mode 100644
index 0000000000..19b752a4bc
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/cb_search_arm4.h
@@ -0,0 +1,137 @@
1/* Copyright (C) 2004 Jean-Marc Valin */
2/**
3 @file cb_search_arm4.h
4 @brief Fixed codebook functions (ARM4 version)
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35/* This optimization is temporaly disabled until it is fixed to account for the fact
36 that "r" is now a 16-bit array */
37#if 0
38#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
39static void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
40{
41 int i, j, k;
42 //const signed char *shape;
43 for (i=0;i<shape_cb_size;i+=4)
44 {
45
46 //shape = shape_cb;
47 E[0]=0;
48 E[1]=0;
49 E[2]=0;
50 E[3]=0;
51
52 /* Compute codeword response using convolution with impulse response */
53 for(j=0;j<subvect_size;j++)
54 {
55#if 1
56 spx_word16_t *res;
57 res = resp+j;
58 spx_word32_t resj0,resj1,resj2,resj3;
59 spx_word32_t dead1, dead2, dead3, dead4, dead5, dead6, dead7, dead8;
60 __asm__ __volatile__ (
61 "mov %0, #0 \n\t"
62 "mov %1, #0 \n\t"
63 "mov %2, #0 \n\t"
64 "mov %3, #0 \n\t"
65 ".weighted%=: \n\t"
66 "ldrsb %8, [%6] \n\t"
67 "ldr %10, [%5], #-4 \n\t"
68 "mov %9, %6 \n\t"
69 "ldrsb %11, [%9, %7]! \n\t"
70 "mla %0, %10, %8, %0 \n\t"
71 "ldrsb %8, [%9, %7]! \n\t"
72 "mla %1, %10, %11, %1 \n\t"
73 "ldrsb %11, [%9, %7]! \n\t"
74 "mla %2, %10, %8, %2 \n\t"
75 "subs %4, %4, #1 \n\t"
76 "mla %3, %10, %11, %3 \n\t"
77 "add %6, %6, #1 \n\t"
78 "bne .weighted%= \n\t"
79 : "=r" (resj0), "=r" (resj1), "=r" (resj2), "=r" (resj3),
80 "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
81 "=r" (dead5), "=r" (dead6), "=r" (dead7), "=r" (dead8)
82 : "4" (j+1), "5" (r+j), "6" (shape_cb), "7" (subvect_size)
83 : "cc", "memory");
84#else
85 spx_word16_t *res;
86 res = resp+j;
87 spx_word32_t resj0=0;
88 spx_word32_t resj1=0;
89 spx_word32_t resj2=0;
90 spx_word32_t resj3=0;
91 for (k=0;k<=j;k++)
92 {
93 const signed char *shape=shape_cb+k;
94 resj0 = MAC16_16(resj0,*shape,r[j-k]);
95 shape += subvect_size;
96 resj1 = MAC16_16(resj1,*shape,r[j-k]);
97 shape += subvect_size;
98 resj2 = MAC16_16(resj2,*shape,r[j-k]);
99 shape += subvect_size;
100 resj3 = MAC16_16(resj3,*shape,r[j-k]);
101 shape += subvect_size;
102 }
103#endif
104
105#ifdef FIXED_POINT
106 resj0 = SHR(resj0, 11);
107 resj1 = SHR(resj1, 11);
108 resj2 = SHR(resj2, 11);
109 resj3 = SHR(resj3, 11);
110#else
111 resj0 *= 0.03125;
112 resj1 *= 0.03125;
113 resj2 *= 0.03125;
114 resj3 *= 0.03125;
115#endif
116
117 /* Compute codeword energy */
118 E[0]=ADD32(E[0],MULT16_16(resj0,resj0));
119 E[1]=ADD32(E[1],MULT16_16(resj1,resj1));
120 E[2]=ADD32(E[2],MULT16_16(resj2,resj2));
121 E[3]=ADD32(E[3],MULT16_16(resj3,resj3));
122 *res = resj0;
123 res += subvect_size;
124 *res = resj1;
125 res += subvect_size;
126 *res = resj2;
127 res += subvect_size;
128 *res = resj3;
129 res += subvect_size;
130 }
131 resp += subvect_size<<2;
132 shape_cb += subvect_size<<2;
133 E+=4;
134 }
135
136}
137#endif
diff --git a/lib/rbcodec/codecs/libspeex/cb_search_bfin.h b/lib/rbcodec/codecs/libspeex/cb_search_bfin.h
new file mode 100644
index 0000000000..ae9cf8343d
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/cb_search_bfin.h
@@ -0,0 +1,112 @@
1/* Copyright (C) 2005 Analog Devices */
2/**
3 @author Jean-Marc Valin
4 @file cb_search_bfin.h
5 @brief Fixed codebook functions (Blackfin version)
6*/
7/*
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 - Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 - Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19 - Neither the name of the Xiph.org Foundation nor the names of its
20 contributors may be used to endorse or promote products derived from
21 this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
37void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
38{
39 int i;
40 for (i=0;i<shape_cb_size;i++)
41 {
42 __asm__ __volatile__ (
43 "P0 = %0;\n\t"
44 "LC0 = P0;\n\t"
45 "P1 = %1;\n\t"
46 "P2 = %2;\n\t"
47 "P3 = %3;\n\t"
48 "P0 = 1;\n\t"
49 "L0 = 0;\n\t"
50 "L1 = 0;\n\t"
51 "R2 = 0;\n\t"
52 "A1 = 0;\n\t"
53 "LOOP outter%= LC0;\n\t"
54 "LOOP_BEGIN outter%=;\n\t"
55 "A0 = 0;\n\t"
56 "P4 = P1;\n\t"
57 "I1 = P2;\n\t"
58 "R0 = B[P4++] (X) || R1.L = W[I1--];\n\t"
59 "LOOP inner%= LC1 = P0;\n\t"
60 "LOOP_BEGIN inner%=;\n\t"
61 "A0 += R0.L*R1.L (IS) || R0 = B[P4++] (X) || R1.L = W[I1--];\n\t"
62 "LOOP_END inner%=;\n\t"
63 "R0 = A0;\n\t"
64 "R0 >>>= 13;\n\t"
65 "A1 += R0.L*R0.L (IS);\n\t"
66 "W[P3++] = R0;\n\t"
67 "P0 += 1;\n\t"
68 "P2 += 2;\n\t"
69 "LOOP_END outter%=;\n\t"
70 "P4 = %4;\n\t"
71 "R1 = A1;\n\t"
72 "[P4] = R1;\n\t"
73 :
74 : "m" (subvect_size), "m" (shape_cb), "m" (r), "m" (resp), "m" (E)
75 : "A0", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "I0", "I1", "L0",
76 "L1", "A0", "A1", "memory"
77#if !(__GNUC__ == 3)
78 , "LC0", "LC1" /* gcc 3.4 doesn't know about LC registers */
79#endif
80 );
81 shape_cb += subvect_size;
82 resp += subvect_size;
83 E++;
84 }
85}
86
87#define OVERRIDE_TARGET_UPDATE
88static inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len)
89{
90 if (!len)
91 return;
92 __asm__ __volatile__
93 (
94 "I0 = %0;\n\t"
95 "I1 = %1;\n\t"
96 "L0 = 0;\n\t"
97 "L1 = 0;\n\t"
98 "R2 = 4096;\n\t"
99 "LOOP tupdate%= LC0 = %3;\n\t"
100 "LOOP_BEGIN tupdate%=;\n\t"
101 "R0.L = W[I0] || R1.L = W[I1++];\n\t"
102 "R1 = (A1 = R1.L*%2.L) (IS);\n\t"
103 "R1 = R1 + R2;\n\t"
104 "R1 >>>= 13;\n\t"
105 "R0.L = R0.L - R1.L;\n\t"
106 "W[I0++] = R0.L;\n\t"
107 "LOOP_END tupdate%=;\n\t"
108 :
109 : "a" (t), "a" (r), "d" (g), "a" (len)
110 : "R0", "R1", "R2", "A1", "I0", "I1", "L0", "L1"
111 );
112}
diff --git a/lib/rbcodec/codecs/libspeex/cb_search_sse.h b/lib/rbcodec/codecs/libspeex/cb_search_sse.h
new file mode 100644
index 0000000000..8b039686fb
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/cb_search_sse.h
@@ -0,0 +1,84 @@
1/* Copyright (C) 2004 Jean-Marc Valin */
2/**
3 @file cb_search_sse.h
4 @brief Fixed codebook functions (SSE version)
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#include <xmmintrin.h>
36
37static inline void _spx_mm_getr_ps (__m128 U, float *__Z, float *__Y, float *__X, float *__W)
38{
39 union {
40 float __a[4];
41 __m128 __v;
42 } __u;
43
44 __u.__v = U;
45
46 *__Z = __u.__a[0];
47 *__Y = __u.__a[1];
48 *__X = __u.__a[2];
49 *__W = __u.__a[3];
50
51}
52
53#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
54static void compute_weighted_codebook(const signed char *shape_cb, const spx_sig_t *_r, float *resp, __m128 *resp2, __m128 *E, int shape_cb_size, int subvect_size, char *stack)
55{
56 int i, j, k;
57 __m128 resj, EE;
58 VARDECL(__m128 *r);
59 VARDECL(__m128 *shape);
60 ALLOC(r, subvect_size, __m128);
61 ALLOC(shape, subvect_size, __m128);
62 for(j=0;j<subvect_size;j++)
63 r[j] = _mm_load_ps1(_r+j);
64 for (i=0;i<shape_cb_size;i+=4)
65 {
66 float *_res = resp+i*subvect_size;
67 const signed char *_shape = shape_cb+i*subvect_size;
68 EE = _mm_setzero_ps();
69 for(j=0;j<subvect_size;j++)
70 {
71 shape[j] = _mm_setr_ps(0.03125*_shape[j], 0.03125*_shape[subvect_size+j], 0.03125*_shape[2*subvect_size+j], 0.03125*_shape[3*subvect_size+j]);
72 }
73 for(j=0;j<subvect_size;j++)
74 {
75 resj = _mm_setzero_ps();
76 for (k=0;k<=j;k++)
77 resj = _mm_add_ps(resj, _mm_mul_ps(shape[k],r[j-k]));
78 _spx_mm_getr_ps(resj, _res+j, _res+subvect_size+j, _res+2*subvect_size+j, _res+3*subvect_size+j);
79 *resp2++ = resj;
80 EE = _mm_add_ps(EE, _mm_mul_ps(resj, resj));
81 }
82 E[i>>2] = EE;
83 }
84}
diff --git a/lib/rbcodec/codecs/libspeex/config-speex.h b/lib/rbcodec/codecs/libspeex/config-speex.h
new file mode 100644
index 0000000000..7e0672c150
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/config-speex.h
@@ -0,0 +1,186 @@
1#ifndef ROCKBOX_VOICE_ENCODER
2#include "codeclib.h"
3#include "autoconf.h"
4#else
5#define ICODE_ATTR
6#define IDATA_ATTR
7#define IBSS_ATTR
8#define ICONST_ATTR
9#endif
10/* config.h. Generated from config.h.in by configure. */
11/* config.h.in. Generated from configure.ac by autoheader. */
12
13#ifndef ROCKBOX_VOICE_ENCODER
14
15#define DISABLE_FLOAT_API
16#define DISABLE_VBR
17
18/* Make use of ARM4E assembly optimizations */
19#if defined(CPU_ARM)
20#define ARM4_ASM
21#endif
22
23/* Make use of Coldfire assembly optimizations */
24#if defined(CPU_COLDFIRE)
25#define COLDFIRE_ASM
26#endif
27
28/* Make use of Blackfin assembly optimizations */
29/* #undef BFIN_ASM */
30#endif /* ROCKBOX_VOICE_ENCODER */
31
32/* Disable wideband codec */
33/* #undef DISABLE_WIDEBAND */
34
35/* Enable valgrind extra checks */
36/* #undef ENABLE_VALGRIND */
37
38/* Debug fixed-point implementation */
39/* #undef FIXED_DEBUG */
40
41#ifndef ROCKBOX_VOICE_ENCODER
42/* Compile target codec as fixed point */
43#define FIXED_POINT
44#else
45/* Compile voice clip encoder as floating point */
46#define FLOATING_POINT
47#endif
48
49#ifndef ROCKBOX_VOICE_CODEC
50#define EXC_ICONST_ATTR ICONST_ATTR
51#define GAIN_ICONST_ATTR ICONST_ATTR
52#define HEXC_ICONST_ATTR ICONST_ATTR
53#define LSP_ICONST_ATTR ICONST_ATTR
54#else
55#define EXC_ICONST_ATTR
56#define GAIN_ICONST_ATTR
57#define HEXC_ICONST_ATTR
58#define LSP_ICONST_ATTR
59#endif
60
61/* Define to 1 if you have the <dlfcn.h> header file. */
62/* #undef HAVE_DLFCN_H */
63
64/* Define to 1 if you have the `getopt_long' function. */
65#define HAVE_GETOPT_LONG 1
66
67/* Define to 1 if you have the <inttypes.h> header file. */
68#define HAVE_INTTYPES_H 1
69
70/* Define to 1 if you have the `m' library (-lm). */
71/* #undef HAVE_LIBM */
72
73/* Define to 1 if you have the `winmm' library (-lwinmm). */
74/* #undef HAVE_LIBWINMM */
75
76/* Define to 1 if you have the <memory.h> header file. */
77/* #define HAVE_MEMORY_H 1 */
78
79/* Define to 1 if you have the <stdint.h> header file. */
80#define HAVE_STDINT_H 1
81
82/* Define to 1 if you have the <stdlib.h> header file. */
83#define HAVE_STDLIB_H 1
84
85/* Define to 1 if you have the <strings.h> header file. */
86#define HAVE_STRINGS_H 1
87
88/* Define to 1 if you have the <string.h> header file. */
89#define HAVE_STRING_H 1
90
91/* Define to 1 if you have the <sys/audioio.h> header file. */
92/* #undef HAVE_SYS_AUDIOIO_H */
93
94/* Define to 1 if you have the <sys/soundcard.h> header file. */
95#define HAVE_SYS_SOUNDCARD_H 1
96
97/* Define to 1 if you have the <sys/stat.h> header file. */
98#define HAVE_SYS_STAT_H 1
99
100/* Define to 1 if you have the <sys/types.h> header file. */
101#define HAVE_SYS_TYPES_H 1
102
103/* Define to 1 if you have the <unistd.h> header file. */
104#define HAVE_UNISTD_H 1
105
106/* Define to the address where bug reports for this package should be sent. */
107#define PACKAGE_BUGREPORT ""
108
109/* Define to the full name of this package. */
110#define PACKAGE_NAME ""
111
112/* Define to the full name and version of this package. */
113#define PACKAGE_STRING ""
114
115/* Define to the one symbol short name of this package. */
116#define PACKAGE_TARNAME ""
117
118/* Define to the version of this package. */
119#define PACKAGE_VERSION ""
120
121/* Reduce precision to 16 bits (EXPERIMENTAL) */
122/* #undef PRECISION16 */
123
124/* The size of `int', as computed by sizeof. */
125#define SIZEOF_INT 4
126
127/* The size of `long', as computed by sizeof. */
128#define SIZEOF_LONG 4
129
130/* The size of `short', as computed by sizeof. */
131#define SIZEOF_SHORT 2
132
133/* Version extra */
134#define SPEEX_EXTRA_VERSION "-git"
135
136/* Version major */
137#define SPEEX_MAJOR_VERSION 1
138
139/* Version micro */
140#define SPEEX_MICRO_VERSION 15
141
142/* Version minor */
143#define SPEEX_MINOR_VERSION 1
144
145/* Complete version string */
146#define SPEEX_VERSION "1.2beta3"
147
148/* Define to 1 if you have the ANSI C header files. */
149#define STDC_HEADERS 1
150
151/* Enable support for TI C55X DSP */
152/* #undef TI_C55X */
153
154/* Make use of alloca */
155/* #undef USE_ALLOCA */
156
157/* Use C99 variable-size arrays */
158#define VAR_ARRAYS
159
160/* Enable Vorbis-style psychoacoustics (EXPERIMENTAL) */
161/* #undef VORBIS_PSYCHO */
162
163/* Define to 1 if your processor stores words with the most significant byte
164 first (like Motorola and SPARC, unlike Intel and VAX). */
165#ifdef ROCKBOX_BIG_ENDIAN
166#define WORDS_BIGENDIAN 1
167#endif
168
169/* Enable SSE support */
170/* #undef _USE_SSE */
171
172/* Define to empty if `const' does not conform to ANSI C. */
173/* #undef const */
174
175/* Define to `__inline__' or `__inline' if that's what the C compiler
176 calls it, or to nothing if 'inline' is not supported under any name. */
177#ifndef __cplusplus
178/* #undef inline */
179#endif
180
181/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
182 supported. Do not define if restrict is supported directly. */
183#define restrict __restrict
184
185#define RELEASE 1
186
diff --git a/lib/rbcodec/codecs/libspeex/exc_10_16_table.c b/lib/rbcodec/codecs/libspeex/exc_10_16_table.c
new file mode 100644
index 0000000000..755c5a0b7f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/exc_10_16_table.c
@@ -0,0 +1,51 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: exc_10_16_table.c
3 Codebook for excitation in narrowband CELP mode (3200 bps)
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#include "config-speex.h"
34
35const signed char exc_10_16_table[160] EXC_ICONST_ATTR = {
3622,39,14,44,11,35,-2,23,-4,6,
3746,-28,13,-27,-23,12,4,20,-5,9,
3837,-18,-23,23,0,9,-6,-20,4,-1,
39-17,-5,-4,17,0,1,9,-2,1,2,
402,-12,8,-25,39,15,9,16,-55,-11,
419,11,5,10,-2,-60,8,13,-6,11,
42-16,27,-47,-12,11,1,16,-7,9,-3,
43-29,9,-14,25,-19,34,36,12,40,-10,
44-3,-24,-14,-37,-21,-35,-2,-36,3,-6,
4567,28,6,-17,-3,-12,-16,-15,-17,-7,
46-59,-36,-13,1,7,1,2,10,2,11,
4713,10,8,-2,7,3,5,4,2,2,
48-3,-8,4,-5,6,7,-42,15,35,-2,
49-46,38,28,-20,-9,1,7,-3,0,-2,
500,0,0,0,0,0,0,0,0,0,
51-15,-28,52,32,5,-5,-17,-20,-10,-1};
diff --git a/lib/rbcodec/codecs/libspeex/exc_10_32_table.c b/lib/rbcodec/codecs/libspeex/exc_10_32_table.c
new file mode 100644
index 0000000000..1c94b5511c
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/exc_10_32_table.c
@@ -0,0 +1,67 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: exc_10_32_table.c
3 Codebook for excitation in narrowband CELP mode (4000 bps)
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#include "config-speex.h"
34
35const signed char exc_10_32_table[320] EXC_ICONST_ATTR = {
367,17,17,27,25,22,12,4,-3,0,
3728,-36,39,-24,-15,3,-9,15,-5,10,
3831,-28,11,31,-21,9,-11,-11,-2,-7,
39-25,14,-22,31,4,-14,19,-12,14,-5,
404,-7,4,-5,9,0,-2,42,-47,-16,
411,8,0,9,23,-57,0,28,-11,6,
42-31,55,-45,3,-5,4,2,-2,4,-7,
43-3,6,-2,7,-3,12,5,8,54,-10,
448,-7,-8,-24,-25,-27,-14,-5,8,5,
4544,23,5,-9,-11,-11,-13,-9,-12,-8,
46-29,-8,-22,6,-15,3,-12,-1,-5,-3,
4734,-1,29,-16,17,-4,12,2,1,4,
48-2,-4,2,-1,11,-3,-52,28,30,-9,
49-32,25,44,-20,-24,4,6,-1,0,0,
500,0,0,0,0,0,0,0,0,0,
51-25,-10,22,29,13,-13,-22,-13,-4,0,
52-4,-16,10,15,-36,-24,28,25,-1,-3,
5366,-33,-11,-15,6,0,3,4,-2,5,
5424,-20,-47,29,19,-2,-4,-1,0,-1,
55-2,3,1,8,-11,5,5,-57,28,28,
560,-16,4,-4,12,-6,-1,2,-20,61,
57-9,24,-22,-42,29,6,17,8,4,2,
58-65,15,8,10,5,6,5,3,2,-2,
59-3,5,-9,4,-5,23,13,23,-3,-63,
603,-5,-4,-6,0,-3,23,-36,-46,9,
615,5,8,4,9,-5,1,-3,10,1,
62-6,10,-11,24,-47,31,22,-12,14,-10,
636,11,-7,-7,7,-31,51,-12,-6,7,
646,-17,9,-11,-20,52,-19,3,-6,-6,
65-8,-5,23,-41,37,1,-21,10,-14,8,
667,5,-15,-15,23,39,-26,-33,7,2,
67-32,-30,-21,-8,4,12,17,15,14,11};
diff --git a/lib/rbcodec/codecs/libspeex/exc_20_32_table.c b/lib/rbcodec/codecs/libspeex/exc_20_32_table.c
new file mode 100644
index 0000000000..40dbb34e9e
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/exc_20_32_table.c
@@ -0,0 +1,67 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: exc_20_32_table.c
3 Codebook for excitation in narrowband CELP mode (2000 bps)
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#include "config-speex.h"
34
35const signed char exc_20_32_table[640] EXC_ICONST_ATTR = {
3612,32,25,46,36,33,9,14,-3,6,1,-8,0,-10,-5,-7,-7,-7,-5,-5,
3731,-27,24,-32,-4,10,-11,21,-3,19,23,-9,22,24,-10,-1,-10,-13,-7,-11,
3842,-33,31,19,-8,0,-10,-16,1,-21,-17,10,-8,14,8,4,11,-2,5,-2,
39-33,11,-16,33,11,-4,9,-4,11,2,6,-5,8,-5,11,-4,-6,26,-36,-16,
400,4,-2,-8,12,6,-1,34,-46,-22,9,9,21,9,5,-66,-5,26,2,10,
4113,2,19,9,12,-81,3,13,13,0,-14,22,-35,6,-7,-4,6,-6,10,-6,
42-31,38,-33,0,-10,-11,5,-12,12,-17,5,0,-6,13,-9,10,8,25,33,2,
43-12,8,-6,10,-2,21,7,17,43,5,11,-7,-9,-20,-36,-20,-23,-4,-4,-3,
4427,-9,-9,-49,-39,-38,-11,-9,6,5,23,25,5,3,3,4,1,2,-3,-1,
4587,39,17,-21,-9,-19,-9,-15,-13,-14,-17,-11,-10,-11,-8,-6,-1,-3,-3,-1,
46-54,-34,-27,-8,-11,-4,-5,0,0,4,8,6,9,7,9,7,6,5,5,5,
4748,10,19,-10,12,-1,9,-3,2,5,-3,2,-2,-2,0,-2,-26,6,9,-7,
48-16,-9,2,7,7,-5,-43,11,22,-11,-9,34,37,-15,-13,-6,1,-1,1,1,
49-64,56,52,-11,-27,5,4,3,1,2,1,3,-1,-4,-4,-10,-7,-4,-4,2,
50-1,-7,-7,-12,-10,-15,-9,-5,-5,-11,-16,-13,6,16,4,-13,-16,-10,-4,2,
51-47,-13,25,47,19,-14,-20,-8,-17,0,-3,-13,1,6,-17,-14,15,1,10,6,
52-24,0,-10,19,-69,-8,14,49,17,-5,33,-29,3,-4,0,2,-8,5,-6,2,
53120,-56,-12,-47,23,-9,6,-5,1,2,-5,1,-10,4,-1,-1,4,-1,0,-3,
5430,-52,-67,30,22,11,-1,-4,3,0,7,2,0,1,-10,-4,-8,-13,5,1,
551,-1,5,13,-9,-3,-10,-62,22,48,-4,-6,2,3,5,1,1,4,1,13,
563,-20,10,-9,13,-2,-4,9,-20,44,-1,20,-32,-67,19,0,28,11,8,2,
57-11,15,-19,-53,31,2,34,10,6,-4,-58,8,10,13,14,1,12,2,0,0,
58-128,37,-8,44,-9,26,-3,18,2,6,11,-1,9,1,5,3,0,1,1,2,
5912,3,-2,-3,7,25,9,18,-6,-37,3,-8,-16,3,-10,-7,17,-34,-44,11,
6017,-15,-3,-16,-1,-13,11,-46,-65,-2,8,13,2,4,4,5,15,5,9,6,
610,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62-9,19,-12,12,-28,38,29,-1,12,2,5,23,-10,3,4,-15,21,-4,3,3,
636,17,-9,-4,-8,-20,26,5,-10,6,1,-19,18,-15,-12,47,-6,-2,-7,-9,
64-1,-17,-2,-2,-14,30,-14,2,-7,-4,-1,-12,11,-25,16,-3,-12,11,-7,7,
65-17,1,19,-28,31,-7,-10,7,-10,3,12,5,-16,6,24,41,-29,-54,0,1,
667,-1,5,-6,13,10,-4,-8,8,-9,-27,-53,-38,-1,10,19,17,16,12,12,
670,3,-7,-4,13,12,-31,-14,6,-5,3,5,17,43,50,25,10,1,-6,-2};
diff --git a/lib/rbcodec/codecs/libspeex/exc_5_256_table.c b/lib/rbcodec/codecs/libspeex/exc_5_256_table.c
new file mode 100644
index 0000000000..1a32057956
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/exc_5_256_table.c
@@ -0,0 +1,291 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: exc_5_256_table.c
3 Codebook for excitation in narrowband CELP mode (12800 bps)
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#include "config-speex.h"
34
35const signed char exc_5_256_table[1280] EXC_ICONST_ATTR = {
36-8,-37,5,-43,5,
3773,61,39,12,-3,
38-61,-32,2,42,30,
39-3,17,-27,9,34,
4020,-1,-5,2,23,
41-7,-46,26,53,-47,
4220,-2,-33,-89,-51,
43-64,27,11,15,-34,
44-5,-56,25,-9,-1,
45-29,1,40,67,-23,
46-16,16,33,19,7,
4714,85,22,-10,-10,
48-12,-7,-1,52,89,
4929,11,-20,-37,-46,
50-15,17,-24,-28,24,
512,1,0,23,-101,
5223,14,-1,-23,-18,
539,5,-13,38,1,
54-28,-28,4,27,51,
55-26,34,-40,35,47,
5654,38,-54,-26,-6,
5742,-25,13,-30,-36,
5818,41,-4,-33,23,
59-32,-7,-4,51,-3,
6017,-52,56,-47,36,
61-2,-21,36,10,8,
62-33,31,19,9,-5,
63-40,10,-9,-21,19,
6418,-78,-18,-5,0,
65-26,-36,-47,-51,-44,
6618,40,27,-2,29,
6749,-26,2,32,-54,
6830,-73,54,3,-5,
6936,22,53,10,-1,
70-84,-53,-29,-5,3,
71-44,53,-51,4,22,
7271,-35,-1,33,-5,
73-27,-7,36,17,-23,
74-39,16,-9,-55,-15,
75-20,39,-35,6,-39,
76-14,18,48,-64,-17,
77-15,9,39,81,37,
78-68,37,47,-21,-6,
79-104,13,6,9,-2,
8035,8,-23,18,42,
8145,21,33,-5,-49,
829,-6,-43,-56,39,
832,-16,-25,87,1,
84-3,-9,17,-25,-11,
85-9,-1,10,2,-14,
86-14,4,-1,-10,28,
87-23,40,-32,26,-9,
8826,4,-27,-23,3,
8942,-60,1,49,-3,
9027,10,-52,-40,-2,
9118,45,-23,17,-44,
923,-3,17,-46,52,
93-40,-47,25,75,31,
94-49,53,30,-30,-32,
95-36,38,-6,-15,-16,
9654,-27,-48,3,38,
97-29,-32,-22,-14,-4,
98-23,-13,32,-39,9,
998,-45,-13,34,-16,
10049,40,32,31,28,
10123,23,32,47,59,
102-68,8,62,44,25,
103-14,-24,-65,-16,36,
10467,-25,-38,-21,4,
105-33,-2,42,5,-63,
10640,11,26,-42,-23,
107-61,79,-31,23,-20,
10810,-32,53,-25,-36,
10910,-26,-5,3,0,
110-71,5,-10,-37,1,
111-24,21,-54,-17,1,
112-29,-25,-15,-27,32,
11368,45,-16,-37,-18,
114-5,1,0,-77,71,
115-6,3,-20,71,-67,
11629,-35,10,-30,19,
1174,16,17,5,0,
118-14,19,2,28,26,
11959,3,2,24,39,
12055,-50,-45,-18,-17,
12133,-35,14,-1,1,
1228,87,-35,-29,0,
123-27,13,-7,23,-13,
12437,-40,50,-35,14,
12519,-7,-14,49,54,
126-5,22,-2,-29,-8,
127-27,38,13,27,48,
12812,-41,-21,-15,28,
1297,-16,-24,-19,-20,
13011,-20,9,2,13,
13123,-20,11,27,-27,
13271,-69,8,2,-6,
13322,12,16,16,9,
134-16,-8,-17,1,25,
1351,40,-37,-33,66,
13694,53,4,-22,-25,
137-41,-42,25,35,-16,
138-15,57,31,-29,-32,
13921,16,-60,45,15,
140-1,7,57,-26,-47,
141-29,11,8,15,19,
142-105,-8,54,27,10,
143-17,6,-12,-1,-10,
1444,0,23,-10,31,
14513,11,10,12,-64,
14623,-3,-8,-19,16,
14752,24,-40,16,10,
14840,5,9,0,-13,
149-7,-21,-8,-6,-7,
150-21,59,16,-53,18,
151-60,11,-47,14,-18,
15225,-13,-24,4,-39,
15316,-28,54,26,-67,
15430,27,-20,-52,20,
155-12,55,12,18,-16,
15639,-14,-6,-26,56,
157-88,-55,12,25,26,
158-37,6,75,0,-34,
159-81,54,-30,1,-7,
16049,-23,-14,21,10,
161-62,-58,-57,-47,-34,
16215,-4,34,-78,31,
16325,-11,7,50,-10,
16442,-63,14,-36,-4,
16557,55,57,53,42,
166-42,-1,15,40,37,
16715,25,-11,6,1,
16831,-2,-6,-1,-7,
169-64,34,28,30,-1,
1703,21,0,-88,-12,
171-56,25,-28,40,8,
172-28,-14,9,12,2,
173-6,-17,22,49,-6,
174-26,14,28,-20,4,
175-12,50,35,40,13,
176-38,-58,-29,17,30,
17722,60,26,-54,-39,
178-12,58,-28,-63,10,
179-21,-8,-12,26,-62,
1806,-10,-11,-22,-6,
181-7,4,1,18,2,
182-70,11,14,4,13,
18319,-24,-34,24,67,
18417,51,-21,13,23,
18554,-30,48,1,-13,
18680,26,-16,-2,13,
187-4,6,-30,29,-24,
18873,-58,30,-27,20,
189-2,-21,41,45,30,
190-27,-3,-5,-18,-20,
191-49,-3,-35,10,42,
192-19,-67,-53,-11,9,
19313,-15,-33,-51,-30,
19415,7,25,-30,4,
19528,-22,-34,54,-29,
19639,-46,20,16,34,
197-4,47,75,1,-44,
198-55,-24,7,-1,9,
199-42,50,-8,-36,41,
20068,0,-4,-10,-23,
201-15,-50,64,36,-9,
202-27,12,25,-38,-47,
203-37,32,-49,51,-36,
2042,-4,69,-26,19,
2057,45,67,46,13,
206-63,46,15,-47,4,
207-41,13,-6,5,-21,
20837,26,-55,-7,33,
209-1,-28,10,-17,-64,
210-14,0,-36,-17,93,
211-3,-9,-66,44,-21,
2123,-12,38,-6,-13,
213-12,19,13,43,-43,
214-10,-12,6,-5,9,
215-49,32,-5,2,4,
2165,15,-16,10,-21,
2178,-62,-8,64,8,
21879,-1,-66,-49,-18,
2195,40,-5,-30,-45,
2201,-6,21,-32,93,
221-18,-30,-21,32,21,
222-18,22,8,5,-41,
223-54,80,22,-10,-7,
224-8,-23,-64,66,56,
225-14,-30,-41,-46,-14,
226-29,-37,27,-14,42,
227-2,-9,-29,34,14,
22833,-14,22,4,10,
22926,26,28,32,23,
230-72,-32,3,0,-14,
23135,-42,-78,-32,6,
23229,-18,-45,-5,7,
233-33,-45,-3,-22,-34,
2348,-8,4,-51,-25,
235-9,59,-78,21,-5,
236-25,-48,66,-15,-17,
237-24,-49,-13,25,-23,
238-64,-6,40,-24,-19,
239-11,57,-33,-8,1,
24010,-52,-54,28,39,
24149,34,-11,-61,-41,
242-43,10,15,-15,51,
24330,15,-51,32,-34,
244-2,-34,14,18,16,
2451,1,-3,-3,1,
2461,-18,6,16,48,
24712,-5,-42,7,36,
24848,7,-20,-10,7,
24912,2,54,39,-38,
25037,54,4,-11,-8,
251-46,-10,5,-10,-34,
25246,-12,29,-37,39,
25336,-11,24,56,17,
25414,20,25,0,-25,
255-28,55,-7,-5,27,
2563,9,-26,-8,6,
257-24,-10,-30,-31,-34,
25818,4,22,21,40,
259-1,-29,-37,-8,-21,
26092,-29,11,-3,11,
26173,23,22,7,4,
262-44,-9,-11,21,-13,
26311,9,-78,-1,47,
264114,-12,-37,-19,-5,
265-11,-22,19,12,-30,
2667,38,45,-21,-8,
267-9,55,-45,56,-21,
2687,17,46,-57,-87,
269-6,27,31,31,7,
270-56,-12,46,21,-5,
271-12,36,3,3,-21,
27243,19,12,-7,9,
273-14,0,-9,-33,-91,
2747,26,3,-11,64,
27583,-31,-46,25,2,
2769,5,2,2,-1,
27720,-17,10,-5,-27,
278-8,20,8,-19,16,
279-21,-13,-31,5,5,
28042,24,9,34,-20,
28128,-61,22,11,-39,
28264,-20,-1,-30,-9,
283-20,24,-25,-24,-29,
28422,-60,6,-5,41,
285-9,-87,14,34,15,
286-57,52,69,15,-3,
287-102,58,16,3,6,
28860,-75,-32,26,7,
289-57,-27,-32,-24,-21,
290-29,-16,62,-46,31,
29130,-27,-15,7,15};
diff --git a/lib/rbcodec/codecs/libspeex/exc_5_64_table.c b/lib/rbcodec/codecs/libspeex/exc_5_64_table.c
new file mode 100644
index 0000000000..7d29f60373
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/exc_5_64_table.c
@@ -0,0 +1,99 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: exc_5_64_table.c
3 Codebook for excitation in narrowband CELP mode (9600 bps)
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#include "config-speex.h"
34
35const signed char exc_5_64_table[320] EXC_ICONST_ATTR = {
361,5,-15,49,-66,
37-48,-4,50,-44,7,
3837,16,-18,25,-26,
39-26,-15,19,19,-27,
40-47,28,57,5,-17,
41-32,-41,68,21,-2,
4264,56,8,-16,-13,
43-26,-9,-16,11,6,
44-39,25,-19,22,-31,
4520,-45,55,-43,10,
46-16,47,-40,40,-20,
47-51,3,-17,-14,-15,
48-24,53,-20,-46,46,
4927,-68,32,3,-18,
50-5,9,-31,16,-9,
51-10,-1,-23,48,95,
5247,25,-41,-32,-3,
5315,-25,-55,36,41,
54-27,20,5,13,14,
55-22,5,2,-23,18,
5646,-15,17,-18,-34,
57-5,-8,27,-55,73,
5816,2,-1,-17,40,
59-78,33,0,2,19,
604,53,-16,-15,-16,
61-28,-3,-13,49,8,
62-7,-29,27,-13,32,
6320,32,-61,16,14,
6441,44,40,24,20,
657,4,48,-60,-77,
6617,-6,-48,65,-15,
6732,-30,-71,-10,-3,
68-6,10,-2,-7,-29,
69-56,67,-30,7,-5,
7086,-6,-10,0,5,
71-31,60,34,-38,-3,
7224,10,-2,30,23,
7324,-41,12,70,-43,
7415,-17,6,13,16,
75-13,8,30,-15,-8,
765,23,-34,-98,-4,
77-13,13,-48,-31,70,
7812,31,25,24,-24,
7926,-7,33,-16,8,
805,-11,-14,-8,-65,
8113,10,-2,-9,0,
82-3,-68,5,35,7,
830,-31,-1,-17,-9,
84-9,16,-37,-18,-1,
8569,-48,-28,22,-21,
86-11,5,49,55,23,
87-86,-36,16,2,13,
8863,-51,30,-11,13,
8924,-18,-6,14,-19,
901,41,9,-5,27,
91-36,-44,-34,-37,-21,
92-26,31,-39,15,43,
935,-8,29,20,-8,
94-20,-52,-28,-1,13,
9526,-34,-10,-9,27,
96-8,8,27,-66,4,
9712,-22,49,10,-77,
9832,-18,3,-38,12,
99-3,-1,2,2,0};
diff --git a/lib/rbcodec/codecs/libspeex/exc_8_128_table.c b/lib/rbcodec/codecs/libspeex/exc_8_128_table.c
new file mode 100644
index 0000000000..02a58e052c
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/exc_8_128_table.c
@@ -0,0 +1,163 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: exc_8_128_table.c
3 Codebook for excitation in narrowband CELP mode (7000 bps)
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#include "config-speex.h"
34
35const signed char exc_8_128_table[1024] EXC_ICONST_ATTR = {
36-14,9,13,-32,2,-10,31,-10,
37-8,-8,6,-4,-1,10,-64,23,
386,20,13,6,8,-22,16,34,
397,42,-49,-28,5,26,4,-15,
4041,34,41,32,33,24,23,14,
418,40,34,4,-24,-41,-19,-15,
4213,-13,33,-54,24,27,-44,33,
4327,-15,-15,24,-19,14,-36,14,
44-9,24,-12,-4,37,-5,16,-34,
455,10,33,-15,-54,-16,12,25,
4612,1,2,0,3,-1,-4,-4,
4711,2,-56,54,27,-20,13,-6,
48-46,-41,-33,-11,-5,7,12,14,
49-14,-5,8,20,6,3,4,-8,
50-5,-42,11,8,-14,25,-2,2,
5113,11,-22,39,-9,9,5,-45,
52-9,7,-9,12,-7,34,-17,-102,
537,2,-42,18,35,-9,-34,11,
54-5,-2,3,22,46,-52,-25,-9,
55-94,8,11,-5,-5,-5,4,-7,
56-35,-7,54,5,-32,3,24,-9,
57-22,8,65,37,-1,-12,-23,-6,
58-9,-28,55,-33,14,-3,2,18,
59-60,41,-17,8,-16,17,-11,0,
60-11,29,-28,37,9,-53,33,-14,
61-9,7,-25,-7,-11,26,-32,-8,
6224,-21,22,-19,19,-10,29,-14,
630,0,0,0,0,0,0,0,
64-5,-52,10,41,6,-30,-4,16,
6532,22,-27,-22,32,-3,-28,-3,
663,-35,6,17,23,21,8,2,
674,-45,-17,14,23,-4,-31,-11,
68-3,14,1,19,-11,2,61,-8,
699,-12,7,-10,12,-3,-24,99,
70-48,23,50,-37,-5,-23,0,8,
71-14,35,-64,-5,46,-25,13,-1,
72-49,-19,-15,9,34,50,25,11,
73-6,-9,-16,-20,-32,-33,-32,-27,
7410,-8,12,-15,56,-14,-32,33,
753,-9,1,65,-9,-9,-10,-2,
76-6,-23,9,17,3,-28,13,-32,
774,-2,-10,4,-16,76,12,-52,
786,13,33,-6,4,-14,-9,-3,
791,-15,-16,28,1,-15,11,16,
809,4,-21,-37,-40,-6,22,12,
81-15,-23,-14,-17,-16,-9,-10,-9,
8213,-39,41,5,-9,16,-38,25,
8346,-47,4,49,-14,17,-2,6,
8418,5,-6,-33,-22,44,50,-2,
851,3,-6,7,7,-3,-21,38,
86-18,34,-14,-41,60,-13,6,16,
87-24,35,19,-13,-36,24,3,-17,
88-14,-10,36,44,-44,-29,-3,3,
89-54,-8,12,55,26,4,-2,-5,
902,-11,22,-23,2,22,1,-25,
91-39,66,-49,21,-8,-2,10,-14,
92-60,25,6,10,27,-25,16,5,
93-2,-9,26,-13,-20,58,-2,7,
9452,-9,2,5,-4,-15,23,-1,
95-38,23,8,27,-6,0,-27,-7,
9639,-10,-14,26,11,-45,-12,9,
97-5,34,4,-35,10,43,-22,-11,
9856,-7,20,1,10,1,-26,9,
9994,11,-27,-14,-13,1,-11,0,
10014,-5,-6,-10,-4,-15,-8,-41,
10121,-5,1,-28,-8,22,-9,33,
102-23,-4,-4,-12,39,4,-7,3,
103-60,80,8,-17,2,-6,12,-5,
1041,9,15,27,31,30,27,23,
10561,47,26,10,-5,-8,-12,-13,
1065,-18,25,-15,-4,-15,-11,12,
107-2,-2,-16,-2,-6,24,12,11,
108-4,9,1,-9,14,-45,57,12,
10920,-35,26,11,-64,32,-10,-10,
11042,-4,-9,-16,32,24,7,10,
11152,-11,-57,29,0,8,0,-6,
11217,-17,-56,-40,7,20,18,12,
113-6,16,5,7,-1,9,1,10,
11429,12,16,13,-2,23,7,9,
115-3,-4,-5,18,-64,13,55,-25,
1169,-9,24,14,-25,15,-11,-40,
117-30,37,1,-19,22,-5,-31,13,
118-2,0,7,-4,16,-67,12,66,
119-36,24,-8,18,-15,-23,19,0,
120-45,-7,4,3,-13,13,35,5,
12113,33,10,27,23,0,-7,-11,
12243,-74,36,-12,2,5,-8,6,
123-33,11,-16,-14,-5,-7,-3,17,
124-34,27,-16,11,-9,15,33,-31,
1258,-16,7,-6,-7,63,-55,-17,
12611,-1,20,-46,34,-30,6,9,
12719,28,-9,5,-24,-8,-23,-2,
12831,-19,-16,-5,-15,-18,0,26,
12918,37,-5,-15,-2,17,5,-27,
13021,-33,44,12,-27,-9,17,11,
13125,-21,-31,-7,13,33,-8,-25,
132-7,7,-10,4,-6,-9,48,-82,
133-23,-8,6,11,-23,3,-3,49,
134-29,25,31,4,14,16,9,-4,
135-18,10,-26,3,5,-44,-9,9,
136-47,-55,15,9,28,1,4,-3,
13746,6,-6,-38,-29,-31,-15,-6,
1383,0,14,-6,8,-54,-50,33,
139-5,1,-14,33,-48,26,-4,-5,
140-3,-5,-3,-5,-28,-22,77,55,
141-1,2,10,10,-9,-14,-66,-49,
14211,-36,-6,-20,10,-10,16,12,
1434,-1,-16,45,-44,-50,31,-2,
14425,42,23,-32,-22,0,11,20,
145-40,-35,-40,-36,-32,-26,-21,-13,
14652,-22,6,-24,-20,17,-5,-8,
14736,-25,-11,21,-26,6,34,-8,
1487,20,-3,5,-25,-8,18,-5,
149-9,-4,1,-9,20,20,39,48,
150-24,9,5,-65,22,29,4,3,
151-43,-11,32,-6,9,19,-27,-10,
152-47,-14,24,10,-7,-36,-7,-1,
153-4,-5,-5,16,53,25,-26,-29,
154-4,-12,45,-58,-34,33,-5,2,
155-1,27,-48,31,-15,22,-5,4,
1567,7,-25,-3,11,-22,16,-12,
1578,-3,7,-11,45,14,-73,-19,
15856,-46,24,-20,28,-12,-2,-1,
159-36,-3,-33,19,-6,7,2,-15,
1605,-31,-45,8,35,13,20,0,
161-9,48,-13,-43,-3,-13,2,-5,
16272,-68,-27,2,1,-2,-7,5,
16336,33,-40,-12,-4,-5,23,19};
diff --git a/lib/rbcodec/codecs/libspeex/fftwrap.c b/lib/rbcodec/codecs/libspeex/fftwrap.c
new file mode 100644
index 0000000000..2312f755d6
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/fftwrap.c
@@ -0,0 +1,288 @@
1/* Copyright (C) 2005-2006 Jean-Marc Valin
2 File: fftwrap.c
3
4 Wrapper for various FFTs
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35#ifdef HAVE_CONFIG_H
36#include "config-speex.h"
37#endif
38
39/*#define USE_SMALLFT*/
40#define USE_KISS_FFT
41
42
43#include "arch.h"
44#include "os_support.h"
45
46#define MAX_FFT_SIZE 2048
47
48#ifdef FIXED_POINT
49static int maximize_range(spx_word16_t *in, spx_word16_t *out, spx_word16_t bound, int len)
50{
51 int i, shift;
52 spx_word16_t max_val = 0;
53 for (i=0;i<len;i++)
54 {
55 if (in[i]>max_val)
56 max_val = in[i];
57 if (-in[i]>max_val)
58 max_val = -in[i];
59 }
60 shift=0;
61 while (max_val <= (bound>>1) && max_val != 0)
62 {
63 max_val <<= 1;
64 shift++;
65 }
66 for (i=0;i<len;i++)
67 {
68 out[i] = SHL16(in[i], shift);
69 }
70 return shift;
71}
72
73static void renorm_range(spx_word16_t *in, spx_word16_t *out, int shift, int len)
74{
75 int i;
76 for (i=0;i<len;i++)
77 {
78 out[i] = PSHR16(in[i], shift);
79 }
80}
81#endif
82
83#ifdef USE_SMALLFT
84
85#include "smallft.h"
86#include <math.h>
87
88void *spx_fft_init(int size)
89{
90 struct drft_lookup *table;
91 table = speex_alloc(sizeof(struct drft_lookup));
92 spx_drft_init((struct drft_lookup *)table, size);
93 return (void*)table;
94}
95
96void spx_fft_destroy(void *table)
97{
98 spx_drft_clear(table);
99 speex_free(table);
100}
101
102void spx_fft(void *table, float *in, float *out)
103{
104 if (in==out)
105 {
106 int i;
107 float scale = 1./((struct drft_lookup *)table)->n;
108 speex_warning("FFT should not be done in-place");
109 for (i=0;i<((struct drft_lookup *)table)->n;i++)
110 out[i] = scale*in[i];
111 } else {
112 int i;
113 float scale = 1./((struct drft_lookup *)table)->n;
114 for (i=0;i<((struct drft_lookup *)table)->n;i++)
115 out[i] = scale*in[i];
116 }
117 spx_drft_forward((struct drft_lookup *)table, out);
118}
119
120void spx_ifft(void *table, float *in, float *out)
121{
122 if (in==out)
123 {
124 speex_warning("FFT should not be done in-place");
125 } else {
126 int i;
127 for (i=0;i<((struct drft_lookup *)table)->n;i++)
128 out[i] = in[i];
129 }
130 spx_drft_backward((struct drft_lookup *)table, out);
131}
132
133#elif defined(USE_KISS_FFT)
134
135#include "kiss_fftr.h"
136#include "kiss_fft.h"
137
138struct kiss_config {
139 kiss_fftr_cfg forward;
140 kiss_fftr_cfg backward;
141 int N;
142};
143
144void *spx_fft_init(int size)
145{
146 struct kiss_config *table;
147 table = (struct kiss_config*)speex_alloc(sizeof(struct kiss_config));
148 table->forward = kiss_fftr_alloc(size,0,NULL,NULL);
149 table->backward = kiss_fftr_alloc(size,1,NULL,NULL);
150 table->N = size;
151 return table;
152}
153
154void spx_fft_destroy(void *table)
155{
156 struct kiss_config *t = (struct kiss_config *)table;
157 kiss_fftr_free(t->forward);
158 kiss_fftr_free(t->backward);
159 speex_free(table);
160}
161
162#ifdef FIXED_POINT
163
164void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
165{
166 int shift;
167 struct kiss_config *t = (struct kiss_config *)table;
168 shift = maximize_range(in, in, 32000, t->N);
169 kiss_fftr2(t->forward, in, out);
170 renorm_range(in, in, shift, t->N);
171 renorm_range(out, out, shift, t->N);
172}
173
174#else
175
176void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
177{
178 int i;
179 float scale;
180 struct kiss_config *t = (struct kiss_config *)table;
181 scale = 1./t->N;
182 kiss_fftr2(t->forward, in, out);
183 for (i=0;i<t->N;i++)
184 out[i] *= scale;
185}
186#endif
187
188void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
189{
190 struct kiss_config *t = (struct kiss_config *)table;
191 kiss_fftri2(t->backward, in, out);
192}
193
194
195#else
196
197#error No other FFT implemented
198
199#endif
200
201
202#ifdef FIXED_POINT
203/*#include "smallft.h"*/
204
205
206void spx_fft_float(void *table, float *in, float *out)
207{
208 int i;
209#ifdef USE_SMALLFT
210 int N = ((struct drft_lookup *)table)->n;
211#elif defined(USE_KISS_FFT)
212 int N = ((struct kiss_config *)table)->N;
213#else
214#endif
215#ifdef VAR_ARRAYS
216 spx_word16_t _in[N];
217 spx_word16_t _out[N];
218#else
219 spx_word16_t _in[MAX_FFT_SIZE];
220 spx_word16_t _out[MAX_FFT_SIZE];
221#endif
222 for (i=0;i<N;i++)
223 _in[i] = (int)floor(.5+in[i]);
224 spx_fft(table, _in, _out);
225 for (i=0;i<N;i++)
226 out[i] = _out[i];
227#if 0
228 if (!fixed_point)
229 {
230 float scale;
231 struct drft_lookup t;
232 spx_drft_init(&t, ((struct kiss_config *)table)->N);
233 scale = 1./((struct kiss_config *)table)->N;
234 for (i=0;i<((struct kiss_config *)table)->N;i++)
235 out[i] = scale*in[i];
236 spx_drft_forward(&t, out);
237 spx_drft_clear(&t);
238 }
239#endif
240}
241
242void spx_ifft_float(void *table, float *in, float *out)
243{
244 int i;
245#ifdef USE_SMALLFT
246 int N = ((struct drft_lookup *)table)->n;
247#elif defined(USE_KISS_FFT)
248 int N = ((struct kiss_config *)table)->N;
249#else
250#endif
251#ifdef VAR_ARRAYS
252 spx_word16_t _in[N];
253 spx_word16_t _out[N];
254#else
255 spx_word16_t _in[MAX_FFT_SIZE];
256 spx_word16_t _out[MAX_FFT_SIZE];
257#endif
258 for (i=0;i<N;i++)
259 _in[i] = (int)floor(.5+in[i]);
260 spx_ifft(table, _in, _out);
261 for (i=0;i<N;i++)
262 out[i] = _out[i];
263#if 0
264 if (!fixed_point)
265 {
266 int i;
267 struct drft_lookup t;
268 spx_drft_init(&t, ((struct kiss_config *)table)->N);
269 for (i=0;i<((struct kiss_config *)table)->N;i++)
270 out[i] = in[i];
271 spx_drft_backward(&t, out);
272 spx_drft_clear(&t);
273 }
274#endif
275}
276
277#else
278
279void spx_fft_float(void *table, float *in, float *out)
280{
281 spx_fft(table, in, out);
282}
283void spx_ifft_float(void *table, float *in, float *out)
284{
285 spx_ifft(table, in, out);
286}
287
288#endif
diff --git a/lib/rbcodec/codecs/libspeex/fftwrap.h b/lib/rbcodec/codecs/libspeex/fftwrap.h
new file mode 100644
index 0000000000..dfaf489441
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/fftwrap.h
@@ -0,0 +1,58 @@
1/* Copyright (C) 2005 Jean-Marc Valin
2 File: fftwrap.h
3
4 Wrapper for various FFTs
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35#ifndef FFTWRAP_H
36#define FFTWRAP_H
37
38#include "arch.h"
39
40/** Compute tables for an FFT */
41void *spx_fft_init(int size);
42
43/** Destroy tables for an FFT */
44void spx_fft_destroy(void *table);
45
46/** Forward (real to half-complex) transform */
47void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out);
48
49/** Backward (half-complex to real) transform */
50void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out);
51
52/** Forward (real to half-complex) transform of float data */
53void spx_fft_float(void *table, float *in, float *out);
54
55/** Backward (half-complex to real) transform of float data */
56void spx_ifft_float(void *table, float *in, float *out);
57
58#endif
diff --git a/lib/rbcodec/codecs/libspeex/filterbank.c b/lib/rbcodec/codecs/libspeex/filterbank.c
new file mode 100644
index 0000000000..d2a8f1af90
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/filterbank.c
@@ -0,0 +1,227 @@
1/* Copyright (C) 2006 Jean-Marc Valin */
2/**
3 @file filterbank.c
4 @brief Converting between psd and filterbank
5 */
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10
11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 3. The name of the author may not be used to endorse or promote products
19 derived from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.
32*/
33
34#ifdef HAVE_CONFIG_H
35#include "config-speex.h"
36#endif
37
38#include "filterbank.h"
39#include "arch.h"
40#include <math.h>
41#include "math_approx.h"
42#include "os_support.h"
43
44#ifdef FIXED_POINT
45
46#define toBARK(n) (MULT16_16(26829,spx_atan(SHR32(MULT16_16(97,n),2))) + MULT16_16(4588,spx_atan(MULT16_32_Q15(20,MULT16_16(n,n)))) + MULT16_16(3355,n))
47
48#else
49#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
50#endif
51
52#define toMEL(n) (2595.f*log10(1.f+(n)/700.f))
53
54FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type)
55{
56 FilterBank *bank;
57 spx_word32_t df;
58 spx_word32_t max_mel, mel_interval;
59 int i;
60 int id1;
61 int id2;
62 df = DIV32(SHL32(sampling,15),MULT16_16(2,len));
63 max_mel = toBARK(EXTRACT16(sampling/2));
64 mel_interval = PDIV32(max_mel,banks-1);
65
66 bank = (FilterBank*)speex_alloc(sizeof(FilterBank));
67 bank->nb_banks = banks;
68 bank->len = len;
69 bank->bank_left = (int*)speex_alloc(len*sizeof(int));
70 bank->bank_right = (int*)speex_alloc(len*sizeof(int));
71 bank->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
72 bank->filter_right = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
73 /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */
74#ifndef FIXED_POINT
75 bank->scaling = (float*)speex_alloc(banks*sizeof(float));
76#endif
77 for (i=0;i<len;i++)
78 {
79 spx_word16_t curr_freq;
80 spx_word32_t mel;
81 spx_word16_t val;
82 curr_freq = EXTRACT16(MULT16_32_P15(i,df));
83 mel = toBARK(curr_freq);
84 if (mel > max_mel)
85 break;
86#ifdef FIXED_POINT
87 id1 = DIV32(mel,mel_interval);
88#else
89 id1 = (int)(floor(mel/mel_interval));
90#endif
91 if (id1>banks-2)
92 {
93 id1 = banks-2;
94 val = Q15_ONE;
95 } else {
96 val = DIV32_16(mel - id1*mel_interval,EXTRACT16(PSHR32(mel_interval,15)));
97 }
98 id2 = id1+1;
99 bank->bank_left[i] = id1;
100 bank->filter_left[i] = SUB16(Q15_ONE,val);
101 bank->bank_right[i] = id2;
102 bank->filter_right[i] = val;
103 }
104
105 /* Think I can safely disable normalisation for fixed-point (and probably float as well) */
106#ifndef FIXED_POINT
107 for (i=0;i<bank->nb_banks;i++)
108 bank->scaling[i] = 0;
109 for (i=0;i<bank->len;i++)
110 {
111 int id = bank->bank_left[i];
112 bank->scaling[id] += bank->filter_left[i];
113 id = bank->bank_right[i];
114 bank->scaling[id] += bank->filter_right[i];
115 }
116 for (i=0;i<bank->nb_banks;i++)
117 bank->scaling[i] = Q15_ONE/(bank->scaling[i]);
118#endif
119 return bank;
120}
121
122void filterbank_destroy(FilterBank *bank)
123{
124 speex_free(bank->bank_left);
125 speex_free(bank->bank_right);
126 speex_free(bank->filter_left);
127 speex_free(bank->filter_right);
128#ifndef FIXED_POINT
129 speex_free(bank->scaling);
130#endif
131 speex_free(bank);
132}
133
134void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel)
135{
136 int i;
137 for (i=0;i<bank->nb_banks;i++)
138 mel[i] = 0;
139
140 for (i=0;i<bank->len;i++)
141 {
142 int id;
143 id = bank->bank_left[i];
144 mel[id] += MULT16_32_P15(bank->filter_left[i],ps[i]);
145 id = bank->bank_right[i];
146 mel[id] += MULT16_32_P15(bank->filter_right[i],ps[i]);
147 }
148 /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */
149#ifndef FIXED_POINT
150 /*for (i=0;i<bank->nb_banks;i++)
151 mel[i] = MULT16_32_P15(Q15(bank->scaling[i]),mel[i]);
152 */
153#endif
154}
155
156void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *ps)
157{
158 int i;
159 for (i=0;i<bank->len;i++)
160 {
161 spx_word32_t tmp;
162 int id1, id2;
163 id1 = bank->bank_left[i];
164 id2 = bank->bank_right[i];
165 tmp = MULT16_16(mel[id1],bank->filter_left[i]);
166 tmp += MULT16_16(mel[id2],bank->filter_right[i]);
167 ps[i] = EXTRACT16(PSHR32(tmp,15));
168 }
169}
170
171
172#ifndef FIXED_POINT
173void filterbank_compute_bank(FilterBank *bank, float *ps, float *mel)
174{
175 int i;
176 for (i=0;i<bank->nb_banks;i++)
177 mel[i] = 0;
178
179 for (i=0;i<bank->len;i++)
180 {
181 int id = bank->bank_left[i];
182 mel[id] += bank->filter_left[i]*ps[i];
183 id = bank->bank_right[i];
184 mel[id] += bank->filter_right[i]*ps[i];
185 }
186 for (i=0;i<bank->nb_banks;i++)
187 mel[i] *= bank->scaling[i];
188}
189
190void filterbank_compute_psd(FilterBank *bank, float *mel, float *ps)
191{
192 int i;
193 for (i=0;i<bank->len;i++)
194 {
195 int id = bank->bank_left[i];
196 ps[i] = mel[id]*bank->filter_left[i];
197 id = bank->bank_right[i];
198 ps[i] += mel[id]*bank->filter_right[i];
199 }
200}
201
202void filterbank_psy_smooth(FilterBank *bank, float *ps, float *mask)
203{
204 /* Low freq slope: 14 dB/Bark*/
205 /* High freq slope: 9 dB/Bark*/
206 /* Noise vs tone: 5 dB difference */
207 /* FIXME: Temporary kludge */
208 float bark[100];
209 int i;
210 /* Assumes 1/3 Bark resolution */
211 float decay_low = 0.34145f;
212 float decay_high = 0.50119f;
213 filterbank_compute_bank(bank, ps, bark);
214 for (i=1;i<bank->nb_banks;i++)
215 {
216 /*float decay_high = 13-1.6*log10(bark[i-1]);
217 decay_high = pow(10,(-decay_high/30.f));*/
218 bark[i] = bark[i] + decay_high*bark[i-1];
219 }
220 for (i=bank->nb_banks-2;i>=0;i--)
221 {
222 bark[i] = bark[i] + decay_low*bark[i+1];
223 }
224 filterbank_compute_psd(bank, bark, mask);
225}
226
227#endif
diff --git a/lib/rbcodec/codecs/libspeex/filterbank.h b/lib/rbcodec/codecs/libspeex/filterbank.h
new file mode 100644
index 0000000000..3e889a22f7
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/filterbank.h
@@ -0,0 +1,66 @@
1/* Copyright (C) 2006 Jean-Marc Valin */
2/**
3 @file filterbank.h
4 @brief Converting between psd and filterbank
5 */
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10
11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 3. The name of the author may not be used to endorse or promote products
19 derived from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.
32*/
33
34#ifndef FILTERBANK_H
35#define FILTERBANK_H
36
37#include "arch.h"
38
39typedef struct {
40 int *bank_left;
41 int *bank_right;
42 spx_word16_t *filter_left;
43 spx_word16_t *filter_right;
44#ifndef FIXED_POINT
45 float *scaling;
46#endif
47 int nb_banks;
48 int len;
49} FilterBank;
50
51
52FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type);
53
54void filterbank_destroy(FilterBank *bank);
55
56void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel);
57
58void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *psd);
59
60#ifndef FIXED_POINT
61void filterbank_compute_bank(FilterBank *bank, float *psd, float *mel);
62void filterbank_compute_psd(FilterBank *bank, float *mel, float *psd);
63#endif
64
65
66#endif
diff --git a/lib/rbcodec/codecs/libspeex/filters.c b/lib/rbcodec/codecs/libspeex/filters.c
new file mode 100644
index 0000000000..09f93c2a59
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/filters.c
@@ -0,0 +1,845 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin
2 File: filters.c
3 Various analysis/synthesis filters
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#ifdef HAVE_CONFIG_H
34#include "config-speex.h"
35#endif
36
37#include "filters.h"
38#include "stack_alloc.h"
39#include "arch.h"
40#include "math_approx.h"
41#include "ltp.h"
42#include <math.h>
43
44#ifdef _USE_SSE
45#include "filters_sse.h"
46#elif defined (ARM4_ASM) || defined(ARM5E_ASM)
47#include "filters_arm4.h"
48#define OVERRIDE_IIR_MEM16
49#define OVERRIDE_QMF_SYNTH
50#define OVERRIDE_SIGNAL_MUL
51#elif defined (COLDFIRE_ASM)
52#define OVERRIDE_IIR_MEM16
53#define OVERRIDE_QMF_SYNTH
54#define OVERRIDE_SIGNAL_MUL
55#elif defined (BFIN_ASM)
56#include "filters_bfin.h"
57#endif
58
59
60
61void bw_lpc(spx_word16_t gamma, const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order)
62{
63 int i;
64 spx_word16_t tmp=gamma;
65 for (i=0;i<order;i++)
66 {
67 lpc_out[i] = MULT16_16_P15(tmp,lpc_in[i]);
68 tmp = MULT16_16_P15(tmp, gamma);
69 }
70}
71
72void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len)
73{
74 int i;
75 for (i=0;i<len;i++)
76 {
77 /* It's important we do the test that way so we can catch NaNs, which are neither greater nor smaller */
78 if (!(vec[i]>=min_val && vec[i] <= max_val))
79 {
80 if (vec[i] < min_val)
81 vec[i] = min_val;
82 else if (vec[i] > max_val)
83 vec[i] = max_val;
84 else /* Has to be NaN */
85 vec[i] = 0;
86 }
87 }
88}
89
90void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem)
91{
92 int i;
93#ifdef FIXED_POINT
94 static const spx_word16_t Pcoef[5][3] ICONST_ATTR = {{16384, -31313, 14991}, {16384, -31569, 15249}, {16384, -31677, 15328}, {16384, -32313, 15947}, {16384, -22446, 6537}};
95 static const spx_word16_t Zcoef[5][3] ICONST_ATTR = {{15672, -31344, 15672}, {15802, -31601, 15802}, {15847, -31694, 15847}, {16162, -32322, 16162}, {14418, -28836, 14418}};
96#else
97 const spx_word16_t Pcoef[5][3] = {{1.00000f, -1.91120f, 0.91498f}, {1.00000f, -1.92683f, 0.93071f}, {1.00000f, -1.93338f, 0.93553f}, {1.00000f, -1.97226f, 0.97332f}, {1.00000f, -1.37000f, 0.39900f}};
98 const spx_word16_t Zcoef[5][3] = {{0.95654f, -1.91309f, 0.95654f}, {0.96446f, -1.92879f, 0.96446f}, {0.96723f, -1.93445f, 0.96723f}, {0.98645f, -1.97277f, 0.98645f}, {0.88000f, -1.76000f, 0.88000f}};
99#endif
100 const spx_word16_t *den, *num;
101 if (filtID>4)
102 filtID=4;
103
104 den = Pcoef[filtID]; num = Zcoef[filtID];
105 /*return;*/
106 for (i=0;i<len;i++)
107 {
108 spx_word16_t yi;
109 spx_word32_t vout = ADD32(MULT16_16(num[0], x[i]),mem[0]);
110 yi = EXTRACT16(SATURATE(PSHR32(vout,14),32767));
111 mem[0] = ADD32(MAC16_16(mem[1], num[1],x[i]), SHL32(MULT16_32_Q15(-den[1],vout),1));
112 mem[1] = ADD32(MULT16_16(num[2],x[i]), SHL32(MULT16_32_Q15(-den[2],vout),1));
113 y[i] = yi;
114 }
115}
116
117#ifdef FIXED_POINT
118
119#ifndef OVERRIDE_SIGNAL_MUL
120/* FIXME: These functions are ugly and probably introduce too much error */
121void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
122{
123 int i;
124 for (i=0;i<len;i++)
125 {
126 y[i] = SHL32(MULT16_32_Q14(EXTRACT16(SHR32(x[i],7)),scale),7);
127 }
128}
129#endif
130
131#ifndef SPEEX_DISABLE_ENCODER
132void signal_div(const spx_word16_t *x, spx_word16_t *y, spx_word32_t scale, int len)
133{
134 int i;
135 if (scale > SHL32(EXTEND32(SIG_SCALING), 8))
136 {
137 spx_word16_t scale_1;
138 scale = PSHR32(scale, SIG_SHIFT);
139 scale_1 = EXTRACT16(PDIV32_16(SHL32(EXTEND32(SIG_SCALING),7),scale));
140 for (i=0;i<len;i++)
141 {
142 y[i] = MULT16_16_P15(scale_1, x[i]);
143 }
144 } else if (scale > SHR32(EXTEND32(SIG_SCALING), 2)) {
145 spx_word16_t scale_1;
146 scale = PSHR32(scale, SIG_SHIFT-5);
147 scale_1 = DIV32_16(SHL32(EXTEND32(SIG_SCALING),3),scale);
148 for (i=0;i<len;i++)
149 {
150 y[i] = PSHR32(MULT16_16(scale_1, SHL16(x[i],2)),8);
151 }
152 } else {
153 spx_word16_t scale_1;
154 scale = PSHR32(scale, SIG_SHIFT-7);
155 if (scale < 5)
156 scale = 5;
157 scale_1 = DIV32_16(SHL32(EXTEND32(SIG_SCALING),3),scale);
158 for (i=0;i<len;i++)
159 {
160 y[i] = PSHR32(MULT16_16(scale_1, SHL16(x[i],2)),6);
161 }
162 }
163}
164#endif /* SPEEX_DISABLE_ENCODER */
165
166#else
167
168void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
169{
170 int i;
171 for (i=0;i<len;i++)
172 y[i] = scale*x[i];
173}
174
175void signal_div(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
176{
177 int i;
178 float scale_1 = 1/scale;
179 for (i=0;i<len;i++)
180 y[i] = scale_1*x[i];
181}
182#endif
183
184
185
186#ifdef FIXED_POINT
187
188
189
190#ifndef SPEEX_DISABLE_ENCODER
191spx_word16_t compute_rms(const spx_sig_t *x, int len)
192{
193 int i;
194 spx_word32_t sum=0;
195 spx_sig_t max_val=1;
196 int sig_shift;
197
198 for (i=0;i<len;i++)
199 {
200 spx_sig_t tmp = x[i];
201 if (tmp<0)
202 tmp = -tmp;
203 if (tmp > max_val)
204 max_val = tmp;
205 }
206
207 sig_shift=0;
208 while (max_val>16383)
209 {
210 sig_shift++;
211 max_val >>= 1;
212 }
213
214 for (i=0;i<len;i+=4)
215 {
216 spx_word32_t sum2=0;
217 spx_word16_t tmp;
218 tmp = EXTRACT16(SHR32(x[i],sig_shift));
219 sum2 = MAC16_16(sum2,tmp,tmp);
220 tmp = EXTRACT16(SHR32(x[i+1],sig_shift));
221 sum2 = MAC16_16(sum2,tmp,tmp);
222 tmp = EXTRACT16(SHR32(x[i+2],sig_shift));
223 sum2 = MAC16_16(sum2,tmp,tmp);
224 tmp = EXTRACT16(SHR32(x[i+3],sig_shift));
225 sum2 = MAC16_16(sum2,tmp,tmp);
226 sum = ADD32(sum,SHR32(sum2,6));
227 }
228
229 return EXTRACT16(PSHR32(SHL32(EXTEND32(spx_sqrt(DIV32(sum,len))),(sig_shift+3)),SIG_SHIFT));
230}
231#endif /*SPEEX_DISABLE_ENCODER */
232
233spx_word16_t compute_rms16(const spx_word16_t *x, int len)
234{
235 int i;
236 spx_word16_t max_val=10;
237
238 for (i=0;i<len;i++)
239 {
240 spx_sig_t tmp = x[i];
241 if (tmp<0)
242 tmp = -tmp;
243 if (tmp > max_val)
244 max_val = tmp;
245 }
246 if (max_val>16383)
247 {
248 spx_word32_t sum=0;
249 for (i=0;i<len;i+=4)
250 {
251 spx_word32_t sum2=0;
252 sum2 = MAC16_16(sum2,SHR16(x[i],1),SHR16(x[i],1));
253 sum2 = MAC16_16(sum2,SHR16(x[i+1],1),SHR16(x[i+1],1));
254 sum2 = MAC16_16(sum2,SHR16(x[i+2],1),SHR16(x[i+2],1));
255 sum2 = MAC16_16(sum2,SHR16(x[i+3],1),SHR16(x[i+3],1));
256 sum = ADD32(sum,SHR32(sum2,6));
257 }
258 return SHL16(spx_sqrt(DIV32(sum,len)),4);
259 } else {
260 spx_word32_t sum=0;
261 int sig_shift=0;
262 if (max_val < 8192)
263 sig_shift=1;
264 if (max_val < 4096)
265 sig_shift=2;
266 if (max_val < 2048)
267 sig_shift=3;
268 for (i=0;i<len;i+=4)
269 {
270 spx_word32_t sum2=0;
271 sum2 = MAC16_16(sum2,SHL16(x[i],sig_shift),SHL16(x[i],sig_shift));
272 sum2 = MAC16_16(sum2,SHL16(x[i+1],sig_shift),SHL16(x[i+1],sig_shift));
273 sum2 = MAC16_16(sum2,SHL16(x[i+2],sig_shift),SHL16(x[i+2],sig_shift));
274 sum2 = MAC16_16(sum2,SHL16(x[i+3],sig_shift),SHL16(x[i+3],sig_shift));
275 sum = ADD32(sum,SHR32(sum2,6));
276 }
277 return SHL16(spx_sqrt(DIV32(sum,len)),3-sig_shift);
278 }
279}
280
281#ifndef OVERRIDE_NORMALIZE16
282int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)
283{
284 int i;
285 spx_sig_t max_val=1;
286 int sig_shift;
287
288 for (i=0;i<len;i++)
289 {
290 spx_sig_t tmp = x[i];
291 if (tmp<0)
292 tmp = NEG32(tmp);
293 if (tmp >= max_val)
294 max_val = tmp;
295 }
296
297 sig_shift=0;
298 while (max_val>max_scale)
299 {
300 sig_shift++;
301 max_val >>= 1;
302 }
303
304 for (i=0;i<len;i++)
305 y[i] = EXTRACT16(SHR32(x[i], sig_shift));
306
307 return sig_shift;
308}
309#endif
310
311#else
312
313spx_word16_t compute_rms(const spx_sig_t *x, int len)
314{
315 int i;
316 float sum=0;
317 for (i=0;i<len;i++)
318 {
319 sum += x[i]*x[i];
320 }
321 return sqrt(.1+sum/len);
322}
323spx_word16_t compute_rms16(const spx_word16_t *x, int len)
324{
325 return compute_rms(x, len);
326}
327#endif
328
329
330
331#ifndef SPEEX_DISABLE_ENCODER
332#ifndef OVERRIDE_FILTER_MEM16
333void 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)
334{
335 int i,j;
336 spx_word16_t xi,yi,nyi;
337 for (i=0;i<N;i++)
338 {
339 xi= x[i];
340 yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));
341 nyi = NEG16(yi);
342 for (j=0;j<ord-1;j++)
343 {
344 mem[j] = MAC16_16(MAC16_16(mem[j+1], num[j],xi), den[j],nyi);
345 }
346 mem[ord-1] = ADD32(MULT16_16(num[ord-1],xi), MULT16_16(den[ord-1],nyi));
347 y[i] = yi;
348 }
349}
350#endif
351#endif /* SPEEX_DISABLE_ENCODER */
352
353#ifndef OVERRIDE_IIR_MEM16
354void 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)
355{
356 (void)stack;
357 int i,j;
358 spx_word16_t yi,nyi;
359
360 for (i=0;i<N;i++)
361 {
362 yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));
363 nyi = NEG16(yi);
364 for (j=0;j<ord-1;j++)
365 {
366 mem[j] = MAC16_16(mem[j+1],den[j],nyi);
367 }
368 mem[ord-1] = MULT16_16(den[ord-1],nyi);
369 y[i] = yi;
370 }
371}
372#endif
373
374#ifndef SPEEX_DISABLE_ENCODER
375#ifndef OVERRIDE_FIR_MEM16
376void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
377{
378 int i,j;
379 spx_word16_t xi,yi;
380
381 for (i=0;i<N;i++)
382 {
383 xi=x[i];
384 yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));
385 for (j=0;j<ord-1;j++)
386 {
387 mem[j] = MAC16_16(mem[j+1], num[j],xi);
388 }
389 mem[ord-1] = MULT16_16(num[ord-1],xi);
390 y[i] = yi;
391 }
392}
393#endif
394
395
396void syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
397{
398 int i;
399 VARDECL(spx_mem_t *mem);
400 ALLOC(mem, ord, spx_mem_t);
401 for (i=0;i<ord;i++)
402 mem[i]=0;
403 iir_mem16(xx, ak, y, N, ord, mem, stack);
404 for (i=0;i<ord;i++)
405 mem[i]=0;
406 filter_mem16(y, awk1, awk2, y, N, ord, mem, stack);
407}
408void residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
409{
410 int i;
411 VARDECL(spx_mem_t *mem);
412 ALLOC(mem, ord, spx_mem_t);
413 for (i=0;i<ord;i++)
414 mem[i]=0;
415 filter_mem16(xx, ak, awk1, y, N, ord, mem, stack);
416 for (i=0;i<ord;i++)
417 mem[i]=0;
418 fir_mem16(y, awk2, y, N, ord, mem, stack);
419}
420
421
422#ifndef OVERRIDE_COMPUTE_IMPULSE_RESPONSE
423void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
424{
425 int i,j;
426 spx_word16_t y1, ny1i, ny2i;
427 VARDECL(spx_mem_t *mem1);
428 VARDECL(spx_mem_t *mem2);
429 ALLOC(mem1, ord, spx_mem_t);
430 ALLOC(mem2, ord, spx_mem_t);
431
432 y[0] = LPC_SCALING;
433 for (i=0;i<ord;i++)
434 y[i+1] = awk1[i];
435 i++;
436 for (;i<N;i++)
437 y[i] = VERY_SMALL;
438 for (i=0;i<ord;i++)
439 mem1[i] = mem2[i] = 0;
440 for (i=0;i<N;i++)
441 {
442 y1 = ADD16(y[i], EXTRACT16(PSHR32(mem1[0],LPC_SHIFT)));
443 ny1i = NEG16(y1);
444 y[i] = PSHR32(ADD32(SHL32(EXTEND32(y1),LPC_SHIFT+1),mem2[0]),LPC_SHIFT);
445 ny2i = NEG16(y[i]);
446 for (j=0;j<ord-1;j++)
447 {
448 mem1[j] = MAC16_16(mem1[j+1], awk2[j],ny1i);
449 mem2[j] = MAC16_16(mem2[j+1], ak[j],ny2i);
450 }
451 mem1[ord-1] = MULT16_16(awk2[ord-1],ny1i);
452 mem2[ord-1] = MULT16_16(ak[ord-1],ny2i);
453 }
454}
455#endif
456
457/* Decomposes a signal into low-band and high-band using a QMF */
458void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *y1, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack)
459{
460 int i,j,k,M2;
461 VARDECL(spx_word16_t *a);
462 VARDECL(spx_word16_t *x);
463 spx_word16_t *x2;
464
465 ALLOC(a, M, spx_word16_t);
466 ALLOC(x, N+M-1, spx_word16_t);
467 x2=x+M-1;
468 M2=M>>1;
469 for (i=0;i<M;i++)
470 a[M-i-1]= aa[i];
471 for (i=0;i<M-1;i++)
472 x[i]=mem[M-i-2];
473 for (i=0;i<N;i++)
474 x[i+M-1]=SHR16(xx[i],1);
475 for (i=0;i<M-1;i++)
476 mem[i]=SHR16(xx[N-i-1],1);
477 for (i=0,k=0;i<N;i+=2,k++)
478 {
479 spx_word32_t y1k=0, y2k=0;
480 for (j=0;j<M2;j++)
481 {
482 y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));
483 y2k=SUB32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));
484 j++;
485 y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));
486 y2k=ADD32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));
487 }
488 y1[k] = EXTRACT16(SATURATE(PSHR32(y1k,15),32767));
489 y2[k] = EXTRACT16(SATURATE(PSHR32(y2k,15),32767));
490 }
491}
492#endif /* SPEEX_DISABLE_ENCODER */
493
494#ifndef OVERRIDE_QMF_SYNTH
495/* Re-synthesised a signal from the QMF low-band and high-band signals */
496void 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)
497 /* assumptions:
498 all odd x[i] are zero -- well, actually they are left out of the array now
499 N and M are multiples of 4 */
500{
501 (void)stack;
502 int i, j;
503 int M2, N2;
504 VARDECL(spx_word16_t *xx1);
505 VARDECL(spx_word16_t *xx2);
506
507 M2 = M>>1;
508 N2 = N>>1;
509 ALLOC(xx1, M2+N2, spx_word16_t);
510 ALLOC(xx2, M2+N2, spx_word16_t);
511
512 for (i = 0; i < N2; i++)
513 xx1[i] = x1[N2-1-i];
514 for (i = 0; i < M2; i++)
515 xx1[N2+i] = mem1[2*i+1];
516 for (i = 0; i < N2; i++)
517 xx2[i] = x2[N2-1-i];
518 for (i = 0; i < M2; i++)
519 xx2[N2+i] = mem2[2*i+1];
520
521 for (i = 0; i < N2; i += 2) {
522 spx_sig_t y0, y1, y2, y3;
523 spx_word16_t x10, x20;
524
525 y0 = y1 = y2 = y3 = 0;
526 x10 = xx1[N2-2-i];
527 x20 = xx2[N2-2-i];
528
529 for (j = 0; j < M2; j += 2) {
530 spx_word16_t x11, x21;
531 spx_word16_t a0, a1;
532
533 a0 = a[2*j];
534 a1 = a[2*j+1];
535 x11 = xx1[N2-1+j-i];
536 x21 = xx2[N2-1+j-i];
537
538#ifdef FIXED_POINT
539 /* We multiply twice by the same coef to avoid overflows */
540 y0 = MAC16_16(MAC16_16(y0, a0, x11), NEG16(a0), x21);
541 y1 = MAC16_16(MAC16_16(y1, a1, x11), a1, x21);
542 y2 = MAC16_16(MAC16_16(y2, a0, x10), NEG16(a0), x20);
543 y3 = MAC16_16(MAC16_16(y3, a1, x10), a1, x20);
544#else
545 y0 = ADD32(y0,MULT16_16(a0, x11-x21));
546 y1 = ADD32(y1,MULT16_16(a1, x11+x21));
547 y2 = ADD32(y2,MULT16_16(a0, x10-x20));
548 y3 = ADD32(y3,MULT16_16(a1, x10+x20));
549#endif
550 a0 = a[2*j+2];
551 a1 = a[2*j+3];
552 x10 = xx1[N2+j-i];
553 x20 = xx2[N2+j-i];
554
555#ifdef FIXED_POINT
556 /* We multiply twice by the same coef to avoid overflows */
557 y0 = MAC16_16(MAC16_16(y0, a0, x10), NEG16(a0), x20);
558 y1 = MAC16_16(MAC16_16(y1, a1, x10), a1, x20);
559 y2 = MAC16_16(MAC16_16(y2, a0, x11), NEG16(a0), x21);
560 y3 = MAC16_16(MAC16_16(y3, a1, x11), a1, x21);
561#else
562 y0 = ADD32(y0,MULT16_16(a0, x10-x20));
563 y1 = ADD32(y1,MULT16_16(a1, x10+x20));
564 y2 = ADD32(y2,MULT16_16(a0, x11-x21));
565 y3 = ADD32(y3,MULT16_16(a1, x11+x21));
566#endif
567 }
568#ifdef FIXED_POINT
569 y[2*i] = EXTRACT16(SATURATE32(PSHR32(y0,15),32767));
570 y[2*i+1] = EXTRACT16(SATURATE32(PSHR32(y1,15),32767));
571 y[2*i+2] = EXTRACT16(SATURATE32(PSHR32(y2,15),32767));
572 y[2*i+3] = EXTRACT16(SATURATE32(PSHR32(y3,15),32767));
573#else
574 /* Normalize up explicitly if we're in float */
575 y[2*i] = 2.f*y0;
576 y[2*i+1] = 2.f*y1;
577 y[2*i+2] = 2.f*y2;
578 y[2*i+3] = 2.f*y3;
579#endif
580 }
581
582 for (i = 0; i < M2; i++)
583 mem1[2*i+1] = xx1[i];
584 for (i = 0; i < M2; i++)
585 mem2[2*i+1] = xx2[i];
586}
587#endif
588
589#ifdef FIXED_POINT
590#if 0
591const spx_word16_t shift_filt[3][7] = {{-33, 1043, -4551, 19959, 19959, -4551, 1043},
592 {-98, 1133, -4425, 29179, 8895, -2328, 444},
593 {444, -2328, 8895, 29179, -4425, 1133, -98}};
594#else
595const spx_word16_t shift_filt[3][7] = {{-390, 1540, -4993, 20123, 20123, -4993, 1540},
596 {-1064, 2817, -6694, 31589, 6837, -990, -209},
597 {-209, -990, 6837, 31589, -6694, 2817, -1064}};
598#endif
599#else
600#if 0
601const float shift_filt[3][7] = {{-9.9369e-04, 3.1831e-02, -1.3889e-01, 6.0910e-01, 6.0910e-01, -1.3889e-01, 3.1831e-02},
602 {-0.0029937, 0.0345613, -0.1350474, 0.8904793, 0.2714479, -0.0710304, 0.0135403},
603 {0.0135403, -0.0710304, 0.2714479, 0.8904793, -0.1350474, 0.0345613, -0.0029937}};
604#else
605const float shift_filt[3][7] = {{-0.011915f, 0.046995f, -0.152373f, 0.614108f, 0.614108f, -0.152373f, 0.046995f},
606 {-0.0324855f, 0.0859768f, -0.2042986f, 0.9640297f, 0.2086420f, -0.0302054f, -0.0063646f},
607 {-0.0063646f, -0.0302054f, 0.2086420f, 0.9640297f, -0.2042986f, 0.0859768f, -0.0324855f}};
608#endif
609#endif
610
611static int interp_pitch(
612spx_word16_t *exc, /*decoded excitation*/
613spx_word16_t *interp, /*decoded excitation*/
614int pitch, /*pitch period*/
615int len
616)
617{
618 int i,j,k;
619 spx_word32_t corr[4][7];
620 spx_word32_t maxcorr;
621 int maxi, maxj;
622 for (i=0;i<7;i++)
623 {
624 corr[0][i] = inner_prod(exc, exc-pitch-3+i, len);
625 }
626 for (i=0;i<3;i++)
627 {
628 for (j=0;j<7;j++)
629 {
630 int i1, i2;
631 spx_word32_t tmp=0;
632 i1 = 3-j;
633 if (i1<0)
634 i1 = 0;
635 i2 = 10-j;
636 if (i2>7)
637 i2 = 7;
638 for (k=i1;k<i2;k++)
639 tmp += MULT16_32_Q15(shift_filt[i][k],corr[0][j+k-3]);
640 corr[i+1][j] = tmp;
641 }
642 }
643 maxi=maxj=0;
644 maxcorr = corr[0][0];
645 for (i=0;i<4;i++)
646 {
647 for (j=0;j<7;j++)
648 {
649 if (corr[i][j] > maxcorr)
650 {
651 maxcorr = corr[i][j];
652 maxi=i;
653 maxj=j;
654 }
655 }
656 }
657 for (i=0;i<len;i++)
658 {
659 spx_word32_t tmp = 0;
660 if (maxi>0)
661 {
662 for (k=0;k<7;k++)
663 {
664 tmp += MULT16_16(exc[i-(pitch-maxj+3)+k-3],shift_filt[maxi-1][k]);
665 }
666 } else {
667 tmp = SHL32(exc[i-(pitch-maxj+3)],15);
668 }
669 interp[i] = PSHR32(tmp,15);
670 }
671 return pitch-maxj+3;
672}
673
674void multicomb(
675spx_word16_t *exc, /*decoded excitation*/
676spx_word16_t *new_exc, /*enhanced excitation*/
677spx_coef_t *ak, /*LPC filter coefs*/
678int p, /*LPC order*/
679int nsf, /*sub-frame size*/
680int pitch, /*pitch period*/
681int max_pitch,
682spx_word16_t comb_gain, /*gain of comb filter*/
683char *stack
684)
685{
686 (void)ak;
687 (void)p;
688 (void)stack;
689 int i;
690 VARDECL(spx_word16_t *iexc);
691 spx_word16_t old_ener, new_ener;
692 int corr_pitch;
693
694 spx_word16_t iexc0_mag, iexc1_mag, exc_mag;
695 spx_word32_t corr0, corr1;
696 spx_word16_t gain0, gain1;
697 spx_word16_t pgain1, pgain2;
698 spx_word16_t c1, c2;
699 spx_word16_t g1, g2;
700 spx_word16_t ngain;
701 spx_word16_t gg1, gg2;
702#ifdef FIXED_POINT
703 int scaledown=0;
704#endif
705#if 0 /* Set to 1 to enable full pitch search */
706 int nol_pitch[6];
707 spx_word16_t nol_pitch_coef[6];
708 spx_word16_t ol_pitch_coef;
709 open_loop_nbest_pitch(exc, 20, 120, nsf,
710 nol_pitch, nol_pitch_coef, 6, stack);
711 corr_pitch=nol_pitch[0];
712 ol_pitch_coef = nol_pitch_coef[0];
713 /*Try to remove pitch multiples*/
714 for (i=1;i<6;i++)
715 {
716#ifdef FIXED_POINT
717 if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],19661)) &&
718#else
719 if ((nol_pitch_coef[i]>.6*nol_pitch_coef[0]) &&
720#endif
721 (ABS(2*nol_pitch[i]-corr_pitch)<=2 || ABS(3*nol_pitch[i]-corr_pitch)<=3 ||
722 ABS(4*nol_pitch[i]-corr_pitch)<=4 || ABS(5*nol_pitch[i]-corr_pitch)<=5))
723 {
724 corr_pitch = nol_pitch[i];
725 }
726 }
727#else
728 corr_pitch = pitch;
729#endif
730
731 ALLOC(iexc, 2*nsf, spx_word16_t);
732
733 interp_pitch(exc, iexc, corr_pitch, 80);
734 if (corr_pitch>max_pitch)
735 interp_pitch(exc, iexc+nsf, 2*corr_pitch, 80);
736 else
737 interp_pitch(exc, iexc+nsf, -corr_pitch, 80);
738
739#ifdef FIXED_POINT
740 for (i=0;i<nsf;i++)
741 {
742 if (ABS16(exc[i])>16383)
743 {
744 scaledown = 1;
745 break;
746 }
747 }
748 if (scaledown)
749 {
750 for (i=0;i<nsf;i++)
751 exc[i] = SHR16(exc[i],1);
752 for (i=0;i<2*nsf;i++)
753 iexc[i] = SHR16(iexc[i],1);
754 }
755#endif
756 /*interp_pitch(exc, iexc+2*nsf, 2*corr_pitch, 80);*/
757
758 /*printf ("%d %d %f\n", pitch, corr_pitch, max_corr*ener_1);*/
759 iexc0_mag = spx_sqrt(1000+inner_prod(iexc,iexc,nsf));
760 iexc1_mag = spx_sqrt(1000+inner_prod(iexc+nsf,iexc+nsf,nsf));
761 exc_mag = spx_sqrt(1+inner_prod(exc,exc,nsf));
762 corr0 = inner_prod(iexc,exc,nsf);
763 if (corr0<0)
764 corr0=0;
765 corr1 = inner_prod(iexc+nsf,exc,nsf);
766 if (corr1<0)
767 corr1=0;
768#ifdef FIXED_POINT
769 /* Doesn't cost much to limit the ratio and it makes the rest easier */
770 if (SHL32(EXTEND32(iexc0_mag),6) < EXTEND32(exc_mag))
771 iexc0_mag = ADD16(1,PSHR16(exc_mag,6));
772 if (SHL32(EXTEND32(iexc1_mag),6) < EXTEND32(exc_mag))
773 iexc1_mag = ADD16(1,PSHR16(exc_mag,6));
774#endif
775 if (corr0 > MULT16_16(iexc0_mag,exc_mag))
776 pgain1 = QCONST16(1., 14);
777 else
778 pgain1 = PDIV32_16(SHL32(PDIV32(corr0, exc_mag),14),iexc0_mag);
779 if (corr1 > MULT16_16(iexc1_mag,exc_mag))
780 pgain2 = QCONST16(1., 14);
781 else
782 pgain2 = PDIV32_16(SHL32(PDIV32(corr1, exc_mag),14),iexc1_mag);
783 gg1 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc0_mag);
784 gg2 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc1_mag);
785 if (comb_gain>0)
786 {
787#ifdef FIXED_POINT
788 c1 = (MULT16_16_Q15(QCONST16(.4,15),comb_gain)+QCONST16(.07,15));
789 c2 = QCONST16(.5,15)+MULT16_16_Q14(QCONST16(1.72,14),(c1-QCONST16(.07,15)));
790#else
791 c1 = .4*comb_gain+.07;
792 c2 = .5+1.72*(c1-.07);
793#endif
794 } else
795 {
796 c1=c2=0;
797 }
798#ifdef FIXED_POINT
799 g1 = 32767 - MULT16_16_Q13(MULT16_16_Q15(c2, pgain1),pgain1);
800 g2 = 32767 - MULT16_16_Q13(MULT16_16_Q15(c2, pgain2),pgain2);
801#else
802 g1 = 1-c2*pgain1*pgain1;
803 g2 = 1-c2*pgain2*pgain2;
804#endif
805 if (g1<c1)
806 g1 = c1;
807 if (g2<c1)
808 g2 = c1;
809 g1 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g1);
810 g2 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g2);
811 if (corr_pitch>max_pitch)
812 {
813 gain0 = MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q14(g1,gg1));
814 gain1 = MULT16_16_Q15(QCONST16(.3,15),MULT16_16_Q14(g2,gg2));
815 } else {
816 gain0 = MULT16_16_Q15(QCONST16(.6,15),MULT16_16_Q14(g1,gg1));
817 gain1 = MULT16_16_Q15(QCONST16(.6,15),MULT16_16_Q14(g2,gg2));
818 }
819 for (i=0;i<nsf;i++)
820 new_exc[i] = ADD16(exc[i], EXTRACT16(PSHR32(ADD32(MULT16_16(gain0,iexc[i]), MULT16_16(gain1,iexc[i+nsf])),8)));
821 /* FIXME: compute_rms16 is currently not quite accurate enough (but close) */
822 new_ener = compute_rms16(new_exc, nsf);
823 old_ener = compute_rms16(exc, nsf);
824
825 if (old_ener < 1)
826 old_ener = 1;
827 if (new_ener < 1)
828 new_ener = 1;
829 if (old_ener > new_ener)
830 old_ener = new_ener;
831 ngain = PDIV32_16(SHL32(EXTEND32(old_ener),14),new_ener);
832
833 for (i=0;i<nsf;i++)
834 new_exc[i] = MULT16_16_Q14(ngain, new_exc[i]);
835#ifdef FIXED_POINT
836 if (scaledown)
837 {
838 for (i=0;i<nsf;i++)
839 exc[i] = SHL16(exc[i],1);
840 for (i=0;i<nsf;i++)
841 new_exc[i] = SHL16(SATURATE16(new_exc[i],16383),1);
842 }
843#endif
844}
845
diff --git a/lib/rbcodec/codecs/libspeex/filters.h b/lib/rbcodec/codecs/libspeex/filters.h
new file mode 100644
index 0000000000..e3a5980e70
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/filters.h
@@ -0,0 +1,90 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file filters.h
4 @brief Various analysis/synthesis filters
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef FILTERS_H
36#define FILTERS_H
37
38#include "arch.h"
39
40spx_word16_t compute_rms(const spx_sig_t *x, int len);
41spx_word16_t compute_rms16(const spx_word16_t *x, int len);
42void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len);
43void signal_div(const spx_word16_t *x, spx_word16_t *y, spx_word32_t scale, int len);
44
45#ifdef FIXED_POINT
46
47int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len);
48
49#endif
50
51
52#define HIGHPASS_NARROWBAND 0
53#define HIGHPASS_WIDEBAND 2
54#define HIGHPASS_INPUT 0
55#define HIGHPASS_OUTPUT 1
56#define HIGHPASS_IRS 4
57
58void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem);
59
60
61void 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);
62void 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);
63
64void 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);
65void 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);
66void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);
67
68/* Apply bandwidth expansion on LPC coef */
69void bw_lpc(spx_word16_t , const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order);
70void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len);
71
72
73void syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
74void residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
75
76void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
77
78void multicomb(
79spx_word16_t *exc, /*decoded excitation*/
80spx_word16_t *new_exc, /*enhanced excitation*/
81spx_coef_t *ak, /*LPC filter coefs*/
82int p, /*LPC order*/
83int nsf, /*sub-frame size*/
84int pitch, /*pitch period*/
85int max_pitch, /*pitch gain (3-tap)*/
86spx_word16_t comb_gain, /*gain of comb filter*/
87char *stack
88);
89
90#endif
diff --git a/lib/rbcodec/codecs/libspeex/filters_arm4.S b/lib/rbcodec/codecs/libspeex/filters_arm4.S
new file mode 100644
index 0000000000..e652ede554
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/filters_arm4.S
@@ -0,0 +1,328 @@
1/* Copyright (C) 2007 Thom Johansen */
2/**
3 @file filters_arm4.S
4 @brief Various analysis/synthesis filters (ARMv4 version)
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#include "config.h"
36#if CONFIG_CPU == PP5002
37 .section .icode,"ax",%progbits
38#else
39 .text
40#endif
41
42/* 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) */
43 .global iir_mem16
44iir_mem16:
45 stmdb sp!, { r4-r11, lr }
46 ldr r5, [sp, #36] @ r0 = x, r1 = den, r2 = y, r3 = N
47 ldr r4, [sp, #40] @ r4 = mem, r5 = ord
48 cmp r5, #10
49 beq .order_10
50 cmp r5, #8
51 beq .order_8
52 ldmpc regs=r4-r11 @ Non-supported order, return
53
54 @ TODO: try using direct form 1 filtering
55.order_8:
56 ldmia r4, { r5-r12 } @ r5-r12 = mem[0..7]
570:
58 add r5, r5, #4096 @ Rounding constant
59 ldrsh r14, [r0], #2
60 add r14, r14, r5, asr #13 @ (mem[0] + 4096) >> 13 + x[i]
61 mov r5, #0x7f00
62 orr r5, r5, #0xff @ r5 = 32767
63 cmp r14, r5
64 movgt r14, r5 @ Clip positive
65 cmn r14, r5
66 rsblt r14, r5, #0 @ Clip negative
67 strh r14, [r2], #2 @ Write result to y[i]
68
69 ldrsh r4, [r1]
70 mul r5, r4, r14
71 sub r5, r6, r5 @ mem[0] = mem[1] - den[0]*y[i]
72 ldrsh r4, [r1, #2]
73 mul r6, r4, r14
74 sub r6, r7, r6 @ mem[1] = mem[2] - den[1]*y[i]
75 ldrsh r4, [r1, #4]
76 mul r7, r4, r14
77 sub r7, r8, r7 @ mem[2] = mem[3] - den[2]*y[i]
78 ldrsh r4, [r1, #6]
79 mul r8, r4, r14
80 sub r8, r9, r8 @ mem[3] = mem[4] - den[3]*y[i]
81 ldrsh r4, [r1, #8]
82 mul r9, r4, r14
83 sub r9, r10, r9 @ mem[4] = mem[5] - den[4]*y[i]
84 ldrsh r4, [r1, #10]
85 mul r10, r4, r14
86 sub r10, r11, r10 @ mem[5] = mem[6] - den[5]*y[i]
87 ldrsh r4, [r1, #12]
88 mul r11, r4, r14
89 sub r11, r12, r11 @ mem[6] = mem[7] - den[6]*y[i]
90 ldrsh r4, [r1, #14]
91 mul r12, r4, r14
92 rsb r12, r12, #0 @ mem[7] = -den[7]*y[i]
93 subs r3, r3, #1
94 bne 0b
95 ldr r4, [sp, #40] @ r4 = mem
96 stmia r4, { r5-r12 } @ Save back mem[]
97 ldmpc regs=r4-r11 @ Exit
98
99.order_10:
100 ldmia r4, { r5-r9 } @ r5-r9 = mem[0..4]
101 add r5, r5, #4096 @ Rounding constant
102 ldrsh r14, [r0], #2
103 add r14, r14, r5, asr #13 @ (mem[0] + 4096) >> 13 + x[i]
104 mov r5, #0x7f00
105 orr r5, r5, #0xff @ r5 = 32767
106 cmp r14, r5
107 movgt r14, r5 @ Clip positive
108 cmn r14, r5
109 rsblt r14, r5, #0 @ Clip negative
110 strh r14, [r2], #2 @ Write result to y[i]
111
112 ldmia r1!, { r10-r12 } @ r10-r12 = den[0..5]
113 mov r5, r10, lsl #16
114 mov r5, r5, asr #16
115 mul r5, r14, r5
116 sub r5, r6, r5 @ mem[0] = mem[1] - den[0]*y[i]
117 mov r10, r10, asr #16
118 mul r6, r14, r10
119 sub r6, r7, r6 @ mem[1] = mem[2] - den[1]*y[i]
120 mov r10, r11, lsl #16
121 mov r10, r10, asr #16
122 mul r7, r14, r10
123 sub r7, r8, r7 @ mem[2] = mem[3] - den[2]*y[i]
124 mov r10, r11, asr #16
125 mul r8, r14, r10
126 sub r8, r9, r8 @ mem[3] = mem[4] - den[3]*y[i]
127 stmia r4!, { r5-r8 } @ Write back mem[0..3], r4 = &mem[4]
128 mov r10, r12, lsl #16
129 mov r10, r10, asr #16
130 mul r5, r14, r10
131
132 ldmib r4, { r6-r10 } @ r6-r10 = mem[5..9]
133 sub r5, r6, r5 @ mem[4] = mem[5] - den[4]*y[i]
134 mov r12, r12, asr #16
135 mul r6, r14, r12
136 sub r6, r7, r6 @ mem[5] = mem[6] - den[5]*y[i]
137 ldmia r1!, { r11-r12 } @ r11-r12 = den[6..9]
138 mov r7, r11, lsl #16
139 mov r7, r7, asr #16
140 mul r7, r14, r7
141 sub r7, r8, r7 @ mem[6] = mem[7] - den[6]*y[i]
142 mov r11, r11, asr #16
143 mul r8, r14, r11
144 sub r8, r9, r8 @ mem[7] = mem[8] - den[7]*y[i]
145 mov r11, r12, lsl #16
146 mov r11, r11, asr #16
147 mul r9, r14, r11
148 sub r9, r10, r9 @ mem[8] = mem[9] - den[8]*y[i]
149 mov r12, r12, asr #16
150 mul r10, r14, r12
151 rsb r10, r10, #0 @ mem[9] = -den[9]*y[i]
152 stmia r4!, { r5-r10 } @ Write back mem[4..9]
153 sub r4, r4, #10*4
154 sub r1, r1, #10*2
155 subs r3, r3, #1
156 bne .order_10
157 ldmpc regs=r4-r11 @ Exit
158
159
160/* 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) */
161 .global qmf_synth
162qmf_synth:
163 stmdb sp!, { r4-r11, lr }
164 add r7, sp, #36 @ r0 = x1, r1 = x2, r2 = a, r3 = y
165 ldmia r7, { r4-r7 } @ r4 = N, r5 = M, r6 = mem1, r7 = mem2
166
167 add r8, r4, r5
168 sub r9, sp, r8 @ r9 = sp - (N + M >> 1) = xx2
169 sub r8, r9, r8 @ r8 = r9 - (N + M >> 1) = xx1
170 str sp, [r8, #-4] @ Stack old sp
171 sub sp, r8, #4 @ Update sp
172
173 add r0, r0, r4 @ x1 += N >> 1
174 add r1, r1, r4 @ x2 += N >> 1
175 mov r14, r4 @ Loop counter is N
1760:
177 @ Backwards copy x1 and x2 arrays to xx1 and xx2, assume N2 is power of two
178 @ N should always be a multiple of four, so this should be OK
179 ldmdb r0!, { r10-r11 }
180 mov r12, r10, ror #16
181 mov r11, r11, ror #16
182 stmia r8!, { r11-r12 }
183 ldmdb r1!, { r10-r11 }
184 mov r12, r10, ror #16
185 mov r11, r11, ror #16
186 stmia r9!, { r11-r12 }
187 subs r14, r14, #8
188 bne 0b
189
190 @ Copy alternate members of mem1 and mem2 to last part of xx1 and xx2
191 mov r14, r5 @ Loop counter is M
192 add r6, r6, #2
193 add r7, r7, #2
194 stmdb sp!, { r6-r7 } @ Stack &mem1[1], &mem2[1]
1950:
196 ldrh r10, [r6], #4
197 ldrh r11, [r6], #4
198 ldrh r12, [r7], #4
199 orr r10, r10, r11, lsl #16
200 ldrh r11, [r7], #4
201 orr r11, r12, r11, lsl #16
202 str r10, [r8], #4
203 str r11, [r9], #4
204 subs r14, r14, #4
205 bne 0b
206
207 sub r0, r8, r5 @ r0 = &xx1[N2]
208 sub r1, r9, r5 @ r1 = &xx2[N2]
209 str r4, [sp, #-4]! @ Stack N
210 mov r4, r5
211 str r4, [sp, #-4]! @ Stack M
212 @ Main loop, register usage:
213 @ r0 = xx1, r1 = xx2, r2 = a, r3 = y, r4 = M, r5 = x10, r6 = x11, r7 = x20
214 @ r8 = x21, r9 = [a1, a0], r10 = acc0, r11 = acc1, r12 = acc2, r14 = acc3
2150: @ Outerloop
216 mov r10, #16384 @ Init acccumulators to rounding const
217 mov r11, #16384
218 mov r12, #16384
219 mov r14, #16384
220
221 ldrsh r5, [r0, #-4]! @ r5 = x10, r0 = &xx1[N2 - 2]
222 ldrsh r7, [r1, #-4]! @ r7 = x20, r1 = &xx2[N2 - 2]
2231: @ Innerloop
224 ldrsh r9, [r2], #2 @ r9 = a0
225 ldrsh r6, [r0, #2]! @ r6 = x11
226 ldrsh r8, [r1, #2]! @ r8 = x21
227 sub r5, r5, r7 @ r5 = x10 - x20
228 add r7, r5, r7, asl #1 @ r7 = x10 + x20
229 mla r12, r9, r5, r12 @ acc2 += a0*(x10 - x20)
230 sub r5, r6, r8 @ r5 = x11 - x21
231 mla r10, r9, r5, r10 @ acc0 += a0*(x11 - x21)
232 ldrsh r9, [r2], #2 @ r9 = a1
233 add r5, r6, r8 @ r5 = x11 + x21
234 mla r14, r9, r7, r14 @ acc3 += a1*(x10 + x20)
235 mla r11, r9, r5, r11 @ acc1 += a1*(x11 + x21)
236
237 ldrsh r9, [r2], #2 @ r9 = a1
238 ldrsh r5, [r0, #2]! @ r5 = x10
239 ldrsh r7, [r1, #2]! @ r7 = x20
240 sub r6, r6, r8 @ r6 = x11 - x21
241 add r8, r6, r8, asl #1 @ r8 = x11 + x21
242 mla r12, r9, r6, r12 @ acc2 += a0*(x11 - x21)
243 sub r6, r5, r7 @ r6 = x10 - x20
244 mla r10, r9, r6, r10 @ acc0 += a0*(x10 - x20)
245 ldrsh r9, [r2], #2 @ r9 = a1
246 add r6, r5, r7 @ r5 = x10 + x20
247 mla r14, r9, r8, r14 @ acc3 += a1*(x11 + x21)
248 mla r11, r9, r6, r11 @ acc1 += a1*(x10 + x10)
249 subs r4, r4, #4
250 bne 1b
251
252 ldr r4, [sp] @ r4 = M
253 sub r2, r2, r4, lsl #1 @ r2 = &a[0]
254 sub r0, r0, r4 @ r0 = &xx1[N2 - 2 - i]
255 sub r1, r1, r4 @ r1 = &xx2[N2 - 2 - i]
256
257 mov r10, r10, asr #15 @ Shift outputs down
258 mov r11, r11, asr #15
259 mov r12, r12, asr #15
260 mov r14, r14, asr #15
261
262 @ Clip output to -32768..32767 range, which works fine despite not being
263 @ Speex' usual clipping range.
264 mvn r9, #0x8000
265 mov r5, r10, asr #15
266 teq r5, r5, asr #31
267 eorne r10, r9, r5, asr #31
268 mov r5, r11, asr #15
269 teq r5, r5, asr #31
270 eorne r11, r9, r5, asr #31
271 mov r5, r12, asr #15
272 teq r5, r5, asr #31
273 eorne r12, r9, r5, asr #31
274 mov r5, r14, asr #15
275 teq r5, r5, asr #31
276 eorne r14, r9, r5, asr #31
277
278 strh r10, [r3], #2 @ Write outputs
279 strh r11, [r3], #2
280 strh r12, [r3], #2
281 strh r14, [r3], #2
282 ldr r10, [sp, #4] @ Load N
283 subs r10, r10, #4 @ Are we done?
284 strne r10, [sp, #4] @ no ->
285 bne 0b @ do outer loop
286
287 @ Copy start of xx1 and xx2 back to alternate mem1 and mem2 entries
288 @ r0 and r1 are &xx1[0] and &xx2[0] at this point
289 add sp, sp, #8
290 ldmia sp, { r5-r6, sp } @ Fetch &mem1[1], &mem2[1], restore sp
2910:
292 ldr r7, [r0], #4
293 ldr r8, [r1], #4
294 strh r7, [r5], #4
295 strh r8, [r6], #4
296 mov r7, r7, lsr #16
297 mov r8, r8, lsr #16
298 strh r7, [r5], #4
299 strh r8, [r6], #4
300 subs r4, r4, #4
301 bne 0b
302 ldmpc regs=r4-r11 @ Exit
303
304
305/* void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len) */
306 .global signal_mul
307signal_mul:
308 stmdb sp!, { r4-r8, lr }
3090:
310 ldmia r0!, { r5-r8 } @ Load four input samples
311 smull r5, r12, r2, r5
312 mov r12, r12, lsl #18 @ Recombine upper and lower parts
313 orr r5, r12, r5, lsr #14
314 smull r6, r12, r2, r6
315 mov r12, r12, lsl #18
316 orr r6, r12, r6, lsr #14
317 smull r7, r12, r2, r7
318 mov r12, r12, lsl #18
319 orr r7, r12, r7, lsr #14
320 smull r8, r12, r2, r8
321 mov r12, r12, lsl #18
322 orr r8, r12, r8, lsr #14
323 stmia r1!, { r5-r8 } @ Store four output samples
324 subs r3, r3, #4 @ Are we done?
325 bne 0b
326
327 ldmpc regs=r4-r8 @ Exit
328
diff --git a/lib/rbcodec/codecs/libspeex/filters_arm4.h b/lib/rbcodec/codecs/libspeex/filters_arm4.h
new file mode 100644
index 0000000000..18c2a7d448
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/filters_arm4.h
@@ -0,0 +1,96 @@
1/* Copyright (C) 2004 Jean-Marc Valin */
2/**
3 @file filters_arm4.h
4 @brief Various analysis/synthesis filters (ARM4 version)
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#define OVERRIDE_NORMALIZE16
36int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)
37{
38 spx_sig_t max_val=1;
39 int sig_shift;
40 int dead1, dead2, dead3, dead4, dead5, dead6;
41
42 __asm__ __volatile__ (
43 "\tmov %1, #1 \n"
44 "\tmov %3, #0 \n"
45
46 ".normalize16loop1%=: \n"
47
48 "\tldr %4, [%0], #4 \n"
49 "\tcmp %4, %1 \n"
50 "\tmovgt %1, %4 \n"
51 "\tcmp %4, %3 \n"
52 "\tmovlt %3, %4 \n"
53
54 "\tsubs %2, %2, #1 \n"
55 "\tbne .normalize16loop1%=\n"
56
57 "\trsb %3, %3, #0 \n"
58 "\tcmp %1, %3 \n"
59 "\tmovlt %1, %3 \n"
60 : "=r" (dead1), "=r" (max_val), "=r" (dead3), "=r" (dead4),
61 "=r" (dead5), "=r" (dead6)
62 : "0" (x), "2" (len)
63 : "cc", "memory");
64
65 sig_shift=0;
66 while (max_val>max_scale)
67 {
68 sig_shift++;
69 max_val >>= 1;
70 }
71
72 __asm__ __volatile__ (
73 ".normalize16loop%=: \n"
74
75 "\tldr %4, [%0], #4 \n"
76 "\tldr %5, [%0], #4 \n"
77 "\tmov %4, %4, asr %3 \n"
78 "\tstrh %4, [%1], #2 \n"
79 "\tldr %4, [%0], #4 \n"
80 "\tmov %5, %5, asr %3 \n"
81 "\tstrh %5, [%1], #2 \n"
82 "\tldr %5, [%0], #4 \n"
83 "\tmov %4, %4, asr %3 \n"
84 "\tstrh %4, [%1], #2 \n"
85 "\tsubs %2, %2, #1 \n"
86 "\tmov %5, %5, asr %3 \n"
87 "\tstrh %5, [%1], #2 \n"
88
89 "\tbge .normalize16loop%=\n"
90 : "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
91 "=r" (dead5), "=r" (dead6)
92 : "0" (x), "1" (y), "2" (len>>2), "3" (sig_shift)
93 : "cc", "memory");
94 return sig_shift;
95}
96
diff --git a/lib/rbcodec/codecs/libspeex/filters_bfin.h b/lib/rbcodec/codecs/libspeex/filters_bfin.h
new file mode 100644
index 0000000000..1e433ee167
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/filters_bfin.h
@@ -0,0 +1,515 @@
1/* Copyright (C) 2005 Analog Devices */
2/**
3 @file filters_bfin.h
4 @brief Various analysis/synthesis filters (Blackfin version)
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#define OVERRIDE_NORMALIZE16
36int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)
37{
38 spx_sig_t max_val=1;
39 int sig_shift;
40 __asm__
41 (
42 "%0 = 0;\n\t"
43 "I0 = %1;\n\t"
44 "L0 = 0;\n\t"
45 "R1 = [I0++];\n\t"
46 "LOOP norm_max%= LC0 = %2;\n\t"
47 "LOOP_BEGIN norm_max%=;\n\t"
48 "R2 = ABS R1 || R1 = [I0++];\n\t"
49 "%0 = MAX(%0, R2);\n\t"
50 "LOOP_END norm_max%=;\n\t"
51 : "=&d" (max_val)
52 : "a" (x), "a" (len)
53 : "R1", "R2"
54 );
55
56 sig_shift=0;
57 while (max_val>max_scale)
58 {
59 sig_shift++;
60 max_val >>= 1;
61 }
62
63 __asm__ __volatile__
64 (
65 "I0 = %0;\n\t"
66 "L0 = 0;\n\t"
67 "P1 = %1;\n\t"
68 "R0 = [I0++];\n\t"
69 "LOOP norm_shift%= LC0 = %3;\n\t"
70 "LOOP_BEGIN norm_shift%=;\n\t"
71 "R1 = ASHIFT R0 by %2.L || R0 = [I0++];\n\t"
72 "W[P1++] = R1;\n\t"
73 "LOOP_END norm_shift%=;\n\t"
74 "R1 = ASHIFT R0 by %2.L;\n\t"
75 "W[P1++] = R1;\n\t"
76 : : "a" (x), "a" (y), "d" (-sig_shift), "a" (len-1)
77 : "I0", "L0", "P1", "R0", "R1", "memory"
78 );
79 return sig_shift;
80}
81
82
83
84#define OVERRIDE_FILTER_MEM16
85void 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)
86{
87 VARDECL(spx_word32_t *xy2);
88 VARDECL(spx_word32_t *numden_a);
89 spx_word32_t *xy;
90 spx_word16_t *numden;
91 int i;
92
93 ALLOC(xy2, (N+1), spx_word32_t);
94 ALLOC(numden_a, (2*ord+2), spx_word32_t);
95 xy = xy2+1;
96 numden = (spx_word16_t*) numden_a;
97
98 for (i=0;i<ord;i++)
99 {
100 numden[2*i] = num[i];
101 numden[2*i+1] = den[i];
102 }
103 __asm__ __volatile__
104 (
105 /* Register setup */
106 "R0 = %5;\n\t" /*ord */
107
108 "P0 = %3;\n\t"
109 "I0 = P0;\n\t"
110 "B0 = P0;\n\t" /* numden */
111 "L0 = 0;\n\t"
112
113 "P2 = %0;\n\t" /* Fused xy */
114 "I2 = P2;\n\t"
115 "L2 = 0;\n\t"
116
117 "P4 = %6;\n\t" /* mem */
118 "P0 = %1;\n\t" /* _x */
119 "P1 = %2;\n\t" /* _y */
120
121 /* First sample */
122 "R1 = [P4++];\n\t"
123 "R1 <<= 3;\n\t" /* shift mem */
124 "R1.L = R1 (RND);\n\t"
125 "R2 = W[P0++];\n\t" /* load x[0] */
126 "R1.L = R1.L + R2.L;\n\t"
127 "W[P1++] = R1;\n\t" /* store y[0] */
128 "R2 = PACK(R1.L, R2.L);\n\t" /* pack x16 and y16 */
129 "[P2] = R2;\n\t"
130
131 /* Samples 1 to ord-1 (using memory) */
132 "R0 += -1;\n\t"
133 "R3 = 0;\n\t"
134 "LC0 = R0;\n\t"
135 "LOOP filter_start%= LC0;\n\t"
136 "LOOP_BEGIN filter_start%=;\n\t"
137 "R3 += 1;\n\t"
138 "LC1 = R3;\n\t"
139
140 "R1 = [P4++];\n\t"
141 "A1 = R1;\n\t"
142 "A0 = 0;\n\t"
143 "I0 = B0;\n\t"
144 "I2 = P2;\n\t"
145 "P2 += 4;\n\t"
146 "R4 = [I0++] || R5 = [I2--];\n\t"
147 "LOOP filter_start_inner%= LC1;\n\t"
148 "LOOP_BEGIN filter_start_inner%=;\n\t"
149 "A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t"
150 "LOOP_END filter_start_inner%=;\n\t"
151 "A0 += A1;\n\t"
152 "R4 = A0;\n\t"
153 "R4 <<= 3;\n\t" /* shift mem */
154 "R4.L = R4 (RND);\n\t"
155 "R2 = W[P0++];\n\t" /* load x */
156 "R4.L = R4.L + R2.L;\n\t"
157 "W[P1++] = R4;\n\t" /* store y */
158 //"R4 <<= 2;\n\t"
159 //"R2 <<= 2;\n\t"
160 "R2 = PACK(R4.L, R2.L);\n\t" /* pack x16 and y16 */
161 "[P2] = R2;\n\t"
162
163 "LOOP_END filter_start%=;\n\t"
164
165 /* Samples ord to N*/
166 "R0 = %5;\n\t"
167 "R0 <<= 1;\n\t"
168 "I0 = B0;\n\t" /* numden */
169 "R0 <<= 1;\n\t"
170 "L0 = R0;\n\t"
171
172 "R0 = %5;\n\t" /* org */
173 "R2 = %4;\n\t" /* N */
174 "R2 = R2 - R0;\n\t"
175 "R4 = [I0++];\n\t" /* numden */
176 "LC0 = R2;\n\t"
177 "P3 = R0;\n\t"
178 "R0 <<= 2;\n\t"
179 "R0 += 8;\n\t"
180 "I2 = P2;\n\t"
181 "M0 = R0;\n\t"
182 "A1 = A0 = 0;\n\t"
183 "R5 = [I2--];\n\t" /* load xy */
184 "LOOP filter_mid%= LC0;\n\t"
185 "LOOP_BEGIN filter_mid%=;\n\t"
186 "LOOP filter_mid_inner%= LC1=P3;\n\t"
187 "LOOP_BEGIN filter_mid_inner%=;\n\t"
188 "A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t"
189 "LOOP_END filter_mid_inner%=;\n\t"
190 "R0 = (A0 += A1) || I2 += M0;\n\t"
191 "R0 = R0 << 3 || R5 = W[P0++];\n\t" /* load x */
192 "R0.L = R0 (RND);\n\t"
193 "R0.L = R0.L + R5.L;\n\t"
194 "R5 = PACK(R0.L, R5.L) || W[P1++] = R0;\n\t" /* shift y | store y */
195 "A1 = A0 = 0 || [I2--] = R5\n\t"
196 "LOOP_END filter_mid%=;\n\t"
197 "I2 += 4;\n\t"
198 "P2 = I2;\n\t"
199 /* Update memory */
200 "P4 = %6;\n\t"
201 "R0 = %5;\n\t"
202 "LC0 = R0;\n\t"
203 "P0 = B0;\n\t"
204 "A1 = A0 = 0;\n\t"
205 "LOOP mem_update%= LC0;\n\t"
206 "LOOP_BEGIN mem_update%=;\n\t"
207 "I2 = P2;\n\t"
208 "I0 = P0;\n\t"
209 "P0 += 4;\n\t"
210 "R0 = LC0;\n\t"
211 "LC1 = R0;\n\t"
212 "R5 = [I2--] || R4 = [I0++];\n\t"
213 "LOOP mem_accum%= LC1;\n\t"
214 "LOOP_BEGIN mem_accum%=;\n\t"
215 "A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t"
216 "LOOP_END mem_accum%=;\n\t"
217 "R0 = (A0 += A1);\n\t"
218 "A1 = A0 = 0 || [P4++] = R0;\n\t"
219 "LOOP_END mem_update%=;\n\t"
220 "L0 = 0;\n\t"
221 : : "m" (xy), "m" (_x), "m" (_y), "m" (numden), "m" (N), "m" (ord), "m" (mem)
222 : "A0", "A1", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1", "P2", "P3", "P4", "B0", "I0", "I2", "L0", "L2", "M0", "memory"
223 );
224
225}
226
227
228
229#define OVERRIDE_IIR_MEM16
230void 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)
231{
232 VARDECL(spx_word16_t *y);
233 spx_word16_t *yy;
234
235 ALLOC(y, (N+2), spx_word16_t);
236 yy = y+2;
237
238 __asm__ __volatile__
239 (
240 /* Register setup */
241 "R0 = %5;\n\t" /*ord */
242
243 "P1 = %3;\n\t"
244 "I1 = P1;\n\t"
245 "B1 = P1;\n\t"
246 "L1 = 0;\n\t"
247
248 "P3 = %0;\n\t"
249 "I3 = P3;\n\t"
250 "L3 = 0;\n\t"
251
252 "P4 = %6;\n\t"
253 "P0 = %1;\n\t"
254 "P1 = %2;\n\t"
255
256 /* First sample */
257 "R1 = [P4++];\n\t"
258 "R1 = R1 << 3 (S);\n\t"
259 "R1.L = R1 (RND);\n\t"
260 "R2 = W[P0++];\n\t"
261 "R1 = R1 + R2;\n\t"
262 "W[P1++] = R1;\n\t"
263 "W[P3] = R1;\n\t"
264
265 /* Samples 1 to ord-1 (using memory) */
266 "R0 += -1;\n\t"
267 "R3 = 0;\n\t"
268 "LC0 = R0;\n\t"
269 "LOOP filter_start%= LC0;\n\t"
270 "LOOP_BEGIN filter_start%=;\n\t"
271 "R3 += 1;\n\t"
272 "LC1 = R3;\n\t"
273
274 "R1 = [P4++];\n\t"
275 "A1 = R1;\n\t"
276 "I1 = B1;\n\t"
277 "I3 = P3;\n\t"
278 "P3 += 2;\n\t"
279 "LOOP filter_start_inner%= LC1;\n\t"
280 "LOOP_BEGIN filter_start_inner%=;\n\t"
281 "R4.L = W[I1++];\n\t"
282 "R5.L = W[I3--];\n\t"
283 "A1 -= R4.L*R5.L (IS);\n\t"
284 "LOOP_END filter_start_inner%=;\n\t"
285
286 "R1 = A1;\n\t"
287 "R1 <<= 3;\n\t"
288 "R1.L = R1 (RND);\n\t"
289 "R2 = W[P0++];\n\t"
290 "R1 = R1 + R2;\n\t"
291 "W[P1++] = R1;\n\t"
292 "W[P3] = R1;\n\t"
293 "LOOP_END filter_start%=;\n\t"
294
295 /* Samples ord to N*/
296 "R0 = %5;\n\t"
297 "R0 <<= 1;\n\t"
298 "I1 = B1;\n\t"
299 "L1 = R0;\n\t"
300
301 "R0 = %5;\n\t"
302 "R2 = %4;\n\t"
303 "R2 = R2 - R0;\n\t"
304 "R4.L = W[I1++];\n\t"
305 "LC0 = R2;\n\t"
306 "LOOP filter_mid%= LC0;\n\t"
307 "LOOP_BEGIN filter_mid%=;\n\t"
308 "LC1 = R0;\n\t"
309 "A1 = 0;\n\t"
310 "I3 = P3;\n\t"
311 "P3 += 2;\n\t"
312 "R5.L = W[I3--];\n\t"
313 "LOOP filter_mid_inner%= LC1;\n\t"
314 "LOOP_BEGIN filter_mid_inner%=;\n\t"
315 "A1 -= R4.L*R5.L (IS) || R4.L = W[I1++] || R5.L = W[I3--];\n\t"
316 "LOOP_END filter_mid_inner%=;\n\t"
317 "R1 = A1;\n\t"
318 "R1 = R1 << 3 || R2 = W[P0++];\n\t"
319 "R1.L = R1 (RND);\n\t"
320 "R1 = R1 + R2;\n\t"
321 "W[P1++] = R1;\n\t"
322 "W[P3] = R1;\n\t"
323 "LOOP_END filter_mid%=;\n\t"
324
325 /* Update memory */
326 "P4 = %6;\n\t"
327 "R0 = %5;\n\t"
328 "LC0 = R0;\n\t"
329 "P1 = B1;\n\t"
330 "LOOP mem_update%= LC0;\n\t"
331 "LOOP_BEGIN mem_update%=;\n\t"
332 "A0 = 0;\n\t"
333 "I3 = P3;\n\t"
334 "I1 = P1;\n\t"
335 "P1 += 2;\n\t"
336 "R0 = LC0;\n\t"
337 "LC1=R0;\n\t"
338 "R5.L = W[I3--] || R4.L = W[I1++];\n\t"
339 "LOOP mem_accum%= LC1;\n\t"
340 "LOOP_BEGIN mem_accum%=;\n\t"
341 "A0 -= R4.L*R5.L (IS) || R4.L = W[I1++] || R5.L = W[I3--];\n\t"
342 "LOOP_END mem_accum%=;\n\t"
343 "R0 = A0;\n\t"
344 "[P4++] = R0;\n\t"
345 "LOOP_END mem_update%=;\n\t"
346 "L1 = 0;\n\t"
347 : : "m" (yy), "m" (_x), "m" (_y), "m" (den), "m" (N), "m" (ord), "m" (mem)
348 : "A0", "A1", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1", "P2", "P3", "P4", "B1", "I1", "I3", "L1", "L3", "memory"
349 );
350
351}
352
353
354#define OVERRIDE_FIR_MEM16
355void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
356{
357 int i;
358 spx_coef_t den2[12];
359 spx_coef_t *den;
360 den = (spx_coef_t*)((((int)den2)+4)&0xfffffffc);
361 for (i=0;i<10;i++)
362 den[i] = 0;
363 filter_mem16(x, num, den, y, N, ord, mem, stack);
364}
365
366
367#define OVERRIDE_COMPUTE_IMPULSE_RESPONSE
368void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
369{
370 int i;
371 VARDECL(spx_word16_t *ytmp);
372 ALLOC(ytmp, N, spx_word16_t);
373 spx_word16_t *ytmp2 = ytmp;
374 y[0] = LPC_SCALING;
375 for (i=0;i<ord;i++)
376 y[i+1] = awk1[i];
377 i++;
378 for (;i<N;i++)
379 y[i] = 0;
380
381 N-=1;
382 __asm__ __volatile__
383 (
384 "I0 = %0;\n\t"
385 "I1 = %1;\n\t"
386 "L0 = 0;\n\t"
387 "L1 = 0;\n\t"
388 "L2 = 0;\n\t"
389 "L3 = 0;\n\t"
390 "R0 = 1;\n\t"
391 "R0 <<= 13;\n\t"
392 "W[I0] = R0.L;\n\t"
393 "R0 <<= 1;\n\t"
394 "W[I1] = R0.L;\n\t"
395 "R0 = %5;\n\t"
396 "LC0 = R0;\n\t"
397 "R2 = 0;\n\t"
398 "LOOP samples%= LC0;\n\t"
399 "LOOP_BEGIN samples%=;\n\t"
400 "R2 += 1;\n\t"
401 "R2 = MIN(R2, %4);\n\t"
402 "I0 = %0;\n\t"
403 "I1 = %1;\n\t"
404 "I2 = %2;\n\t"
405 "I3 = %3;\n\t"
406 "%0 += 2;\n\t"
407 "%1 += 2;\n\t"
408 "A1 = A0 = 0;\n\t"
409 "R0.L = W[I0--] || R1.L = W[I2++];\n\t"
410 "LC1 = R2;\n\t"
411 "LOOP filter%= LC1;\n\t"
412 "LOOP_BEGIN filter%=;\n\t"
413 "A0 -= R0.L*R1.L (IS) || R0.L = W[I1--] || R1.L = W[I3++];\n\t"
414 "A1 -= R0.L*R1.L (IS) || R0.L = W[I0--] || R1.L = W[I2++];\n\t"
415 "LOOP_END filter%=;\n\t"
416 "R0 = A0, R1 = A1;\n\t"
417 "R3 = W[%1] (X);\n\t"
418 "R3 <<= 13;\n\t"
419 "R0 = R0 + R3;\n\t"
420 "R3 = R0 >>> 13;\n\t"
421 "W[%0] = R3.L;\n\t"
422 "R0 <<= 1;\n\t"
423 "R1 = R1 + R0;\n\t"
424 "R1 >>>= 13;\n\t"
425 "W[%1] = R1.L;\n\t"
426 "LOOP_END samples%=;\n\t"
427 : "=a" (ytmp2), "=a" (y)
428 : "a" (awk2), "a" (ak), "d" (ord), "m" (N), "0" (ytmp2), "1" (y)
429 : "A0", "A1", "R0", "R1", "R2", "R3", "I0", "I1", "I2", "I3", "L0", "L1", "L2", "L3", "A0", "A1"
430 );
431}
432
433
434
435#if 0 /* Equivalent C function for filter_mem2 and compute_impulse_response */
436#define min(a,b) ((a)<(b) ? (a):(b))
437
438void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
439{
440 int i,j;
441 VARDECL(spx_word16_t *ytmp);
442 ALLOC(ytmp, N, spx_word16_t);
443
444 y[0] = LPC_SCALING;
445 for (i=0;i<ord;i++)
446 y[i+1] = awk1[i];
447 i++;
448 for (;i<N;i++)
449 y[i] = 0;
450
451 for (i=0;i<N;i++)
452 {
453 spx_word32_t yi = SHL32(EXTEND32(y[i]),LPC_SHIFT);
454 spx_word32_t yi2 = 0;
455 for (j=0;j<min(i,ord);j++)
456 {
457 yi = MAC16_16(yi, awk2[j], -ytmp[i-j-1]);
458 yi2 = MAC16_16(yi2, ak[j], -y[i-j-1]);
459 }
460 ytmp[i] = EXTRACT16(SHR32(yi,LPC_SHIFT));
461 yi2 = ADD32(yi2,SHL32(yi,1));
462 y[i] = EXTRACT16(SHR32(yi2,LPC_SHIFT));
463 }
464
465}
466
467
468void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *_y, int N, int ord, spx_mem_t *mem)
469{
470 int i,j;
471 spx_word16_t xi,yi,nyi;
472 spx_word16_t x[N],y[N];
473 spx_word16_t *xx, *yy;
474 xx = x;
475 yy = y;
476 for (i=0;i<N;i++)
477 {
478 x[i] = EXTRACT16(SHR32(_x[i],SIG_SHIFT));
479 }
480
481 for (i=0;i<ord;i++)
482 {
483 spx_word32_t yi = mem[i];
484 for (j=0;j<i;j++)
485 {
486 yi = MAC16_16(yi, num[j], x[i-j-1]);
487 yi = MAC16_16(yi, den[j], -y[i-j-1]);
488 }
489 _y[i] = ADD32(_x[i],SHL32(yi,1));
490 y[i] = EXTRACT16(SHR32(_y[i],SIG_SHIFT));
491 }
492 for (i=ord;i<N;i++)
493 {
494 spx_word32_t yi = 0;
495 for (j=0;j<ord;j++)
496 {
497 yi = MAC16_16(yi, num[j], x[i-j-1]);
498 yi = MAC16_16(yi, den[j], -y[i-j-1]);
499 }
500 _y[i] = ADD32(_x[i],SHL32(yi,1));
501 y[i] = EXTRACT16(SHR32(_y[i],SIG_SHIFT));
502 }
503
504 for (i=0;i<ord;i++)
505 {
506 spx_mem_t m = 0;
507 for (j=0;j<ord-i;j++)
508 {
509 m = MAC16_16(m, x[N-1-j], num[j+i]);
510 m = MAC16_16(m, -y[N-1-j], den[j+i]);
511 }
512 mem[i] = m;
513 }
514}
515#endif
diff --git a/lib/rbcodec/codecs/libspeex/filters_cf.S b/lib/rbcodec/codecs/libspeex/filters_cf.S
new file mode 100644
index 0000000000..a48af85095
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/filters_cf.S
@@ -0,0 +1,356 @@
1/* Copyright (C) 2007 Thom Johansen */
2/**
3 @file filters_cf.S
4 @brief Various analysis/synthesis filters (Coldfire version)
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35 .text
36/* 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) */
37 .global iir_mem16
38iir_mem16:
39 lea.l (-44, %sp), %sp
40 movem.l %d2-%d7/%a2-%a6, (%sp)
41 movem.l (44+4, %sp), %a3-%a5 | a3 = x, a4 = den, a5 = y
42 movem.l (44+20, %sp), %d0/%a6 | d0 = ord, a6 = mem
43 moveq.l #8, %d1 | Jump to correct routine based on 'ord'
44 cmp.l %d1, %d0
45 jeq .order_8
46 moveq.l #10, %d1
47 cmp.l %d1, %d0
48 jeq .order_10
49 jra .exit
50
51 | TODO: try using direct form 1 filtering
52 | d0 = y[i], d1-d7, a0 = mem[0] .. mem[7]
53 | a3 = x, a4 = den, a5 = y, a6 = temp
54.order_8:
55 movem.l (%a6), %d1-%d7/%a0 | Fetch mem[] array
560:
57 moveq.l #13, %d0
58 add.l #4096, %d1
59 asr.l %d0, %d1 | mem[0] >> 13 with rounding
60 move.w (%a3)+, %d0
61 ext.l %d0
62 add.l %d1, %d0 | Add with x[i]
63 move.l #32767, %d1
64 move.l #65534, %a6
65 add.l %d1, %d0 | Bias result to [-1..65534]
66 cmp.l %a6, %d0 | Now do clip to [0..65534] range
67 jls 2f
68 jpl 1f
69 clr.l %d0 | Clip low
70 .word 0x51fa | trapf.w, shadow next insn
711:
72 move.l %a6, %d0 | Clip high
732:
74 sub.l %d1, %d0 | Bias clipped result back to [-32767..32767]
75 move.w %d0, (%a5)+ | Write result to y[i]
76 neg.l %d0 | msac.w is bugged in gas, do this for now
77 move.l (%a4)+, %a6 | Fetch den[0] and den[1]
78 mac.w %a6u, %d0l, %acc0
79 mac.w %a6l, %d0l, (%a4)+, %a6, %acc1
80 mac.w %a6u, %d0l, %acc2
81 mac.w %a6l, %d0l, (%a4)+, %a6, %acc3
82 movclr.l %acc0, %d1
83 add.l %d2, %d1 | mem[0] = mem[1] - den[0]*y[i]
84 movclr.l %acc1, %d2
85 add.l %d3, %d2 | mem[1] = mem[2] - den[1]*y[i]
86 movclr.l %acc2, %d3
87 add.l %d4, %d3 | mem[2] = mem[3] - den[2]*y[i]
88 movclr.l %acc3, %d4
89 add.l %d5, %d4 | mem[3] = mem[4] - den[3]*y[i]
90 mac.w %a6u, %d0l, %acc0
91 mac.w %a6l, %d0l, (%a4)+, %a6, %acc1
92 mac.w %a6u, %d0l, %acc2
93 mac.w %a6l, %d0l, %acc3
94 lea.l (-16, %a4), %a4 | wrap den pointer back to den[0]
95 movclr.l %acc0, %d5
96 add.l %d6, %d5 | mem[4] = mem[5] - den[4]*y[i]
97 movclr.l %acc1, %d6
98 add.l %d7, %d6 | mem[5] = mem[6] - den[5]*y[i]
99 movclr.l %acc2, %d7
100 add.l %a0, %d7 | mem[6] = mem[7] - den[6]*y[i]
101 movclr.l %acc3, %a0 | mem[7] = -den[7]*y[i]
102 subq.l #1, (44+16, %sp) | Have we done all samples?
103 jne 0b
104 move.l (44+24, %sp), %a6 | Fetch mem pointer
105 movem.l %d1-%d7/%a0, (%a6) | Save back mem[]
106 jra .exit
107
108 | d0 = y[i], d1-d7, a0-a2 = mem[0] .. mem[9]
109 | a3 = x, a4 = den, a5 = y, a6 = temp
110.order_10:
111 movem.l (%a6), %d1-%d7/%a0-%a2 | Fetch mem[] array
1120:
113 moveq.l #13, %d0
114 add.l #4096, %d1
115 asr.l %d0, %d1 | mem[0] >> 13 with rounding
116 move.w (%a3)+, %d0
117 ext.l %d0
118 add.l %d1, %d0 | Add with x[i]
119 move.l #32767, %d1
120 move.l #65534, %a6
121 add.l %d1, %d0 | Bias result to [-1..65534]
122 cmp.l %a6, %d0 | Now do clip to [0..65534] range
123 jls 2f
124 jpl 1f
125 clr.l %d0 | Clip low
126 .word 0x51fa | trapf.w, shadow next insn
1271:
128 move.l %a6, %d0 | Clip high
1292:
130 sub.l %d1, %d0 | Bias clipped result back to [-32767..32767]
131 move.w %d0, (%a5)+ | Write result to y[i]
132 neg.l %d0 | msac.w is bugged in gas, do this for now
133 move.l (%a4)+, %a6 | Fetch den[0] and den[1]
134 mac.w %a6u, %d0l, %acc0
135 mac.w %a6l, %d0l, (%a4)+, %a6, %acc1
136 mac.w %a6u, %d0l, %acc2
137 mac.w %a6l, %d0l, (%a4)+, %a6, %acc3
138 movclr.l %acc0, %d1
139 add.l %d2, %d1 | mem[0] = mem[1] - den[0]*y[i]
140 movclr.l %acc1, %d2
141 add.l %d3, %d2 | mem[1] = mem[2] - den[1]*y[i]
142 movclr.l %acc2, %d3
143 add.l %d4, %d3 | mem[2] = mem[3] - den[2]*y[i]
144 movclr.l %acc3, %d4
145 add.l %d5, %d4 | mem[3] = mem[4] - den[3]*y[i]
146 mac.w %a6u, %d0l, %acc0
147 mac.w %a6l, %d0l, (%a4)+, %a6, %acc1
148 mac.w %a6u, %d0l, %acc2
149 mac.w %a6l, %d0l, (%a4)+, %a6, %acc3
150 lea.l (-20, %a4), %a4 | wrap den pointer back to den[0]
151 movclr.l %acc0, %d5
152 add.l %d6, %d5 | mem[4] = mem[5] - den[4]*y[i]
153 movclr.l %acc1, %d6
154 add.l %d7, %d6 | mem[5] = mem[6] - den[5]*y[i]
155 movclr.l %acc2, %d7
156 add.l %a0, %d7 | mem[6] = mem[7] - den[6]*y[i]
157 movclr.l %acc3, %a0
158 add.l %a1, %a0 | mem[7] = mem[8] - den[7]*y[i]
159 mac.w %a6u, %d0l, %acc0
160 mac.w %a6l, %d0l, %acc1
161 movclr.l %acc0, %a1
162 add.l %a2, %a1 | mem[8] = mem[9] - den[8]*y[i]
163 movclr.l %acc1, %a2 | mem[9] = -den[9]*y[i]
164
165 subq.l #1, (44+16, %sp) | Have we done all samples?
166 jne 0b
167 move.l (44+24, %sp), %a6 | Fetch mem pointer
168 movem.l %d1-%d7/%a0-%a2, (%a6) | Save back mem[]
169
170.exit:
171 movem.l (%sp), %d2-%d7/%a2-%a6
172 lea.l (44, %sp), %sp
173 rts
174
175
176/* 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) */
177 .global qmf_synth
178qmf_synth:
179 lea.l (-44, %sp), %sp
180 movem.l %d2-%d7/%a2-%a6, (%sp)
181 movem.l (44+4, %sp), %a0-%a3 | a0 = x1, a1 = x2, a2 = a, a3 = y
182 movem.l (44+20, %sp), %d0-%d1/%a4-%a5 | d0 = N, d1 = M, a4 = mem1,a5 = mem2
183 move.l #0x80, %macsr | Enable saturation
184
185 | Comments make more sense when compared to the reference C version
186 move.l %a2, %d6 | Backup a
187 lsr.l #1, %d0 | N2 = N >> 1
188 lsr.l #1, %d1 | M2 = M >> 1
189 move.l %d1, %d7 | Backup M2
190 clr.l %d2
191 sub.l %d0, %d2
192 sub.l %d1, %d2 | d2 = -(N2 + M2)
193 lea.l (%sp, %d2.l*2), %a2 | Alloc two buffers of N2 + M2 shorts
194 lea.l (%a2, %d2.l*2), %a6 | a2 = xx1, a6 = xx2
195 move.l %sp, %d3
196 move.l %a6, %sp | Update sp
197 move.l %d3, -(%sp) | Stack old %sp
198
199 | Backwards copy x1 and x2 arrays to xx1 and xx2, assume N2 is power of two
200 | TODO: these copying loops probably have more potential for optimization
201 lea.l (%a0, %d0.l*2), %a0 | x1 += N2
202 lea.l (%a1, %d0.l*2), %a1 | x2 += N2
203 move.l %d0, %d2 | Loop counter is N2
2040:
205 move.l -(%a0), %d3
206 swap.w %d3
207 move.l %d3, (%a2)+
208 move.l -(%a1), %d3
209 swap.w %d3
210 move.l %d3, (%a6)+
211 subq.l #2, %d2
212 jne 0b
213
214 | Copy alternate members of mem1 and mem2 to last part of xx1 and xx2
215 move.l %d1, %d2 | Loop counter is M2
216 addq.l #2, %a4 | a4 = &mem1[1]
217 addq.l #2, %a5 | a5 = &mem2[1]
218 move.l %a4, %d3 | Backup mem1 and mem2
219 move.l %a5, %d4
2200:
221 move.w (%a4), (%a2)+
222 move.w (%a5), (%a6)+
223 addq.l #4, %a4
224 addq.l #4, %a5
225 subq.l #1, %d2
226 jne 0b
227 move.l %d3, %a4 | a4 = &mem1[1]
228 move.l %d4, %a5 | a5 = &mem2[1]
229
230 clr.l %d2
231 sub.l %d1, %d2 | d2 = -M2
232 lea.l (-4, %a2, %d2.l*2), %a0 | a0 = &xx1[N2 - 2]
233 lea.l (-4, %a6, %d2.l*2), %a1 | a1 = &xx2[N2 - 2]
234 move.l %d6, %a2 | a2 = a
235
236 | Main loop, register usage:
237 | d0 = N2 counter, d1 = M2 counter, d7 = M2 backup
238 | d2 = x10, d3 = x11, d4 = x20, d5 = x21, d6 = [a0, a1]
239 | a0 = xx1, a1 = xx2, a2 = a, a3 = y, a4 = mem1, a5 = mem2
2400: | Outerloop
241 move.l #32768, %d2 | Rounding constant
242 move.l %d2, %acc0
243 move.l %d2, %acc1
244 move.l %d2, %acc2
245 move.l %d2, %acc3
246 move.w (%a0)+, %d2 | d2 = x10
247 move.w (%a1)+, %d4 | d4 = x20
248 move.l (%a2)+, %d6 | d6 = [a0, a1]
2491: | Innerloop
250 move.w (%a0)+, %d3 | d3 = x11
251 move.w (%a1)+, %d5 | d5 = x21
252 mac.w %d6u, %d3l, <<, %acc0 | acc0 += a0*x11
253 msac.w %d6u, %d5l, <<, %acc0 | acc0 -= a0*x21
254 mac.w %d6l, %d3l, <<, %acc1 | acc1 += a1*x11
255 mac.w %d6l, %d5l, <<, %acc1 | acc1 += a1*x21
256 mac.w %d6u, %d2l, <<, %acc2 | acc2 += a0*x10
257 msac.w %d6u, %d4l, <<, %acc2 | acc2 -= a0*x20
258 mac.w %d6l, %d2l, <<, %acc3 | acc3 += a1*x10
259 mac.w %d6l, %d4l, <<, (%a2)+, %d6, %acc3 | acc3 += a1*x20
260
261 move.w (%a0)+, %d2 | d2 = x10
262 move.w (%a1)+, %d4 | d4 = x20
263 mac.w %d6u, %d2l, <<, %acc0 | acc0 += a0*x10
264 msac.w %d6u, %d4l, <<, %acc0 | acc0 -= a0*x20
265 mac.w %d6l, %d2l, <<, %acc1 | acc1 += a1*x10
266 mac.w %d6l, %d4l, <<, %acc1 | acc1 += a1*x20
267 mac.w %d6u, %d3l, <<, %acc2 | acc2 += a0*x11
268 msac.w %d6u, %d5l, <<, %acc2 | acc2 -= a0*x21
269 mac.w %d6l, %d3l, <<, %acc3 | acc3 += a1*x11
270 mac.w %d6l, %d5l, <<, (%a2)+, %d6, %acc3 | acc3 += a1*x21
271 subq.l #2, %d1
272 jne 1b
273
274 sub.l %d7, %d1 | d1 = -M2
275 lea.l (-4, %a2, %d1.l*4), %a2 | a2 = &a[0]
276 lea.l (-6, %a0, %d1.l*2), %a0 | a0 = &xx1[N2 - 2 - i]
277 lea.l (-6, %a1, %d1.l*2), %a1 | a1 = &xx2[N2 - 2 - i]
278 neg.l %d1 | d1 = M2
279 movclr.l %acc0, %d2
280 movclr.l %acc1, %d3
281 movclr.l %acc2, %d4
282 movclr.l %acc3, %d5
283 swap.w %d2 | Shift 16 right
284 swap.w %d3
285 swap.w %d4
286 swap.w %d5
287 | Thanks to the extra shift in the mac chain, we get clipping for free.
288 | The clipping will be [-32768..32767], not Speex standard [-32767..32767],
289 | but since qmf_synth() is called so late in the signal chain, it should
290 | work fine.
291 move.w %d2, (%a3)+ | Write results to y[]
292 move.w %d3, (%a3)+
293 move.w %d4, (%a3)+
294 move.w %d5, (%a3)+
295 subq.l #2, %d0
296 jne 0b
297
298 | Copy start of xx1 and xx2 back to alternate mem1 and mem2 entries
299 addq.l #4, %a0 | a0 = &xx1[0]
300 addq.l #4, %a1 | a1 = &xx2[0]
3010:
302 move.w (%a0)+, (%a4)
303 move.w (%a1)+, (%a5)
304 addq.l #4, %a4
305 addq.l #4, %a5
306 subq.l #1, %d1
307 jne 0b
308
309 move.l #0, %macsr
310 move.l (%sp), %sp
311 movem.l (%sp), %d2-%d7/%a2-%a6
312 lea.l (44, %sp), %sp
313 rts
314
315
316/* void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len) */
317 .global signal_mul
318signal_mul:
319 lea.l (-20, %sp), %sp
320 movem.l %d2-%d6, (%sp)
321 movem.l (20+4, %sp), %a0-%a1 | a0 = x, a1 = y
322 movem.l (20+12, %sp), %d0-%d1 | d0 = scale, d1 = len
323 moveq.l #0x20, %d6
324 move.l %d6, %macsr | Set MAC unit to fractional mode
325 asl.l #3, %d0 | Pre-scale 'scale'
326 moveq.l #9, %d6
3270:
328 movem.l (%a0), %d2-%d5 | Fetch input
329 asl.l %d6, %d2 | Shift each value 9 to the left
330 asl.l %d6, %d3
331 asl.l %d6, %d4
332 asl.l %d6, %d5
333 mac.l %d2, %d0, %acc0 | Do multiplies
334 mac.l %d3, %d0, %acc1
335 mac.l %d4, %d0, %acc2
336 mac.l %d5, %d0, %acc3
337 lea.l (16, %a0), %a0
338 movclr.l %acc0, %d2
339 movclr.l %acc1, %d3
340 movclr.l %acc2, %d4
341 movclr.l %acc3, %d5
342 asl.l #5, %d2 | Adjust to proper format
343 asl.l #5, %d3
344 asl.l #5, %d4
345 asl.l #5, %d5
346 movem.l %d2-%d5, (%a1) | Save output
347 lea.l (16, %a1), %a1
348 subq.l #4, %d1
349 jne 0b
350
351 clr.l %d0
352 move.l %d0, %macsr | Set MAC unit back to integer mode
353 movem.l (%sp), %d2-%d6
354 lea.l (20, %sp), %sp
355 rts
356
diff --git a/lib/rbcodec/codecs/libspeex/filters_sse.h b/lib/rbcodec/codecs/libspeex/filters_sse.h
new file mode 100644
index 0000000000..4bb333daf3
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/filters_sse.h
@@ -0,0 +1,336 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file filters_sse.h
4 @brief Various analysis/synthesis filters (SSE version)
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#include <xmmintrin.h>
36
37void filter_mem16_10(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
38{
39 __m128 num[3], den[3], mem[3];
40
41 int i;
42
43 /* Copy numerator, denominator and memory to aligned xmm */
44 for (i=0;i<2;i++)
45 {
46 mem[i] = _mm_loadu_ps(_mem+4*i);
47 num[i] = _mm_loadu_ps(_num+4*i);
48 den[i] = _mm_loadu_ps(_den+4*i);
49 }
50 mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);
51 num[2] = _mm_setr_ps(_num[8], _num[9], 0, 0);
52 den[2] = _mm_setr_ps(_den[8], _den[9], 0, 0);
53
54 for (i=0;i<N;i++)
55 {
56 __m128 xx;
57 __m128 yy;
58 /* Compute next filter result */
59 xx = _mm_load_ps1(x+i);
60 yy = _mm_add_ss(xx, mem[0]);
61 _mm_store_ss(y+i, yy);
62 yy = _mm_shuffle_ps(yy, yy, 0);
63
64 /* Update memory */
65 mem[0] = _mm_move_ss(mem[0], mem[1]);
66 mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
67
68 mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
69 mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
70
71 mem[1] = _mm_move_ss(mem[1], mem[2]);
72 mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
73
74 mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
75 mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
76
77 mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);
78
79 mem[2] = _mm_add_ps(mem[2], _mm_mul_ps(xx, num[2]));
80 mem[2] = _mm_sub_ps(mem[2], _mm_mul_ps(yy, den[2]));
81 }
82 /* Put memory back in its place */
83 _mm_storeu_ps(_mem, mem[0]);
84 _mm_storeu_ps(_mem+4, mem[1]);
85 _mm_store_ss(_mem+8, mem[2]);
86 mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);
87 _mm_store_ss(_mem+9, mem[2]);
88}
89
90void filter_mem16_8(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
91{
92 __m128 num[2], den[2], mem[2];
93
94 int i;
95
96 /* Copy numerator, denominator and memory to aligned xmm */
97 for (i=0;i<2;i++)
98 {
99 mem[i] = _mm_loadu_ps(_mem+4*i);
100 num[i] = _mm_loadu_ps(_num+4*i);
101 den[i] = _mm_loadu_ps(_den+4*i);
102 }
103
104 for (i=0;i<N;i++)
105 {
106 __m128 xx;
107 __m128 yy;
108 /* Compute next filter result */
109 xx = _mm_load_ps1(x+i);
110 yy = _mm_add_ss(xx, mem[0]);
111 _mm_store_ss(y+i, yy);
112 yy = _mm_shuffle_ps(yy, yy, 0);
113
114 /* Update memory */
115 mem[0] = _mm_move_ss(mem[0], mem[1]);
116 mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
117
118 mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
119 mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
120
121 mem[1] = _mm_sub_ss(mem[1], mem[1]);
122 mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
123
124 mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
125 mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
126 }
127 /* Put memory back in its place */
128 _mm_storeu_ps(_mem, mem[0]);
129 _mm_storeu_ps(_mem+4, mem[1]);
130}
131
132
133#define OVERRIDE_FILTER_MEM16
134void filter_mem16(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem, char *stack)
135{
136 if(ord==10)
137 filter_mem16_10(x, _num, _den, y, N, ord, _mem);
138 else if (ord==8)
139 filter_mem16_8(x, _num, _den, y, N, ord, _mem);
140}
141
142
143
144void iir_mem16_10(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
145{
146 __m128 den[3], mem[3];
147
148 int i;
149
150 /* Copy numerator, denominator and memory to aligned xmm */
151 for (i=0;i<2;i++)
152 {
153 mem[i] = _mm_loadu_ps(_mem+4*i);
154 den[i] = _mm_loadu_ps(_den+4*i);
155 }
156 mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);
157 den[2] = _mm_setr_ps(_den[8], _den[9], 0, 0);
158
159 for (i=0;i<N;i++)
160 {
161 __m128 xx;
162 __m128 yy;
163 /* Compute next filter result */
164 xx = _mm_load_ps1(x+i);
165 yy = _mm_add_ss(xx, mem[0]);
166 _mm_store_ss(y+i, yy);
167 yy = _mm_shuffle_ps(yy, yy, 0);
168
169 /* Update memory */
170 mem[0] = _mm_move_ss(mem[0], mem[1]);
171 mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
172
173 mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
174
175 mem[1] = _mm_move_ss(mem[1], mem[2]);
176 mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
177
178 mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
179
180 mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);
181
182 mem[2] = _mm_sub_ps(mem[2], _mm_mul_ps(yy, den[2]));
183 }
184 /* Put memory back in its place */
185 _mm_storeu_ps(_mem, mem[0]);
186 _mm_storeu_ps(_mem+4, mem[1]);
187 _mm_store_ss(_mem+8, mem[2]);
188 mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);
189 _mm_store_ss(_mem+9, mem[2]);
190}
191
192
193void iir_mem16_8(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
194{
195 __m128 den[2], mem[2];
196
197 int i;
198
199 /* Copy numerator, denominator and memory to aligned xmm */
200 for (i=0;i<2;i++)
201 {
202 mem[i] = _mm_loadu_ps(_mem+4*i);
203 den[i] = _mm_loadu_ps(_den+4*i);
204 }
205
206 for (i=0;i<N;i++)
207 {
208 __m128 xx;
209 __m128 yy;
210 /* Compute next filter result */
211 xx = _mm_load_ps1(x+i);
212 yy = _mm_add_ss(xx, mem[0]);
213 _mm_store_ss(y+i, yy);
214 yy = _mm_shuffle_ps(yy, yy, 0);
215
216 /* Update memory */
217 mem[0] = _mm_move_ss(mem[0], mem[1]);
218 mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
219
220 mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
221
222 mem[1] = _mm_sub_ss(mem[1], mem[1]);
223 mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
224
225 mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
226 }
227 /* Put memory back in its place */
228 _mm_storeu_ps(_mem, mem[0]);
229 _mm_storeu_ps(_mem+4, mem[1]);
230}
231
232#define OVERRIDE_IIR_MEM16
233void iir_mem16(const float *x, const float *_den, float *y, int N, int ord, float *_mem, char *stack)
234{
235 if(ord==10)
236 iir_mem16_10(x, _den, y, N, ord, _mem);
237 else if (ord==8)
238 iir_mem16_8(x, _den, y, N, ord, _mem);
239}
240
241
242void fir_mem16_10(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
243{
244 __m128 num[3], mem[3];
245
246 int i;
247
248 /* Copy numerator, denominator and memory to aligned xmm */
249 for (i=0;i<2;i++)
250 {
251 mem[i] = _mm_loadu_ps(_mem+4*i);
252 num[i] = _mm_loadu_ps(_num+4*i);
253 }
254 mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);
255 num[2] = _mm_setr_ps(_num[8], _num[9], 0, 0);
256
257 for (i=0;i<N;i++)
258 {
259 __m128 xx;
260 __m128 yy;
261 /* Compute next filter result */
262 xx = _mm_load_ps1(x+i);
263 yy = _mm_add_ss(xx, mem[0]);
264 _mm_store_ss(y+i, yy);
265 yy = _mm_shuffle_ps(yy, yy, 0);
266
267 /* Update memory */
268 mem[0] = _mm_move_ss(mem[0], mem[1]);
269 mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
270
271 mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
272
273 mem[1] = _mm_move_ss(mem[1], mem[2]);
274 mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
275
276 mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
277
278 mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);
279
280 mem[2] = _mm_add_ps(mem[2], _mm_mul_ps(xx, num[2]));
281 }
282 /* Put memory back in its place */
283 _mm_storeu_ps(_mem, mem[0]);
284 _mm_storeu_ps(_mem+4, mem[1]);
285 _mm_store_ss(_mem+8, mem[2]);
286 mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);
287 _mm_store_ss(_mem+9, mem[2]);
288}
289
290void fir_mem16_8(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
291{
292 __m128 num[2], mem[2];
293
294 int i;
295
296 /* Copy numerator, denominator and memory to aligned xmm */
297 for (i=0;i<2;i++)
298 {
299 mem[i] = _mm_loadu_ps(_mem+4*i);
300 num[i] = _mm_loadu_ps(_num+4*i);
301 }
302
303 for (i=0;i<N;i++)
304 {
305 __m128 xx;
306 __m128 yy;
307 /* Compute next filter result */
308 xx = _mm_load_ps1(x+i);
309 yy = _mm_add_ss(xx, mem[0]);
310 _mm_store_ss(y+i, yy);
311 yy = _mm_shuffle_ps(yy, yy, 0);
312
313 /* Update memory */
314 mem[0] = _mm_move_ss(mem[0], mem[1]);
315 mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
316
317 mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
318
319 mem[1] = _mm_sub_ss(mem[1], mem[1]);
320 mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
321
322 mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
323 }
324 /* Put memory back in its place */
325 _mm_storeu_ps(_mem, mem[0]);
326 _mm_storeu_ps(_mem+4, mem[1]);
327}
328
329#define OVERRIDE_FIR_MEM16
330void fir_mem16(const float *x, const float *_num, float *y, int N, int ord, float *_mem, char *stack)
331{
332 if(ord==10)
333 fir_mem16_10(x, _num, y, N, ord, _mem);
334 else if (ord==8)
335 fir_mem16_8(x, _num, y, N, ord, _mem);
336}
diff --git a/lib/rbcodec/codecs/libspeex/fixed_arm4.h b/lib/rbcodec/codecs/libspeex/fixed_arm4.h
new file mode 100644
index 0000000000..b6981cae72
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/fixed_arm4.h
@@ -0,0 +1,148 @@
1/* Copyright (C) 2004 Jean-Marc Valin */
2/**
3 @file fixed_arm4.h
4 @brief ARM4 fixed-point operations
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef FIXED_ARM4_H
36#define FIXED_ARM4_H
37
38#undef MULT16_32_Q14
39static inline spx_word32_t MULT16_32_Q14(spx_word16_t x, spx_word32_t y) {
40 int res;
41 int dummy;
42 asm (
43 "smull %0,%1,%2,%3 \n\t"
44 "mov %0, %0, lsr #14 \n\t"
45 "add %0, %0, %1, lsl #18 \n\t"
46 : "=&r"(res), "=&r" (dummy)
47 : "r"(y),"r"((int)x));
48 return(res);
49}
50
51#undef MULT16_32_Q15
52static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
53 int res;
54 int dummy;
55 asm (
56 "smull %0,%1,%2,%3 \n\t"
57 "mov %0, %0, lsr #15 \n\t"
58 "add %0, %0, %1, lsl #17 \n\t"
59 : "=&r"(res), "=&r" (dummy)
60 : "r"(y),"r"((int)x));
61 return(res);
62}
63
64#undef DIV32_16
65static inline short DIV32_16(int a, int b)
66{
67 int res=0;
68 int dead1, dead2, dead3, dead4, dead5;
69 __asm__ __volatile__ (
70 "\teor %5, %0, %1\n"
71 "\tmovs %4, %0\n"
72 "\trsbmi %0, %0, #0 \n"
73 "\tmovs %4, %1\n"
74 "\trsbmi %1, %1, #0 \n"
75 "\tmov %4, #1\n"
76
77 "\tsubs %3, %0, %1, asl #14 \n"
78 "\tmovpl %0, %3 \n"
79 "\torrpl %2, %2, %4, asl #14 \n"
80
81 "\tsubs %3, %0, %1, asl #13 \n"
82 "\tmovpl %0, %3 \n"
83 "\torrpl %2, %2, %4, asl #13 \n"
84
85 "\tsubs %3, %0, %1, asl #12 \n"
86 "\tmovpl %0, %3 \n"
87 "\torrpl %2, %2, %4, asl #12 \n"
88
89 "\tsubs %3, %0, %1, asl #11 \n"
90 "\tmovpl %0, %3 \n"
91 "\torrpl %2, %2, %4, asl #11 \n"
92
93 "\tsubs %3, %0, %1, asl #10 \n"
94 "\tmovpl %0, %3 \n"
95 "\torrpl %2, %2, %4, asl #10 \n"
96
97 "\tsubs %3, %0, %1, asl #9 \n"
98 "\tmovpl %0, %3 \n"
99 "\torrpl %2, %2, %4, asl #9 \n"
100
101 "\tsubs %3, %0, %1, asl #8 \n"
102 "\tmovpl %0, %3 \n"
103 "\torrpl %2, %2, %4, asl #8 \n"
104
105 "\tsubs %3, %0, %1, asl #7 \n"
106 "\tmovpl %0, %3 \n"
107 "\torrpl %2, %2, %4, asl #7 \n"
108
109 "\tsubs %3, %0, %1, asl #6 \n"
110 "\tmovpl %0, %3 \n"
111 "\torrpl %2, %2, %4, asl #6 \n"
112
113 "\tsubs %3, %0, %1, asl #5 \n"
114 "\tmovpl %0, %3 \n"
115 "\torrpl %2, %2, %4, asl #5 \n"
116
117 "\tsubs %3, %0, %1, asl #4 \n"
118 "\tmovpl %0, %3 \n"
119 "\torrpl %2, %2, %4, asl #4 \n"
120
121 "\tsubs %3, %0, %1, asl #3 \n"
122 "\tmovpl %0, %3 \n"
123 "\torrpl %2, %2, %4, asl #3 \n"
124
125 "\tsubs %3, %0, %1, asl #2 \n"
126 "\tmovpl %0, %3 \n"
127 "\torrpl %2, %2, %4, asl #2 \n"
128
129 "\tsubs %3, %0, %1, asl #1 \n"
130 "\tmovpl %0, %3 \n"
131 "\torrpl %2, %2, %4, asl #1 \n"
132
133 "\tsubs %3, %0, %1 \n"
134 "\tmovpl %0, %3 \n"
135 "\torrpl %2, %2, %4 \n"
136
137 "\tmovs %5, %5, lsr #31 \n"
138 "\trsbne %2, %2, #0 \n"
139 : "=r" (dead1), "=r" (dead2), "=r" (res),
140 "=r" (dead3), "=r" (dead4), "=r" (dead5)
141 : "0" (a), "1" (b), "2" (res)
142 : "cc"
143 );
144 return res;
145}
146
147
148#endif
diff --git a/lib/rbcodec/codecs/libspeex/fixed_arm5e.h b/lib/rbcodec/codecs/libspeex/fixed_arm5e.h
new file mode 100644
index 0000000000..9b4861c9a7
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/fixed_arm5e.h
@@ -0,0 +1,178 @@
1/* Copyright (C) 2003 Jean-Marc Valin */
2/**
3 @file fixed_arm5e.h
4 @brief ARM-tuned fixed-point operations
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef FIXED_ARM5E_H
36#define FIXED_ARM5E_H
37
38#undef MULT16_16
39static inline spx_word32_t MULT16_16(spx_word16_t x, spx_word16_t y) {
40 int res;
41 asm ("smulbb %0,%1,%2;\n"
42 : "=&r"(res)
43 : "%r"(x),"r"(y));
44 return(res);
45}
46
47#undef MAC16_16
48static inline spx_word32_t MAC16_16(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
49 int res;
50 asm ("smlabb %0,%1,%2,%3;\n"
51 : "=&r"(res)
52 : "%r"(x),"r"(y),"r"(a));
53 return(res);
54}
55
56#undef MULT16_32_Q15
57static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
58 int res;
59 asm ("smulwb %0,%1,%2;\n"
60 : "=&r"(res)
61 : "%r"(y<<1),"r"(x));
62 return(res);
63}
64
65#undef MAC16_32_Q15
66static inline spx_word32_t MAC16_32_Q15(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
67 int res;
68 asm ("smlawb %0,%1,%2,%3;\n"
69 : "=&r"(res)
70 : "%r"(y<<1),"r"(x),"r"(a));
71 return(res);
72}
73
74#undef MULT16_32_Q11
75static inline spx_word32_t MULT16_32_Q11(spx_word16_t x, spx_word32_t y) {
76 int res;
77 asm ("smulwb %0,%1,%2;\n"
78 : "=&r"(res)
79 : "%r"(y<<5),"r"(x));
80 return(res);
81}
82
83#undef MAC16_32_Q11
84static inline spx_word32_t MAC16_32_Q11(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
85 int res;
86 asm ("smlawb %0,%1,%2,%3;\n"
87 : "=&r"(res)
88 : "%r"(y<<5),"r"(x),"r"(a));
89 return(res);
90}
91
92#undef DIV32_16
93static inline short DIV32_16(int a, int b)
94{
95 int res=0;
96 int dead1, dead2, dead3, dead4, dead5;
97 __asm__ __volatile__ (
98 "\teor %5, %0, %1\n"
99 "\tmovs %4, %0\n"
100 "\trsbmi %0, %0, #0 \n"
101 "\tmovs %4, %1\n"
102 "\trsbmi %1, %1, #0 \n"
103 "\tmov %4, #1\n"
104
105 "\tsubs %3, %0, %1, asl #14 \n"
106 "\torrpl %2, %2, %4, asl #14 \n"
107 "\tmovpl %0, %3 \n"
108
109 "\tsubs %3, %0, %1, asl #13 \n"
110 "\torrpl %2, %2, %4, asl #13 \n"
111 "\tmovpl %0, %3 \n"
112
113 "\tsubs %3, %0, %1, asl #12 \n"
114 "\torrpl %2, %2, %4, asl #12 \n"
115 "\tmovpl %0, %3 \n"
116
117 "\tsubs %3, %0, %1, asl #11 \n"
118 "\torrpl %2, %2, %4, asl #11 \n"
119 "\tmovpl %0, %3 \n"
120
121 "\tsubs %3, %0, %1, asl #10 \n"
122 "\torrpl %2, %2, %4, asl #10 \n"
123 "\tmovpl %0, %3 \n"
124
125 "\tsubs %3, %0, %1, asl #9 \n"
126 "\torrpl %2, %2, %4, asl #9 \n"
127 "\tmovpl %0, %3 \n"
128
129 "\tsubs %3, %0, %1, asl #8 \n"
130 "\torrpl %2, %2, %4, asl #8 \n"
131 "\tmovpl %0, %3 \n"
132
133 "\tsubs %3, %0, %1, asl #7 \n"
134 "\torrpl %2, %2, %4, asl #7 \n"
135 "\tmovpl %0, %3 \n"
136
137 "\tsubs %3, %0, %1, asl #6 \n"
138 "\torrpl %2, %2, %4, asl #6 \n"
139 "\tmovpl %0, %3 \n"
140
141 "\tsubs %3, %0, %1, asl #5 \n"
142 "\torrpl %2, %2, %4, asl #5 \n"
143 "\tmovpl %0, %3 \n"
144
145 "\tsubs %3, %0, %1, asl #4 \n"
146 "\torrpl %2, %2, %4, asl #4 \n"
147 "\tmovpl %0, %3 \n"
148
149 "\tsubs %3, %0, %1, asl #3 \n"
150 "\torrpl %2, %2, %4, asl #3 \n"
151 "\tmovpl %0, %3 \n"
152
153 "\tsubs %3, %0, %1, asl #2 \n"
154 "\torrpl %2, %2, %4, asl #2 \n"
155 "\tmovpl %0, %3 \n"
156
157 "\tsubs %3, %0, %1, asl #1 \n"
158 "\torrpl %2, %2, %4, asl #1 \n"
159 "\tmovpl %0, %3 \n"
160
161 "\tsubs %3, %0, %1 \n"
162 "\torrpl %2, %2, %4 \n"
163 "\tmovpl %0, %3 \n"
164
165 "\tmovs %5, %5, lsr #31 \n"
166 "\trsbne %2, %2, #0 \n"
167 : "=r" (dead1), "=r" (dead2), "=r" (res),
168 "=r" (dead3), "=r" (dead4), "=r" (dead5)
169 : "0" (a), "1" (b), "2" (res)
170 : "memory", "cc"
171 );
172 return res;
173}
174
175
176
177
178#endif
diff --git a/lib/rbcodec/codecs/libspeex/fixed_bfin.h b/lib/rbcodec/codecs/libspeex/fixed_bfin.h
new file mode 100644
index 0000000000..aa26f6a87d
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/fixed_bfin.h
@@ -0,0 +1,173 @@
1/* Copyright (C) 2005 Analog Devices
2 Author: Jean-Marc Valin */
3/**
4 @file fixed_bfin.h
5 @brief Blackfin fixed-point operations
6*/
7/*
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 - Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 - Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19 - Neither the name of the Xiph.org Foundation nor the names of its
20 contributors may be used to endorse or promote products derived from
21 this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#ifndef FIXED_BFIN_H
37#define FIXED_BFIN_H
38
39#undef PDIV32_16
40static inline spx_word16_t PDIV32_16(spx_word32_t a, spx_word16_t b)
41{
42 spx_word32_t res, bb;
43 bb = b;
44 a += b>>1;
45 __asm__ (
46 "P0 = 15;\n\t"
47 "R0 = %1;\n\t"
48 "R1 = %2;\n\t"
49 //"R0 = R0 + R1;\n\t"
50 "R0 <<= 1;\n\t"
51 "DIVS (R0, R1);\n\t"
52 "LOOP divide%= LC0 = P0;\n\t"
53 "LOOP_BEGIN divide%=;\n\t"
54 "DIVQ (R0, R1);\n\t"
55 "LOOP_END divide%=;\n\t"
56 "R0 = R0.L;\n\t"
57 "%0 = R0;\n\t"
58 : "=m" (res)
59 : "m" (a), "m" (bb)
60 : "P0", "R0", "R1", "cc");
61 return res;
62}
63
64#undef DIV32_16
65static inline spx_word16_t DIV32_16(spx_word32_t a, spx_word16_t b)
66{
67 spx_word32_t res, bb;
68 bb = b;
69 /* Make the roundinf consistent with the C version
70 (do we need to do that?)*/
71 if (a<0)
72 a += (b-1);
73 __asm__ (
74 "P0 = 15;\n\t"
75 "R0 = %1;\n\t"
76 "R1 = %2;\n\t"
77 "R0 <<= 1;\n\t"
78 "DIVS (R0, R1);\n\t"
79 "LOOP divide%= LC0 = P0;\n\t"
80 "LOOP_BEGIN divide%=;\n\t"
81 "DIVQ (R0, R1);\n\t"
82 "LOOP_END divide%=;\n\t"
83 "R0 = R0.L;\n\t"
84 "%0 = R0;\n\t"
85 : "=m" (res)
86 : "m" (a), "m" (bb)
87 : "P0", "R0", "R1", "cc");
88 return res;
89}
90
91#undef MAX16
92static inline spx_word16_t MAX16(spx_word16_t a, spx_word16_t b)
93{
94 spx_word32_t res;
95 __asm__ (
96 "%1 = %1.L (X);\n\t"
97 "%2 = %2.L (X);\n\t"
98 "%0 = MAX(%1,%2);"
99 : "=d" (res)
100 : "%d" (a), "d" (b)
101 );
102 return res;
103}
104
105#undef MULT16_32_Q15
106static inline spx_word32_t MULT16_32_Q15(spx_word16_t a, spx_word32_t b)
107{
108 spx_word32_t res;
109 __asm__
110 (
111 "A1 = %2.L*%1.L (M);\n\t"
112 "A1 = A1 >>> 15;\n\t"
113 "%0 = (A1 += %2.L*%1.H) ;\n\t"
114 : "=&W" (res), "=&d" (b)
115 : "d" (a), "1" (b)
116 : "A1"
117 );
118 return res;
119}
120
121#undef MAC16_32_Q15
122static inline spx_word32_t MAC16_32_Q15(spx_word32_t c, spx_word16_t a, spx_word32_t b)
123{
124 spx_word32_t res;
125 __asm__
126 (
127 "A1 = %2.L*%1.L (M);\n\t"
128 "A1 = A1 >>> 15;\n\t"
129 "%0 = (A1 += %2.L*%1.H);\n\t"
130 "%0 = %0 + %4;\n\t"
131 : "=&W" (res), "=&d" (b)
132 : "d" (a), "1" (b), "d" (c)
133 : "A1"
134 );
135 return res;
136}
137
138#undef MULT16_32_Q14
139static inline spx_word32_t MULT16_32_Q14(spx_word16_t a, spx_word32_t b)
140{
141 spx_word32_t res;
142 __asm__
143 (
144 "%2 <<= 1;\n\t"
145 "A1 = %1.L*%2.L (M);\n\t"
146 "A1 = A1 >>> 15;\n\t"
147 "%0 = (A1 += %1.L*%2.H);\n\t"
148 : "=W" (res), "=d" (a), "=d" (b)
149 : "1" (a), "2" (b)
150 : "A1"
151 );
152 return res;
153}
154
155#undef MAC16_32_Q14
156static inline spx_word32_t MAC16_32_Q14(spx_word32_t c, spx_word16_t a, spx_word32_t b)
157{
158 spx_word32_t res;
159 __asm__
160 (
161 "%1 <<= 1;\n\t"
162 "A1 = %2.L*%1.L (M);\n\t"
163 "A1 = A1 >>> 15;\n\t"
164 "%0 = (A1 += %2.L*%1.H);\n\t"
165 "%0 = %0 + %4;\n\t"
166 : "=&W" (res), "=&d" (b)
167 : "d" (a), "1" (b), "d" (c)
168 : "A1"
169 );
170 return res;
171}
172
173#endif
diff --git a/lib/rbcodec/codecs/libspeex/fixed_debug.h b/lib/rbcodec/codecs/libspeex/fixed_debug.h
new file mode 100644
index 0000000000..d5c449f4d9
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/fixed_debug.h
@@ -0,0 +1,487 @@
1/* Copyright (C) 2003 Jean-Marc Valin */
2/**
3 @file fixed_debug.h
4 @brief Fixed-point operations with debugging
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef FIXED_DEBUG_H
36#define FIXED_DEBUG_H
37
38#include <stdio.h>
39
40extern long long spx_mips;
41#define MIPS_INC spx_mips++,
42
43#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
44#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
45
46
47#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
48#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
49
50static inline short NEG16(int x)
51{
52 int res;
53 if (!VERIFY_SHORT(x))
54 {
55 fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
56 }
57 res = -x;
58 if (!VERIFY_SHORT(res))
59 fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
60 spx_mips++;
61 return res;
62}
63static inline int NEG32(long long x)
64{
65 long long res;
66 if (!VERIFY_INT(x))
67 {
68 fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
69 }
70 res = -x;
71 if (!VERIFY_INT(res))
72 fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
73 spx_mips++;
74 return res;
75}
76
77#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__)
78static inline short _EXTRACT16(int x, char *file, int line)
79{
80 int res;
81 if (!VERIFY_SHORT(x))
82 {
83 fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
84 }
85 res = x;
86 spx_mips++;
87 return res;
88}
89
90#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__)
91static inline int _EXTEND32(int x, char *file, int line)
92{
93 int res;
94 if (!VERIFY_SHORT(x))
95 {
96 fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
97 }
98 res = x;
99 spx_mips++;
100 return res;
101}
102
103#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__)
104static inline short _SHR16(int a, int shift, char *file, int line)
105{
106 int res;
107 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
108 {
109 fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
110 }
111 res = a>>shift;
112 if (!VERIFY_SHORT(res))
113 fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
114 spx_mips++;
115 return res;
116}
117#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__)
118static inline short _SHL16(int a, int shift, char *file, int line)
119{
120 int res;
121 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
122 {
123 fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
124 }
125 res = a<<shift;
126 if (!VERIFY_SHORT(res))
127 fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
128 spx_mips++;
129 return res;
130}
131
132static inline int SHR32(long long a, int shift)
133{
134 long long res;
135 if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
136 {
137 fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
138 }
139 res = a>>shift;
140 if (!VERIFY_INT(res))
141 {
142 fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
143 }
144 spx_mips++;
145 return res;
146}
147static inline int SHL32(long long a, int shift)
148{
149 long long res;
150 if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
151 {
152 fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift);
153 }
154 res = a<<shift;
155 if (!VERIFY_INT(res))
156 {
157 fprintf (stderr, "SHL32: output is not int: %d\n", (int)res);
158 }
159 spx_mips++;
160 return res;
161}
162
163#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift))
164#define PSHR32(a,shift) (SHR32(ADD32((a),((1<<((shift))>>1))),shift))
165#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
166
167#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
168#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
169
170//#define SHR(a,shift) ((a) >> (shift))
171//#define SHL(a,shift) ((a) << (shift))
172
173#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__)
174static inline short _ADD16(int a, int b, char *file, int line)
175{
176 int res;
177 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
178 {
179 fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
180 }
181 res = a+b;
182 if (!VERIFY_SHORT(res))
183 {
184 fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
185 }
186 spx_mips++;
187 return res;
188}
189
190#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__)
191static inline short _SUB16(int a, int b, char *file, int line)
192{
193 int res;
194 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
195 {
196 fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
197 }
198 res = a-b;
199 if (!VERIFY_SHORT(res))
200 fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
201 spx_mips++;
202 return res;
203}
204
205#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__)
206static inline int _ADD32(long long a, long long b, char *file, int line)
207{
208 long long res;
209 if (!VERIFY_INT(a) || !VERIFY_INT(b))
210 {
211 fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
212 }
213 res = a+b;
214 if (!VERIFY_INT(res))
215 {
216 fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
217 }
218 spx_mips++;
219 return res;
220}
221
222static inline int SUB32(long long a, long long b)
223{
224 long long res;
225 if (!VERIFY_INT(a) || !VERIFY_INT(b))
226 {
227 fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b);
228 }
229 res = a-b;
230 if (!VERIFY_INT(res))
231 fprintf (stderr, "SUB32: output is not int: %d\n", (int)res);
232 spx_mips++;
233 return res;
234}
235
236#define ADD64(a,b) (MIPS_INC(a)+(b))
237
238/* result fits in 16 bits */
239static inline short MULT16_16_16(int a, int b)
240{
241 int res;
242 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
243 {
244 fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
245 }
246 res = a*b;
247 if (!VERIFY_SHORT(res))
248 fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
249 spx_mips++;
250 return res;
251}
252
253#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__)
254static inline int _MULT16_16(int a, int b, char *file, int line)
255{
256 long long res;
257 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
258 {
259 fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
260 }
261 res = ((long long)a)*b;
262 if (!VERIFY_INT(res))
263 fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
264 spx_mips++;
265 return res;
266}
267
268#define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b))))
269#define MAC16_16_Q11(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11)))))
270#define MAC16_16_Q13(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13)))))
271#define MAC16_16_P13(c,a,b) (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13))))
272
273
274#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__)
275static inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line)
276{
277 long long res;
278 if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
279 {
280 fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
281 }
282 if (ABS32(b)>=(1<<(15+Q)))
283 fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
284 res = (((long long)a)*(long long)b) >> Q;
285 if (!VERIFY_INT(res))
286 fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line);
287 spx_mips+=5;
288 return res;
289}
290
291static inline int MULT16_32_PX(int a, long long b, int Q)
292{
293 long long res;
294 if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
295 {
296 fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b);
297 }
298 if (ABS32(b)>=(1<<(15+Q)))
299 fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b);
300 res = ((((long long)a)*(long long)b) + ((1<<Q)>>1))>> Q;
301 if (!VERIFY_INT(res))
302 fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res);
303 spx_mips+=5;
304 return res;
305}
306
307
308#define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11)
309#define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b)))
310#define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12)
311#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13)
312#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14)
313#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
314#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15)
315#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b)))
316
317static inline int SATURATE(int a, int b)
318{
319 if (a>b)
320 a=b;
321 if (a<-b)
322 a = -b;
323 return a;
324}
325
326static inline int MULT16_16_Q11_32(int a, int b)
327{
328 long long res;
329 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
330 {
331 fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
332 }
333 res = ((long long)a)*b;
334 res >>= 11;
335 if (!VERIFY_INT(res))
336 fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
337 spx_mips+=3;
338 return res;
339}
340static inline short MULT16_16_Q13(int a, int b)
341{
342 long long res;
343 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
344 {
345 fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
346 }
347 res = ((long long)a)*b;
348 res >>= 13;
349 if (!VERIFY_SHORT(res))
350 fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
351 spx_mips+=3;
352 return res;
353}
354static inline short MULT16_16_Q14(int a, int b)
355{
356 long long res;
357 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
358 {
359 fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
360 }
361 res = ((long long)a)*b;
362 res >>= 14;
363 if (!VERIFY_SHORT(res))
364 fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
365 spx_mips+=3;
366 return res;
367}
368static inline short MULT16_16_Q15(int a, int b)
369{
370 long long res;
371 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
372 {
373 fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
374 }
375 res = ((long long)a)*b;
376 res >>= 15;
377 if (!VERIFY_SHORT(res))
378 {
379 fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
380 }
381 spx_mips+=3;
382 return res;
383}
384
385static inline short MULT16_16_P13(int a, int b)
386{
387 long long res;
388 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
389 {
390 fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
391 }
392 res = ((long long)a)*b;
393 res += 4096;
394 if (!VERIFY_INT(res))
395 fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
396 res >>= 13;
397 if (!VERIFY_SHORT(res))
398 fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
399 spx_mips+=4;
400 return res;
401}
402static inline short MULT16_16_P14(int a, int b)
403{
404 long long res;
405 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
406 {
407 fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
408 }
409 res = ((long long)a)*b;
410 res += 8192;
411 if (!VERIFY_INT(res))
412 fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
413 res >>= 14;
414 if (!VERIFY_SHORT(res))
415 fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
416 spx_mips+=4;
417 return res;
418}
419static inline short MULT16_16_P15(int a, int b)
420{
421 long long res;
422 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
423 {
424 fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
425 }
426 res = ((long long)a)*b;
427 res += 16384;
428 if (!VERIFY_INT(res))
429 fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
430 res >>= 15;
431 if (!VERIFY_SHORT(res))
432 fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
433 spx_mips+=4;
434 return res;
435}
436
437#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__)
438
439static inline int _DIV32_16(long long a, long long b, char *file, int line)
440{
441 long long res;
442 if (b==0)
443 {
444 fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
445 return 0;
446 }
447 if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
448 {
449 fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
450 }
451 res = a/b;
452 if (!VERIFY_SHORT(res))
453 {
454 fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
455 if (res>32767)
456 res = 32767;
457 if (res<-32768)
458 res = -32768;
459 }
460 spx_mips+=20;
461 return res;
462}
463
464#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__)
465static inline int _DIV32(long long a, long long b, char *file, int line)
466{
467 long long res;
468 if (b==0)
469 {
470 fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
471 return 0;
472 }
473
474 if (!VERIFY_INT(a) || !VERIFY_INT(b))
475 {
476 fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
477 }
478 res = a/b;
479 if (!VERIFY_INT(res))
480 fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
481 spx_mips+=36;
482 return res;
483}
484#define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b)
485#define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b)
486
487#endif
diff --git a/lib/rbcodec/codecs/libspeex/fixed_generic.h b/lib/rbcodec/codecs/libspeex/fixed_generic.h
new file mode 100644
index 0000000000..2948177c0b
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/fixed_generic.h
@@ -0,0 +1,106 @@
1/* Copyright (C) 2003 Jean-Marc Valin */
2/**
3 @file fixed_generic.h
4 @brief Generic fixed-point operations
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef FIXED_GENERIC_H
36#define FIXED_GENERIC_H
37
38#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
39#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
40
41#define NEG16(x) (-(x))
42#define NEG32(x) (-(x))
43#define EXTRACT16(x) ((spx_word16_t)(x))
44#define EXTEND32(x) ((spx_word32_t)(x))
45#define SHR16(a,shift) ((a) >> (shift))
46#define SHL16(a,shift) ((a) << (shift))
47#define SHR32(a,shift) ((a) >> (shift))
48#define SHL32(a,shift) ((a) << (shift))
49#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift))
50#define PSHR32(a,shift) (SHR32((a)+((1<<((shift))>>1)),shift))
51#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
52#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
53#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
54
55#define SHR(a,shift) ((a) >> (shift))
56#define SHL(a,shift) ((spx_word32_t)(a) << (shift))
57#define PSHR(a,shift) (SHR((a)+((1<<((shift))>>1)),shift))
58#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
59
60
61#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b)))
62#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b))
63#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b))
64#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b))
65
66
67/* result fits in 16 bits */
68#define MULT16_16_16(a,b) ((((spx_word16_t)(a))*((spx_word16_t)(b))))
69
70/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */
71#define MULT16_16(a,b) (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b)))
72
73#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
74#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
75#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
76#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
77
78#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
79#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
80
81#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15))
82#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
83#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
84
85
86#define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11)))
87#define MAC16_16_Q13(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),13)))
88#define MAC16_16_P13(c,a,b) (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13)))
89
90#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
91#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
92#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
93#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
94
95#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
96#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
97#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
98
99#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
100
101#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b))))
102#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b))))
103#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b)))
104#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b)))
105
106#endif
diff --git a/lib/rbcodec/codecs/libspeex/gain_table.c b/lib/rbcodec/codecs/libspeex/gain_table.c
new file mode 100644
index 0000000000..bf236e80fc
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/gain_table.c
@@ -0,0 +1,162 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: gain_table.c
3 Codebook for 3-tap pitch prediction gain (128 entries)
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 3. The name of the author may not be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#include "config-speex.h"
33
34const signed char gain_cdbk_nb[512] GAIN_ICONST_ATTR = {
35-32, -32, -32, 0,
36-28, -67, -5, 33,
37-42, -6, -32, 18,
38-57, -10, -54, 35,
39-16, 27, -41, 42,
4019, -19, -40, 36,
41-45, 24, -21, 40,
42-8, -14, -18, 28,
431, 14, -58, 53,
44-18, -88, -39, 39,
45-38, 21, -18, 37,
46-19, 20, -43, 38,
4710, 17, -48, 54,
48-52, -58, -13, 33,
49-44, -1, -11, 32,
50-12, -11, -34, 22,
5114, 0, -46, 46,
52-37, -35, -34, 5,
53-25, 44, -30, 43,
546, -4, -63, 49,
55-31, 43, -41, 43,
56-23, 30, -43, 41,
57-43, 26, -14, 44,
58-33, 1, -13, 27,
59-13, 18, -37, 37,
60-46, -73, -45, 34,
61-36, 24, -25, 34,
62-36, -11, -20, 19,
63-25, 12, -18, 33,
64-36, -69, -59, 34,
65-45, 6, 8, 46,
66-22, -14, -24, 18,
67-1, 13, -44, 44,
68-39, -48, -26, 15,
69-32, 31, -37, 34,
70-33, 15, -46, 31,
71-24, 30, -36, 37,
72-41, 31, -23, 41,
73-50, 22, -4, 50,
74-22, 2, -21, 28,
75-17, 30, -34, 40,
76-7, -60, -28, 29,
77-38, 42, -28, 42,
78-44, -11, 21, 43,
79-16, 8, -44, 34,
80-39, -55, -43, 21,
81-11, -35, 26, 41,
82-9, 0, -34, 29,
83-8, 121, -81, 113,
847, -16, -22, 33,
85-37, 33, -31, 36,
86-27, -7, -36, 17,
87-34, 70, -57, 65,
88-37, -11, -48, 21,
89-40, 17, -1, 44,
90-33, 6, -6, 33,
91-9, 0, -20, 34,
92-21, 69, -33, 57,
93-29, 33, -31, 35,
94-55, 12, -1, 49,
95-33, 27, -22, 35,
96-50, -33, -47, 17,
97-50, 54, 51, 94,
98-1, -5, -44, 35,
99-4, 22, -40, 45,
100-39, -66, -25, 24,
101-33, 1, -26, 20,
102-24, -23, -25, 12,
103-11, 21, -45, 44,
104-25, -45, -19, 17,
105-43, 105, -16, 82,
1065, -21, 1, 41,
107-16, 11, -33, 30,
108-13, -99, -4, 57,
109-37, 33, -15, 44,
110-25, 37, -63, 54,
111-36, 24, -31, 31,
112-53, -56, -38, 26,
113-41, -4, 4, 37,
114-33, 13, -30, 24,
11549, 52, -94, 114,
116-5, -30, -15, 23,
1171, 38, -40, 56,
118-23, 12, -36, 29,
119-17, 40, -47, 51,
120-37, -41, -39, 11,
121-49, 34, 0, 58,
122-18, -7, -4, 34,
123-16, 17, -27, 35,
12430, 5, -62, 65,
1254, 48, -68, 76,
126-43, 11, -11, 38,
127-18, 19, -15, 41,
128-23, -62, -39, 23,
129-42, 10, -2, 41,
130-21, -13, -13, 25,
131-9, 13, -47, 42,
132-23, -62, -24, 24,
133-44, 60, -21, 58,
134-18, -3, -52, 32,
135-22, 22, -36, 34,
136-75, 57, 16, 90,
137-19, 3, 10, 45,
138-29, 23, -38, 32,
139-5, -62, -51, 38,
140-51, 40, -18, 53,
141-42, 13, -24, 32,
142-34, 14, -20, 30,
143-56, -75, -26, 37,
144-26, 32, 15, 59,
145-26, 17, -29, 29,
146-7, 28, -52, 53,
147-12, -30, 5, 30,
148-5, -48, -5, 35,
1492, 2, -43, 40,
15021, 16, 16, 75,
151-25, -45, -32, 10,
152-43, 18, -10, 42,
1539, 0, -1, 52,
154-1, 7, -30, 36,
15519, -48, -4, 48,
156-28, 25, -29, 32,
157-22, 0, -31, 22,
158-32, 17, -10, 36,
159-64, -41, -62, 36,
160-52, 15, 16, 58,
161-30, -22, -32, 6,
162-7, 9, -38, 36};
diff --git a/lib/rbcodec/codecs/libspeex/gain_table_lbr.c b/lib/rbcodec/codecs/libspeex/gain_table_lbr.c
new file mode 100644
index 0000000000..b74df318a3
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/gain_table_lbr.c
@@ -0,0 +1,66 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: gain_table_lbr.c
3 Codebook for 3-tap pitch prediction gain (32 entries)
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 3. The name of the author may not be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#include "config-speex.h"
33
34const signed char gain_cdbk_lbr[128] GAIN_ICONST_ATTR = {
35-32, -32, -32, 0,
36-31, -58, -16, 22,
37-41, -24, -43, 14,
38-56, -22, -55, 29,
39-13, 33, -41, 47,
40-4, -39, -9, 29,
41-41, 15, -12, 38,
42-8, -15, -12, 31,
431, 2, -44, 40,
44-22, -66, -42, 27,
45-38, 28, -23, 38,
46-21, 14, -37, 31,
470, 21, -50, 52,
48-53, -71, -27, 33,
49-37, -1, -19, 25,
50-19, -5, -28, 22,
516, 65, -44, 74,
52-33, -48, -33, 9,
53-40, 57, -14, 58,
54-17, 4, -45, 32,
55-31, 38, -33, 36,
56-23, 28, -40, 39,
57-43, 29, -12, 46,
58-34, 13, -23, 28,
59-16, 15, -27, 34,
60-14, -82, -15, 43,
61-31, 25, -32, 29,
62-21, 5, -5, 38,
63-47, -63, -51, 33,
64-46, 12, 3, 47,
65-28, -17, -29, 11,
66-10, 14, -40, 38};
diff --git a/lib/rbcodec/codecs/libspeex/hexc_10_32_table.c b/lib/rbcodec/codecs/libspeex/hexc_10_32_table.c
new file mode 100644
index 0000000000..9a924e7ff0
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/hexc_10_32_table.c
@@ -0,0 +1,68 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: hexc_10_32_table.c
3 Codebook for high-band excitation in SB-CELP mode (4000 bps)
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#include "config-speex.h"
34
35const signed char hexc_10_32_table[320] HEXC_ICONST_ATTR = {
36-3, -2, -1, 0, -4, 5, 35, -40, -9, 13,
37-44, 5, -27, -1, -7, 6, -11, 7, -8, 7,
3819, -14, 15, -4, 9, -10, 10, -8, 10, -9,
39-1, 1, 0, 0, 2, 5, -18, 22, -53, 50,
401, -23, 50, -36, 15, 3, -13, 14, -10, 6,
411, 5, -3, 4, -2, 5, -32, 25, 5, -2,
42-1, -4, 1, 11, -29, 26, -6, -15, 30, -18,
430, 15, -17, 40, -41, 3, 9, -2, -2, 3,
44-3, -1, -5, 2, 21, -6, -16, -21, 23, 2,
4560, 15, 16, -16, -9, 14, 9, -1, 7, -9,
460, 1, 1, 0, -1, -6, 17, -28, 54, -45,
47-1, 1, -1, -6, -6, 2, 11, 26, -29, -2,
4846, -21, 34, 12, -23, 32, -23, 16, -10, 3,
4966, 19, -20, 24, 7, 11, -3, 0, -3, -1,
50-50, -46, 2, -18, -3, 4, -1, -2, 3, -3,
51-19, 41, -36, 9, 11, -24, 21, -16, 9, -3,
52-25, -3, 10, 18, -9, -2, -5, -1, -5, 6,
53-4, -3, 2, -26, 21, -19, 35, -15, 7, -13,
5417, -19, 39, -43, 48, -31, 16, -9, 7, -2,
55-5, 3, -4, 9, -19, 27, -55, 63, -35, 10,
5626, -44, -2, 9, 4, 1, -6, 8, -9, 5,
57-8, -1, -3, -16, 45, -42, 5, 15, -16, 10,
580, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59-16, 24, -55, 47, -38, 27, -19, 7, -3, 1,
6016, 27, 20, -19, 18, 5, -7, 1, -5, 2,
61-6, 8, -22, 0, -3, -3, 8, -1, 7, -8,
621, -3, 5, 0, 17, -48, 58, -52, 29, -7,
63-2, 3, -10, 6, -26, 58, -31, 1, -6, 3,
6493, -29, 39, 3, 17, 5, 6, -1, -1, -1,
6527, 13, 10, 19, -7, -34, 12, 10, -4, 9,
66-76, 9, 8, -28, -2, -11, 2, -1, 3, 1,
67-83, 38, -39, 4, -16, -6, -2, -5, 5, -2,
68};
diff --git a/lib/rbcodec/codecs/libspeex/hexc_table.c b/lib/rbcodec/codecs/libspeex/hexc_table.c
new file mode 100644
index 0000000000..d892abd18c
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/hexc_table.c
@@ -0,0 +1,164 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: hexc_table.c
3 Codebook for high-band excitation in SB-CELP mode (8000 bps with sign)
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#include "config-speex.h"
34
35const signed char hexc_table[1024] HEXC_ICONST_ATTR = {
36-24, 21, -20, 5, -5, -7, 14, -10,
372, -27, 16, -20, 0, -32, 26, 19,
388, -11, -41, 31, 28, -27, -32, 34,
3942, 34, -17, 22, -10, 13, -29, 18,
40-12, -26, -24, 11, 22, 5, -5, -5,
4154, -68, -43, 57, -25, 24, 4, 4,
4226, -8, -12, -17, 54, 30, -45, 1,
4310, -15, 18, -41, 11, 68, -67, 37,
44-16, -24, -16, 38, -22, 6, -29, 30,
4566, -27, 5, 7, -16, 13, 2, -12,
46-7, -3, -20, 36, 4, -28, 9, 3,
4732, 48, 26, 39, 3, 0, 7, -21,
48-13, 5, -82, -7, 73, -20, 34, -9,
49-5, 1, -1, 10, -5, -10, -1, 9,
501, -9, 10, 0, -14, 11, -1, -2,
51-1, 11, 20, 96, -81, -22, -12, -9,
52-58, 9, 24, -30, 26, -35, 27, -12,
5313, -18, 56, -59, 15, -7, 23, -15,
54-1, 6, -25, 14, -22, -20, 47, -11,
5516, 2, 38, -23, -19, -30, -9, 40,
56-11, 5, 4, -6, 8, 26, -21, -11,
57127, 4, 1, 6, -9, 2, -7, -2,
58-3, 7, -5, 10, -19, 7, -106, 91,
59-3, 9, -4, 21, -8, 26, -80, 8,
601, -2, -10, -17, -17, -27, 32, 71,
616, -29, 11, -23, 54, -38, 29, -22,
6239, 87, -31, -12, -20, 3, -2, -2,
632, 20, 0, -1, -35, 27, 9, -6,
64-12, 3, -12, -6, 13, 1, 14, -22,
65-59, -15, -17, -25, 13, -7, 7, 3,
660, 1, -7, 6, -3, 61, -37, -23,
67-23, -29, 38, -31, 27, 1, -8, 2,
68-27, 23, -26, 36, -34, 5, 24, -24,
69-6, 7, 3, -59, 78, -62, 44, -16,
701, 6, 0, 17, 8, 45, 0, -110,
716, 14, -2, 32, -77, -56, 62, -3,
723, -13, 4, -16, 102, -15, -36, -1,
739, -113, 6, 23, 0, 9, 9, 5,
74-8, -1, -14, 5, -12, 121, -53, -27,
75-8, -9, 22, -13, 3, 2, -3, 1,
76-2, -71, 95, 38, -19, 15, -16, -5,
7771, 10, 2, -32, -13, -5, 15, -1,
78-2, -14, -85, 30, 29, 6, 3, 2,
790, 0, 0, 0, 0, 0, 0, 0,
802, -65, -56, -9, 18, 18, 23, -14,
81-2, 0, 12, -29, 26, -12, 1, 2,
82-12, -64, 90, -6, 4, 1, 5, -5,
83-110, -3, -31, 22, -29, 9, 0, 8,
84-40, -5, 21, -5, -5, 13, 10, -18,
8540, 1, 35, -20, 30, -28, 11, -6,
8619, 7, 14, 18, -64, 9, -6, 16,
8751, 68, 8, 16, 12, -8, 0, -9,
8820, -22, 25, 7, -4, -13, 41, -35,
8993, -18, -54, 11, -1, 1, -9, 4,
90-66, 66, -31, 20, -22, 25, -23, 11,
9110, 9, 19, 15, 11, -5, -31, -10,
92-23, -28, -6, -6, -3, -4, 5, 3,
93-28, 22, -11, -42, 25, -25, -16, 41,
9434, 47, -6, 2, 42, -19, -22, 5,
95-39, 32, 6, -35, 22, 17, -30, 8,
96-26, -11, -11, 3, -12, 33, 33, -37,
9721, -1, 6, -4, 3, 0, -5, 5,
9812, -12, 57, 27, -61, -3, 20, -17,
992, 0, 4, 0, -2, -33, -58, 81,
100-23, 39, -10, -5, 2, 6, -7, 5,
1014, -3, -2, -13, -23, -72, 107, 15,
102-5, 0, -7, -3, -6, 5, -4, 15,
10347, 12, -31, 25, -16, 8, 22, -25,
104-62, -56, -18, 14, 28, 12, 2, -11,
10574, -66, 41, -20, -7, 16, -20, 16,
106-8, 0, -16, 4, -19, 92, 12, -59,
107-14, -39, 49, -25, -16, 23, -27, 19,
108-3, -33, 19, 85, -29, 6, -7, -10,
10916, -7, -12, 1, -6, 2, 4, -2,
11064, 10, -25, 41, -2, -31, 15, 0,
111110, 50, 69, 35, 28, 19, -10, 2,
112-43, -49, -56, -15, -16, 10, 3, 12,
113-1, -8, 1, 26, -12, -1, 7, -11,
114-27, 41, 25, 1, -11, -18, 22, -7,
115-1, -47, -8, 23, -3, -17, -7, 18,
116-125, 59, -5, 3, 18, 1, 2, 3,
11727, -35, 65, -53, 50, -46, 37, -21,
118-28, 7, 14, -37, -5, -5, 12, 5,
119-8, 78, -19, 21, -6, -16, 8, -7,
1205, 2, 7, 2, 10, -6, 12, -60,
12144, 11, -36, -32, 31, 0, 2, -2,
1222, 1, -3, 7, -10, 17, -21, 10,
1236, -2, 19, -2, 59, -38, -86, 38,
1248, -41, -30, -45, -33, 7, 15, 28,
12529, -7, 24, -40, 7, 7, 5, -2,
1269, 24, -23, -18, 6, -29, 30, 2,
12728, 49, -11, -46, 10, 43, -13, -9,
128-1, -3, -7, -7, -17, -6, 97, -33,
129-21, 3, 5, 1, 12, -43, -8, 28,
1307, -43, -7, 17, -20, 19, -1, 2,
131-13, 9, 54, 34, 9, -28, -11, -9,
132-17, 110, -59, 44, -26, 0, 3, -12,
133-47, 73, -34, -43, 38, -33, 16, -5,
134-46, -4, -6, -2, -25, 19, -29, 28,
135-13, 5, 14, 27, -40, -43, 4, 32,
136-13, -2, -35, -4, 112, -42, 9, -12,
13737, -28, 17, 14, -19, 35, -39, 23,
1383, -14, -1, -57, -5, 94, -9, 3,
139-39, 5, 30, -10, -32, 42, -13, -14,
140-97, -63, 30, -9, 1, -7, 12, 5,
14120, 17, -9, -36, -30, 25, 47, -9,
142-15, 12, -22, 98, -8, -50, 15, -27,
14321, -16, -11, 2, 12, -10, 10, -3,
14433, 36, -96, 0, -17, 31, -9, 9,
1453, -20, 13, -11, 8, -4, 10, -10,
1469, 1, 112, -70, -27, 5, -21, 2,
147-57, -3, -29, 10, 19, -21, 21, -10,
148-66, -3, 91, -35, 30, -12, 0, -7,
14959, -28, 26, 2, 14, -18, 1, 1,
15011, 17, 20, -54, -59, 27, 4, 29,
15132, 5, 19, 12, -4, 1, 7, -10,
1525, -2, 10, 0, 23, -5, 28, -104,
15346, 11, 16, 3, 29, 1, -8, -14,
1541, 7, -50, 88, -62, 26, 8, -17,
155-14, 50, 0, 32, -12, -3, -27, 18,
156-8, -5, 8, 3, -20, -11, 37, -12,
1579, 33, 46, -101, -1, -4, 1, 6,
158-1, 28, -42, -15, 16, 5, -1, -2,
159-55, 85, 38, -9, -4, 11, -2, -9,
160-6, 3, -20, -10, -77, 89, 24, -3,
161-104, -57, -26, -31, -20, -6, -9, 14,
16220, -23, 46, -15, -31, 28, 1, -15,
163-2, 6, -2, 31, 45, -76, 23, -25,
164};
diff --git a/lib/rbcodec/codecs/libspeex/high_lsp_tables.c b/lib/rbcodec/codecs/libspeex/high_lsp_tables.c
new file mode 100644
index 0000000000..56dc0f9faa
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/high_lsp_tables.c
@@ -0,0 +1,165 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: high_lsp_tables.c
3 Codebooks for high-band LSPs in SB-CELP mode
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 3. The name of the author may not be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#include "config-speex.h"
33
34const signed char high_lsp_cdbk[512] LSP_ICONST_ATTR ={
3539,12,-14,-20,-29,-61,-67,-76,
36-32,-71,-67,68,77,46,34,5,
37-13,-48,-46,-72,-81,-84,-60,-58,
38-40,-28,82,93,68,45,29,3,
39-19,-47,-28,-43,-35,-30,-8,-13,
40-39,-91,-91,-123,-96,10,10,-6,
41-18,-55,-60,-91,-56,-36,-27,-16,
42-48,-75,40,28,-10,-28,35,9,
4337,19,1,-20,-31,-41,-18,-25,
44-35,-68,-80,45,27,-1,47,13,
450,-29,-35,-57,-50,-79,-73,-38,
46-19,5,35,14,-10,-23,16,-8,
475,-24,-40,-62,-23,-27,-22,-16,
48-18,-46,-72,-77,43,21,33,1,
49-80,-70,-70,-64,-56,-52,-39,-33,
50-31,-38,-19,-19,-15,32,33,-2,
517,-15,-15,-24,-23,-33,-41,-56,
52-24,-57,5,89,64,41,27,5,
53-9,-47,-60,-97,-97,-124,-20,-9,
54-44,-73,31,29,-4,64,48,7,
55-35,-57,0,-3,-26,-47,-3,-6,
56-40,-76,-79,-48,12,81,55,10,
579,-24,-43,-73,-57,-69,16,5,
58-28,-53,18,29,20,0,-4,-11,
596,-13,23,7,-17,-35,-37,-37,
60-30,-68,-63,6,24,-9,-14,3,
6121,-13,-27,-57,-49,-80,-24,-41,
62-5,-16,-5,1,45,25,12,-7,
633,-15,-6,-16,-15,-8,6,-13,
64-42,-81,-80,-87,14,1,-10,-3,
65-43,-69,-46,-24,-28,-29,36,6,
66-43,-56,-12,12,54,79,43,9,
6754,22,2,8,-12,-43,-46,-52,
68-38,-69,-89,-5,75,38,33,5,
69-13,-53,-62,-87,-89,-113,-99,-55,
70-34,-37,62,55,33,16,21,-2,
71-17,-46,-29,-38,-38,-48,-39,-42,
72-36,-75,-72,-88,-48,-30,21,2,
73-15,-57,-64,-98,-84,-76,25,1,
74-46,-80,-12,18,-7,3,34,6,
7538,31,23,4,-1,20,14,-15,
76-43,-78,-91,-24,14,-3,54,16,
770,-27,-28,-44,-56,-83,-92,-89,
78-3,34,56,41,36,22,20,-8,
79-7,-35,-42,-62,-49,3,12,-10,
80-50,-87,-96,-66,92,70,38,9,
81-70,-71,-62,-42,-39,-43,-11,-7,
82-50,-79,-58,-50,-31,32,31,-6,
83-4,-25,7,-17,-38,-70,-58,-27,
84-43,-83,-28,59,36,20,31,2,
85-27,-71,-80,-109,-98,-75,-33,-32,
86-31,-2,33,15,-6,43,33,-5,
870,-22,-10,-27,-34,-49,-11,-20,
88-41,-91,-100,-121,-39,57,41,10,
89-19,-50,-38,-59,-60,-70,-18,-20,
90-8,-31,-8,-15,1,-14,-26,-25,
9133,21,32,17,1,-19,-19,-26,
92-58,-81,-35,-22,45,30,11,-11,
933,-26,-48,-87,-67,-83,-58,3,
94-1,-26,-20,44,10,25,39,5,
95-9,-35,-27,-38,7,10,4,-9,
96-42,-85,-102,-127,52,44,28,10,
97-47,-61,-40,-39,-17,-1,-10,-33,
98-42,-74,-48,21,-4,70,52,10};
99
100
101const signed char high_lsp_cdbk2[512] LSP_ICONST_ATTR ={
102-36,-62,6,-9,-10,-14,-56,23,
1031,-26,23,-48,-17,12,8,-7,
10423,29,-36,-28,-6,-29,-17,-5,
10540,23,10,10,-46,-13,36,6,
1064,-30,-29,62,32,-32,-1,22,
107-14,1,-4,-22,-45,2,54,4,
108-30,-57,-59,-12,27,-3,-31,8,
109-9,5,10,-14,32,66,19,9,
1102,-25,-37,23,-15,18,-38,-31,
1115,-9,-21,15,0,22,62,30,
11215,-12,-14,-46,77,21,33,3,
11334,29,-19,50,2,11,9,-38,
114-12,-37,62,1,-15,54,32,6,
1152,-24,20,35,-21,2,19,24,
116-13,55,4,9,39,-19,30,-1,
117-21,73,54,33,8,18,3,15,
1186,-19,-47,6,-3,-48,-50,1,
11926,20,8,-23,-50,65,-14,-55,
120-17,-31,-37,-28,53,-1,-17,-53,
1211,57,11,-8,-25,-30,-37,64,
1225,-52,-45,15,23,31,15,14,
123-25,24,33,-2,-44,-56,-18,6,
124-21,-43,4,-12,17,-37,20,-10,
12534,15,2,15,55,21,-11,-31,
126-6,46,25,16,-9,-25,-8,-62,
12728,17,20,-32,-29,26,30,25,
128-19,2,-16,-17,26,-51,2,50,
12942,19,-66,23,29,-2,3,19,
130-19,-37,32,15,6,30,-34,13,
13111,-5,40,31,10,-42,4,-9,
13226,-9,-70,17,-2,-23,20,-22,
133-55,51,-24,-31,22,-22,15,-13,
1343,-10,-28,-16,56,4,-63,11,
135-18,-15,-18,-38,-35,16,-7,34,
136-1,-21,-49,-47,9,-37,7,8,
13769,55,20,6,-33,-45,-10,-9,
1386,-9,12,71,15,-3,-42,-7,
139-24,32,-35,-2,-42,-17,-5,0,
140-2,-33,-54,13,-12,-34,47,23,
14119,55,7,-8,74,31,14,16,
142-23,-26,19,12,-18,-49,-28,-31,
143-20,2,-14,-20,-47,78,40,13,
144-23,-11,21,-6,18,1,47,5,
14538,35,32,46,22,8,13,16,
146-14,18,51,19,40,39,11,-26,
147-1,-17,47,2,-53,-15,31,-22,
14838,21,-15,-16,5,-33,53,15,
149-38,86,11,-3,-24,49,13,-4,
150-11,-18,28,20,-12,-27,-26,35,
151-25,-35,-3,-20,-61,30,10,-55,
152-12,-22,-52,-54,-14,19,-32,-12,
15345,15,-8,-48,-9,11,-32,8,
154-16,-34,-13,51,18,38,-2,-32,
155-17,22,-2,-18,-28,-70,59,27,
156-28,-19,-10,-20,-9,-9,-8,-21,
15721,-8,35,-2,45,-3,-9,12,
1580,30,7,-39,43,27,-38,-91,
15930,26,19,-55,-4,63,14,-17,
16013,9,13,2,7,4,6,61,
16172,-1,-17,29,-1,-22,-17,8,
162-28,-37,63,44,41,3,2,14,
1639,-6,75,-8,-7,-12,-15,-12,
16413,9,-4,30,-22,-65,15,0,
165-45,4,-4,1,5,22,11,23};
diff --git a/lib/rbcodec/codecs/libspeex/jitter.c b/lib/rbcodec/codecs/libspeex/jitter.c
new file mode 100644
index 0000000000..d9f6c67b86
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/jitter.c
@@ -0,0 +1,839 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: speex_jitter.h
3
4 Adaptive jitter buffer for Speex
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35/*
36TODO:
37- Add short-term estimate
38- Defensive programming
39 + warn when last returned < last desired (begative buffering)
40 + warn if update_delay not called between get() and tick() or is called twice in a row
41- Linked list structure for holding the packets instead of the current fixed-size array
42 + return memory to a pool
43 + allow pre-allocation of the pool
44 + optional max number of elements
45- Statistics
46 + drift
47 + loss
48 + late
49 + jitter
50 + buffering delay
51*/
52#ifdef HAVE_CONFIG_H
53#include "config-speex.h"
54#endif
55
56
57#include "arch.h"
58#include "speex/speex.h"
59#include "speex/speex_bits.h"
60#include "speex/speex_jitter.h"
61#include "os_support.h"
62
63#ifndef NULL
64#define NULL 0
65#endif
66
67#define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */
68
69#define TSUB(a,b) ((spx_int32_t)((a)-(b)))
70
71#define GT32(a,b) (((spx_int32_t)((a)-(b)))>0)
72#define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0)
73#define LT32(a,b) (((spx_int32_t)((a)-(b)))<0)
74#define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0)
75
76#define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step))
77
78#define MAX_TIMINGS 20
79#define MAX_BUFFERS 3
80#define TOP_DELAY 20
81
82/** Buffer that keeps the time of arrival of the latest packets */
83struct TimingBuffer {
84 int filled; /**< Number of entries occupied in "timing" and "counts"*/
85 int curr_count; /**< Number of packet timings we got (including those we discarded) */
86 spx_int16_t timing[MAX_TIMINGS]; /**< Sorted list of all timings ("latest" packets first) */
87 spx_int16_t counts[MAX_TIMINGS]; /**< Order the packets were put in (will be used for short-term estimate) */
88};
89
90static void tb_init(struct TimingBuffer *tb)
91{
92 tb->filled = 0;
93 tb->curr_count = 0;
94}
95
96/* Add the timing of a new packet to the TimingBuffer */
97static void tb_add(struct TimingBuffer *tb, spx_int16_t timing)
98{
99 int pos;
100 /* Discard packet that won't make it into the list because they're too early */
101 if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1])
102 {
103 tb->curr_count++;
104 return;
105 }
106
107 /* Find where the timing info goes in the sorted list */
108 pos = 0;
109 /* FIXME: Do bisection instead of linear search */
110 while (pos<tb->filled && timing >= tb->timing[pos])
111 {
112 pos++;
113 }
114
115 speex_assert(pos <= tb->filled && pos < MAX_TIMINGS);
116
117 /* Shift everything so we can perform the insertion */
118 if (pos < tb->filled)
119 {
120 int move_size = tb->filled-pos;
121 if (tb->filled == MAX_TIMINGS)
122 move_size -= 1;
123 SPEEX_COPY(&tb->timing[pos+1], &tb->timing[pos], move_size);
124 SPEEX_COPY(&tb->counts[pos+1], &tb->counts[pos], move_size);
125 }
126 /* Insert */
127 tb->timing[pos] = timing;
128 tb->counts[pos] = tb->curr_count;
129
130 tb->curr_count++;
131 if (tb->filled<MAX_TIMINGS)
132 tb->filled++;
133}
134
135
136
137/** Jitter buffer structure */
138struct JitterBuffer_ {
139 spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */
140 spx_uint32_t last_returned_timestamp; /**< Useful for getting the next packet with the same timestamp (for fragmented media) */
141 spx_uint32_t next_stop; /**< Estimated time the next get() will be called */
142
143 spx_int32_t buffered; /**< Amount of data we think is still buffered by the application (timestamp units)*/
144
145 JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */
146 spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */
147
148 void (*destroy) (void *); /**< Callback for destroying a packet */
149
150 spx_int32_t delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */
151 spx_int32_t concealment_size; /**< Size of the packet loss concealment "units" */
152 int reset_state; /**< True if state was just reset */
153 int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */
154 int late_cutoff; /**< How late must a packet be for it not to be considered at all */
155 int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */
156 int auto_adjust; /**< Whether to automatically adjust the delay at any time */
157
158 struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */
159 struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */
160 int window_size; /**< Total window over which the late frames are counted */
161 int subwindow_size; /**< Sub-window size for faster computation */
162 int max_late_rate; /**< Absolute maximum amount of late packets tolerable (in percent) */
163 int latency_tradeoff; /**< Latency equivalent of losing one percent of packets */
164 int auto_tradeoff; /**< Latency equivalent of losing one percent of packets (automatic default) */
165
166 int lost_count; /**< Number of consecutive lost packets */
167};
168
169/** Based on available data, this computes the optimal delay for the jitter buffer.
170 The optimised function is in timestamp units and is:
171 cost = delay + late_factor*[number of frames that would be late if we used that delay]
172 @param tb Array of buffers
173 @param late_factor Equivalent cost of a late frame (in timestamp units)
174 */
175static spx_int16_t compute_opt_delay(JitterBuffer *jitter)
176{
177 int i;
178 spx_int16_t opt=0;
179 spx_int32_t best_cost=0x7fffffff;
180 int late = 0;
181 int pos[MAX_BUFFERS];
182 int tot_count;
183 float late_factor;
184 int penalty_taken = 0;
185 int best = 0;
186 int worst = 0;
187 spx_int32_t deltaT;
188 struct TimingBuffer *tb;
189
190 tb = jitter->_tb;
191
192 /* Number of packet timings we have received (including those we didn't keep) */
193 tot_count = 0;
194 for (i=0;i<MAX_BUFFERS;i++)
195 tot_count += tb[i].curr_count;
196 if (tot_count==0)
197 return 0;
198
199 /* Compute cost for one lost packet */
200 if (jitter->latency_tradeoff != 0)
201 late_factor = jitter->latency_tradeoff * 100.0f / tot_count;
202 else
203 late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count;
204
205 /*fprintf(stderr, "late_factor = %f\n", late_factor);*/
206 for (i=0;i<MAX_BUFFERS;i++)
207 pos[i] = 0;
208
209 /* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late
210 for the current settings) */
211 for (i=0;i<TOP_DELAY;i++)
212 {
213 int j;
214 int next=-1;
215 int latest = 32767;
216 /* Pick latest amoung all sub-windows */
217 for (j=0;j<MAX_BUFFERS;j++)
218 {
219 if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest)
220 {
221 next = j;
222 latest = tb[j].timing[pos[j]];
223 }
224 }
225 if (next != -1)
226 {
227 spx_int32_t cost;
228
229 if (i==0)
230 worst = latest;
231 best = latest;
232 latest = ROUND_DOWN(latest, jitter->delay_step);
233 pos[next]++;
234
235 /* Actual cost function that tells us how bad using this delay would be */
236 cost = -latest + late_factor*late;
237 /*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/
238 if (cost < best_cost)
239 {
240 best_cost = cost;
241 opt = latest;
242 }
243 } else {
244 break;
245 }
246
247 /* For the next timing we will consider, there will be one more late packet to count */
248 late++;
249 /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */
250 if (latest >= 0 && !penalty_taken)
251 {
252 penalty_taken = 1;
253 late+=2;
254 }
255 }
256
257 deltaT = best-worst;
258 /* This is a default "automatic latency tradeoff" when none is provided */
259 jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY;
260 /*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/
261
262 /* FIXME: Compute a short-term estimate too and combine with the long-term one */
263
264 /* Prevents reducing the buffer size when we haven't really had much data */
265 if (tot_count < TOP_DELAY && opt > 0)
266 return 0;
267 return opt;
268}
269
270
271/** Initialise jitter buffer */
272JitterBuffer *jitter_buffer_init(int step_size)
273{
274 JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer));
275 if (jitter)
276 {
277 int i;
278 spx_int32_t tmp;
279 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
280 jitter->packets[i].data=NULL;
281 jitter->delay_step = step_size;
282 jitter->concealment_size = step_size;
283 /*FIXME: Should this be 0 or 1?*/
284 jitter->buffer_margin = 0;
285 jitter->late_cutoff = 50;
286 jitter->destroy = NULL;
287 jitter->latency_tradeoff = 0;
288 jitter->auto_adjust = 1;
289 tmp = 4;
290 jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
291 jitter_buffer_reset(jitter);
292 }
293 return jitter;
294}
295
296/** Reset jitter buffer */
297void jitter_buffer_reset(JitterBuffer *jitter)
298{
299 int i;
300 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
301 {
302 if (jitter->packets[i].data)
303 {
304 if (jitter->destroy)
305 jitter->destroy(jitter->packets[i].data);
306 else
307 speex_free(jitter->packets[i].data);
308 jitter->packets[i].data = NULL;
309 }
310 }
311 /* Timestamp is actually undefined at this point */
312 jitter->pointer_timestamp = 0;
313 jitter->next_stop = 0;
314 jitter->reset_state = 1;
315 jitter->lost_count = 0;
316 jitter->buffered = 0;
317 jitter->auto_tradeoff = 32000;
318
319 for (i=0;i<MAX_BUFFERS;i++)
320 {
321 tb_init(&jitter->_tb[i]);
322 jitter->timeBuffers[i] = &jitter->_tb[i];
323 }
324 /*fprintf (stderr, "reset\n");*/
325}
326
327/** Destroy jitter buffer */
328void jitter_buffer_destroy(JitterBuffer *jitter)
329{
330 jitter_buffer_reset(jitter);
331 speex_free(jitter);
332}
333
334/** Take the following timing into consideration for future calculations */
335static void update_timings(JitterBuffer *jitter, spx_int32_t timing)
336{
337 if (timing < -32767)
338 timing = -32767;
339 if (timing > 32767)
340 timing = 32767;
341 /* If the current sub-window is full, perform a rotation and discard oldest sub-widow */
342 if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size)
343 {
344 int i;
345 /*fprintf(stderr, "Rotate buffer\n");*/
346 struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1];
347 for (i=MAX_BUFFERS-1;i>=1;i--)
348 jitter->timeBuffers[i] = jitter->timeBuffers[i-1];
349 jitter->timeBuffers[0] = tmp;
350 tb_init(jitter->timeBuffers[0]);
351 }
352 tb_add(jitter->timeBuffers[0], timing);
353}
354
355/** Compensate all timings when we do an adjustment of the buffering */
356static void shift_timings(JitterBuffer *jitter, spx_int16_t amount)
357{
358 int i, j;
359 for (i=0;i<MAX_BUFFERS;i++)
360 {
361 for (j=0;j<jitter->timeBuffers[i]->filled;j++)
362 jitter->timeBuffers[i]->timing[j] += amount;
363 }
364}
365
366
367/** Put one packet into the jitter buffer */
368void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
369{
370 int i,j;
371 int late;
372 /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/
373
374 /* Cleanup buffer (remove old packets that weren't played) */
375 if (!jitter->reset_state)
376 {
377 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
378 {
379 /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */
380 if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp))
381 {
382 /*fprintf (stderr, "cleaned (not played)\n");*/
383 if (jitter->destroy)
384 jitter->destroy(jitter->packets[i].data);
385 else
386 speex_free(jitter->packets[i].data);
387 jitter->packets[i].data = NULL;
388 }
389 }
390 }
391
392 /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/
393 /* Check if packet is late (could still be useful though) */
394 if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop))
395 {
396 update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin);
397 late = 1;
398 } else {
399 late = 0;
400 }
401
402 /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */
403 if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp))
404 {
405
406 /*Find an empty slot in the buffer*/
407 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
408 {
409 if (jitter->packets[i].data==NULL)
410 break;
411 }
412
413 /*No place left in the buffer, need to make room for it by discarding the oldest packet */
414 if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
415 {
416 int earliest=jitter->packets[0].timestamp;
417 i=0;
418 for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
419 {
420 if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest))
421 {
422 earliest = jitter->packets[j].timestamp;
423 i=j;
424 }
425 }
426 if (jitter->destroy)
427 jitter->destroy(jitter->packets[i].data);
428 else
429 speex_free(jitter->packets[i].data);
430 jitter->packets[i].data=NULL;
431 if (jitter->lost_count>20)
432 {
433 jitter_buffer_reset(jitter);
434 }
435 /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/
436 }
437
438 /* Copy packet in buffer */
439 if (jitter->destroy)
440 {
441 jitter->packets[i].data = packet->data;
442 } else {
443 jitter->packets[i].data=(char*)speex_alloc(packet->len);
444 for (j=0;j<packet->len;j++)
445 jitter->packets[i].data[j]=packet->data[j];
446 }
447 jitter->packets[i].timestamp=packet->timestamp;
448 jitter->packets[i].span=packet->span;
449 jitter->packets[i].len=packet->len;
450 jitter->packets[i].sequence=packet->sequence;
451 jitter->packets[i].user_data=packet->user_data;
452 if (jitter->reset_state || late)
453 jitter->arrival[i] = 0;
454 else
455 jitter->arrival[i] = jitter->next_stop;
456 }
457
458
459}
460
461/** Get one packet from the jitter buffer */
462int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset)
463{
464 int i;
465 unsigned int j;
466 int incomplete = 0;
467 spx_int16_t opt;
468
469 if (start_offset != NULL)
470 *start_offset = 0;
471
472 /* Syncing on the first call */
473 if (jitter->reset_state)
474 {
475 int found = 0;
476 /* Find the oldest packet */
477 spx_uint32_t oldest=0;
478 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
479 {
480 if (jitter->packets[i].data && (!found || LT32(jitter->packets[i].timestamp,oldest)))
481 {
482 oldest = jitter->packets[i].timestamp;
483 found = 1;
484 }
485 }
486 if (found)
487 {
488 jitter->reset_state=0;
489 jitter->pointer_timestamp = oldest;
490 jitter->next_stop = oldest;
491 } else {
492 packet->timestamp = 0;
493 packet->span = jitter->interp_requested;
494 return JITTER_BUFFER_MISSING;
495 }
496 }
497
498
499 jitter->last_returned_timestamp = jitter->pointer_timestamp;
500
501 if (jitter->interp_requested != 0)
502 {
503 packet->timestamp = jitter->pointer_timestamp;
504 packet->span = jitter->interp_requested;
505
506 /* Increment the pointer because it got decremented in the delay update */
507 jitter->pointer_timestamp += jitter->interp_requested;
508 packet->len = 0;
509 /*fprintf (stderr, "Deferred interpolate\n");*/
510
511 jitter->interp_requested = 0;
512
513 jitter->buffered = packet->span - desired_span;
514
515 return JITTER_BUFFER_INSERTION;
516 }
517
518 /* Searching for the packet that fits best */
519
520 /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */
521 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
522 {
523 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))
524 break;
525 }
526
527 /* If no match, try for an "older" packet that still spans (fully) the current chunk */
528 if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
529 {
530 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
531 {
532 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))
533 break;
534 }
535 }
536
537 /* If still no match, try for an "older" packet that spans part of the current chunk */
538 if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
539 {
540 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
541 {
542 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))
543 break;
544 }
545 }
546
547 /* If still no match, try for earliest packet possible */
548 if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
549 {
550 int found = 0;
551 spx_uint32_t best_time=0;
552 int best_span=0;
553 int besti=0;
554 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
555 {
556 /* check if packet starts within current chunk */
557 if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp))
558 {
559 if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span)))
560 {
561 best_time = jitter->packets[i].timestamp;
562 best_span = jitter->packets[i].span;
563 besti = i;
564 found = 1;
565 }
566 }
567 }
568 if (found)
569 {
570 i=besti;
571 incomplete = 1;
572 /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/
573 }
574 }
575
576 /* If we find something */
577 if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
578 {
579 spx_int32_t offset;
580
581 /* We (obviously) haven't lost this packet */
582 jitter->lost_count = 0;
583
584 /* In this case, 0 isn't as a valid timestamp */
585 if (jitter->arrival[i] != 0)
586 {
587 update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin);
588 }
589
590
591 if (jitter->packets[i].len > packet->len)
592 {
593 speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len);
594 } else {
595 packet->len = jitter->packets[i].len;
596 }
597 /* Copy packet */
598 if (jitter->destroy)
599 {
600 packet->data = jitter->packets[i].data;
601 } else {
602 for (j=0;j<packet->len;j++)
603 packet->data[j] = jitter->packets[i].data[j];
604 /* Remove packet */
605 speex_free(jitter->packets[i].data);
606 }
607 jitter->packets[i].data = NULL;
608 /* Set timestamp and span (if requested) */
609 offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp;
610 if (start_offset != NULL)
611 *start_offset = offset;
612 else if (offset != 0)
613 speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset);
614
615 packet->timestamp = jitter->packets[i].timestamp;
616 jitter->last_returned_timestamp = packet->timestamp;
617
618 packet->span = jitter->packets[i].span;
619 packet->sequence = jitter->packets[i].sequence;
620 packet->user_data = jitter->packets[i].user_data;
621 /* Point to the end of the current packet */
622 jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span;
623
624 jitter->buffered = packet->span - desired_span;
625
626 if (start_offset != NULL)
627 jitter->buffered += *start_offset;
628
629 return JITTER_BUFFER_OK;
630 }
631
632
633 /* If we haven't found anything worth returning */
634
635 /*fprintf (stderr, "not found\n");*/
636 jitter->lost_count++;
637 /*fprintf (stderr, "m");*/
638 /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/
639
640 opt = compute_opt_delay(jitter);
641
642 /* Should we force an increase in the buffer or just do normal interpolation? */
643 if (opt < 0)
644 {
645 /* Need to increase buffering */
646
647 /* Shift histogram to compensate */
648 shift_timings(jitter, -opt);
649
650 packet->timestamp = jitter->pointer_timestamp;
651 packet->span = -opt;
652 /* Don't move the pointer_timestamp forward */
653 packet->len = 0;
654
655 jitter->buffered = packet->span - desired_span;
656 return JITTER_BUFFER_INSERTION;
657 /*jitter->pointer_timestamp -= jitter->delay_step;*/
658 /*fprintf (stderr, "Forced to interpolate\n");*/
659 } else {
660 /* Normal packet loss */
661 packet->timestamp = jitter->pointer_timestamp;
662
663 desired_span = ROUND_DOWN(desired_span, jitter->concealment_size);
664 packet->span = desired_span;
665 jitter->pointer_timestamp += desired_span;
666 packet->len = 0;
667
668 jitter->buffered = packet->span - desired_span;
669 return JITTER_BUFFER_MISSING;
670 /*fprintf (stderr, "Normal loss\n");*/
671 }
672
673
674}
675
676int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet)
677{
678 int i, j;
679 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
680 {
681 if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp)
682 break;
683 }
684 if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
685 {
686 /* Copy packet */
687 packet->len = jitter->packets[i].len;
688 if (jitter->destroy)
689 {
690 packet->data = jitter->packets[i].data;
691 } else {
692 for (j=0;j<packet->len;j++)
693 packet->data[j] = jitter->packets[i].data[j];
694 /* Remove packet */
695 speex_free(jitter->packets[i].data);
696 }
697 jitter->packets[i].data = NULL;
698 packet->timestamp = jitter->packets[i].timestamp;
699 packet->span = jitter->packets[i].span;
700 packet->sequence = jitter->packets[i].sequence;
701 packet->user_data = jitter->packets[i].user_data;
702 return JITTER_BUFFER_OK;
703 } else {
704 packet->data = NULL;
705 packet->len = 0;
706 packet->span = 0;
707 return JITTER_BUFFER_MISSING;
708 }
709}
710
711/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
712static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
713{
714 spx_int16_t opt = compute_opt_delay(jitter);
715 /*fprintf(stderr, "opt adjustment is %d ", opt);*/
716
717 if (opt < 0)
718 {
719 shift_timings(jitter, -opt);
720
721 jitter->pointer_timestamp += opt;
722 jitter->interp_requested = -opt;
723 /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/
724 } else if (opt > 0)
725 {
726 shift_timings(jitter, -opt);
727 jitter->pointer_timestamp += opt;
728 /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/
729 }
730
731 return opt;
732}
733
734/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
735int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
736{
737 /* If the programmer calls jitter_buffer_update_delay() directly,
738 automatically disable auto-adjustment */
739 jitter->auto_adjust = 0;
740
741 return _jitter_buffer_update_delay(jitter, packet, start_offset);
742}
743
744/** Get pointer timestamp of jitter buffer */
745int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
746{
747 return jitter->pointer_timestamp;
748}
749
750void jitter_buffer_tick(JitterBuffer *jitter)
751{
752 /* Automatically-adjust the buffering delay if requested */
753 if (jitter->auto_adjust)
754 _jitter_buffer_update_delay(jitter, NULL, NULL);
755
756 if (jitter->buffered >= 0)
757 {
758 jitter->next_stop = jitter->pointer_timestamp - jitter->buffered;
759 } else {
760 jitter->next_stop = jitter->pointer_timestamp;
761 speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered);
762 }
763 jitter->buffered = 0;
764}
765
766void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem)
767{
768 /* Automatically-adjust the buffering delay if requested */
769 if (jitter->auto_adjust)
770 _jitter_buffer_update_delay(jitter, NULL, NULL);
771
772 if (jitter->buffered < 0)
773 speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered);
774 jitter->next_stop = jitter->pointer_timestamp - rem;
775}
776
777
778/* Used like the ioctl function to control the jitter buffer parameters */
779int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr)
780{
781 int count, i;
782 switch(request)
783 {
784 case JITTER_BUFFER_SET_MARGIN:
785 jitter->buffer_margin = *(spx_int32_t*)ptr;
786 break;
787 case JITTER_BUFFER_GET_MARGIN:
788 *(spx_int32_t*)ptr = jitter->buffer_margin;
789 break;
790 case JITTER_BUFFER_GET_AVALIABLE_COUNT:
791 count = 0;
792 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
793 {
794 if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp))
795 {
796 count++;
797 }
798 }
799 *(spx_int32_t*)ptr = count;
800 break;
801 case JITTER_BUFFER_SET_DESTROY_CALLBACK:
802 jitter->destroy = (void (*) (void *))ptr;
803 break;
804 case JITTER_BUFFER_GET_DESTROY_CALLBACK:
805 *(void (**) (void *))ptr = jitter->destroy;
806 break;
807 case JITTER_BUFFER_SET_DELAY_STEP:
808 jitter->delay_step = *(spx_int32_t*)ptr;
809 break;
810 case JITTER_BUFFER_GET_DELAY_STEP:
811 *(spx_int32_t*)ptr = jitter->delay_step;
812 break;
813 case JITTER_BUFFER_SET_CONCEALMENT_SIZE:
814 jitter->concealment_size = *(spx_int32_t*)ptr;
815 break;
816 case JITTER_BUFFER_GET_CONCEALMENT_SIZE:
817 *(spx_int32_t*)ptr = jitter->concealment_size;
818 break;
819 case JITTER_BUFFER_SET_MAX_LATE_RATE:
820 jitter->max_late_rate = *(spx_int32_t*)ptr;
821 jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate;
822 jitter->subwindow_size = jitter->window_size/MAX_BUFFERS;
823 break;
824 case JITTER_BUFFER_GET_MAX_LATE_RATE:
825 *(spx_int32_t*)ptr = jitter->max_late_rate;
826 break;
827 case JITTER_BUFFER_SET_LATE_COST:
828 jitter->latency_tradeoff = *(spx_int32_t*)ptr;
829 break;
830 case JITTER_BUFFER_GET_LATE_COST:
831 *(spx_int32_t*)ptr = jitter->latency_tradeoff;
832 break;
833 default:
834 speex_warning_int("Unknown jitter_buffer_ctl request: ", request);
835 return -1;
836 }
837 return 0;
838}
839
diff --git a/lib/rbcodec/codecs/libspeex/kiss_fft.c b/lib/rbcodec/codecs/libspeex/kiss_fft.c
new file mode 100644
index 0000000000..5b699a362f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/kiss_fft.c
@@ -0,0 +1,523 @@
1/*
2Copyright (c) 2003-2004, Mark Borgerding
3Copyright (c) 2005-2007, Jean-Marc Valin
4
5All rights reserved.
6
7Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8
9 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10 * 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.
11 * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
12
13THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14*/
15
16
17#ifdef HAVE_CONFIG_H
18#include "config-speex.h"
19#endif
20
21#include "_kiss_fft_guts.h"
22#include "arch.h"
23#include "os_support.h"
24
25/* The guts header contains all the multiplication and addition macros that are defined for
26 fixed or floating point complex numbers. It also delares the kf_ internal functions.
27 */
28
29static void kf_bfly2(
30 kiss_fft_cpx * Fout,
31 const size_t fstride,
32 const kiss_fft_cfg st,
33 int m,
34 int N,
35 int mm
36 )
37{
38 kiss_fft_cpx * Fout2;
39 kiss_fft_cpx * tw1;
40 kiss_fft_cpx t;
41 if (!st->inverse) {
42 int i,j;
43 kiss_fft_cpx * Fout_beg = Fout;
44 for (i=0;i<N;i++)
45 {
46 Fout = Fout_beg + i*mm;
47 Fout2 = Fout + m;
48 tw1 = st->twiddles;
49 for(j=0;j<m;j++)
50 {
51 /* Almost the same as the code path below, except that we divide the input by two
52 (while keeping the best accuracy possible) */
53 spx_word32_t tr, ti;
54 tr = SHR32(SUB32(MULT16_16(Fout2->r , tw1->r),MULT16_16(Fout2->i , tw1->i)), 1);
55 ti = SHR32(ADD32(MULT16_16(Fout2->i , tw1->r),MULT16_16(Fout2->r , tw1->i)), 1);
56 tw1 += fstride;
57 Fout2->r = PSHR32(SUB32(SHL32(EXTEND32(Fout->r), 14), tr), 15);
58 Fout2->i = PSHR32(SUB32(SHL32(EXTEND32(Fout->i), 14), ti), 15);
59 Fout->r = PSHR32(ADD32(SHL32(EXTEND32(Fout->r), 14), tr), 15);
60 Fout->i = PSHR32(ADD32(SHL32(EXTEND32(Fout->i), 14), ti), 15);
61 ++Fout2;
62 ++Fout;
63 }
64 }
65 } else {
66 int i,j;
67 kiss_fft_cpx * Fout_beg = Fout;
68 for (i=0;i<N;i++)
69 {
70 Fout = Fout_beg + i*mm;
71 Fout2 = Fout + m;
72 tw1 = st->twiddles;
73 for(j=0;j<m;j++)
74 {
75 C_MUL (t, *Fout2 , *tw1);
76 tw1 += fstride;
77 C_SUB( *Fout2 , *Fout , t );
78 C_ADDTO( *Fout , t );
79 ++Fout2;
80 ++Fout;
81 }
82 }
83 }
84}
85
86static void kf_bfly4(
87 kiss_fft_cpx * Fout,
88 const size_t fstride,
89 const kiss_fft_cfg st,
90 int m,
91 int N,
92 int mm
93 )
94{
95 kiss_fft_cpx *tw1,*tw2,*tw3;
96 kiss_fft_cpx scratch[6];
97 const size_t m2=2*m;
98 const size_t m3=3*m;
99 int i, j;
100
101 if (st->inverse)
102 {
103 kiss_fft_cpx * Fout_beg = Fout;
104 for (i=0;i<N;i++)
105 {
106 Fout = Fout_beg + i*mm;
107 tw3 = tw2 = tw1 = st->twiddles;
108 for (j=0;j<m;j++)
109 {
110 C_MUL(scratch[0],Fout[m] , *tw1 );
111 C_MUL(scratch[1],Fout[m2] , *tw2 );
112 C_MUL(scratch[2],Fout[m3] , *tw3 );
113
114 C_SUB( scratch[5] , *Fout, scratch[1] );
115 C_ADDTO(*Fout, scratch[1]);
116 C_ADD( scratch[3] , scratch[0] , scratch[2] );
117 C_SUB( scratch[4] , scratch[0] , scratch[2] );
118 C_SUB( Fout[m2], *Fout, scratch[3] );
119 tw1 += fstride;
120 tw2 += fstride*2;
121 tw3 += fstride*3;
122 C_ADDTO( *Fout , scratch[3] );
123
124 Fout[m].r = scratch[5].r - scratch[4].i;
125 Fout[m].i = scratch[5].i + scratch[4].r;
126 Fout[m3].r = scratch[5].r + scratch[4].i;
127 Fout[m3].i = scratch[5].i - scratch[4].r;
128 ++Fout;
129 }
130 }
131 } else
132 {
133 kiss_fft_cpx * Fout_beg = Fout;
134 for (i=0;i<N;i++)
135 {
136 Fout = Fout_beg + i*mm;
137 tw3 = tw2 = tw1 = st->twiddles;
138 for (j=0;j<m;j++)
139 {
140 C_MUL4(scratch[0],Fout[m] , *tw1 );
141 C_MUL4(scratch[1],Fout[m2] , *tw2 );
142 C_MUL4(scratch[2],Fout[m3] , *tw3 );
143
144 Fout->r = PSHR16(Fout->r, 2);
145 Fout->i = PSHR16(Fout->i, 2);
146 C_SUB( scratch[5] , *Fout, scratch[1] );
147 C_ADDTO(*Fout, scratch[1]);
148 C_ADD( scratch[3] , scratch[0] , scratch[2] );
149 C_SUB( scratch[4] , scratch[0] , scratch[2] );
150 Fout[m2].r = PSHR16(Fout[m2].r, 2);
151 Fout[m2].i = PSHR16(Fout[m2].i, 2);
152 C_SUB( Fout[m2], *Fout, scratch[3] );
153 tw1 += fstride;
154 tw2 += fstride*2;
155 tw3 += fstride*3;
156 C_ADDTO( *Fout , scratch[3] );
157
158 Fout[m].r = scratch[5].r + scratch[4].i;
159 Fout[m].i = scratch[5].i - scratch[4].r;
160 Fout[m3].r = scratch[5].r - scratch[4].i;
161 Fout[m3].i = scratch[5].i + scratch[4].r;
162 ++Fout;
163 }
164 }
165 }
166}
167
168static void kf_bfly3(
169 kiss_fft_cpx * Fout,
170 const size_t fstride,
171 const kiss_fft_cfg st,
172 size_t m
173 )
174{
175 size_t k=m;
176 const size_t m2 = 2*m;
177 kiss_fft_cpx *tw1,*tw2;
178 kiss_fft_cpx scratch[5];
179 kiss_fft_cpx epi3;
180 epi3 = st->twiddles[fstride*m];
181
182 tw1=tw2=st->twiddles;
183
184 do{
185 if (!st->inverse) {
186 C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
187 }
188
189 C_MUL(scratch[1],Fout[m] , *tw1);
190 C_MUL(scratch[2],Fout[m2] , *tw2);
191
192 C_ADD(scratch[3],scratch[1],scratch[2]);
193 C_SUB(scratch[0],scratch[1],scratch[2]);
194 tw1 += fstride;
195 tw2 += fstride*2;
196
197 Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
198 Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
199
200 C_MULBYSCALAR( scratch[0] , epi3.i );
201
202 C_ADDTO(*Fout,scratch[3]);
203
204 Fout[m2].r = Fout[m].r + scratch[0].i;
205 Fout[m2].i = Fout[m].i - scratch[0].r;
206
207 Fout[m].r -= scratch[0].i;
208 Fout[m].i += scratch[0].r;
209
210 ++Fout;
211 }while(--k);
212}
213
214static void kf_bfly5(
215 kiss_fft_cpx * Fout,
216 const size_t fstride,
217 const kiss_fft_cfg st,
218 int m
219 )
220{
221 kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
222 int u;
223 kiss_fft_cpx scratch[13];
224 kiss_fft_cpx * twiddles = st->twiddles;
225 kiss_fft_cpx *tw;
226 kiss_fft_cpx ya,yb;
227 ya = twiddles[fstride*m];
228 yb = twiddles[fstride*2*m];
229
230 Fout0=Fout;
231 Fout1=Fout0+m;
232 Fout2=Fout0+2*m;
233 Fout3=Fout0+3*m;
234 Fout4=Fout0+4*m;
235
236 tw=st->twiddles;
237 for ( u=0; u<m; ++u ) {
238 if (!st->inverse) {
239 C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
240 }
241 scratch[0] = *Fout0;
242
243 C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
244 C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
245 C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
246 C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
247
248 C_ADD( scratch[7],scratch[1],scratch[4]);
249 C_SUB( scratch[10],scratch[1],scratch[4]);
250 C_ADD( scratch[8],scratch[2],scratch[3]);
251 C_SUB( scratch[9],scratch[2],scratch[3]);
252
253 Fout0->r += scratch[7].r + scratch[8].r;
254 Fout0->i += scratch[7].i + scratch[8].i;
255
256 scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
257 scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
258
259 scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
260 scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
261
262 C_SUB(*Fout1,scratch[5],scratch[6]);
263 C_ADD(*Fout4,scratch[5],scratch[6]);
264
265 scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
266 scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
267 scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
268 scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
269
270 C_ADD(*Fout2,scratch[11],scratch[12]);
271 C_SUB(*Fout3,scratch[11],scratch[12]);
272
273 ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
274 }
275}
276
277/* perform the butterfly for one stage of a mixed radix FFT */
278static void kf_bfly_generic(
279 kiss_fft_cpx * Fout,
280 const size_t fstride,
281 const kiss_fft_cfg st,
282 int m,
283 int p
284 )
285{
286 int u,k,q1,q;
287 kiss_fft_cpx * twiddles = st->twiddles;
288 kiss_fft_cpx t;
289 kiss_fft_cpx scratchbuf[17];
290 int Norig = st->nfft;
291
292 /*CHECKBUF(scratchbuf,nscratchbuf,p);*/
293 if (p>17)
294 speex_fatal("KissFFT: max radix supported is 17");
295
296 for ( u=0; u<m; ++u ) {
297 k=u;
298 for ( q1=0 ; q1<p ; ++q1 ) {
299 scratchbuf[q1] = Fout[ k ];
300 if (!st->inverse) {
301 C_FIXDIV(scratchbuf[q1],p);
302 }
303 k += m;
304 }
305
306 k=u;
307 for ( q1=0 ; q1<p ; ++q1 ) {
308 int twidx=0;
309 Fout[ k ] = scratchbuf[0];
310 for (q=1;q<p;++q ) {
311 twidx += fstride * k;
312 if (twidx>=Norig) twidx-=Norig;
313 C_MUL(t,scratchbuf[q] , twiddles[twidx] );
314 C_ADDTO( Fout[ k ] ,t);
315 }
316 k += m;
317 }
318 }
319}
320
321static
322void kf_shuffle(
323 kiss_fft_cpx * Fout,
324 const kiss_fft_cpx * f,
325 const size_t fstride,
326 int in_stride,
327 int * factors,
328 const kiss_fft_cfg st
329 )
330{
331 const int p=*factors++; /* the radix */
332 const int m=*factors++; /* stage's fft length/p */
333
334 /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
335 if (m==1)
336 {
337 int j;
338 for (j=0;j<p;j++)
339 {
340 Fout[j] = *f;
341 f += fstride*in_stride;
342 }
343 } else {
344 int j;
345 for (j=0;j<p;j++)
346 {
347 kf_shuffle( Fout , f, fstride*p, in_stride, factors,st);
348 f += fstride*in_stride;
349 Fout += m;
350 }
351 }
352}
353
354static
355void kf_work(
356 kiss_fft_cpx * Fout,
357 const kiss_fft_cpx * f,
358 const size_t fstride,
359 int in_stride,
360 int * factors,
361 const kiss_fft_cfg st,
362 int N,
363 int s2,
364 int m2
365 )
366{
367 int i;
368 kiss_fft_cpx * Fout_beg=Fout;
369 const int p=*factors++; /* the radix */
370 const int m=*factors++; /* stage's fft length/p */
371#if 0
372 /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
373 if (m==1)
374 {
375 /* int j;
376 for (j=0;j<p;j++)
377 {
378 Fout[j] = *f;
379 f += fstride*in_stride;
380 }*/
381 } else {
382 int j;
383 for (j=0;j<p;j++)
384 {
385 kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m);
386 f += fstride*in_stride;
387 Fout += m;
388 }
389 }
390
391 Fout=Fout_beg;
392
393 switch (p) {
394 case 2: kf_bfly2(Fout,fstride,st,m); break;
395 case 3: kf_bfly3(Fout,fstride,st,m); break;
396 case 4: kf_bfly4(Fout,fstride,st,m); break;
397 case 5: kf_bfly5(Fout,fstride,st,m); break;
398 default: kf_bfly_generic(Fout,fstride,st,m,p); break;
399 }
400#else
401 /*printf ("fft %d %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N, m2);*/
402 if (m==1)
403 {
404 /*for (i=0;i<N;i++)
405 {
406 int j;
407 Fout = Fout_beg+i*m2;
408 const kiss_fft_cpx * f2 = f+i*s2;
409 for (j=0;j<p;j++)
410 {
411 *Fout++ = *f2;
412 f2 += fstride*in_stride;
413 }
414 }*/
415 }else{
416 kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m);
417 }
418
419
420
421
422 switch (p) {
423 case 2: kf_bfly2(Fout,fstride,st,m, N, m2); break;
424 case 3: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly3(Fout,fstride,st,m);} break;
425 case 4: kf_bfly4(Fout,fstride,st,m, N, m2); break;
426 case 5: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly5(Fout,fstride,st,m);} break;
427 default: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly_generic(Fout,fstride,st,m,p);} break;
428 }
429#endif
430}
431
432/* facbuf is populated by p1,m1,p2,m2, ...
433 where
434 p[i] * m[i] = m[i-1]
435 m0 = n */
436static
437void kf_factor(int n,int * facbuf)
438{
439 int p=4;
440
441 /*factor out powers of 4, powers of 2, then any remaining primes */
442 do {
443 while (n % p) {
444 switch (p) {
445 case 4: p = 2; break;
446 case 2: p = 3; break;
447 default: p += 2; break;
448 }
449 if (p>32000 || (spx_int32_t)p*(spx_int32_t)p > n)
450 p = n; /* no more factors, skip to end */
451 }
452 n /= p;
453 *facbuf++ = p;
454 *facbuf++ = n;
455 } while (n > 1);
456}
457/*
458 *
459 * User-callable function to allocate all necessary storage space for the fft.
460 *
461 * The return value is a contiguous block of memory, allocated with malloc. As such,
462 * It can be freed with free(), rather than a kiss_fft-specific function.
463 * */
464kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
465{
466 kiss_fft_cfg st=NULL;
467 size_t memneeded = sizeof(struct kiss_fft_state)
468 + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
469
470 if ( lenmem==NULL ) {
471 st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
472 }else{
473 if (mem != NULL && *lenmem >= memneeded)
474 st = (kiss_fft_cfg)mem;
475 *lenmem = memneeded;
476 }
477 if (st) {
478 int i;
479 st->nfft=nfft;
480 st->inverse = inverse_fft;
481#ifdef FIXED_POINT
482 for (i=0;i<nfft;++i) {
483 spx_word32_t phase = i;
484 if (!st->inverse)
485 phase = -phase;
486 kf_cexp2(st->twiddles+i, DIV32(SHL32(phase,17),nfft));
487 }
488#else
489 for (i=0;i<nfft;++i) {
490 const double pi=3.14159265358979323846264338327;
491 double phase = ( -2*pi /nfft ) * i;
492 if (st->inverse)
493 phase *= -1;
494 kf_cexp(st->twiddles+i, phase );
495 }
496#endif
497 kf_factor(nfft,st->factors);
498 }
499 return st;
500}
501
502
503
504
505void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
506{
507 if (fin == fout)
508 {
509 speex_fatal("In-place FFT not supported");
510 /*CHECKBUF(tmpbuf,ntmpbuf,st->nfft);
511 kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
512 SPEEX_MOVE(fout,tmpbuf,st->nfft);*/
513 } else {
514 kf_shuffle( fout, fin, 1,in_stride, st->factors,st);
515 kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1);
516 }
517}
518
519void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
520{
521 kiss_fft_stride(cfg,fin,fout,1);
522}
523
diff --git a/lib/rbcodec/codecs/libspeex/kiss_fft.h b/lib/rbcodec/codecs/libspeex/kiss_fft.h
new file mode 100644
index 0000000000..43319b1ba8
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/kiss_fft.h
@@ -0,0 +1,108 @@
1#ifndef KISS_FFT_H
2#define KISS_FFT_H
3
4#include <stdlib.h>
5#include <math.h>
6#include "arch.h"
7
8#ifdef __cplusplus
9extern "C" {
10#endif
11
12/*
13 ATTENTION!
14 If you would like a :
15 -- a utility that will handle the caching of fft objects
16 -- real-only (no imaginary time component ) FFT
17 -- a multi-dimensional FFT
18 -- a command-line utility to perform ffts
19 -- a command-line utility to perform fast-convolution filtering
20
21 Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
22 in the tools/ directory.
23*/
24
25#ifdef USE_SIMD
26# include <xmmintrin.h>
27# define kiss_fft_scalar __m128
28#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes)
29#else
30#define KISS_FFT_MALLOC speex_alloc
31#endif
32
33
34#ifdef FIXED_POINT
35#include "arch.h"
36# define kiss_fft_scalar spx_int16_t
37#else
38# ifndef kiss_fft_scalar
39/* default is float */
40# define kiss_fft_scalar float
41# endif
42#endif
43
44typedef struct {
45 kiss_fft_scalar r;
46 kiss_fft_scalar i;
47}kiss_fft_cpx;
48
49typedef struct kiss_fft_state* kiss_fft_cfg;
50
51/*
52 * kiss_fft_alloc
53 *
54 * Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
55 *
56 * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
57 *
58 * The return value from fft_alloc is a cfg buffer used internally
59 * by the fft routine or NULL.
60 *
61 * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
62 * The returned value should be free()d when done to avoid memory leaks.
63 *
64 * The state can be placed in a user supplied buffer 'mem':
65 * If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
66 * then the function places the cfg in mem and the size used in *lenmem
67 * and returns mem.
68 *
69 * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
70 * then the function returns NULL and places the minimum cfg
71 * buffer size in *lenmem.
72 * */
73
74kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
75
76/*
77 * kiss_fft(cfg,in_out_buf)
78 *
79 * Perform an FFT on a complex input buffer.
80 * for a forward FFT,
81 * fin should be f[0] , f[1] , ... ,f[nfft-1]
82 * fout will be F[0] , F[1] , ... ,F[nfft-1]
83 * Note that each element is complex and can be accessed like
84 f[k].r and f[k].i
85 * */
86void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
87
88/*
89 A more generic version of the above function. It reads its input from every Nth sample.
90 * */
91void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
92
93/* If kiss_fft_alloc allocated a buffer, it is one contiguous
94 buffer and can be simply free()d when no longer needed*/
95#define kiss_fft_free speex_free
96
97/*
98 Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up
99 your compiler output to call this before you exit.
100*/
101void kiss_fft_cleanup(void);
102
103
104#ifdef __cplusplus
105}
106#endif
107
108#endif
diff --git a/lib/rbcodec/codecs/libspeex/kiss_fftr.c b/lib/rbcodec/codecs/libspeex/kiss_fftr.c
new file mode 100644
index 0000000000..1c694b195d
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/kiss_fftr.c
@@ -0,0 +1,297 @@
1/*
2Copyright (c) 2003-2004, Mark Borgerding
3
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 * 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.
10 * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
12THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*/
14
15#ifdef HAVE_CONFIG_H
16#include "config-speex.h"
17#endif
18
19#include "os_support.h"
20#include "kiss_fftr.h"
21#include "_kiss_fft_guts.h"
22
23struct kiss_fftr_state{
24 kiss_fft_cfg substate;
25 kiss_fft_cpx * tmpbuf;
26 kiss_fft_cpx * super_twiddles;
27#ifdef USE_SIMD
28 long pad;
29#endif
30};
31
32kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
33{
34 int i;
35 kiss_fftr_cfg st = NULL;
36 size_t subsize, memneeded;
37
38 if (nfft & 1) {
39 speex_warning("Real FFT optimization must be even.\n");
40 return NULL;
41 }
42 nfft >>= 1;
43
44 kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);
45 memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 2);
46
47 if (lenmem == NULL) {
48 st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);
49 } else {
50 if (*lenmem >= memneeded)
51 st = (kiss_fftr_cfg) mem;
52 *lenmem = memneeded;
53 }
54 if (!st)
55 return NULL;
56
57 st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
58 st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
59 st->super_twiddles = st->tmpbuf + nfft;
60 kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
61
62#ifdef FIXED_POINT
63 for (i=0;i<nfft;++i) {
64 spx_word32_t phase = i+(nfft>>1);
65 if (!inverse_fft)
66 phase = -phase;
67 kf_cexp2(st->super_twiddles+i, DIV32(SHL32(phase,16),nfft));
68 }
69#else
70 for (i=0;i<nfft;++i) {
71 const double pi=3.14159265358979323846264338327;
72 double phase = pi*(((double)i) /nfft + .5);
73 if (!inverse_fft)
74 phase = -phase;
75 kf_cexp(st->super_twiddles+i, phase );
76 }
77#endif
78 return st;
79}
80
81void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
82{
83 /* input buffer timedata is stored row-wise */
84 int k,ncfft;
85 kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
86
87 if ( st->substate->inverse) {
88 speex_fatal("kiss fft usage error: improper alloc\n");
89 }
90
91 ncfft = st->substate->nfft;
92
93 /*perform the parallel fft of two real signals packed in real,imag*/
94 kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
95 /* The real part of the DC element of the frequency spectrum in st->tmpbuf
96 * contains the sum of the even-numbered elements of the input time sequence
97 * The imag part is the sum of the odd-numbered elements
98 *
99 * The sum of tdc.r and tdc.i is the sum of the input time sequence.
100 * yielding DC of input time sequence
101 * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
102 * yielding Nyquist bin of input time sequence
103 */
104
105 tdc.r = st->tmpbuf[0].r;
106 tdc.i = st->tmpbuf[0].i;
107 C_FIXDIV(tdc,2);
108 CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
109 CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
110 freqdata[0].r = tdc.r + tdc.i;
111 freqdata[ncfft].r = tdc.r - tdc.i;
112#ifdef USE_SIMD
113 freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
114#else
115 freqdata[ncfft].i = freqdata[0].i = 0;
116#endif
117
118 for ( k=1;k <= ncfft/2 ; ++k ) {
119 fpk = st->tmpbuf[k];
120 fpnk.r = st->tmpbuf[ncfft-k].r;
121 fpnk.i = - st->tmpbuf[ncfft-k].i;
122 C_FIXDIV(fpk,2);
123 C_FIXDIV(fpnk,2);
124
125 C_ADD( f1k, fpk , fpnk );
126 C_SUB( f2k, fpk , fpnk );
127 C_MUL( tw , f2k , st->super_twiddles[k]);
128
129 freqdata[k].r = HALF_OF(f1k.r + tw.r);
130 freqdata[k].i = HALF_OF(f1k.i + tw.i);
131 freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r);
132 freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i);
133 }
134}
135
136void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata, kiss_fft_scalar *timedata)
137{
138 /* input buffer timedata is stored row-wise */
139 int k, ncfft;
140
141 if (st->substate->inverse == 0) {
142 speex_fatal("kiss fft usage error: improper alloc\n");
143 }
144
145 ncfft = st->substate->nfft;
146
147 st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;
148 st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;
149 /*C_FIXDIV(st->tmpbuf[0],2);*/
150
151 for (k = 1; k <= ncfft / 2; ++k) {
152 kiss_fft_cpx fk, fnkc, fek, fok, tmp;
153 fk = freqdata[k];
154 fnkc.r = freqdata[ncfft - k].r;
155 fnkc.i = -freqdata[ncfft - k].i;
156 /*C_FIXDIV( fk , 2 );
157 C_FIXDIV( fnkc , 2 );*/
158
159 C_ADD (fek, fk, fnkc);
160 C_SUB (tmp, fk, fnkc);
161 C_MUL (fok, tmp, st->super_twiddles[k]);
162 C_ADD (st->tmpbuf[k], fek, fok);
163 C_SUB (st->tmpbuf[ncfft - k], fek, fok);
164#ifdef USE_SIMD
165 st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
166#else
167 st->tmpbuf[ncfft - k].i *= -1;
168#endif
169 }
170 kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
171}
172
173void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata)
174{
175 /* input buffer timedata is stored row-wise */
176 int k,ncfft;
177 kiss_fft_cpx f2k,tdc;
178 spx_word32_t f1kr, f1ki, twr, twi;
179
180 if ( st->substate->inverse) {
181 speex_fatal("kiss fft usage error: improper alloc\n");
182 }
183
184 ncfft = st->substate->nfft;
185
186 /*perform the parallel fft of two real signals packed in real,imag*/
187 kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
188 /* The real part of the DC element of the frequency spectrum in st->tmpbuf
189 * contains the sum of the even-numbered elements of the input time sequence
190 * The imag part is the sum of the odd-numbered elements
191 *
192 * The sum of tdc.r and tdc.i is the sum of the input time sequence.
193 * yielding DC of input time sequence
194 * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
195 * yielding Nyquist bin of input time sequence
196 */
197
198 tdc.r = st->tmpbuf[0].r;
199 tdc.i = st->tmpbuf[0].i;
200 C_FIXDIV(tdc,2);
201 CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
202 CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
203 freqdata[0] = tdc.r + tdc.i;
204 freqdata[2*ncfft-1] = tdc.r - tdc.i;
205
206 for ( k=1;k <= ncfft/2 ; ++k )
207 {
208 /*fpk = st->tmpbuf[k];
209 fpnk.r = st->tmpbuf[ncfft-k].r;
210 fpnk.i = - st->tmpbuf[ncfft-k].i;
211 C_FIXDIV(fpk,2);
212 C_FIXDIV(fpnk,2);
213
214 C_ADD( f1k, fpk , fpnk );
215 C_SUB( f2k, fpk , fpnk );
216
217 C_MUL( tw , f2k , st->super_twiddles[k]);
218
219 freqdata[2*k-1] = HALF_OF(f1k.r + tw.r);
220 freqdata[2*k] = HALF_OF(f1k.i + tw.i);
221 freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r);
222 freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i);
223 */
224
225 /*f1k.r = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);
226 f1k.i = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);
227 f2k.r = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);
228 f2k.i = SHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);
229
230 C_MUL( tw , f2k , st->super_twiddles[k]);
231
232 freqdata[2*k-1] = HALF_OF(f1k.r + tw.r);
233 freqdata[2*k] = HALF_OF(f1k.i + tw.i);
234 freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r);
235 freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i);
236 */
237 f2k.r = SHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);
238 f2k.i = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);
239
240 f1kr = SHL32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),13);
241 f1ki = SHL32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),13);
242
243 twr = SHR32(SUB32(MULT16_16(f2k.r,st->super_twiddles[k].r),MULT16_16(f2k.i,st->super_twiddles[k].i)), 1);
244 twi = SHR32(ADD32(MULT16_16(f2k.i,st->super_twiddles[k].r),MULT16_16(f2k.r,st->super_twiddles[k].i)), 1);
245
246#ifdef FIXED_POINT
247 freqdata[2*k-1] = PSHR32(f1kr + twr, 15);
248 freqdata[2*k] = PSHR32(f1ki + twi, 15);
249 freqdata[2*(ncfft-k)-1] = PSHR32(f1kr - twr, 15);
250 freqdata[2*(ncfft-k)] = PSHR32(twi - f1ki, 15);
251#else
252 freqdata[2*k-1] = .5f*(f1kr + twr);
253 freqdata[2*k] = .5f*(f1ki + twi);
254 freqdata[2*(ncfft-k)-1] = .5f*(f1kr - twr);
255 freqdata[2*(ncfft-k)] = .5f*(twi - f1ki);
256
257#endif
258 }
259}
260
261void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scalar *timedata)
262{
263 /* input buffer timedata is stored row-wise */
264 int k, ncfft;
265
266 if (st->substate->inverse == 0) {
267 speex_fatal ("kiss fft usage error: improper alloc\n");
268 }
269
270 ncfft = st->substate->nfft;
271
272 st->tmpbuf[0].r = freqdata[0] + freqdata[2*ncfft-1];
273 st->tmpbuf[0].i = freqdata[0] - freqdata[2*ncfft-1];
274 /*C_FIXDIV(st->tmpbuf[0],2);*/
275
276 for (k = 1; k <= ncfft / 2; ++k) {
277 kiss_fft_cpx fk, fnkc, fek, fok, tmp;
278 fk.r = freqdata[2*k-1];
279 fk.i = freqdata[2*k];
280 fnkc.r = freqdata[2*(ncfft - k)-1];
281 fnkc.i = -freqdata[2*(ncfft - k)];
282 /*C_FIXDIV( fk , 2 );
283 C_FIXDIV( fnkc , 2 );*/
284
285 C_ADD (fek, fk, fnkc);
286 C_SUB (tmp, fk, fnkc);
287 C_MUL (fok, tmp, st->super_twiddles[k]);
288 C_ADD (st->tmpbuf[k], fek, fok);
289 C_SUB (st->tmpbuf[ncfft - k], fek, fok);
290#ifdef USE_SIMD
291 st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
292#else
293 st->tmpbuf[ncfft - k].i *= -1;
294#endif
295 }
296 kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
297}
diff --git a/lib/rbcodec/codecs/libspeex/kiss_fftr.h b/lib/rbcodec/codecs/libspeex/kiss_fftr.h
new file mode 100644
index 0000000000..7bfb423340
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/kiss_fftr.h
@@ -0,0 +1,51 @@
1#ifndef KISS_FTR_H
2#define KISS_FTR_H
3
4#include "kiss_fft.h"
5#ifdef __cplusplus
6extern "C" {
7#endif
8
9
10/*
11
12 Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
13
14
15
16 */
17
18typedef struct kiss_fftr_state *kiss_fftr_cfg;
19
20
21kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
22/*
23 nfft must be even
24
25 If you don't care to allocate space, use mem = lenmem = NULL
26*/
27
28
29void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
30/*
31 input timedata has nfft scalar points
32 output freqdata has nfft/2+1 complex points
33*/
34
35void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata);
36
37void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
38
39void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata, kiss_fft_scalar *timedata);
40
41/*
42 input freqdata has nfft/2+1 complex points
43 output timedata has nfft scalar points
44*/
45
46#define kiss_fftr_free speex_free
47
48#ifdef __cplusplus
49}
50#endif
51#endif
diff --git a/lib/rbcodec/codecs/libspeex/libspeex.make b/lib/rbcodec/codecs/libspeex/libspeex.make
new file mode 100644
index 0000000000..6138dff4a9
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/libspeex.make
@@ -0,0 +1,66 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10# we need to build two different speex libraries
11# (one for codec, one for core voice)
12# so a little trickery is necessary
13
14# disable strict aliasing optimizations for now, it gives warnings due to
15# some horrid typecasting
16_SPEEXFLAGS = $(filter-out -fstrict-aliasing, $(CODECFLAGS)) \
17 -fno-strict-aliasing -DHAVE_CONFIG_H -DSPEEX_DISABLE_ENCODER \
18 -I$(RBCODECLIB_DIR)/codecs/libspeex
19
20# build voice codec with core -O switch
21VOICESPEEXFLAGS = $(filter-out -ffunction-sections, $(filter-out -DCODEC,$(_SPEEXFLAGS))) -DROCKBOX_VOICE_CODEC
22
23# libspeex is faster on ARM-targets with -O1 instead of -O2
24SPEEXFLAGS = $(filter-out -O%,$(_SPEEXFLAGS))
25
26ifeq ($(ARCH),arch_arm)
27 SPEEXFLAGS += -O1
28else
29 SPEEXFLAGS += -O2
30endif
31
32# libspeex
33SPEEXLIB := $(CODECDIR)/libspeex.a
34SPEEXLIB_SRC := $(call preprocess, $(RBCODECLIB_DIR)/codecs/libspeex/SOURCES)
35SPEEXLIB_OBJ := $(call c2obj, $(SPEEXLIB_SRC))
36OTHER_SRC += $(SPEEXLIB_SRC)
37
38$(SPEEXLIB): $(SPEEXLIB_OBJ)
39 $(SILENT)$(shell rm -f $@)
40 $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null
41
42# libspeex-voice
43VOICESPEEXLIB := $(CODECDIR)/libspeex-voice.a
44VOICESPEEXLIB_SRC := $(call preprocess, $(RBCODECLIB_DIR)/codecs/libspeex/SOURCES)
45VOICESPEEXLIB_OBJ := $(addsuffix .o,$(basename $(subst $(RBCODECLIB_DIR)/codecs/libspeex,$(RBCODEC_BLD)/codecs/libspeex-voice,$(VOICESPEEXLIB_SRC))))
46
47$(VOICESPEEXLIB): $(VOICESPEEXLIB_OBJ)
48 $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null
49
50# pattern rules
51
52$(CODECDIR)/libspeex-voice/%.o : $(RBCODECLIB_DIR)/codecs/libspeex/%.c
53 $(SILENT)mkdir -p $(dir $@)
54 $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) $(VOICESPEEXFLAGS) -c $< -o $@
55
56$(CODECDIR)/libspeex-voice/%.o : $(RBCODECLIB_DIR)/codecs/libspeex/%.S
57 $(SILENT)mkdir -p $(dir $@)
58 $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) $(VOICESPEEXFLAGS) $(ASMFLAGS) -c $< -o $@
59
60$(CODECDIR)/libspeex/%.o: $(RBCODECLIB_DIR)/codecs/libspeex/%.c
61 $(SILENT)mkdir -p $(dir $@)
62 $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) $(SPEEXFLAGS) -c $< -o $@
63
64$(CODECDIR)/libspeex/%.o: $(RBCODECLIB_DIR)/codecs/libspeex/%.S
65 $(SILENT)mkdir -p $(dir $@)
66 $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) $(SPEEXFLAGS) $(ASMFLAGS) -c $< -o $@
diff --git a/lib/rbcodec/codecs/libspeex/lpc.c b/lib/rbcodec/codecs/libspeex/lpc.c
new file mode 100644
index 0000000000..9845633a6c
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/lpc.c
@@ -0,0 +1,201 @@
1/*
2 Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
3 Technische Universitaet Berlin
4
5 Any use of this software is permitted provided that this notice is not
6 removed and that neither the authors nor the Technische Universitaet Berlin
7 are deemed to have made any representations as to the suitability of this
8 software for any purpose nor are held responsible for any defects of
9 this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
10
11 As a matter of courtesy, the authors request to be informed about uses
12 this software has found, about bugs in this software, and about any
13 improvements that may be of general interest.
14
15 Berlin, 28.11.1994
16 Jutta Degener
17 Carsten Bormann
18
19
20 Code modified by Jean-Marc Valin
21
22 Speex License:
23
24 Redistribution and use in source and binary forms, with or without
25 modification, are permitted provided that the following conditions
26 are met:
27
28 - Redistributions of source code must retain the above copyright
29 notice, this list of conditions and the following disclaimer.
30
31 - Redistributions in binary form must reproduce the above copyright
32 notice, this list of conditions and the following disclaimer in the
33 documentation and/or other materials provided with the distribution.
34
35 - Neither the name of the Xiph.org Foundation nor the names of its
36 contributors may be used to endorse or promote products derived from
37 this software without specific prior written permission.
38
39 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
40 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
41 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
42 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
43 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
45 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
46 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
47 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
48 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50*/
51
52#ifdef HAVE_CONFIG_H
53#include "config-speex.h"
54#endif
55
56#include "lpc.h"
57
58#ifdef BFIN_ASM
59#include "lpc_bfin.h"
60#endif
61
62/* LPC analysis
63 *
64 * The next two functions calculate linear prediction coefficients
65 * and/or the related reflection coefficients from the first P_MAX+1
66 * values of the autocorrelation function.
67 */
68
69/* Invented by N. Levinson in 1947, modified by J. Durbin in 1959.
70 */
71
72/* returns minimum mean square error */
73spx_word32_t _spx_lpc(
74spx_coef_t *lpc, /* out: [0...p-1] LPC coefficients */
75const spx_word16_t *ac, /* in: [0...p] autocorrelation values */
76int p
77)
78{
79 int i, j;
80 spx_word16_t r;
81 spx_word16_t error = ac[0];
82
83 if (ac[0] == 0)
84 {
85 for (i = 0; i < p; i++)
86 lpc[i] = 0;
87 return 0;
88 }
89
90 for (i = 0; i < p; i++) {
91
92 /* Sum up this iteration's reflection coefficient */
93 spx_word32_t rr = NEG32(SHL32(EXTEND32(ac[i + 1]),13));
94 for (j = 0; j < i; j++)
95 rr = SUB32(rr,MULT16_16(lpc[j],ac[i - j]));
96#ifdef FIXED_POINT
97 r = DIV32_16(rr+PSHR32(error,1),ADD16(error,8));
98#else
99 r = rr/(error+.003*ac[0]);
100#endif
101 /* Update LPC coefficients and total error */
102 lpc[i] = r;
103 for (j = 0; j < i>>1; j++)
104 {
105 spx_word16_t tmp = lpc[j];
106 lpc[j] = MAC16_16_P13(lpc[j],r,lpc[i-1-j]);
107 lpc[i-1-j] = MAC16_16_P13(lpc[i-1-j],r,tmp);
108 }
109 if (i & 1)
110 lpc[j] = MAC16_16_P13(lpc[j],lpc[j],r);
111
112 error = SUB16(error,MULT16_16_Q13(r,MULT16_16_Q13(error,r)));
113 }
114 return error;
115}
116
117
118#ifdef FIXED_POINT
119
120/* Compute the autocorrelation
121 * ,--,
122 * ac(i) = > x(n) * x(n-i) for all n
123 * `--'
124 * for lags between 0 and lag-1, and x == 0 outside 0...n-1
125 */
126
127#ifndef OVERRIDE_SPEEX_AUTOCORR
128void _spx_autocorr(
129const spx_word16_t *x, /* in: [0...n-1] samples x */
130spx_word16_t *ac, /* out: [0...lag-1] ac values */
131int lag,
132int n
133)
134{
135 spx_word32_t d;
136 int i, j;
137 spx_word32_t ac0=1;
138 int shift, ac_shift;
139
140 for (j=0;j<n;j++)
141 ac0 = ADD32(ac0,SHR32(MULT16_16(x[j],x[j]),8));
142 ac0 = ADD32(ac0,n);
143 shift = 8;
144 while (shift && ac0<0x40000000)
145 {
146 shift--;
147 ac0 <<= 1;
148 }
149 ac_shift = 18;
150 while (ac_shift && ac0<0x40000000)
151 {
152 ac_shift--;
153 ac0 <<= 1;
154 }
155
156
157 for (i=0;i<lag;i++)
158 {
159 d=0;
160 for (j=i;j<n;j++)
161 {
162 d = ADD32(d,SHR32(MULT16_16(x[j],x[j-i]), shift));
163 }
164
165 ac[i] = SHR32(d, ac_shift);
166 }
167}
168#endif
169
170
171#else
172
173
174
175/* Compute the autocorrelation
176 * ,--,
177 * ac(i) = > x(n) * x(n-i) for all n
178 * `--'
179 * for lags between 0 and lag-1, and x == 0 outside 0...n-1
180 */
181void _spx_autocorr(
182const spx_word16_t *x, /* in: [0...n-1] samples x */
183float *ac, /* out: [0...lag-1] ac values */
184int lag,
185int n
186)
187{
188 float d;
189 int i;
190 while (lag--)
191 {
192 for (i = lag, d = 0; i < n; i++)
193 d += x[i] * x[i-lag];
194 ac[lag] = d;
195 }
196 ac[0] += 10;
197}
198
199#endif
200
201
diff --git a/lib/rbcodec/codecs/libspeex/lpc.h b/lib/rbcodec/codecs/libspeex/lpc.h
new file mode 100644
index 0000000000..952ecdd933
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/lpc.h
@@ -0,0 +1,53 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file lpc.h
4 @brief Functions for LPC (Linear Prediction Coefficients) analysis
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef LPC_H
36#define LPC_H
37
38#include "arch.h"
39
40void _spx_autocorr(
41 const spx_word16_t * x, /* in: [0...n-1] samples x */
42 spx_word16_t *ac, /* out: [0...lag-1] ac values */
43 int lag, int n);
44
45spx_word32_t /* returns minimum mean square error */
46_spx_lpc(
47 spx_coef_t * lpc, /* [0...p-1] LPC coefficients */
48 const spx_word16_t * ac, /* in: [0...p] autocorrelation values */
49 int p
50 );
51
52
53#endif
diff --git a/lib/rbcodec/codecs/libspeex/lpc_bfin.h b/lib/rbcodec/codecs/libspeex/lpc_bfin.h
new file mode 100644
index 0000000000..7310ffba52
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/lpc_bfin.h
@@ -0,0 +1,131 @@
1/* Copyright (C) 2005 Analog Devices */
2/**
3 @file lpc_bfin.h
4 @author Jean-Marc Valin
5 @brief Functions for LPC (Linear Prediction Coefficients) analysis (Blackfin version)
6*/
7/*
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 - Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 - Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19 - Neither the name of the Xiph.org Foundation nor the names of its
20 contributors may be used to endorse or promote products derived from
21 this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#define OVERRIDE_SPEEX_AUTOCORR
37void _spx_autocorr(
38const spx_word16_t *x, /* in: [0...n-1] samples x */
39spx_word16_t *ac, /* out: [0...lag-1] ac values */
40int lag,
41int n
42 )
43{
44 spx_word32_t d;
45 const spx_word16_t *xs;
46 int i, j;
47 spx_word32_t ac0=1;
48 spx_word32_t ac32[11], *ac32top;
49 int shift, ac_shift;
50 ac32top = ac32+lag-1;
51 int lag_1, N_lag;
52 int nshift;
53 lag_1 = lag-1;
54 N_lag = n-lag_1;
55 for (j=0;j<n;j++)
56 ac0 = ADD32(ac0,SHR32(MULT16_16(x[j],x[j]),8));
57 ac0 = ADD32(ac0,n);
58 shift = 8;
59 while (shift && ac0<0x40000000)
60 {
61 shift--;
62 ac0 <<= 1;
63 }
64 ac_shift = 18;
65 while (ac_shift && ac0<0x40000000)
66 {
67 ac_shift--;
68 ac0 <<= 1;
69 }
70
71 xs = x+lag-1;
72 nshift = -shift;
73 __asm__ __volatile__
74 (
75 "P2 = %0;\n\t"
76 "I0 = P2;\n\t" /* x in I0 */
77 "B0 = P2;\n\t" /* x in B0 */
78 "R0 = %3;\n\t" /* len in R0 */
79 "P3 = %3;\n\t" /* len in R0 */
80 "P4 = %4;\n\t" /* nb_pitch in R0 */
81 "R1 = R0 << 1;\n\t" /* number of bytes in x */
82 "L0 = R1;\n\t"
83 "P0 = %1;\n\t"
84 "P1 = %2;\n\t"
85 "B1 = P1;\n\t"
86 "R4 = %5;\n\t"
87 "L1 = 0;\n\t" /*Disable looping on I1*/
88
89 "r0 = [I0++];\n\t"
90 "R2 = 0;R3=0;"
91 "LOOP pitch%= LC0 = P4 >> 1;\n\t"
92 "LOOP_BEGIN pitch%=;\n\t"
93 "I1 = P0;\n\t"
94 "A1 = A0 = 0;\n\t"
95 "R1 = [I1++];\n\t"
96 "LOOP inner_prod%= LC1 = P3 >> 1;\n\t"
97 "LOOP_BEGIN inner_prod%=;\n\t"
98 "A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\n\t"
99 "A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R1.H = W[I1++] || R0 = [I0++];\n\t"
100 "LOOP_END inner_prod%=;\n\t"
101 "A0 = ASHIFT A0 by R4.L;\n\t"
102 "A1 = ASHIFT A1 by R4.L;\n\t"
103
104 "R2 = A0, R3 = A1;\n\t"
105 "[P1--] = R2;\n\t"
106 "[P1--] = R3;\n\t"
107 "P0 += 4;\n\t"
108 "LOOP_END pitch%=;\n\t"
109 : : "m" (xs), "m" (x), "m" (ac32top), "m" (N_lag), "m" (lag_1), "m" (nshift)
110 : "A0", "A1", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "R3", "R4", "I0", "I1", "L0", "L1", "B0", "B1", "memory"
111 );
112 d=0;
113 for (j=0;j<n;j++)
114 {
115 d = ADD32(d,SHR32(MULT16_16(x[j],x[j]), shift));
116 }
117 ac32[0] = d;
118
119 for (i=0;i<lag;i++)
120 {
121 d=0;
122 for (j=i;j<lag_1;j++)
123 {
124 d = ADD32(d,SHR32(MULT16_16(x[j],x[j-i]), shift));
125 }
126 if (i)
127 ac32[i] += d;
128 ac[i] = SHR32(ac32[i], ac_shift);
129 }
130}
131
diff --git a/lib/rbcodec/codecs/libspeex/lsp.c b/lib/rbcodec/codecs/libspeex/lsp.c
new file mode 100644
index 0000000000..8408d782aa
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/lsp.c
@@ -0,0 +1,661 @@
1/*---------------------------------------------------------------------------*\
2Original copyright
3 FILE........: lsp.c
4 AUTHOR......: David Rowe
5 DATE CREATED: 24/2/93
6
7Heavily modified by Jean-Marc Valin (c) 2002-2006 (fixed-point,
8 optimizations, additional functions, ...)
9
10 This file contains functions for converting Linear Prediction
11 Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the
12 LSP coefficients are not in radians format but in the x domain of the
13 unit circle.
14
15 Speex License:
16
17 Redistribution and use in source and binary forms, with or without
18 modification, are permitted provided that the following conditions
19 are met:
20
21 - Redistributions of source code must retain the above copyright
22 notice, this list of conditions and the following disclaimer.
23
24 - Redistributions in binary form must reproduce the above copyright
25 notice, this list of conditions and the following disclaimer in the
26 documentation and/or other materials provided with the distribution.
27
28 - Neither the name of the Xiph.org Foundation nor the names of its
29 contributors may be used to endorse or promote products derived from
30 this software without specific prior written permission.
31
32 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
36 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
37 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
38 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
39 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
40 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
41 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43*/
44
45/*---------------------------------------------------------------------------*\
46
47 Introduction to Line Spectrum Pairs (LSPs)
48 ------------------------------------------
49
50 LSPs are used to encode the LPC filter coefficients {ak} for
51 transmission over the channel. LSPs have several properties (like
52 less sensitivity to quantisation noise) that make them superior to
53 direct quantisation of {ak}.
54
55 A(z) is a polynomial of order lpcrdr with {ak} as the coefficients.
56
57 A(z) is transformed to P(z) and Q(z) (using a substitution and some
58 algebra), to obtain something like:
59
60 A(z) = 0.5[P(z)(z+z^-1) + Q(z)(z-z^-1)] (1)
61
62 As you can imagine A(z) has complex zeros all over the z-plane. P(z)
63 and Q(z) have the very neat property of only having zeros _on_ the
64 unit circle. So to find them we take a test point z=exp(jw) and
65 evaluate P (exp(jw)) and Q(exp(jw)) using a grid of points between 0
66 and pi.
67
68 The zeros (roots) of P(z) also happen to alternate, which is why we
69 swap coefficients as we find roots. So the process of finding the
70 LSP frequencies is basically finding the roots of 5th order
71 polynomials.
72
73 The root so P(z) and Q(z) occur in symmetrical pairs at +/-w, hence
74 the name Line Spectrum Pairs (LSPs).
75
76 To convert back to ak we just evaluate (1), "clocking" an impulse
77 thru it lpcrdr times gives us the impulse response of A(z) which is
78 {ak}.
79
80\*---------------------------------------------------------------------------*/
81
82#ifdef HAVE_CONFIG_H
83#include "config-speex.h"
84#endif
85
86#include <math.h>
87#include "lsp.h"
88#include "stack_alloc.h"
89#include "math_approx.h"
90
91#ifndef M_PI
92#define M_PI 3.14159265358979323846 /* pi */
93#endif
94
95#ifndef NULL
96#define NULL 0
97#endif
98
99#ifdef FIXED_POINT
100
101#define FREQ_SCALE 16384
102
103/*#define ANGLE2X(a) (32768*cos(((a)/8192.)))*/
104#define ANGLE2X(a) (SHL16(spx_cos(a),2))
105
106/*#define X2ANGLE(x) (acos(.00006103515625*(x))*LSP_SCALING)*/
107#define X2ANGLE(x) (spx_acos(x))
108
109#ifdef BFIN_ASM
110#include "lsp_bfin.h"
111#endif
112
113#else
114
115/*#define C1 0.99940307
116#define C2 -0.49558072
117#define C3 0.03679168*/
118
119#define FREQ_SCALE 1.
120#define ANGLE2X(a) (spx_cos(a))
121#define X2ANGLE(x) (acos(x))
122
123#endif
124
125
126/*---------------------------------------------------------------------------*\
127
128 FUNCTION....: cheb_poly_eva()
129
130 AUTHOR......: David Rowe
131 DATE CREATED: 24/2/93
132
133 This function evaluates a series of Chebyshev polynomials
134
135\*---------------------------------------------------------------------------*/
136
137#ifndef SPEEX_DISABLE_ENCODER
138
139#ifdef FIXED_POINT
140
141#ifndef OVERRIDE_CHEB_POLY_EVA
142static inline spx_word32_t cheb_poly_eva(
143 spx_word16_t *coef, /* P or Q coefs in Q13 format */
144 spx_word16_t x, /* cos of freq (-1.0 to 1.0) in Q14 format */
145 int m, /* LPC order/2 */
146 char *stack
147)
148{
149 int i;
150 spx_word16_t b0, b1;
151 spx_word32_t sum;
152
153 /*Prevents overflows*/
154 if (x>16383)
155 x = 16383;
156 if (x<-16383)
157 x = -16383;
158
159 /* Initialise values */
160 b1=16384;
161 b0=x;
162
163 /* Evaluate Chebyshev series formulation usin g iterative approach */
164 sum = ADD32(EXTEND32(coef[m]), EXTEND32(MULT16_16_P14(coef[m-1],x)));
165 for(i=2;i<=m;i++)
166 {
167 spx_word16_t tmp=b0;
168 b0 = SUB16(MULT16_16_Q13(x,b0), b1);
169 b1 = tmp;
170 sum = ADD32(sum, EXTEND32(MULT16_16_P14(coef[m-i],b0)));
171 }
172
173 return sum;
174}
175#endif
176
177#else
178
179static float cheb_poly_eva(spx_word32_t *coef, spx_word16_t x, int m, char *stack)
180{
181 int k;
182 float b0, b1, tmp;
183
184 /* Initial conditions */
185 b0=0; /* b_(m+1) */
186 b1=0; /* b_(m+2) */
187
188 x*=2;
189
190 /* Calculate the b_(k) */
191 for(k=m;k>0;k--)
192 {
193 tmp=b0; /* tmp holds the previous value of b0 */
194 b0=x*b0-b1+coef[m-k]; /* b0 holds its new value based on b0 and b1 */
195 b1=tmp; /* b1 holds the previous value of b0 */
196 }
197
198 return(-b1+.5*x*b0+coef[m]);
199}
200#endif
201
202/*---------------------------------------------------------------------------*\
203
204 FUNCTION....: lpc_to_lsp()
205
206 AUTHOR......: David Rowe
207 DATE CREATED: 24/2/93
208
209 This function converts LPC coefficients to LSP
210 coefficients.
211
212\*---------------------------------------------------------------------------*/
213
214#ifdef FIXED_POINT
215#define SIGN_CHANGE(a,b) (((a)&0x70000000)^((b)&0x70000000)||(b==0))
216#else
217#define SIGN_CHANGE(a,b) (((a)*(b))<0.0)
218#endif
219
220
221int lpc_to_lsp (spx_coef_t *a,int lpcrdr,spx_lsp_t *freq,int nb,spx_word16_t delta, char *stack)
222/* float *a lpc coefficients */
223/* int lpcrdr order of LPC coefficients (10) */
224/* float *freq LSP frequencies in the x domain */
225/* int nb number of sub-intervals (4) */
226/* float delta grid spacing interval (0.02) */
227
228
229{
230 spx_word16_t temp_xr,xl,xr,xm=0;
231 spx_word32_t psuml,psumr,psumm,temp_psumr/*,temp_qsumr*/;
232 int i,j,m,flag,k;
233 VARDECL(spx_word32_t *Q); /* ptrs for memory allocation */
234 VARDECL(spx_word32_t *P);
235 VARDECL(spx_word16_t *Q16); /* ptrs for memory allocation */
236 VARDECL(spx_word16_t *P16);
237 spx_word32_t *px; /* ptrs of respective P'(z) & Q'(z) */
238 spx_word32_t *qx;
239 spx_word32_t *p;
240 spx_word32_t *q;
241 spx_word16_t *pt; /* ptr used for cheb_poly_eval()
242 whether P' or Q' */
243 int roots=0; /* DR 8/2/94: number of roots found */
244 flag = 1; /* program is searching for a root when,
245 1 else has found one */
246 m = lpcrdr/2; /* order of P'(z) & Q'(z) polynomials */
247
248 /* Allocate memory space for polynomials */
249 ALLOC(Q, (m+1), spx_word32_t);
250 ALLOC(P, (m+1), spx_word32_t);
251
252 /* determine P'(z)'s and Q'(z)'s coefficients where
253 P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */
254
255 px = P; /* initialise ptrs */
256 qx = Q;
257 p = px;
258 q = qx;
259
260#ifdef FIXED_POINT
261 *px++ = LPC_SCALING;
262 *qx++ = LPC_SCALING;
263 for(i=0;i<m;i++){
264 *px++ = SUB32(ADD32(EXTEND32(a[i]),EXTEND32(a[lpcrdr-i-1])), *p++);
265 *qx++ = ADD32(SUB32(EXTEND32(a[i]),EXTEND32(a[lpcrdr-i-1])), *q++);
266 }
267 px = P;
268 qx = Q;
269 for(i=0;i<m;i++)
270 {
271 /*if (fabs(*px)>=32768)
272 speex_warning_int("px", *px);
273 if (fabs(*qx)>=32768)
274 speex_warning_int("qx", *qx);*/
275 *px = PSHR32(*px,2);
276 *qx = PSHR32(*qx,2);
277 px++;
278 qx++;
279 }
280 /* The reason for this lies in the way cheb_poly_eva() is implemented for fixed-point */
281 P[m] = PSHR32(P[m],3);
282 Q[m] = PSHR32(Q[m],3);
283#else
284 *px++ = LPC_SCALING;
285 *qx++ = LPC_SCALING;
286 for(i=0;i<m;i++){
287 *px++ = (a[i]+a[lpcrdr-1-i]) - *p++;
288 *qx++ = (a[i]-a[lpcrdr-1-i]) + *q++;
289 }
290 px = P;
291 qx = Q;
292 for(i=0;i<m;i++){
293 *px = 2**px;
294 *qx = 2**qx;
295 px++;
296 qx++;
297 }
298#endif
299
300 px = P; /* re-initialise ptrs */
301 qx = Q;
302
303 /* now that we have computed P and Q convert to 16 bits to
304 speed up cheb_poly_eval */
305
306 ALLOC(P16, m+1, spx_word16_t);
307 ALLOC(Q16, m+1, spx_word16_t);
308
309 for (i=0;i<m+1;i++)
310 {
311 P16[i] = P[i];
312 Q16[i] = Q[i];
313 }
314
315 /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z).
316 Keep alternating between the two polynomials as each zero is found */
317
318 xr = 0; /* initialise xr to zero */
319 xl = FREQ_SCALE; /* start at point xl = 1 */
320
321 for(j=0;j<lpcrdr;j++){
322 if(j&1) /* determines whether P' or Q' is eval. */
323 pt = Q16;
324 else
325 pt = P16;
326
327 psuml = cheb_poly_eva(pt,xl,m,stack); /* evals poly. at xl */
328 flag = 1;
329 while(flag && (xr >= -FREQ_SCALE)){
330 spx_word16_t dd;
331 /* Modified by JMV to provide smaller steps around x=+-1 */
332#ifdef FIXED_POINT
333 dd = MULT16_16_Q15(delta,SUB16(FREQ_SCALE, MULT16_16_Q14(MULT16_16_Q14(xl,xl),14000)));
334 if (psuml<512 && psuml>-512)
335 dd = PSHR16(dd,1);
336#else
337 dd=delta*(1-.9*xl*xl);
338 if (fabs(psuml)<.2)
339 dd *= .5;
340#endif
341 xr = SUB16(xl, dd); /* interval spacing */
342 psumr = cheb_poly_eva(pt,xr,m,stack);/* poly(xl-delta_x) */
343 temp_psumr = psumr;
344 temp_xr = xr;
345
346 /* if no sign change increment xr and re-evaluate poly(xr). Repeat til
347 sign change.
348 if a sign change has occurred the interval is bisected and then
349 checked again for a sign change which determines in which
350 interval the zero lies in.
351 If there is no sign change between poly(xm) and poly(xl) set interval
352 between xm and xr else set interval between xl and xr and repeat till
353 root is located within the specified limits */
354
355 if(SIGN_CHANGE(psumr,psuml))
356 {
357 roots++;
358
359 psumm=psuml;
360 for(k=0;k<=nb;k++){
361#ifdef FIXED_POINT
362 xm = ADD16(PSHR16(xl,1),PSHR16(xr,1)); /* bisect the interval */
363#else
364 xm = .5*(xl+xr); /* bisect the interval */
365#endif
366 psumm=cheb_poly_eva(pt,xm,m,stack);
367 /*if(psumm*psuml>0.)*/
368 if(!SIGN_CHANGE(psumm,psuml))
369 {
370 psuml=psumm;
371 xl=xm;
372 } else {
373 psumr=psumm;
374 xr=xm;
375 }
376 }
377
378 /* once zero is found, reset initial interval to xr */
379 freq[j] = X2ANGLE(xm);
380 xl = xm;
381 flag = 0; /* reset flag for next search */
382 }
383 else{
384 psuml=temp_psumr;
385 xl=temp_xr;
386 }
387 }
388 }
389 return(roots);
390}
391
392#endif /* SPEEX_DISABLE_ENCODER */
393
394/*---------------------------------------------------------------------------*\
395
396 FUNCTION....: lsp_to_lpc()
397
398 AUTHOR......: David Rowe
399 DATE CREATED: 24/2/93
400
401 Converts LSP coefficients to LPC coefficients.
402
403\*---------------------------------------------------------------------------*/
404
405#ifdef FIXED_POINT
406
407void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)
408/* float *freq array of LSP frequencies in the x domain */
409/* float *ak array of LPC coefficients */
410/* int lpcrdr order of LPC coefficients */
411{
412 (void)stack;
413 int i,j;
414 spx_word32_t xout1,xout2,xin;
415 spx_word32_t mult, a;
416 VARDECL(spx_word16_t *freqn);
417 VARDECL(spx_word32_t **xp);
418 VARDECL(spx_word32_t *xpmem);
419 VARDECL(spx_word32_t **xq);
420 VARDECL(spx_word32_t *xqmem);
421 int m = lpcrdr>>1;
422
423 /*
424
425 Reconstruct P(z) and Q(z) by cascading second order polynomials
426 in form 1 - 2cos(w)z(-1) + z(-2), where w is the LSP frequency.
427 In the time domain this is:
428
429 y(n) = x(n) - 2cos(w)x(n-1) + x(n-2)
430
431 This is what the ALLOCS below are trying to do:
432
433 int xp[m+1][lpcrdr+1+2]; // P matrix in QIMP
434 int xq[m+1][lpcrdr+1+2]; // Q matrix in QIMP
435
436 These matrices store the output of each stage on each row. The
437 final (m-th) row has the output of the final (m-th) cascaded
438 2nd order filter. The first row is the impulse input to the
439 system (not written as it is known).
440
441 The version below takes advantage of the fact that a lot of the
442 outputs are zero or known, for example if we put an inpulse
443 into the first section the "clock" it 10 times only the first 3
444 outputs samples are non-zero (it's an FIR filter).
445 */
446
447 ALLOC(xp, (m+1), spx_word32_t*);
448 ALLOC(xpmem, (m+1)*(lpcrdr+1+2), spx_word32_t);
449
450 ALLOC(xq, (m+1), spx_word32_t*);
451 ALLOC(xqmem, (m+1)*(lpcrdr+1+2), spx_word32_t);
452
453 for(i=0; i<=m; i++) {
454 xp[i] = xpmem + i*(lpcrdr+1+2);
455 xq[i] = xqmem + i*(lpcrdr+1+2);
456 }
457
458 /* work out 2cos terms in Q14 */
459
460 ALLOC(freqn, lpcrdr, spx_word16_t);
461 for (i=0;i<lpcrdr;i++)
462 freqn[i] = ANGLE2X(freq[i]);
463
464 #define QIMP 21 /* scaling for impulse */
465
466 xin = SHL32(EXTEND32(1), (QIMP-1)); /* 0.5 in QIMP format */
467
468 /* first col and last non-zero values of each row are trivial */
469
470 for(i=0;i<=m;i++) {
471 xp[i][1] = 0;
472 xp[i][2] = xin;
473 xp[i][2+2*i] = xin;
474 xq[i][1] = 0;
475 xq[i][2] = xin;
476 xq[i][2+2*i] = xin;
477 }
478
479 /* 2nd row (first output row) is trivial */
480
481 xp[1][3] = -MULT16_32_Q14(freqn[0],xp[0][2]);
482 xq[1][3] = -MULT16_32_Q14(freqn[1],xq[0][2]);
483
484 xout1 = xout2 = 0;
485
486 /* now generate remaining rows */
487
488 for(i=1;i<m;i++) {
489
490 for(j=1;j<2*(i+1)-1;j++) {
491 mult = MULT16_32_Q14(freqn[2*i],xp[i][j+1]);
492 xp[i+1][j+2] = ADD32(SUB32(xp[i][j+2], mult), xp[i][j]);
493 mult = MULT16_32_Q14(freqn[2*i+1],xq[i][j+1]);
494 xq[i+1][j+2] = ADD32(SUB32(xq[i][j+2], mult), xq[i][j]);
495 }
496
497 /* for last col xp[i][j+2] = xq[i][j+2] = 0 */
498
499 mult = MULT16_32_Q14(freqn[2*i],xp[i][j+1]);
500 xp[i+1][j+2] = SUB32(xp[i][j], mult);
501 mult = MULT16_32_Q14(freqn[2*i+1],xq[i][j+1]);
502 xq[i+1][j+2] = SUB32(xq[i][j], mult);
503 }
504
505 /* process last row to extra a{k} */
506
507 for(j=1;j<=lpcrdr;j++) {
508 int shift = QIMP-13;
509
510 /* final filter sections */
511 a = PSHR32(xp[m][j+2] + xout1 + xq[m][j+2] - xout2, shift);
512 xout1 = xp[m][j+2];
513 xout2 = xq[m][j+2];
514
515 /* hard limit ak's to +/- 32767 */
516
517 if (a < -32767) a = -32767;
518 if (a > 32767) a = 32767;
519 ak[j-1] = (short)a;
520
521 }
522
523}
524
525#else
526
527void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)
528/* float *freq array of LSP frequencies in the x domain */
529/* float *ak array of LPC coefficients */
530/* int lpcrdr order of LPC coefficients */
531
532
533{
534 int i,j;
535 float xout1,xout2,xin1,xin2;
536 VARDECL(float *Wp);
537 float *pw,*n1,*n2,*n3,*n4=NULL;
538 VARDECL(float *x_freq);
539 int m = lpcrdr>>1;
540
541 ALLOC(Wp, 4*m+2, float);
542 pw = Wp;
543
544 /* initialise contents of array */
545
546 for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */
547 *pw++ = 0.0;
548 }
549
550 /* Set pointers up */
551
552 pw = Wp;
553 xin1 = 1.0;
554 xin2 = 1.0;
555
556 ALLOC(x_freq, lpcrdr, float);
557 for (i=0;i<lpcrdr;i++)
558 x_freq[i] = ANGLE2X(freq[i]);
559
560 /* reconstruct P(z) and Q(z) by cascading second order
561 polynomials in form 1 - 2xz(-1) +z(-2), where x is the
562 LSP coefficient */
563
564 for(j=0;j<=lpcrdr;j++){
565 int i2=0;
566 for(i=0;i<m;i++,i2+=2){
567 n1 = pw+(i*4);
568 n2 = n1 + 1;
569 n3 = n2 + 1;
570 n4 = n3 + 1;
571 xout1 = xin1 - 2.f*x_freq[i2] * *n1 + *n2;
572 xout2 = xin2 - 2.f*x_freq[i2+1] * *n3 + *n4;
573 *n2 = *n1;
574 *n4 = *n3;
575 *n1 = xin1;
576 *n3 = xin2;
577 xin1 = xout1;
578 xin2 = xout2;
579 }
580 xout1 = xin1 + *(n4+1);
581 xout2 = xin2 - *(n4+2);
582 if (j>0)
583 ak[j-1] = (xout1 + xout2)*0.5f;
584 *(n4+1) = xin1;
585 *(n4+2) = xin2;
586
587 xin1 = 0.0;
588 xin2 = 0.0;
589 }
590
591}
592#endif
593
594
595#ifdef FIXED_POINT
596
597/*Makes sure the LSPs are stable*/
598void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin)
599{
600 int i;
601 spx_word16_t m = margin;
602 spx_word16_t m2 = 25736-margin;
603
604 if (lsp[0]<m)
605 lsp[0]=m;
606 if (lsp[len-1]>m2)
607 lsp[len-1]=m2;
608 for (i=1;i<len-1;i++)
609 {
610 if (lsp[i]<lsp[i-1]+m)
611 lsp[i]=lsp[i-1]+m;
612
613 if (lsp[i]>lsp[i+1]-m)
614 lsp[i]= SHR16(lsp[i],1) + SHR16(lsp[i+1]-m,1);
615 }
616}
617
618
619void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes)
620{
621 int i;
622 spx_word16_t tmp = DIV32_16(SHL32(EXTEND32(1 + subframe),14),nb_subframes);
623 spx_word16_t tmp2 = 16384-tmp;
624 for (i=0;i<len;i++)
625 {
626 interp_lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]);
627 }
628}
629
630#else
631
632/*Makes sure the LSPs are stable*/
633void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin)
634{
635 int i;
636 if (lsp[0]<LSP_SCALING*margin)
637 lsp[0]=LSP_SCALING*margin;
638 if (lsp[len-1]>LSP_SCALING*(M_PI-margin))
639 lsp[len-1]=LSP_SCALING*(M_PI-margin);
640 for (i=1;i<len-1;i++)
641 {
642 if (lsp[i]<lsp[i-1]+LSP_SCALING*margin)
643 lsp[i]=lsp[i-1]+LSP_SCALING*margin;
644
645 if (lsp[i]>lsp[i+1]-LSP_SCALING*margin)
646 lsp[i]= .5f* (lsp[i] + lsp[i+1]-LSP_SCALING*margin);
647 }
648}
649
650
651void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes)
652{
653 int i;
654 float tmp = (1.0f + subframe)/nb_subframes;
655 for (i=0;i<len;i++)
656 {
657 interp_lsp[i] = (1-tmp)*old_lsp[i] + tmp*new_lsp[i];
658 }
659}
660
661#endif
diff --git a/lib/rbcodec/codecs/libspeex/lsp.h b/lib/rbcodec/codecs/libspeex/lsp.h
new file mode 100644
index 0000000000..c53e7769d3
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/lsp.h
@@ -0,0 +1,64 @@
1/*---------------------------------------------------------------------------*\
2Original Copyright
3 FILE........: AK2LSPD.H
4 TYPE........: Turbo C header file
5 COMPANY.....: Voicetronix
6 AUTHOR......: James Whitehall
7 DATE CREATED: 21/11/95
8
9Modified by Jean-Marc Valin
10
11 This file contains functions for converting Linear Prediction
12 Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the
13 LSP coefficients are not in radians format but in the x domain of the
14 unit circle.
15
16\*---------------------------------------------------------------------------*/
17/**
18 @file lsp.h
19 @brief Line Spectral Pair (LSP) functions.
20*/
21/* Speex License:
22
23 Redistribution and use in source and binary forms, with or without
24 modification, are permitted provided that the following conditions
25 are met:
26
27 - Redistributions of source code must retain the above copyright
28 notice, this list of conditions and the following disclaimer.
29
30 - Redistributions in binary form must reproduce the above copyright
31 notice, this list of conditions and the following disclaimer in the
32 documentation and/or other materials provided with the distribution.
33
34 - Neither the name of the Xiph.org Foundation nor the names of its
35 contributors may be used to endorse or promote products derived from
36 this software without specific prior written permission.
37
38 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
39 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
40 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
41 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
42 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
43 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
44 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
45 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
46 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
47 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49*/
50
51#ifndef __AK2LSPD__
52#define __AK2LSPD__
53
54#include "arch.h"
55
56int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack);
57void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack);
58
59/*Added by JMV*/
60void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin);
61
62void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes);
63
64#endif /* __AK2LSPD__ */
diff --git a/lib/rbcodec/codecs/libspeex/lsp_bfin.h b/lib/rbcodec/codecs/libspeex/lsp_bfin.h
new file mode 100644
index 0000000000..20e505287e
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/lsp_bfin.h
@@ -0,0 +1,89 @@
1/* Copyright (C) 2006 David Rowe */
2/**
3 @file lsp_bfin.h
4 @author David Rowe
5 @brief LSP routines optimised for the Blackfin
6*/
7/*
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 - Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 - Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19 - Neither the name of the Xiph.org Foundation nor the names of its
20 contributors may be used to endorse or promote products derived from
21 this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#define OVERRIDE_CHEB_POLY_EVA
37#ifdef OVERRIDE_CHEB_POLY_EVA
38static inline spx_word32_t cheb_poly_eva(
39 spx_word16_t *coef, /* P or Q coefs in Q13 format */
40 spx_word16_t x, /* cos of freq (-1.0 to 1.0) in Q14 format */
41 int m, /* LPC order/2 */
42 char *stack
43)
44{
45 spx_word32_t sum;
46
47 __asm__ __volatile__
48 (
49 "P0 = %2;\n\t" /* P0: coef[m], coef[m-1],..., coef[0] */
50 "R4 = 8192;\n\t" /* R4: rounding constant */
51 "R2 = %1;\n\t" /* R2: x */
52
53 "R5 = -16383;\n\t"
54 "R2 = MAX(R2,R5);\n\t"
55 "R5 = 16383;\n\t"
56 "R2 = MIN(R2,R5);\n\t"
57
58 "R3 = W[P0--] (X);\n\t" /* R3: sum */
59 "R5 = W[P0--] (X);\n\t"
60 "R5 = R5.L * R2.L (IS);\n\t"
61 "R5 = R5 + R4;\n\t"
62 "R5 >>>= 14;\n\t"
63 "R3 = R3 + R5;\n\t"
64
65 "R0 = R2;\n\t" /* R0: b0 */
66 "R1 = 16384;\n\t" /* R1: b1 */
67 "LOOP cpe%= LC0 = %3;\n\t"
68 "LOOP_BEGIN cpe%=;\n\t"
69 "P1 = R0;\n\t"
70 "R0 = R2.L * R0.L (IS) || R5 = W[P0--] (X);\n\t"
71 "R0 >>>= 13;\n\t"
72 "R0 = R0 - R1;\n\t"
73 "R1 = P1;\n\t"
74 "R5 = R5.L * R0.L (IS);\n\t"
75 "R5 = R5 + R4;\n\t"
76 "R5 >>>= 14;\n\t"
77 "R3 = R3 + R5;\n\t"
78 "LOOP_END cpe%=;\n\t"
79 "%0 = R3;\n\t"
80 : "=&d" (sum)
81 : "a" (x), "a" (&coef[m]), "a" (m-1)
82 : "R0", "R1", "R3", "R2", "R4", "R5", "P0", "P1"
83 );
84 return sum;
85}
86#endif
87
88
89
diff --git a/lib/rbcodec/codecs/libspeex/lsp_tables_nb.c b/lib/rbcodec/codecs/libspeex/lsp_tables_nb.c
new file mode 100644
index 0000000000..6bdd2e4d0f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/lsp_tables_nb.c
@@ -0,0 +1,362 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: lsp_tables_nb.c
3 Codebooks for LSPs in narrowband CELP mode
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 3. The name of the author may not be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#include "config-speex.h"
33
34const signed char cdbk_nb[640] LSP_ICONST_ATTR = {
3530,19,38,34,40,32,46,43,58,43,
365,-18,-25,-40,-33,-55,-52,20,34,28,
37-20,-63,-97,-92,61,53,47,49,53,75,
38-14,-53,-77,-79,0,-3,-5,19,22,26,
39-9,-53,-55,66,90,72,85,68,74,52,
40-4,-41,-58,-31,-18,-31,27,32,30,18,
4124,3,8,5,-12,-3,26,28,74,63,
42-2,-39,-67,-77,-106,-74,59,59,73,65,
4344,40,71,72,82,83,98,88,89,60,
44-6,-31,-47,-48,-13,-39,-9,7,2,79,
45-1,-39,-60,-17,87,81,65,50,45,19,
46-21,-67,-91,-87,-41,-50,7,18,39,74,
4710,-31,-28,39,24,13,23,5,56,45,
4829,10,-5,-13,-11,-35,-18,-8,-10,-8,
49-25,-71,-77,-21,2,16,50,63,87,87,
505,-32,-40,-51,-68,0,12,6,54,34,
515,-12,32,52,68,64,69,59,65,45,
5214,-16,-31,-40,-65,-67,41,49,47,37,
53-11,-52,-75,-84,-4,57,48,42,42,33,
54-11,-51,-68,-6,13,0,8,-8,26,32,
55-23,-53,0,36,56,76,97,105,111,97,
56-1,-28,-39,-40,-43,-54,-44,-40,-18,35,
5716,-20,-19,-28,-42,29,47,38,74,45,
583,-29,-48,-62,-80,-104,-33,56,59,59,
5910,17,46,72,84,101,117,123,123,106,
60-7,-33,-49,-51,-70,-67,-27,-31,70,67,
61-16,-62,-85,-20,82,71,86,80,85,74,
62-19,-58,-75,-45,-29,-33,-18,-25,45,57,
63-12,-42,-5,12,28,36,52,64,81,82,
6413,-9,-27,-28,22,3,2,22,26,6,
65-6,-44,-51,2,15,10,48,43,49,34,
66-19,-62,-84,-89,-102,-24,8,17,61,68,
6739,24,23,19,16,-5,12,15,27,15,
68-8,-44,-49,-60,-18,-32,-28,52,54,62,
69-8,-48,-77,-70,66,101,83,63,61,37,
70-12,-50,-75,-64,33,17,13,25,15,77,
711,-42,-29,72,64,46,49,31,61,44,
72-8,-47,-54,-46,-30,19,20,-1,-16,0,
7316,-12,-18,-9,-26,-27,-10,-22,53,45,
74-10,-47,-75,-82,-105,-109,8,25,49,77,
7550,65,114,117,124,118,115,96,90,61,
76-9,-45,-63,-60,-75,-57,8,11,20,29,
770,-35,-49,-43,40,47,35,40,55,38,
78-24,-76,-103,-112,-27,3,23,34,52,75,
798,-29,-43,12,63,38,35,29,24,8,
8025,11,1,-15,-18,-43,-7,37,40,21,
81-20,-56,-19,-19,-4,-2,11,29,51,63,
82-2,-44,-62,-75,-89,30,57,51,74,51,
8350,46,68,64,65,52,63,55,65,43,
8418,-9,-26,-35,-55,-69,3,6,8,17,
85-15,-61,-86,-97,1,86,93,74,78,67,
86-1,-38,-66,-48,48,39,29,25,17,-1,
8713,13,29,39,50,51,69,82,97,98,
88-2,-36,-46,-27,-16,-30,-13,-4,-7,-4,
8925,-5,-11,-6,-25,-21,33,12,31,29,
90-8,-38,-52,-63,-68,-89,-33,-1,10,74,
91-2,-15,59,91,105,105,101,87,84,62,
92-7,-33,-50,-35,-54,-47,25,17,82,81,
93-13,-56,-83,21,58,31,42,25,72,65,
94-24,-66,-91,-56,9,-2,21,10,69,75,
952,-24,11,22,25,28,38,34,48,33,
967,-29,-26,17,15,-1,14,0,-2,0,
97-6,-41,-67,6,-2,-9,19,2,85,74,
98-22,-67,-84,-71,-50,3,11,-9,2,62};
99
100const signed char cdbk_nb_low1[320] LSP_ICONST_ATTR = {
101-34,-52,-15,45,2,
10223,21,52,24,-33,
103-9,-1,9,-44,-41,
104-13,-17,44,22,-17,
105-6,-4,-1,22,38,
10626,16,2,50,27,
107-35,-34,-9,-41,6,
1080,-16,-34,51,8,
109-14,-31,-49,15,-33,
11045,49,33,-11,-37,
111-62,-54,45,11,-5,
112-72,11,-1,-12,-11,
11324,27,-11,-43,46,
11443,33,-12,-9,-1,
1151,-4,-23,-57,-71,
11611,8,16,17,-8,
117-20,-31,-41,53,48,
118-16,3,65,-24,-8,
119-23,-32,-37,-32,-49,
120-10,-17,6,38,5,
121-9,-17,-46,8,52,
1223,6,45,40,39,
123-7,-6,-34,-74,31,
1248,1,-16,43,68,
125-11,-19,-31,4,6,
1260,-6,-17,-16,-38,
127-16,-30,2,9,-39,
128-16,-1,43,-10,48,
1293,3,-16,-31,-3,
13062,68,43,13,3,
131-10,8,20,-56,12,
13212,-2,-18,22,-15,
133-40,-36,1,7,41,
1340,1,46,-6,-62,
135-4,-12,-2,-11,-83,
136-13,-2,91,33,-10,
1370,4,-11,-16,79,
13832,37,14,9,51,
139-21,-28,-56,-34,0,
14021,9,-26,11,28,
141-42,-54,-23,-2,-15,
14231,30,8,-39,-66,
143-39,-36,31,-28,-40,
144-46,35,40,22,24,
14533,48,23,-34,14,
14640,32,17,27,-3,
14725,26,-13,-61,-17,
14811,4,31,60,-6,
149-26,-41,-64,13,16,
150-26,54,31,-11,-23,
151-9,-11,-34,-71,-21,
152-34,-35,55,50,29,
153-22,-27,-50,-38,57,
15433,42,57,48,26,
15511,0,-49,-31,26,
156-4,-14,5,78,37,
15717,0,-49,-12,-23,
15826,14,2,2,-43,
159-17,-12,10,-8,-4,
1608,18,12,-6,20,
161-12,-6,-13,-25,34,
16215,40,49,7,8,
16313,20,20,-19,-22,
164-2,-8,2,51,-51};
165
166const signed char cdbk_nb_low2[320] LSP_ICONST_ATTR = {
167-6,53,-21,-24,4,
16826,17,-4,-37,25,
16917,-36,-13,31,3,
170-6,27,15,-10,31,
17128,26,-10,-10,-40,
17216,-7,15,13,41,
173-9,0,-4,50,-6,
174-7,14,38,22,0,
175-48,2,1,-13,-19,
17632,-3,-60,11,-17,
177-1,-24,-34,-1,35,
178-5,-27,28,44,13,
17925,15,42,-11,15,
18051,35,-36,20,8,
181-4,-12,-29,19,-47,
18249,-15,-4,16,-29,
183-39,14,-30,4,25,
184-9,-5,-51,-14,-3,
185-40,-32,38,5,-9,
186-8,-4,-1,-22,71,
187-3,14,26,-18,-22,
18824,-41,-25,-24,6,
18923,19,-10,39,-26,
190-27,65,45,2,-7,
191-26,-8,22,-12,16,
19215,16,-35,-5,33,
193-21,-8,0,23,33,
19434,6,21,36,6,
195-7,-22,8,-37,-14,
19631,38,11,-4,-3,
197-39,-32,-8,32,-23,
198-6,-12,16,20,-28,
199-4,23,13,-52,-1,
20022,6,-33,-40,-6,
2014,-62,13,5,-26,
20235,39,11,2,57,
203-11,9,-20,-28,-33,
20452,-5,-6,-2,22,
205-14,-16,-48,35,1,
206-58,20,13,33,-1,
207-74,56,-18,-22,-31,
20812,6,-14,4,-2,
209-9,-47,10,-3,29,
210-17,-5,61,14,47,
211-12,2,72,-39,-17,
21292,64,-53,-51,-15,
213-30,-38,-41,-29,-28,
21427,9,36,9,-35,
215-42,81,-21,20,25,
216-16,-5,-17,-35,21,
21715,-28,48,2,-2,
2189,-19,29,-40,30,
219-18,-18,18,-16,-57,
22015,-20,-12,-15,-37,
221-15,33,-39,21,-22,
222-13,35,11,13,-38,
223-63,29,23,-27,32,
22418,3,-26,42,33,
225-64,-66,-17,16,56,
2262,36,3,31,21,
227-41,-39,8,-57,14,
22837,-2,19,-36,-19,
229-23,-29,-16,1,-3,
230-8,-10,31,64,-65};
231
232const signed char cdbk_nb_high1[320] LSP_ICONST_ATTR = {
233-26,-8,29,21,4,
23419,-39,33,-7,-36,
23556,54,48,40,29,
236-4,-24,-42,-66,-43,
237-60,19,-2,37,41,
238-10,-37,-60,-64,18,
239-22,77,73,40,25,
2404,19,-19,-66,-2,
24111,5,21,14,26,
242-25,-86,-4,18,1,
24326,-37,10,37,-1,
24424,-12,-59,-11,20,
245-6,34,-16,-16,42,
24619,-28,-51,53,32,
2474,10,62,21,-12,
248-34,27,4,-48,-48,
249-50,-49,31,-7,-21,
250-42,-25,-4,-43,-22,
25159,2,27,12,-9,
252-6,-16,-8,-32,-58,
253-16,-29,-5,41,23,
254-30,-33,-46,-13,-10,
255-38,52,52,1,-17,
256-9,10,26,-25,-6,
25733,-20,53,55,25,
258-32,-5,-42,23,21,
25966,5,-28,20,9,
26075,29,-7,-42,-39,
26115,3,-23,21,6,
26211,1,-29,14,63,
26310,54,26,-24,-51,
264-49,7,-23,-51,15,
265-66,1,60,25,10,
2660,-30,-4,-15,17,
26719,59,40,4,-5,
26833,6,-22,-58,-70,
269-5,23,-6,60,44,
270-29,-16,-47,-29,52,
271-19,50,28,16,35,
27231,36,0,-21,6,
27321,27,22,42,7,
274-66,-40,-8,7,19,
27546,0,-4,60,36,
27645,-7,-29,-6,-32,
277-39,2,6,-9,33,
27820,-51,-34,18,-6,
27919,6,11,5,-19,
280-29,-2,42,-11,-45,
281-21,-55,57,37,2,
282-14,-67,-16,-27,-38,
28369,48,19,2,-17,
28420,-20,-16,-34,-17,
285-25,-61,10,73,45,
28616,-40,-64,-17,-29,
287-22,56,17,-39,8,
288-11,8,-25,-18,-13,
289-19,8,54,57,36,
290-17,-26,-4,6,-21,
29140,42,-4,20,31,
29253,10,-34,-53,31,
293-17,35,0,15,-6,
294-20,-63,-73,22,25,
29529,17,8,-29,-39,
296-69,18,15,-15,-5};
297
298const signed char cdbk_nb_high2[320] LSP_ICONST_ATTR = {
29911,47,16,-9,-46,
300-32,26,-64,34,-5,
30138,-7,47,20,2,
302-73,-99,-3,-45,20,
30370,-52,15,-6,-7,
304-82,31,21,47,51,
30539,-3,9,0,-41,
306-7,-15,-54,2,0,
30727,-31,9,-45,-22,
308-38,-24,-24,8,-33,
30923,5,50,-36,-17,
310-18,-51,-2,13,19,
31143,12,-15,-12,61,
31238,38,7,13,0,
3136,-1,3,62,9,
31427,22,-33,38,-35,
315-9,30,-43,-9,-32,
316-1,4,-4,1,-5,
317-11,-8,38,31,11,
318-10,-42,-21,-37,1,
31943,15,-13,-35,-19,
320-18,15,23,-26,59,
3211,-21,53,8,-41,
322-50,-14,-28,4,21,
32325,-28,-40,5,-40,
324-41,4,51,-33,-8,
325-8,1,17,-60,12,
32625,-41,17,34,43,
32719,45,7,-37,24,
328-15,56,-2,35,-10,
32948,4,-47,-2,5,
330-5,-54,5,-3,-33,
331-10,30,-2,-44,-24,
332-38,9,-9,42,4,
3336,-56,44,-16,9,
334-40,-26,18,-20,10,
33528,-41,-21,-4,13,
336-18,32,-30,-3,37,
33715,22,28,50,-40,
3383,-29,-64,7,51,
339-19,-11,17,-27,-40,
340-64,24,-12,-7,-27,
3413,37,48,-1,2,
342-9,-38,-34,46,1,
34327,-6,19,-13,26,
34410,34,20,25,40,
34550,-6,-7,30,9,
346-24,0,-23,71,-61,
34722,58,-34,-4,2,
348-49,-33,25,30,-8,
349-6,-16,77,2,38,
350-8,-35,-6,-30,56,
35178,31,33,-20,13,
352-39,20,22,4,21,
353-8,4,-6,10,-83,
354-41,9,-25,-43,15,
355-7,-12,-34,-39,-37,
356-33,19,30,16,-33,
35742,-25,25,-68,44,
358-15,-11,-4,23,50,
35914,4,-39,-43,20,
360-30,60,9,-20,7,
36116,19,-33,37,29,
36216,-35,7,38,-27};
diff --git a/lib/rbcodec/codecs/libspeex/ltp.c b/lib/rbcodec/codecs/libspeex/ltp.c
new file mode 100644
index 0000000000..9f10bc09d8
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/ltp.c
@@ -0,0 +1,856 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin
2 File: ltp.c
3 Long-Term Prediction functions
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#ifdef HAVE_CONFIG_H
34#include "config-speex.h"
35#endif
36
37#include <math.h>
38#include "ltp.h"
39#include "stack_alloc.h"
40#include "filters.h"
41#include "speex/speex_bits.h"
42#include "math_approx.h"
43#include "os_support.h"
44
45#ifndef NULL
46#define NULL 0
47#endif
48
49
50#ifdef _USE_SSE
51#include "ltp_sse.h"
52#elif defined (ARM4_ASM) || defined(ARM5E_ASM)
53#include "ltp_arm4.h"
54#elif defined (COLDFIRE_ASM)
55#define OVERRIDE_INNER_PROD
56#elif defined (BFIN_ASM)
57#include "ltp_bfin.h"
58#endif
59
60#ifndef OVERRIDE_INNER_PROD
61spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
62{
63 spx_word32_t sum=0;
64 len >>= 2;
65 while(len--)
66 {
67 spx_word32_t part=0;
68 part = MAC16_16(part,*x++,*y++);
69 part = MAC16_16(part,*x++,*y++);
70 part = MAC16_16(part,*x++,*y++);
71 part = MAC16_16(part,*x++,*y++);
72 /* HINT: If you had a 40-bit accumulator, you could shift only at the end */
73 sum = ADD32(sum,SHR32(part,6));
74 }
75 return sum;
76}
77#endif
78
79#ifndef SPEEX_DISABLE_ENCODER
80#ifndef OVERRIDE_PITCH_XCORR
81#if 0 /* HINT: Enable this for machines with enough registers (i.e. not x86) */
82void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
83{
84 int i,j;
85 for (i=0;i<nb_pitch;i+=4)
86 {
87 /* Compute correlation*/
88 /*corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);*/
89 spx_word32_t sum1=0;
90 spx_word32_t sum2=0;
91 spx_word32_t sum3=0;
92 spx_word32_t sum4=0;
93 const spx_word16_t *y = _y+i;
94 const spx_word16_t *x = _x;
95 spx_word16_t y0, y1, y2, y3;
96 /*y0=y[0];y1=y[1];y2=y[2];y3=y[3];*/
97 y0=*y++;
98 y1=*y++;
99 y2=*y++;
100 y3=*y++;
101 for (j=0;j<len;j+=4)
102 {
103 spx_word32_t part1;
104 spx_word32_t part2;
105 spx_word32_t part3;
106 spx_word32_t part4;
107 part1 = MULT16_16(*x,y0);
108 part2 = MULT16_16(*x,y1);
109 part3 = MULT16_16(*x,y2);
110 part4 = MULT16_16(*x,y3);
111 x++;
112 y0=*y++;
113 part1 = MAC16_16(part1,*x,y1);
114 part2 = MAC16_16(part2,*x,y2);
115 part3 = MAC16_16(part3,*x,y3);
116 part4 = MAC16_16(part4,*x,y0);
117 x++;
118 y1=*y++;
119 part1 = MAC16_16(part1,*x,y2);
120 part2 = MAC16_16(part2,*x,y3);
121 part3 = MAC16_16(part3,*x,y0);
122 part4 = MAC16_16(part4,*x,y1);
123 x++;
124 y2=*y++;
125 part1 = MAC16_16(part1,*x,y3);
126 part2 = MAC16_16(part2,*x,y0);
127 part3 = MAC16_16(part3,*x,y1);
128 part4 = MAC16_16(part4,*x,y2);
129 x++;
130 y3=*y++;
131
132 sum1 = ADD32(sum1,SHR32(part1,6));
133 sum2 = ADD32(sum2,SHR32(part2,6));
134 sum3 = ADD32(sum3,SHR32(part3,6));
135 sum4 = ADD32(sum4,SHR32(part4,6));
136 }
137 corr[nb_pitch-1-i]=sum1;
138 corr[nb_pitch-2-i]=sum2;
139 corr[nb_pitch-3-i]=sum3;
140 corr[nb_pitch-4-i]=sum4;
141 }
142
143}
144#else
145void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
146{
147 int i;
148 for (i=0;i<nb_pitch;i++)
149 {
150 /* Compute correlation*/
151 corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len);
152 }
153
154}
155#endif
156#endif
157
158#ifndef OVERRIDE_COMPUTE_PITCH_ERROR
159static inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control)
160{
161 spx_word32_t sum = 0;
162 sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0]));
163 sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1]));
164 sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2]));
165 sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3]));
166 sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4]));
167 sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5]));
168 sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6]));
169 sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7]));
170 sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8]));
171 return sum;
172}
173#endif
174
175#ifndef OVERRIDE_OPEN_LOOP_NBEST_PITCH
176void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)
177{
178 int i,j,k;
179 VARDECL(spx_word32_t *best_score);
180 VARDECL(spx_word32_t *best_ener);
181 spx_word32_t e0;
182 VARDECL(spx_word32_t *corr);
183#ifdef FIXED_POINT
184 /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16)
185 arrays for (normalized) 16-bit values */
186 VARDECL(spx_word16_t *corr16);
187 VARDECL(spx_word16_t *ener16);
188 spx_word32_t *energy;
189 int cshift=0, eshift=0;
190 int scaledown = 0;
191 ALLOC(corr16, end-start+1, spx_word16_t);
192 ALLOC(ener16, end-start+1, spx_word16_t);
193 ALLOC(corr, end-start+1, spx_word32_t);
194 energy = corr;
195#else
196 /* In floating-point, we need to float arrays and no normalized copies */
197 VARDECL(spx_word32_t *energy);
198 spx_word16_t *corr16;
199 spx_word16_t *ener16;
200 ALLOC(energy, end-start+2, spx_word32_t);
201 ALLOC(corr, end-start+1, spx_word32_t);
202 corr16 = corr;
203 ener16 = energy;
204#endif
205
206 ALLOC(best_score, N, spx_word32_t);
207 ALLOC(best_ener, N, spx_word32_t);
208 for (i=0;i<N;i++)
209 {
210 best_score[i]=-1;
211 best_ener[i]=0;
212 pitch[i]=start;
213 }
214
215#ifdef FIXED_POINT
216 for (i=-end;i<len;i++)
217 {
218 if (ABS16(sw[i])>16383)
219 {
220 scaledown=1;
221 break;
222 }
223 }
224 /* If the weighted input is close to saturation, then we scale it down */
225 if (scaledown)
226 {
227 for (i=-end;i<len;i++)
228 {
229 sw[i]=SHR16(sw[i],1);
230 }
231 }
232#endif
233 energy[0]=inner_prod(sw-start, sw-start, len);
234 e0=inner_prod(sw, sw, len);
235 for (i=start;i<end;i++)
236 {
237 /* Update energy for next pitch*/
238 energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(sw[-i-1],sw[-i-1]),6)), SHR32(MULT16_16(sw[-i+len-1],sw[-i+len-1]),6));
239 if (energy[i-start+1] < 0)
240 energy[i-start+1] = 0;
241 }
242
243#ifdef FIXED_POINT
244 eshift = normalize16(energy, ener16, 32766, end-start+1);
245#endif
246
247 /* In fixed-point, this actually overrites the energy array (aliased to corr) */
248 pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);
249
250#ifdef FIXED_POINT
251 /* Normalize to 180 so we can square it and it still fits in 16 bits */
252 cshift = normalize16(corr, corr16, 180, end-start+1);
253 /* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */
254 if (scaledown)
255 {
256 for (i=-end;i<len;i++)
257 {
258 sw[i]=SHL16(sw[i],1);
259 }
260 }
261#endif
262
263 /* Search for the best pitch prediction gain */
264 for (i=start;i<=end;i++)
265 {
266 spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);
267 /* Instead of dividing the tmp by the energy, we multiply on the other side */
268 if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
269 {
270 /* We can safely put it last and then check */
271 best_score[N-1]=tmp;
272 best_ener[N-1]=ener16[i-start]+1;
273 pitch[N-1]=i;
274 /* Check if it comes in front of others */
275 for (j=0;j<N-1;j++)
276 {
277 if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
278 {
279 for (k=N-1;k>j;k--)
280 {
281 best_score[k]=best_score[k-1];
282 best_ener[k]=best_ener[k-1];
283 pitch[k]=pitch[k-1];
284 }
285 best_score[j]=tmp;
286 best_ener[j]=ener16[i-start]+1;
287 pitch[j]=i;
288 break;
289 }
290 }
291 }
292 }
293
294 /* Compute open-loop gain if necessary */
295 if (gain)
296 {
297 for (j=0;j<N;j++)
298 {
299 spx_word16_t g;
300 i=pitch[j];
301 g = DIV32(SHL32(EXTEND32(corr16[i-start]),cshift), 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(SHL32(EXTEND32(ener16[i-start]),eshift))),6));
302 /* FIXME: g = max(g,corr/energy) */
303 if (g<0)
304 g = 0;
305 gain[j]=g;
306 }
307 }
308
309
310}
311#endif
312
313#ifndef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ
314static int pitch_gain_search_3tap_vq(
315 const signed char *gain_cdbk,
316 int gain_cdbk_size,
317 spx_word16_t *C16,
318 spx_word16_t max_gain
319)
320{
321 const signed char *ptr=gain_cdbk;
322 int best_cdbk=0;
323 spx_word32_t best_sum=-VERY_LARGE32;
324 spx_word32_t sum=0;
325 spx_word16_t g[3];
326 spx_word16_t pitch_control=64;
327 spx_word16_t gain_sum;
328 int i;
329
330 for (i=0;i<gain_cdbk_size;i++) {
331
332 ptr = gain_cdbk+4*i;
333 g[0]=ADD16((spx_word16_t)ptr[0],32);
334 g[1]=ADD16((spx_word16_t)ptr[1],32);
335 g[2]=ADD16((spx_word16_t)ptr[2],32);
336 gain_sum = (spx_word16_t)ptr[3];
337
338 sum = compute_pitch_error(C16, g, pitch_control);
339
340 if (sum>best_sum && gain_sum<=max_gain) {
341 best_sum=sum;
342 best_cdbk=i;
343 }
344 }
345
346 return best_cdbk;
347}
348#endif
349
350/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
351static spx_word32_t pitch_gain_search_3tap(
352const spx_word16_t target[], /* Target vector */
353const spx_coef_t ak[], /* LPCs for this subframe */
354const spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
355const spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
356spx_sig_t exc[], /* Excitation */
357const signed char *gain_cdbk,
358int gain_cdbk_size,
359int pitch, /* Pitch value */
360int p, /* Number of LPC coeffs */
361int nsf, /* Number of samples in subframe */
362SpeexBits *bits,
363char *stack,
364const spx_word16_t *exc2,
365const spx_word16_t *r,
366spx_word16_t *new_target,
367int *cdbk_index,
368int plc_tuning,
369spx_word32_t cumul_gain,
370int scaledown
371)
372{
373 int i,j;
374 VARDECL(spx_word16_t *tmp1);
375 VARDECL(spx_word16_t *e);
376 spx_word16_t *x[3];
377 spx_word32_t corr[3];
378 spx_word32_t A[3][3];
379 spx_word16_t gain[3];
380 spx_word32_t err;
381 spx_word16_t max_gain=128;
382 int best_cdbk=0;
383
384 ALLOC(tmp1, 3*nsf, spx_word16_t);
385 ALLOC(e, nsf, spx_word16_t);
386
387 if (cumul_gain > 262144)
388 max_gain = 31;
389
390 x[0]=tmp1;
391 x[1]=tmp1+nsf;
392 x[2]=tmp1+2*nsf;
393
394 for (j=0;j<nsf;j++)
395 new_target[j] = target[j];
396
397 {
398 VARDECL(spx_mem_t *mm);
399 int pp=pitch-1;
400 ALLOC(mm, p, spx_mem_t);
401 for (j=0;j<nsf;j++)
402 {
403 if (j-pp<0)
404 e[j]=exc2[j-pp];
405 else if (j-pp-pitch<0)
406 e[j]=exc2[j-pp-pitch];
407 else
408 e[j]=0;
409 }
410#ifdef FIXED_POINT
411 /* Scale target and excitation down if needed (avoiding overflow) */
412 if (scaledown)
413 {
414 for (j=0;j<nsf;j++)
415 e[j] = SHR16(e[j],1);
416 for (j=0;j<nsf;j++)
417 new_target[j] = SHR16(new_target[j],1);
418 }
419#endif
420 for (j=0;j<p;j++)
421 mm[j] = 0;
422 iir_mem16(e, ak, e, nsf, p, mm, stack);
423 for (j=0;j<p;j++)
424 mm[j] = 0;
425 filter_mem16(e, awk1, awk2, e, nsf, p, mm, stack);
426 for (j=0;j<nsf;j++)
427 x[2][j] = e[j];
428 }
429 for (i=1;i>=0;i--)
430 {
431 spx_word16_t e0=exc2[-pitch-1+i];
432#ifdef FIXED_POINT
433 /* Scale excitation down if needed (avoiding overflow) */
434 if (scaledown)
435 e0 = SHR16(e0,1);
436#endif
437 x[i][0]=MULT16_16_Q14(r[0], e0);
438 for (j=0;j<nsf-1;j++)
439 x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));
440 }
441
442 for (i=0;i<3;i++)
443 corr[i]=inner_prod(x[i],new_target,nsf);
444 for (i=0;i<3;i++)
445 for (j=0;j<=i;j++)
446 A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
447
448 {
449 spx_word32_t C[9];
450#ifdef FIXED_POINT
451 spx_word16_t C16[9];
452#else
453 spx_word16_t *C16=C;
454#endif
455 C[0]=corr[2];
456 C[1]=corr[1];
457 C[2]=corr[0];
458 C[3]=A[1][2];
459 C[4]=A[0][1];
460 C[5]=A[0][2];
461 C[6]=A[2][2];
462 C[7]=A[1][1];
463 C[8]=A[0][0];
464
465 /*plc_tuning *= 2;*/
466 if (plc_tuning<2)
467 plc_tuning=2;
468 if (plc_tuning>30)
469 plc_tuning=30;
470#ifdef FIXED_POINT
471 C[0] = SHL32(C[0],1);
472 C[1] = SHL32(C[1],1);
473 C[2] = SHL32(C[2],1);
474 C[3] = SHL32(C[3],1);
475 C[4] = SHL32(C[4],1);
476 C[5] = SHL32(C[5],1);
477 C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]);
478 C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]);
479 C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]);
480 normalize16(C, C16, 32767, 9);
481#else
482 C[6]*=.5*(1+.02*plc_tuning);
483 C[7]*=.5*(1+.02*plc_tuning);
484 C[8]*=.5*(1+.02*plc_tuning);
485#endif
486
487 best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain);
488
489#ifdef FIXED_POINT
490 gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]);
491 gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]);
492 gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+2]);
493 /*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/
494#else
495 gain[0] = 0.015625*gain_cdbk[best_cdbk*4] + .5;
496 gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5;
497 gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5;
498#endif
499 *cdbk_index=best_cdbk;
500 }
501
502 SPEEX_MEMSET(exc, 0, nsf);
503 for (i=0;i<3;i++)
504 {
505 int j;
506 int tmp1, tmp3;
507 int pp=pitch+1-i;
508 tmp1=nsf;
509 if (tmp1>pp)
510 tmp1=pp;
511 for (j=0;j<tmp1;j++)
512 exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]);
513 tmp3=nsf;
514 if (tmp3>pp+pitch)
515 tmp3=pp+pitch;
516 for (j=tmp1;j<tmp3;j++)
517 exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]);
518 }
519 for (i=0;i<nsf;i++)
520 {
521 spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])),
522 MULT16_16(gain[2],x[0][i]));
523 new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6)));
524 }
525 err = inner_prod(new_target, new_target, nsf);
526
527 return err;
528}
529
530/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
531int pitch_search_3tap(
532spx_word16_t target[], /* Target vector */
533spx_word16_t *sw,
534spx_coef_t ak[], /* LPCs for this subframe */
535spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
536spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
537spx_sig_t exc[], /* Excitation */
538const void *par,
539int start, /* Smallest pitch value allowed */
540int end, /* Largest pitch value allowed */
541spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
542int p, /* Number of LPC coeffs */
543int nsf, /* Number of samples in subframe */
544SpeexBits *bits,
545char *stack,
546spx_word16_t *exc2,
547spx_word16_t *r,
548int complexity,
549int cdbk_offset,
550int plc_tuning,
551spx_word32_t *cumul_gain
552)
553{
554 int i;
555 int cdbk_index, pitch=0, best_gain_index=0;
556 VARDECL(spx_sig_t *best_exc);
557 VARDECL(spx_word16_t *new_target);
558 VARDECL(spx_word16_t *best_target);
559 int best_pitch=0;
560 spx_word32_t err, best_err=-1;
561 int N;
562 const ltp_params *params;
563 const signed char *gain_cdbk;
564 int gain_cdbk_size;
565 int scaledown=0;
566
567 VARDECL(int *nbest);
568
569 params = (const ltp_params*) par;
570 gain_cdbk_size = 1<<params->gain_bits;
571 gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
572
573 N=complexity;
574 if (N>10)
575 N=10;
576 if (N<1)
577 N=1;
578
579 ALLOC(nbest, N, int);
580 params = (const ltp_params*) par;
581
582 if (end<start)
583 {
584 speex_bits_pack(bits, 0, params->pitch_bits);
585 speex_bits_pack(bits, 0, params->gain_bits);
586 SPEEX_MEMSET(exc, 0, nsf);
587 return start;
588 }
589
590#ifdef FIXED_POINT
591 /* Check if we need to scale everything down in the pitch search to avoid overflows */
592 for (i=0;i<nsf;i++)
593 {
594 if (ABS16(target[i])>16383)
595 {
596 scaledown=1;
597 break;
598 }
599 }
600 for (i=-end;i<nsf;i++)
601 {
602 if (ABS16(exc2[i])>16383)
603 {
604 scaledown=1;
605 break;
606 }
607 }
608#endif
609 if (N>end-start+1)
610 N=end-start+1;
611 if (end != start)
612 open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack);
613 else
614 nbest[0] = start;
615
616 ALLOC(best_exc, nsf, spx_sig_t);
617 ALLOC(new_target, nsf, spx_word16_t);
618 ALLOC(best_target, nsf, spx_word16_t);
619
620 for (i=0;i<N;i++)
621 {
622 pitch=nbest[i];
623 SPEEX_MEMSET(exc, 0, nsf);
624 err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf,
625 bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown);
626 if (err<best_err || best_err<0)
627 {
628 SPEEX_COPY(best_exc, exc, nsf);
629 SPEEX_COPY(best_target, new_target, nsf);
630 best_err=err;
631 best_pitch=pitch;
632 best_gain_index=cdbk_index;
633 }
634 }
635 /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
636 speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
637 speex_bits_pack(bits, best_gain_index, params->gain_bits);
638#ifdef FIXED_POINT
639 *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain));
640#else
641 *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3];
642#endif
643 /*printf ("%f\n", cumul_gain);*/
644 /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
645 SPEEX_COPY(exc, best_exc, nsf);
646 SPEEX_COPY(target, best_target, nsf);
647#ifdef FIXED_POINT
648 /* Scale target back up if needed */
649 if (scaledown)
650 {
651 for (i=0;i<nsf;i++)
652 target[i]=SHL16(target[i],1);
653 }
654#endif
655 return pitch;
656}
657#endif /* SPEEX_DISABLE_ENCODER */
658
659void pitch_unquant_3tap(
660spx_word16_t exc[], /* Input excitation */
661spx_word32_t exc_out[], /* Output excitation */
662int start, /* Smallest pitch value allowed */
663int end, /* Largest pitch value allowed */
664spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
665const void *par,
666int nsf, /* Number of samples in subframe */
667int *pitch_val,
668spx_word16_t *gain_val,
669SpeexBits *bits,
670char *stack,
671int count_lost,
672int subframe_offset,
673spx_word16_t last_pitch_gain,
674int cdbk_offset
675)
676{
677 (void)end;
678 (void)pitch_coef;
679 (void)stack;
680 int i;
681 int pitch;
682 int gain_index;
683 spx_word16_t gain[3];
684 const signed char *gain_cdbk;
685 int gain_cdbk_size;
686 const ltp_params *params;
687
688 params = (const ltp_params*) par;
689 gain_cdbk_size = 1<<params->gain_bits;
690 gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
691
692 pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
693 pitch += start;
694 gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
695 /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
696#ifdef FIXED_POINT
697 gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]);
698 gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]);
699 gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]);
700#else
701 gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5;
702 gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5;
703 gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5;
704#endif
705
706 if (count_lost && pitch > subframe_offset)
707 {
708 spx_word16_t gain_sum;
709 if (1) {
710#ifdef FIXED_POINT
711 spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1);
712 if (tmp>62)
713 tmp=62;
714#else
715 spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain;
716 if (tmp>.95)
717 tmp=.95;
718#endif
719 gain_sum = gain_3tap_to_1tap(gain);
720
721 if (gain_sum > tmp)
722 {
723 spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum);
724 for (i=0;i<3;i++)
725 gain[i]=MULT16_16_Q14(fact,gain[i]);
726 }
727
728 }
729
730 }
731
732 *pitch_val = pitch;
733 gain_val[0]=gain[0];
734 gain_val[1]=gain[1];
735 gain_val[2]=gain[2];
736 gain[0] = SHL16(gain[0],7);
737 gain[1] = SHL16(gain[1],7);
738 gain[2] = SHL16(gain[2],7);
739 SPEEX_MEMSET(exc_out, 0, nsf);
740 for (i=0;i<3;i++)
741 {
742 int j;
743 int tmp1, tmp3;
744 int pp=pitch+1-i;
745 tmp1=nsf;
746 if (tmp1>pp)
747 tmp1=pp;
748 for (j=0;j<tmp1;j++)
749 exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]);
750 tmp3=nsf;
751 if (tmp3>pp+pitch)
752 tmp3=pp+pitch;
753 for (j=tmp1;j<tmp3;j++)
754 exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]);
755 }
756 /*for (i=0;i<nsf;i++)
757 exc[i]=PSHR32(exc32[i],13);*/
758}
759
760
761#ifndef SPEEX_DISABLE_ENCODER
762/** Forced pitch delay and gain */
763int forced_pitch_quant(
764spx_word16_t target[], /* Target vector */
765spx_word16_t *sw,
766spx_coef_t ak[], /* LPCs for this subframe */
767spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
768spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
769spx_sig_t exc[], /* Excitation */
770const void *par,
771int start, /* Smallest pitch value allowed */
772int end, /* Largest pitch value allowed */
773spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
774int p, /* Number of LPC coeffs */
775int nsf, /* Number of samples in subframe */
776SpeexBits *bits,
777char *stack,
778spx_word16_t *exc2,
779spx_word16_t *r,
780int complexity,
781int cdbk_offset,
782int plc_tuning,
783spx_word32_t *cumul_gain
784)
785{
786 int i;
787 VARDECL(spx_word16_t *res);
788 ALLOC(res, nsf, spx_word16_t);
789#ifdef FIXED_POINT
790 if (pitch_coef>63)
791 pitch_coef=63;
792#else
793 if (pitch_coef>.99)
794 pitch_coef=.99;
795#endif
796 for (i=0;i<nsf&&i<start;i++)
797 {
798 exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]);
799 }
800 for (;i<nsf;i++)
801 {
802 exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]);
803 }
804 for (i=0;i<nsf;i++)
805 res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1));
806 syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack);
807 for (i=0;i<nsf;i++)
808 target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700));
809 return start;
810}
811#endif /* SPEEX_DISABLE_ENCODER */
812
813/** Unquantize forced pitch delay and gain */
814void forced_pitch_unquant(
815spx_word16_t exc[], /* Input excitation */
816spx_word32_t exc_out[], /* Output excitation */
817int start, /* Smallest pitch value allowed */
818int end, /* Largest pitch value allowed */
819spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
820const void *par,
821int nsf, /* Number of samples in subframe */
822int *pitch_val,
823spx_word16_t *gain_val,
824SpeexBits *bits,
825char *stack,
826int count_lost,
827int subframe_offset,
828spx_word16_t last_pitch_gain,
829int cdbk_offset
830)
831{
832 (void)end;
833 (void)par;
834 (void)bits;
835 (void)stack;
836 (void)count_lost;
837 (void)subframe_offset;
838 (void)last_pitch_gain;
839 (void)cdbk_offset;
840 int i;
841#ifdef FIXED_POINT
842 if (pitch_coef>63)
843 pitch_coef=63;
844#else
845 if (pitch_coef>.99)
846 pitch_coef=.99;
847#endif
848 for (i=0;i<nsf;i++)
849 {
850 exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));
851 exc[i] = EXTRACT16(PSHR32(exc_out[i],13));
852 }
853 *pitch_val = start;
854 gain_val[0]=gain_val[2]=0;
855 gain_val[1] = pitch_coef;
856}
diff --git a/lib/rbcodec/codecs/libspeex/ltp.h b/lib/rbcodec/codecs/libspeex/ltp.h
new file mode 100644
index 0000000000..872f072e4e
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/ltp.h
@@ -0,0 +1,141 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file ltp.h
4 @brief Long-Term Prediction functions
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#include "speex/speex_bits.h"
36#include "arch.h"
37
38/** LTP parameters. */
39typedef struct {
40 const signed char *gain_cdbk;
41 int gain_bits;
42 int pitch_bits;
43} ltp_params;
44
45#ifdef FIXED_POINT
46#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -SHR16(g[0],1)) + (g[2]>0 ? g[2] : -SHR16(g[2],1)))
47#else
48#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -.5*g[0]) + (g[2]>0 ? g[2] : -.5*g[2]))
49#endif
50
51spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len);
52void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack);
53
54void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack);
55
56
57/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
58int pitch_search_3tap(
59spx_word16_t target[], /* Target vector */
60spx_word16_t *sw,
61spx_coef_t ak[], /* LPCs for this subframe */
62spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
63spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
64spx_sig_t exc[], /* Overlapping codebook */
65const void *par,
66int start, /* Smallest pitch value allowed */
67int end, /* Largest pitch value allowed */
68spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
69int p, /* Number of LPC coeffs */
70int nsf, /* Number of samples in subframe */
71SpeexBits *bits,
72char *stack,
73spx_word16_t *exc2,
74spx_word16_t *r,
75int complexity,
76int cdbk_offset,
77int plc_tuning,
78spx_word32_t *cumul_gain
79);
80
81/*Unquantize adaptive codebook and update pitch contribution*/
82void pitch_unquant_3tap(
83spx_word16_t exc[], /* Input excitation */
84spx_word32_t exc_out[], /* Output excitation */
85int start, /* Smallest pitch value allowed */
86int end, /* Largest pitch value allowed */
87spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
88const void *par,
89int nsf, /* Number of samples in subframe */
90int *pitch_val,
91spx_word16_t *gain_val,
92SpeexBits *bits,
93char *stack,
94int lost,
95int subframe_offset,
96spx_word16_t last_pitch_gain,
97int cdbk_offset
98);
99
100/** Forced pitch delay and gain */
101int forced_pitch_quant(
102spx_word16_t target[], /* Target vector */
103spx_word16_t *sw,
104spx_coef_t ak[], /* LPCs for this subframe */
105spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
106spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
107spx_sig_t exc[], /* Excitation */
108const void *par,
109int start, /* Smallest pitch value allowed */
110int end, /* Largest pitch value allowed */
111spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
112int p, /* Number of LPC coeffs */
113int nsf, /* Number of samples in subframe */
114SpeexBits *bits,
115char *stack,
116spx_word16_t *exc2,
117spx_word16_t *r,
118int complexity,
119int cdbk_offset,
120int plc_tuning,
121spx_word32_t *cumul_gain
122);
123
124/** Unquantize forced pitch delay and gain */
125void forced_pitch_unquant(
126spx_word16_t exc[], /* Input excitation */
127spx_word32_t exc_out[], /* Output excitation */
128int start, /* Smallest pitch value allowed */
129int end, /* Largest pitch value allowed */
130spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
131const void *par,
132int nsf, /* Number of samples in subframe */
133int *pitch_val,
134spx_word16_t *gain_val,
135SpeexBits *bits,
136char *stack,
137int lost,
138int subframe_offset,
139spx_word16_t last_pitch_gain,
140int cdbk_offset
141);
diff --git a/lib/rbcodec/codecs/libspeex/ltp_arm4.h b/lib/rbcodec/codecs/libspeex/ltp_arm4.h
new file mode 100644
index 0000000000..46ecfa40ec
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/ltp_arm4.h
@@ -0,0 +1,188 @@
1/* Copyright (C) 2004 Jean-Marc Valin */
2/**
3 @file ltp_arm4.h
4 @brief Long-Term Prediction functions (ARM4 version)
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#define OVERRIDE_INNER_PROD
36spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
37{
38 spx_word32_t sum1=0,sum2=0;
39 spx_word16_t *deadx, *deady;
40 int deadlen, dead1, dead2, dead3, dead4, dead5, dead6;
41 __asm__ __volatile__ (
42 "\tldrsh %5, [%0], #2 \n"
43 "\tldrsh %6, [%1], #2 \n"
44 ".inner_prod_loop%=:\n"
45 "\tsub %7, %7, %7\n"
46 "\tsub %10, %10, %10\n"
47
48 "\tldrsh %8, [%0], #2 \n"
49 "\tldrsh %9, [%1], #2 \n"
50 "\tmla %7, %5, %6, %7\n"
51 "\tldrsh %5, [%0], #2 \n"
52 "\tldrsh %6, [%1], #2 \n"
53 "\tmla %10, %8, %9, %10\n"
54 "\tldrsh %8, [%0], #2 \n"
55 "\tldrsh %9, [%1], #2 \n"
56 "\tmla %7, %5, %6, %7\n"
57 "\tldrsh %5, [%0], #2 \n"
58 "\tldrsh %6, [%1], #2 \n"
59 "\tmla %10, %8, %9, %10\n"
60
61 "\tldrsh %8, [%0], #2 \n"
62 "\tldrsh %9, [%1], #2 \n"
63 "\tmla %7, %5, %6, %7\n"
64 "\tldrsh %5, [%0], #2 \n"
65 "\tldrsh %6, [%1], #2 \n"
66 "\tmla %10, %8, %9, %10\n"
67 "\tldrsh %8, [%0], #2 \n"
68 "\tldrsh %9, [%1], #2 \n"
69 "\tmla %7, %5, %6, %7\n"
70 "\tldrsh %5, [%0], #2 \n"
71 "\tldrsh %6, [%1], #2 \n"
72 "\tmla %10, %8, %9, %10\n"
73
74 "\tsubs %4, %4, #1\n"
75 "\tadd %2, %2, %7, asr #5\n"
76 "\tadd %3, %3, %10, asr #5\n"
77 "\tbne .inner_prod_loop%=\n"
78 : "=r" (deadx), "=r" (deady), "+r" (sum1), "+r" (sum2),
79 "=r" (deadlen), "=r" (dead1), "=r" (dead2), "=r" (dead3),
80 "=r" (dead4), "=r" (dead5), "=r" (dead6)
81 : "0" (x), "1" (y), "4" (len>>3)
82 : "cc", "memory"
83 );
84 return (sum1+sum2)>>1;
85}
86
87#define OVERRIDE_PITCH_XCORR
88void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
89{
90 (void)stack;
91 int i,j;
92 for (i=0;i<nb_pitch;i+=4)
93 {
94 /* Compute correlation*/
95 //corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);
96 spx_word32_t sum1=0;
97 spx_word32_t sum2=0;
98 spx_word32_t sum3=0;
99 spx_word32_t sum4=0;
100 const spx_word16_t *y = _y+i;
101 const spx_word16_t *x = _x;
102 spx_word32_t y0, y1, y2, y3;
103 y0=*y++;
104 y1=*y++;
105 y2=*y++;
106 y3=*y++;
107 for (j=0;j<len;j+=4)
108 {
109 spx_word32_t part1, part2, part3, part4, x0;
110 spx_word32_t dead1;
111 __asm__ __volatile__ (
112#ifdef SHORTCUTS
113 "\tldrsh %10, [%8], #4 \n"
114 "\tmul %4, %10, %0 \n"
115 "\tldrsh %15, [%8], #4 \n"
116 "\tmul %5, %10, %1 \n"
117 "\tldrsh %0, [%9], #2 \n"
118 "\tmul %6, %10, %2 \n"
119 "\tldrsh %1, [%9], #2 \n"
120 "\tmul %7, %10, %3 \n"
121
122
123 "\tmla %4, %15, %2, %4 \n"
124 "\tldrsh %2, [%9], #2 \n"
125 "\tmla %5, %15, %3, %5 \n"
126 "\tldrsh %3, [%9], #2 \n"
127 "\tmla %6, %15, %0, %6 \n"
128 "\tmla %7, %15, %1, %7 \n"
129
130#else
131 "\tldrsh %10, [%8], #2 \n"
132 "\tmul %4, %10, %0 \n"
133 "\tmul %5, %10, %1 \n"
134 "\tmul %6, %10, %2 \n"
135 "\tmul %7, %10, %3 \n"
136
137 "\tldrsh %10, [%8], #2 \n"
138 "\tldrsh %0, [%9], #2 \n"
139 "\tmla %4, %10, %1, %4 \n"
140 "\tmla %5, %10, %2, %5 \n"
141 "\tmla %6, %10, %3, %6 \n"
142 "\tmla %7, %10, %0, %7 \n"
143
144 "\tldrsh %10, [%8], #2 \n"
145 "\tldrsh %1, [%9], #2 \n"
146 "\tmla %4, %10, %2, %4 \n"
147 "\tmla %5, %10, %3, %5 \n"
148 "\tmla %6, %10, %0, %6 \n"
149 "\tmla %7, %10, %1, %7 \n"
150
151 "\tldrsh %10, [%8], #2 \n"
152 "\tldrsh %2, [%9], #2 \n"
153 "\tmla %4, %10, %3, %4 \n"
154 "\tmla %5, %10, %0, %5 \n"
155 "\tmla %6, %10, %1, %6 \n"
156 "\tmla %7, %10, %2, %7 \n"
157
158 "\tldrsh %3, [%9], #2 \n"
159#endif
160
161 "\tldr %10, %11 \n"
162 "\tldr %15, %12 \n"
163 "\tadd %4, %10, %4, asr #6 \n"
164 "\tstr %4, %11 \n"
165 "\tldr %10, %13 \n"
166 "\tadd %5, %15, %5, asr #6 \n"
167 "\tstr %5, %12 \n"
168 "\tldr %15, %14 \n"
169 "\tadd %6, %10, %6, asr #6 \n"
170 "\tadd %7, %15, %7, asr #6 \n"
171 "\tstr %6, %13 \n"
172 "\tstr %7, %14 \n"
173
174 : "+r" (y0), "+r" (y1), "+r" (y2), "+r" (y3),
175 "=r" (part1), "=r" (part2), "=r" (part3), "=r" (part4),
176 "+r" (x), "+r" (y), "=r" (x0), "+m" (sum1),
177 "+m" (sum2), "+m" (sum3), "+m" (sum4), "=r" (dead1)
178 :
179 : "cc", "memory"
180 );
181 }
182 corr[nb_pitch-1-i]=sum1;
183 corr[nb_pitch-2-i]=sum2;
184 corr[nb_pitch-3-i]=sum3;
185 corr[nb_pitch-4-i]=sum4;
186 }
187
188}
diff --git a/lib/rbcodec/codecs/libspeex/ltp_bfin.h b/lib/rbcodec/codecs/libspeex/ltp_bfin.h
new file mode 100644
index 0000000000..8d7225b017
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/ltp_bfin.h
@@ -0,0 +1,419 @@
1/* Copyright (C) 2005 Analog Devices */
2/**
3 @file ltp_bfin.h
4 @author Jean-Marc Valin
5 @brief Long-Term Prediction functions (Blackfin version)
6*/
7/*
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 - Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 - Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19 - Neither the name of the Xiph.org Foundation nor the names of its
20 contributors may be used to endorse or promote products derived from
21 this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#define OVERRIDE_INNER_PROD
37spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
38{
39 spx_word32_t sum=0;
40 __asm__ __volatile__ (
41 "P0 = %3;\n\t"
42 "P1 = %1;\n\t"
43 "P2 = %2;\n\t"
44 "I0 = P1;\n\t"
45 "I1 = P2;\n\t"
46 "L0 = 0;\n\t"
47 "L1 = 0;\n\t"
48 "A0 = 0;\n\t"
49 "R0.L = W[I0++] || R1.L = W[I1++];\n\t"
50 "LOOP inner%= LC0 = P0;\n\t"
51 "LOOP_BEGIN inner%=;\n\t"
52 "A0 += R0.L*R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\n\t"
53 "LOOP_END inner%=;\n\t"
54 "A0 += R0.L*R1.L (IS);\n\t"
55 "A0 = A0 >>> 6;\n\t"
56 "R0 = A0;\n\t"
57 "%0 = R0;\n\t"
58 : "=m" (sum)
59 : "m" (x), "m" (y), "d" (len-1)
60 : "P0", "P1", "P2", "R0", "R1", "A0", "I0", "I1", "L0", "L1", "R3"
61 );
62 return sum;
63}
64
65#define OVERRIDE_PITCH_XCORR
66void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
67{
68 corr += nb_pitch - 1;
69 __asm__ __volatile__ (
70 "P2 = %0;\n\t"
71 "I0 = P2;\n\t" /* x in I0 */
72 "B0 = P2;\n\t" /* x in B0 */
73 "R0 = %3;\n\t" /* len in R0 */
74 "P3 = %3;\n\t"
75 "P3 += -2;\n\t" /* len in R0 */
76 "P4 = %4;\n\t" /* nb_pitch in R0 */
77 "R1 = R0 << 1;\n\t" /* number of bytes in x */
78 "L0 = R1;\n\t"
79 "P0 = %1;\n\t"
80
81 "P1 = %2;\n\t"
82 "B1 = P1;\n\t"
83 "L1 = 0;\n\t" /*Disable looping on I1*/
84
85 "r0 = [I0++];\n\t"
86 "LOOP pitch%= LC0 = P4 >> 1;\n\t"
87 "LOOP_BEGIN pitch%=;\n\t"
88 "I1 = P0;\n\t"
89 "A1 = A0 = 0;\n\t"
90 "R1 = [I1++];\n\t"
91 "LOOP inner_prod%= LC1 = P3 >> 1;\n\t"
92 "LOOP_BEGIN inner_prod%=;\n\t"
93 "A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\n\t"
94 "A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R1.H = W[I1++] || R0 = [I0++];\n\t"
95 "LOOP_END inner_prod%=;\n\t"
96 "A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\n\t"
97 "A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R0 = [I0++];\n\t"
98 "A0 = A0 >>> 6;\n\t"
99 "A1 = A1 >>> 6;\n\t"
100 "R2 = A0, R3 = A1;\n\t"
101 "[P1--] = r2;\n\t"
102 "[P1--] = r3;\n\t"
103 "P0 += 4;\n\t"
104 "LOOP_END pitch%=;\n\t"
105 "L0 = 0;\n\t"
106 : : "m" (_x), "m" (_y), "m" (corr), "m" (len), "m" (nb_pitch)
107 : "A0", "A1", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "R3", "I0", "I1", "L0", "L1", "B0", "B1", "memory"
108 );
109}
110
111#define OVERRIDE_COMPUTE_PITCH_ERROR
112static inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control)
113{
114 spx_word32_t sum;
115 __asm__ __volatile__
116 (
117 "A0 = 0;\n\t"
118
119 "R0 = W[%1++];\n\t"
120 "R1.L = %2.L*%5.L (IS);\n\t"
121 "A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
122
123 "R1.L = %3.L*%5.L (IS);\n\t"
124 "A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
125
126 "R1.L = %4.L*%5.L (IS);\n\t"
127 "A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
128
129 "R1.L = %2.L*%3.L (IS);\n\t"
130 "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
131
132 "R1.L = %4.L*%3.L (IS);\n\t"
133 "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
134
135 "R1.L = %4.L*%2.L (IS);\n\t"
136 "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
137
138 "R1.L = %2.L*%2.L (IS);\n\t"
139 "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
140
141 "R1.L = %3.L*%3.L (IS);\n\t"
142 "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
143
144 "R1.L = %4.L*%4.L (IS);\n\t"
145 "A0 -= R1.L*R0.L (IS);\n\t"
146
147 "%0 = A0;\n\t"
148 : "=&D" (sum), "=a" (C)
149 : "d" (g[0]), "d" (g[1]), "d" (g[2]), "d" (pitch_control), "1" (C)
150 : "R0", "R1", "R2", "A0"
151 );
152 return sum;
153}
154
155#define OVERRIDE_OPEN_LOOP_NBEST_PITCH
156#ifdef OVERRIDE_OPEN_LOOP_NBEST_PITCH
157void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)
158{
159 int i,j,k;
160 VARDECL(spx_word32_t *best_score);
161 VARDECL(spx_word32_t *best_ener);
162 spx_word32_t e0;
163 VARDECL(spx_word32_t *corr);
164 VARDECL(spx_word32_t *energy);
165
166 ALLOC(best_score, N, spx_word32_t);
167 ALLOC(best_ener, N, spx_word32_t);
168 ALLOC(corr, end-start+1, spx_word32_t);
169 ALLOC(energy, end-start+2, spx_word32_t);
170
171 for (i=0;i<N;i++)
172 {
173 best_score[i]=-1;
174 best_ener[i]=0;
175 pitch[i]=start;
176 }
177
178 energy[0]=inner_prod(sw-start, sw-start, len);
179 e0=inner_prod(sw, sw, len);
180
181 /* energy update -------------------------------------*/
182
183 __asm__ __volatile__
184 (
185" P0 = %0;\n\t"
186" I1 = %1;\n\t"
187" L1 = 0;\n\t"
188" I2 = %2;\n\t"
189" L2 = 0;\n\t"
190" R2 = [P0++];\n\t"
191" R3 = 0;\n\t"
192" LSETUP (eu1, eu2) LC1 = %3;\n\t"
193"eu1: R1.L = W [I1--] || R0.L = W [I2--] ;\n\t"
194" R1 = R1.L * R1.L (IS);\n\t"
195" R0 = R0.L * R0.L (IS);\n\t"
196" R1 >>>= 6;\n\t"
197" R1 = R1 + R2;\n\t"
198" R0 >>>= 6;\n\t"
199" R1 = R1 - R0;\n\t"
200" R2 = MAX(R1,R3);\n\t"
201"eu2: [P0++] = R2;\n\t"
202 : : "d" (energy), "d" (&sw[-start-1]), "d" (&sw[-start+len-1]),
203 "a" (end-start)
204 : "P0", "I1", "I2", "R0", "R1", "R2", "R3"
205#if (__GNUC__ == 4)
206 , "LC1"
207#endif
208 );
209
210 pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);
211
212 /* FIXME: Fixed-point and floating-point code should be merged */
213 {
214 VARDECL(spx_word16_t *corr16);
215 VARDECL(spx_word16_t *ener16);
216 ALLOC(corr16, end-start+1, spx_word16_t);
217 ALLOC(ener16, end-start+1, spx_word16_t);
218 /* Normalize to 180 so we can square it and it still fits in 16 bits */
219 normalize16(corr, corr16, 180, end-start+1);
220 normalize16(energy, ener16, 180, end-start+1);
221
222 if (N == 1) {
223 /* optimised asm to handle N==1 case */
224 __asm__ __volatile__
225 (
226" I0 = %1;\n\t" /* I0: corr16[] */
227" L0 = 0;\n\t"
228" I1 = %2;\n\t" /* I1: energy */
229" L1 = 0;\n\t"
230" R2 = -1;\n\t" /* R2: best score */
231" R3 = 0;\n\t" /* R3: best energy */
232" P0 = %4;\n\t" /* P0: best pitch */
233" P1 = %4;\n\t" /* P1: counter */
234" LSETUP (sl1, sl2) LC1 = %3;\n\t"
235"sl1: R0.L = W [I0++] || R1.L = W [I1++];\n\t"
236" R0 = R0.L * R0.L (IS);\n\t"
237" R1 += 1;\n\t"
238" R4 = R0.L * R3.L;\n\t"
239" R5 = R2.L * R1.L;\n\t"
240" cc = R5 < R4;\n\t"
241" if cc R2 = R0;\n\t"
242" if cc R3 = R1;\n\t"
243" if cc P0 = P1;\n\t"
244"sl2: P1 += 1;\n\t"
245" %0 = P0;\n\t"
246 : "=&d" (pitch[0])
247 : "a" (corr16), "a" (ener16), "a" (end+1-start), "d" (start)
248 : "P0", "P1", "I0", "I1", "R0", "R1", "R2", "R3", "R4", "R5"
249#if (__GNUC__ == 4)
250 , "LC1"
251#endif
252 );
253
254 }
255 else {
256 for (i=start;i<=end;i++)
257 {
258 spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);
259 /* Instead of dividing the tmp by the energy, we multiply on the other side */
260 if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
261 {
262 /* We can safely put it last and then check */
263 best_score[N-1]=tmp;
264 best_ener[N-1]=ener16[i-start]+1;
265 pitch[N-1]=i;
266 /* Check if it comes in front of others */
267 for (j=0;j<N-1;j++)
268 {
269 if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
270 {
271 for (k=N-1;k>j;k--)
272 {
273 best_score[k]=best_score[k-1];
274 best_ener[k]=best_ener[k-1];
275 pitch[k]=pitch[k-1];
276 }
277 best_score[j]=tmp;
278 best_ener[j]=ener16[i-start]+1;
279 pitch[j]=i;
280 break;
281 }
282 }
283 }
284 }
285 }
286 }
287
288 /* Compute open-loop gain */
289 if (gain)
290 {
291 for (j=0;j<N;j++)
292 {
293 spx_word16_t g;
294 i=pitch[j];
295 g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6));
296 /* FIXME: g = max(g,corr/energy) */
297 if (g<0)
298 g = 0;
299 gain[j]=g;
300 }
301 }
302}
303#endif
304
305#define OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ
306#ifdef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ
307static int pitch_gain_search_3tap_vq(
308 const signed char *gain_cdbk,
309 int gain_cdbk_size,
310 spx_word16_t *C16,
311 spx_word16_t max_gain
312)
313{
314 const signed char *ptr=gain_cdbk;
315 int best_cdbk=0;
316 spx_word32_t best_sum=-VERY_LARGE32;
317 spx_word32_t sum=0;
318 spx_word16_t g[3];
319 spx_word16_t pitch_control=64;
320 spx_word16_t gain_sum;
321 int i;
322
323 /* fast asm version of VQ codebook search */
324
325 __asm__ __volatile__
326 (
327
328" P0 = %2;\n\t" /* P0: ptr to gain_cdbk */
329" L1 = 0;\n\t" /* no circ addr for L1 */
330" %0 = 0;\n\t" /* %0: best_sum */
331" %1 = 0;\n\t" /* %1: best_cbdk */
332" P1 = 0;\n\t" /* P1: loop counter */
333
334" LSETUP (pgs1, pgs2) LC1 = %4;\n\t"
335"pgs1: R2 = B [P0++] (X);\n\t" /* R2: g[0] */
336" R3 = B [P0++] (X);\n\t" /* R3: g[1] */
337" R4 = B [P0++] (X);\n\t" /* R4: g[2] */
338" R2 += 32;\n\t"
339" R3 += 32;\n\t"
340" R4 += 32;\n\t"
341" R4.H = 64;\n\t" /* R4.H: pitch_control */
342
343" R0 = B [P0++] (X);\n\t"
344" B0 = R0;\n\t" /* BO: gain_sum */
345
346 /* compute_pitch_error() -------------------------------*/
347
348" I1 = %3;\n\t" /* I1: ptr to C */
349" A0 = 0;\n\t"
350
351" R0.L = W[I1++];\n\t"
352" R1.L = R2.L*R4.H (IS);\n\t"
353" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
354
355" R1.L = R3.L*R4.H (IS);\n\t"
356" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
357
358" R1.L = R4.L*R4.H (IS);\n\t"
359" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
360
361" R1.L = R2.L*R3.L (IS);\n\t"
362" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
363
364" R1.L = R4.L*R3.L (IS);\n\t"
365" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
366
367" R1.L = R4.L*R2.L (IS);\n\t"
368" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
369
370" R1.L = R2.L*R2.L (IS);\n\t"
371" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
372
373" R1.L = R3.L*R3.L (IS);\n\t"
374" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
375
376" R1.L = R4.L*R4.L (IS);\n\t"
377" R0 = (A0 -= R1.L*R0.L) (IS);\n\t"
378
379/*
380 Re-arrange the if-then to code efficiently on the Blackfin:
381
382 if (sum>best_sum && gain_sum<=max_gain) ------ (1)
383
384 if (sum>best_sum && !(gain_sum>max_gain)) ------ (2)
385
386 if (max_gain<=gain_sum) { ------ (3)
387 sum = -VERY_LARGE32;
388 }
389 if (best_sum<=sum)
390
391 The blackin cc instructions are all of the form:
392
393 cc = x < y (or cc = x <= y)
394*/
395" R1 = B0\n\t"
396" R2 = %5\n\t"
397" R3 = %6\n\t"
398" cc = R2 <= R1;\n\t"
399" if cc R0 = R3;\n\t"
400" cc = %0 <= R0;\n\t"
401" if cc %0 = R0;\n\t"
402" if cc %1 = P1;\n\t"
403
404"pgs2: P1 += 1;\n\t"
405
406 : "=&d" (best_sum), "=&d" (best_cdbk)
407 : "a" (gain_cdbk), "a" (C16), "a" (gain_cdbk_size), "a" (max_gain),
408 "b" (-VERY_LARGE32)
409 : "R0", "R1", "R2", "R3", "R4", "P0",
410 "P1", "I1", "L1", "A0", "B0"
411#if (__GNUC__ == 4)
412 , "LC1"
413#endif
414 );
415
416 return best_cdbk;
417}
418#endif
419
diff --git a/lib/rbcodec/codecs/libspeex/ltp_cf.S b/lib/rbcodec/codecs/libspeex/ltp_cf.S
new file mode 100644
index 0000000000..a1baed6d41
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/ltp_cf.S
@@ -0,0 +1,85 @@
1/* Copyright (C) 2007 Thom Johansen */
2/**
3 @file ltp_cf.S
4 @brief Long-Term Prediction functions (Coldfire version)
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35 .text
36/* spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) */
37 .global inner_prod
38inner_prod:
39 lea.l (-28, %sp), %sp
40 movem.l %d2-%d7/%a2, (%sp)
41 movem.l (28+4, %sp), %a0-%a1 | a0 = x, a1 = y
42 move.l (28+12, %sp), %d0 | d0 = len
43
44 | We assume we're never called with a 'len' of zero
45 btst #2, %d0 | Check if we need to do one round of four
46 jeq 0f | samples before we do runs of eight
47 movem.l (%a0), %d1-%d2 | Fetch four samples from x
48 movem.l (%a1), %d3-%d4 | Fetch four samples from y
49 mac.w %d1u, %d3u, %acc0
50 mac.w %d1l, %d3l, %acc0
51 mac.w %d2u, %d4u, %acc0
52 mac.w %d2l, %d4l, %acc0
53 addq.l #8, %a0
54 addq.l #8, %a1
55 subq.l #4, %d0
56 jeq .save
57
580:
59 movem.l (%a0), %d1-%d4 | Fetch eight samples from x
60 movem.l (%a1), %d5-%d7/%a2 | Fetch eight samples from y
61 mac.w %d1u, %d5u, %acc0
62 mac.w %d1l, %d5l, %acc0
63 mac.w %d2u, %d6u, %acc0
64 mac.w %d2l, %d6l, %acc0
65 mac.w %d3u, %d7u, %acc0
66 mac.w %d3l, %d7l, %acc0
67 mac.w %d4u, %a2u, %acc0
68 mac.w %d4l, %a2l, %acc0
69 lea.l (16, %a0), %a0
70 lea.l (16, %a1), %a1
71 subq.l #8, %d0
72 jne 0b
73
74.save:
75 move.l %accext01, %d1 | Fetch top 8 bits of answer
76 movclr.l %acc0, %d0 | Fetch lower 32 bits
77 lsr.l #6, %d0
78 moveq.l #26, %d2
79 asl.l %d2, %d1
80 or.l %d1, %d0 | Combine (top << 26) | (lower >> 6)
81
82 movem.l (%sp), %d2-%d7/%a2
83 lea.l (28, %sp), %sp
84 rts
85
diff --git a/lib/rbcodec/codecs/libspeex/ltp_sse.h b/lib/rbcodec/codecs/libspeex/ltp_sse.h
new file mode 100644
index 0000000000..bed6eaac9a
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/ltp_sse.h
@@ -0,0 +1,92 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file ltp_sse.h
4 @brief Long-Term Prediction functions (SSE version)
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#include <xmmintrin.h>
36
37#define OVERRIDE_INNER_PROD
38float inner_prod(const float *a, const float *b, int len)
39{
40 int i;
41 float ret;
42 __m128 sum = _mm_setzero_ps();
43 for (i=0;i<(len>>2);i+=2)
44 {
45 sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+0), _mm_loadu_ps(b+0)));
46 sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+4), _mm_loadu_ps(b+4)));
47 a += 8;
48 b += 8;
49 }
50 sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
51 sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
52 _mm_store_ss(&ret, sum);
53 return ret;
54}
55
56#define OVERRIDE_PITCH_XCORR
57void pitch_xcorr(const float *_x, const float *_y, float *corr, int len, int nb_pitch, char *stack)
58{
59 int i, offset;
60 VARDECL(__m128 *x);
61 VARDECL(__m128 *y);
62 int N, L;
63 N = len>>2;
64 L = nb_pitch>>2;
65 ALLOC(x, N, __m128);
66 ALLOC(y, N+L, __m128);
67 for (i=0;i<N;i++)
68 x[i] = _mm_loadu_ps(_x+(i<<2));
69 for (offset=0;offset<4;offset++)
70 {
71 for (i=0;i<N+L;i++)
72 y[i] = _mm_loadu_ps(_y+(i<<2)+offset);
73 for (i=0;i<L;i++)
74 {
75 int j;
76 __m128 sum, *xx, *yy;
77 sum = _mm_setzero_ps();
78 yy = y+i;
79 xx = x;
80 for (j=0;j<N;j+=2)
81 {
82 sum = _mm_add_ps(sum, _mm_mul_ps(xx[0], yy[0]));
83 sum = _mm_add_ps(sum, _mm_mul_ps(xx[1], yy[1]));
84 xx += 2;
85 yy += 2;
86 }
87 sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
88 sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
89 _mm_store_ss(corr+nb_pitch-1-(i<<2)-offset, sum);
90 }
91 }
92}
diff --git a/lib/rbcodec/codecs/libspeex/math_approx.h b/lib/rbcodec/codecs/libspeex/math_approx.h
new file mode 100644
index 0000000000..9ca830755d
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/math_approx.h
@@ -0,0 +1,332 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file math_approx.h
4 @brief Various math approximation functions for Speex
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef MATH_APPROX_H
36#define MATH_APPROX_H
37
38#include "arch.h"
39
40#ifndef FIXED_POINT
41
42#define spx_sqrt sqrt
43#define spx_acos acos
44#define spx_exp exp
45#define spx_cos_norm(x) (cos((.5f*M_PI)*(x)))
46#define spx_atan atan
47
48/** Generate a pseudo-random number */
49static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
50{
51 const unsigned int jflone = 0x3f800000;
52 const unsigned int jflmsk = 0x007fffff;
53 union {int i; float f;} ran;
54 *seed = 1664525 * *seed + 1013904223;
55 ran.i = jflone | (jflmsk & *seed);
56 ran.f -= 1.5;
57 return 3.4642*std*ran.f;
58}
59
60
61#endif
62
63
64static inline spx_int16_t spx_ilog2(spx_uint32_t x)
65{
66 int r=0;
67 if (x>=(spx_int32_t)65536)
68 {
69 x >>= 16;
70 r += 16;
71 }
72 if (x>=256)
73 {
74 x >>= 8;
75 r += 8;
76 }
77 if (x>=16)
78 {
79 x >>= 4;
80 r += 4;
81 }
82 if (x>=4)
83 {
84 x >>= 2;
85 r += 2;
86 }
87 if (x>=2)
88 {
89 r += 1;
90 }
91 return r;
92}
93
94static inline spx_int16_t spx_ilog4(spx_uint32_t x)
95{
96 int r=0;
97 if (x>=(spx_int32_t)65536)
98 {
99 x >>= 16;
100 r += 8;
101 }
102 if (x>=256)
103 {
104 x >>= 8;
105 r += 4;
106 }
107 if (x>=16)
108 {
109 x >>= 4;
110 r += 2;
111 }
112 if (x>=4)
113 {
114 r += 1;
115 }
116 return r;
117}
118
119#ifdef FIXED_POINT
120
121/** Generate a pseudo-random number */
122static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
123{
124 spx_word32_t res;
125 *seed = 1664525 * *seed + 1013904223;
126 res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
127 return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14));
128}
129
130/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
131/*#define C0 3634
132#define C1 21173
133#define C2 -12627
134#define C3 4215*/
135
136/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */
137#define C0 3634
138#define C1 21173
139#define C2 -12627
140#define C3 4204
141
142static inline spx_word16_t spx_sqrt(spx_word32_t x)
143{
144 int k;
145 spx_word32_t rt;
146 k = spx_ilog4(x)-6;
147 x = VSHR32(x, (k<<1));
148 rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
149 rt = VSHR32(rt,7-k);
150 return rt;
151}
152
153/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
154
155
156#define A1 16469
157#define A2 2242
158#define A3 1486
159
160static inline spx_word16_t spx_acos(spx_word16_t x)
161{
162 int s=0;
163 spx_word16_t ret;
164 spx_word16_t sq;
165 if (x<0)
166 {
167 s=1;
168 x = NEG16(x);
169 }
170 x = SUB16(16384,x);
171
172 x = x >> 1;
173 sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
174 ret = spx_sqrt(SHL32(EXTEND32(sq),13));
175
176 /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
177 if (s)
178 ret = SUB16(25736,ret);
179 return ret;
180}
181
182
183#define K1 8192
184#define K2 -4096
185#define K3 340
186#define K4 -10
187
188static inline spx_word16_t spx_cos(spx_word16_t x)
189{
190 spx_word16_t x2;
191
192 if (x<12868)
193 {
194 x2 = MULT16_16_P13(x,x);
195 return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
196 } else {
197 x = SUB16(25736,x);
198 x2 = MULT16_16_P13(x,x);
199 return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
200 }
201}
202
203#define L1 32767
204#define L2 -7651
205#define L3 8277
206#define L4 -626
207
208static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x)
209{
210 spx_word16_t x2;
211
212 x2 = MULT16_16_P15(x,x);
213 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))))))));
214}
215
216static inline spx_word16_t spx_cos_norm(spx_word32_t x)
217{
218 x = x&0x0001ffff;
219 if (x>SHL32(EXTEND32(1), 16))
220 x = SUB32(SHL32(EXTEND32(1), 17),x);
221 if (x&0x00007fff)
222 {
223 if (x<SHL32(EXTEND32(1), 15))
224 {
225 return _spx_cos_pi_2(EXTRACT16(x));
226 } else {
227 return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x)));
228 }
229 } else {
230 if (x&0x0000ffff)
231 return 0;
232 else if (x&0x0001ffff)
233 return -32767;
234 else
235 return 32767;
236 }
237}
238
239/*
240 K0 = 1
241 K1 = log(2)
242 K2 = 3-4*log(2)
243 K3 = 3*log(2) - 2
244*/
245#define D0 16384
246#define D1 11356
247#define D2 3726
248#define D3 1301
249/* Input in Q11 format, output in Q16 */
250static inline spx_word32_t spx_exp2(spx_word16_t x)
251{
252 int integer;
253 spx_word16_t frac;
254 integer = SHR16(x,11);
255 if (integer>14)
256 return 0x7fffffff;
257 else if (integer < -15)
258 return 0;
259 frac = SHL16(x-SHL16(integer,11),3);
260 frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac))))));
261 return VSHR32(EXTEND32(frac), -integer-2);
262}
263
264/* Input in Q11 format, output in Q16 */
265static inline spx_word32_t spx_exp(spx_word16_t x)
266{
267 if (x>21290)
268 return 0x7fffffff;
269 else if (x<-21290)
270 return 0;
271 else
272 return spx_exp2(MULT16_16_P14(23637,x));
273}
274#define M1 32767
275#define M2 -21
276#define M3 -11943
277#define M4 4936
278
279static inline spx_word16_t spx_atan01(spx_word16_t x)
280{
281 return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
282}
283
284#undef M1
285#undef M2
286#undef M3
287#undef M4
288
289/* Input in Q15, output in Q14 */
290static inline spx_word16_t spx_atan(spx_word32_t x)
291{
292 if (x <= 32767)
293 {
294 return SHR16(spx_atan01(x),1);
295 } else {
296 int e = spx_ilog2(x);
297 if (e>=29)
298 return 25736;
299 x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14)));
300 return SUB16(25736, SHR16(spx_atan01(x),1));
301 }
302}
303#else
304
305#ifndef M_PI
306#define M_PI 3.14159265358979323846 /* pi */
307#endif
308
309#define C1 0.9999932946f
310#define C2 -0.4999124376f
311#define C3 0.0414877472f
312#define C4 -0.0012712095f
313
314
315#define SPX_PI_2 1.5707963268
316static inline spx_word16_t spx_cos(spx_word16_t x)
317{
318 if (x<SPX_PI_2)
319 {
320 x *= x;
321 return C1 + x*(C2+x*(C3+C4*x));
322 } else {
323 x = M_PI-x;
324 x *= x;
325 return NEG16(C1 + x*(C2+x*(C3+C4*x)));
326 }
327}
328
329#endif
330
331
332#endif
diff --git a/lib/rbcodec/codecs/libspeex/mdf.c b/lib/rbcodec/codecs/libspeex/mdf.c
new file mode 100644
index 0000000000..1994f2a886
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/mdf.c
@@ -0,0 +1,1177 @@
1/* Copyright (C) 2003-2006 Jean-Marc Valin
2
3 File: mdf.c
4 Echo canceller based on the MDF algorithm (see below)
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are
8 met:
9
10 1. Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 3. The name of the author may not be used to endorse or promote products
18 derived from this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31*/
32
33/*
34 The echo canceller is based on the MDF algorithm described in:
35
36 J. S. Soo, K. K. Pang Multidelay block frequency adaptive filter,
37 IEEE Trans. Acoust. Speech Signal Process., Vol. ASSP-38, No. 2,
38 February 1990.
39
40 We use the Alternatively Updated MDF (AUMDF) variant. Robustness to
41 double-talk is achieved using a variable learning rate as described in:
42
43 Valin, J.-M., On Adjusting the Learning Rate in Frequency Domain Echo
44 Cancellation With Double-Talk. IEEE Transactions on Audio,
45 Speech and Language Processing, Vol. 15, No. 3, pp. 1030-1034, 2007.
46 http://people.xiph.org/~jm/papers/valin_taslp2006.pdf
47
48 There is no explicit double-talk detection, but a continuous variation
49 in the learning rate based on residual echo, double-talk and background
50 noise.
51
52 About the fixed-point version:
53 All the signals are represented with 16-bit words. The filter weights
54 are represented with 32-bit words, but only the top 16 bits are used
55 in most cases. The lower 16 bits are completely unreliable (due to the
56 fact that the update is done only on the top bits), but help in the
57 adaptation -- probably by removing a "threshold effect" due to
58 quantization (rounding going to zero) when the gradient is small.
59
60 Another kludge that seems to work good: when performing the weight
61 update, we only move half the way toward the "goal" this seems to
62 reduce the effect of quantization noise in the update phase. This
63 can be seen as applying a gradient descent on a "soft constraint"
64 instead of having a hard constraint.
65
66*/
67
68#ifdef HAVE_CONFIG_H
69#include "config-speex.h"
70#endif
71
72#include "arch.h"
73#include "speex/speex_echo.h"
74#include "fftwrap.h"
75#include "pseudofloat.h"
76#include "math_approx.h"
77#include "os_support.h"
78
79#ifndef M_PI
80#define M_PI 3.14159265358979323846
81#endif
82
83#ifdef FIXED_POINT
84#define WEIGHT_SHIFT 11
85#define NORMALIZE_SCALEDOWN 5
86#define NORMALIZE_SCALEUP 3
87#else
88#define WEIGHT_SHIFT 0
89#endif
90
91/* If enabled, the AEC will use a foreground filter and a background filter to be more robust to double-talk
92 and difficult signals in general. The cost is an extra FFT and a matrix-vector multiply */
93#define TWO_PATH
94
95#ifdef FIXED_POINT
96static const spx_float_t MIN_LEAK = {20972, -22};
97
98/* Constants for the two-path filter */
99static const spx_float_t VAR1_SMOOTH = {23593, -16};
100static const spx_float_t VAR2_SMOOTH = {23675, -15};
101static const spx_float_t VAR1_UPDATE = {16384, -15};
102static const spx_float_t VAR2_UPDATE = {16384, -16};
103static const spx_float_t VAR_BACKTRACK = {16384, -12};
104#define TOP16(x) ((x)>>16)
105
106#else
107
108static const spx_float_t MIN_LEAK = .005f;
109
110/* Constants for the two-path filter */
111static const spx_float_t VAR1_SMOOTH = .36f;
112static const spx_float_t VAR2_SMOOTH = .7225f;
113static const spx_float_t VAR1_UPDATE = .5f;
114static const spx_float_t VAR2_UPDATE = .25f;
115static const spx_float_t VAR_BACKTRACK = 4.f;
116#define TOP16(x) (x)
117#endif
118
119
120#define PLAYBACK_DELAY 2
121
122void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len);
123
124
125/** Speex echo cancellation state. */
126struct SpeexEchoState_ {
127 int frame_size; /**< Number of samples processed each time */
128 int window_size;
129 int M;
130 int cancel_count;
131 int adapted;
132 int saturated;
133 int screwed_up;
134 spx_int32_t sampling_rate;
135 spx_word16_t spec_average;
136 spx_word16_t beta0;
137 spx_word16_t beta_max;
138 spx_word32_t sum_adapt;
139 spx_word16_t leak_estimate;
140
141 spx_word16_t *e; /* scratch */
142 spx_word16_t *x; /* Far-end input buffer (2N) */
143 spx_word16_t *X; /* Far-end buffer (M+1 frames) in frequency domain */
144 spx_word16_t *input; /* scratch */
145 spx_word16_t *y; /* scratch */
146 spx_word16_t *last_y;
147 spx_word16_t *Y; /* scratch */
148 spx_word16_t *E;
149 spx_word32_t *PHI; /* scratch */
150 spx_word32_t *W; /* (Background) filter weights */
151#ifdef TWO_PATH
152 spx_word16_t *foreground; /* Foreground filter weights */
153 spx_word32_t Davg1; /* 1st recursive average of the residual power difference */
154 spx_word32_t Davg2; /* 2nd recursive average of the residual power difference */
155 spx_float_t Dvar1; /* Estimated variance of 1st estimator */
156 spx_float_t Dvar2; /* Estimated variance of 2nd estimator */
157#endif
158 spx_word32_t *power; /* Power of the far-end signal */
159 spx_float_t *power_1;/* Inverse power of far-end */
160 spx_word16_t *wtmp; /* scratch */
161#ifdef FIXED_POINT
162 spx_word16_t *wtmp2; /* scratch */
163#endif
164 spx_word32_t *Rf; /* scratch */
165 spx_word32_t *Yf; /* scratch */
166 spx_word32_t *Xf; /* scratch */
167 spx_word32_t *Eh;
168 spx_word32_t *Yh;
169 spx_float_t Pey;
170 spx_float_t Pyy;
171 spx_word16_t *window;
172 spx_word16_t *prop;
173 void *fft_table;
174 spx_word16_t memX, memD, memE;
175 spx_word16_t preemph;
176 spx_word16_t notch_radius;
177 spx_mem_t notch_mem[2];
178
179 /* NOTE: If you only use speex_echo_cancel() and want to save some memory, remove this */
180 spx_int16_t *play_buf;
181 int play_buf_pos;
182 int play_buf_started;
183};
184
185static inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius, spx_word16_t *out, int len, spx_mem_t *mem)
186{
187 int i;
188 spx_word16_t den2;
189#ifdef FIXED_POINT
190 den2 = MULT16_16_Q15(radius,radius) + MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q15(32767-radius,32767-radius));
191#else
192 den2 = radius*radius + .7*(1-radius)*(1-radius);
193#endif
194 /*printf ("%d %d %d %d %d %d\n", num[0], num[1], num[2], den[0], den[1], den[2]);*/
195 for (i=0;i<len;i++)
196 {
197 spx_word16_t vin = in[i];
198 spx_word32_t vout = mem[0] + SHL32(EXTEND32(vin),15);
199#ifdef FIXED_POINT
200 mem[0] = mem[1] + SHL32(SHL32(-EXTEND32(vin),15) + MULT16_32_Q15(radius,vout),1);
201#else
202 mem[0] = mem[1] + 2*(-vin + radius*vout);
203#endif
204 mem[1] = SHL32(EXTEND32(vin),15) - MULT16_32_Q15(den2,vout);
205 out[i] = SATURATE32(PSHR32(MULT16_32_Q15(radius,vout),15),32767);
206 }
207}
208
209/* This inner product is slightly different from the codec version because of fixed-point */
210static inline spx_word32_t mdf_inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
211{
212 spx_word32_t sum=0;
213 len >>= 1;
214 while(len--)
215 {
216 spx_word32_t part=0;
217 part = MAC16_16(part,*x++,*y++);
218 part = MAC16_16(part,*x++,*y++);
219 /* HINT: If you had a 40-bit accumulator, you could shift only at the end */
220 sum = ADD32(sum,SHR32(part,6));
221 }
222 return sum;
223}
224
225/** Compute power spectrum of a half-complex (packed) vector */
226static inline void power_spectrum(const spx_word16_t *X, spx_word32_t *ps, int N)
227{
228 int i, j;
229 ps[0]=MULT16_16(X[0],X[0]);
230 for (i=1,j=1;i<N-1;i+=2,j++)
231 {
232 ps[j] = MULT16_16(X[i],X[i]) + MULT16_16(X[i+1],X[i+1]);
233 }
234 ps[j]=MULT16_16(X[i],X[i]);
235}
236
237/** Compute cross-power spectrum of a half-complex (packed) vectors and add to acc */
238#ifdef FIXED_POINT
239static inline void spectral_mul_accum(const spx_word16_t *X, const spx_word32_t *Y, spx_word16_t *acc, int N, int M)
240{
241 int i,j;
242 spx_word32_t tmp1=0,tmp2=0;
243 for (j=0;j<M;j++)
244 {
245 tmp1 = MAC16_16(tmp1, X[j*N],TOP16(Y[j*N]));
246 }
247 acc[0] = PSHR32(tmp1,WEIGHT_SHIFT);
248 for (i=1;i<N-1;i+=2)
249 {
250 tmp1 = tmp2 = 0;
251 for (j=0;j<M;j++)
252 {
253 tmp1 = SUB32(MAC16_16(tmp1, X[j*N+i],TOP16(Y[j*N+i])), MULT16_16(X[j*N+i+1],TOP16(Y[j*N+i+1])));
254 tmp2 = MAC16_16(MAC16_16(tmp2, X[j*N+i+1],TOP16(Y[j*N+i])), X[j*N+i], TOP16(Y[j*N+i+1]));
255 }
256 acc[i] = PSHR32(tmp1,WEIGHT_SHIFT);
257 acc[i+1] = PSHR32(tmp2,WEIGHT_SHIFT);
258 }
259 tmp1 = tmp2 = 0;
260 for (j=0;j<M;j++)
261 {
262 tmp1 = MAC16_16(tmp1, X[(j+1)*N-1],TOP16(Y[(j+1)*N-1]));
263 }
264 acc[N-1] = PSHR32(tmp1,WEIGHT_SHIFT);
265}
266static inline void spectral_mul_accum16(const spx_word16_t *X, const spx_word16_t *Y, spx_word16_t *acc, int N, int M)
267{
268 int i,j;
269 spx_word32_t tmp1=0,tmp2=0;
270 for (j=0;j<M;j++)
271 {
272 tmp1 = MAC16_16(tmp1, X[j*N],Y[j*N]);
273 }
274 acc[0] = PSHR32(tmp1,WEIGHT_SHIFT);
275 for (i=1;i<N-1;i+=2)
276 {
277 tmp1 = tmp2 = 0;
278 for (j=0;j<M;j++)
279 {
280 tmp1 = SUB32(MAC16_16(tmp1, X[j*N+i],Y[j*N+i]), MULT16_16(X[j*N+i+1],Y[j*N+i+1]));
281 tmp2 = MAC16_16(MAC16_16(tmp2, X[j*N+i+1],Y[j*N+i]), X[j*N+i], Y[j*N+i+1]);
282 }
283 acc[i] = PSHR32(tmp1,WEIGHT_SHIFT);
284 acc[i+1] = PSHR32(tmp2,WEIGHT_SHIFT);
285 }
286 tmp1 = tmp2 = 0;
287 for (j=0;j<M;j++)
288 {
289 tmp1 = MAC16_16(tmp1, X[(j+1)*N-1],Y[(j+1)*N-1]);
290 }
291 acc[N-1] = PSHR32(tmp1,WEIGHT_SHIFT);
292}
293
294#else
295static inline void spectral_mul_accum(const spx_word16_t *X, const spx_word32_t *Y, spx_word16_t *acc, int N, int M)
296{
297 int i,j;
298 for (i=0;i<N;i++)
299 acc[i] = 0;
300 for (j=0;j<M;j++)
301 {
302 acc[0] += X[0]*Y[0];
303 for (i=1;i<N-1;i+=2)
304 {
305 acc[i] += (X[i]*Y[i] - X[i+1]*Y[i+1]);
306 acc[i+1] += (X[i+1]*Y[i] + X[i]*Y[i+1]);
307 }
308 acc[i] += X[i]*Y[i];
309 X += N;
310 Y += N;
311 }
312}
313#define spectral_mul_accum16 spectral_mul_accum
314#endif
315
316/** Compute weighted cross-power spectrum of a half-complex (packed) vector with conjugate */
317static inline void weighted_spectral_mul_conj(const spx_float_t *w, const spx_float_t p, const spx_word16_t *X, const spx_word16_t *Y, spx_word32_t *prod, int N)
318{
319 int i, j;
320 spx_float_t W;
321 W = FLOAT_AMULT(p, w[0]);
322 prod[0] = FLOAT_MUL32(W,MULT16_16(X[0],Y[0]));
323 for (i=1,j=1;i<N-1;i+=2,j++)
324 {
325 W = FLOAT_AMULT(p, w[j]);
326 prod[i] = FLOAT_MUL32(W,MAC16_16(MULT16_16(X[i],Y[i]), X[i+1],Y[i+1]));
327 prod[i+1] = FLOAT_MUL32(W,MAC16_16(MULT16_16(-X[i+1],Y[i]), X[i],Y[i+1]));
328 }
329 W = FLOAT_AMULT(p, w[j]);
330 prod[i] = FLOAT_MUL32(W,MULT16_16(X[i],Y[i]));
331}
332
333static inline void mdf_adjust_prop(const spx_word32_t *W, int N, int M, spx_word16_t *prop)
334{
335 int i, j;
336 spx_word16_t max_sum = 1;
337 spx_word32_t prop_sum = 1;
338 for (i=0;i<M;i++)
339 {
340 spx_word32_t tmp = 1;
341 for (j=0;j<N;j++)
342 tmp += MULT16_16(EXTRACT16(SHR32(W[i*N+j],18)), EXTRACT16(SHR32(W[i*N+j],18)));
343#ifdef FIXED_POINT
344 /* Just a security in case an overflow were to occur */
345 tmp = MIN32(ABS32(tmp), 536870912);
346#endif
347 prop[i] = spx_sqrt(tmp);
348 if (prop[i] > max_sum)
349 max_sum = prop[i];
350 }
351 for (i=0;i<M;i++)
352 {
353 prop[i] += MULT16_16_Q15(QCONST16(.1f,15),max_sum);
354 prop_sum += EXTEND32(prop[i]);
355 }
356 for (i=0;i<M;i++)
357 {
358 prop[i] = DIV32(MULT16_16(QCONST16(.99f,15), prop[i]),prop_sum);
359 /*printf ("%f ", prop[i]);*/
360 }
361 /*printf ("\n");*/
362}
363
364#ifdef DUMP_ECHO_CANCEL_DATA
365#include <stdio.h>
366static FILE *rFile=NULL, *pFile=NULL, *oFile=NULL;
367
368static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const spx_int16_t *out, int len)
369{
370 if (!(rFile && pFile && oFile))
371 {
372 speex_fatal("Dump files not open");
373 }
374 fwrite(rec, sizeof(spx_int16_t), len, rFile);
375 fwrite(play, sizeof(spx_int16_t), len, pFile);
376 fwrite(out, sizeof(spx_int16_t), len, oFile);
377}
378#endif
379
380/** Creates a new echo canceller state */
381SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length)
382{
383 int i,N,M;
384 SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState));
385
386#ifdef DUMP_ECHO_CANCEL_DATA
387 if (rFile || pFile || oFile)
388 speex_fatal("Opening dump files twice");
389 rFile = fopen("aec_rec.sw", "wb");
390 pFile = fopen("aec_play.sw", "wb");
391 oFile = fopen("aec_out.sw", "wb");
392#endif
393
394 st->frame_size = frame_size;
395 st->window_size = 2*frame_size;
396 N = st->window_size;
397 M = st->M = (filter_length+st->frame_size-1)/frame_size;
398 st->cancel_count=0;
399 st->sum_adapt = 0;
400 st->saturated = 0;
401 st->screwed_up = 0;
402 /* This is the default sampling rate */
403 st->sampling_rate = 8000;
404 st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate);
405#ifdef FIXED_POINT
406 st->beta0 = DIV32_16(SHL32(EXTEND32(st->frame_size), 16), st->sampling_rate);
407 st->beta_max = DIV32_16(SHL32(EXTEND32(st->frame_size), 14), st->sampling_rate);
408#else
409 st->beta0 = (2.0f*st->frame_size)/st->sampling_rate;
410 st->beta_max = (.5f*st->frame_size)/st->sampling_rate;
411#endif
412 st->leak_estimate = 0;
413
414 st->fft_table = spx_fft_init(N);
415
416 st->e = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));
417 st->x = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));
418 st->input = (spx_word16_t*)speex_alloc(st->frame_size*sizeof(spx_word16_t));
419 st->y = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));
420 st->last_y = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));
421 st->Yf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t));
422 st->Rf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t));
423 st->Xf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t));
424 st->Yh = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t));
425 st->Eh = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t));
426
427 st->X = (spx_word16_t*)speex_alloc((M+1)*N*sizeof(spx_word16_t));
428 st->Y = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));
429 st->E = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));
430 st->W = (spx_word32_t*)speex_alloc(M*N*sizeof(spx_word32_t));
431#ifdef TWO_PATH
432 st->foreground = (spx_word16_t*)speex_alloc(M*N*sizeof(spx_word16_t));
433#endif
434 st->PHI = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t));
435 st->power = (spx_word32_t*)speex_alloc((frame_size+1)*sizeof(spx_word32_t));
436 st->power_1 = (spx_float_t*)speex_alloc((frame_size+1)*sizeof(spx_float_t));
437 st->window = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));
438 st->prop = (spx_word16_t*)speex_alloc(M*sizeof(spx_word16_t));
439 st->wtmp = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));
440#ifdef FIXED_POINT
441 st->wtmp2 = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));
442 for (i=0;i<N>>1;i++)
443 {
444 st->window[i] = (16383-SHL16(spx_cos(DIV32_16(MULT16_16(25736,i<<1),N)),1));
445 st->window[N-i-1] = st->window[i];
446 }
447#else
448 for (i=0;i<N;i++)
449 st->window[i] = .5-.5*cos(2*M_PI*i/N);
450#endif
451 for (i=0;i<=st->frame_size;i++)
452 st->power_1[i] = FLOAT_ONE;
453 for (i=0;i<N*M;i++)
454 st->W[i] = 0;
455 {
456 spx_word32_t sum = 0;
457 /* Ratio of ~10 between adaptation rate of first and last block */
458 spx_word16_t decay = SHR32(spx_exp(NEG16(DIV32_16(QCONST16(2.4,11),M))),1);
459 st->prop[0] = QCONST16(.7, 15);
460 sum = EXTEND32(st->prop[0]);
461 for (i=1;i<M;i++)
462 {
463 st->prop[i] = MULT16_16_Q15(st->prop[i-1], decay);
464 sum = ADD32(sum, EXTEND32(st->prop[i]));
465 }
466 for (i=M-1;i>=0;i--)
467 {
468 st->prop[i] = DIV32(MULT16_16(QCONST16(.8,15), st->prop[i]),sum);
469 }
470 }
471
472 st->memX=st->memD=st->memE=0;
473 st->preemph = QCONST16(.9,15);
474 if (st->sampling_rate<12000)
475 st->notch_radius = QCONST16(.9, 15);
476 else if (st->sampling_rate<24000)
477 st->notch_radius = QCONST16(.982, 15);
478 else
479 st->notch_radius = QCONST16(.992, 15);
480
481 st->notch_mem[0] = st->notch_mem[1] = 0;
482 st->adapted = 0;
483 st->Pey = st->Pyy = FLOAT_ONE;
484
485#ifdef TWO_PATH
486 st->Davg1 = st->Davg2 = 0;
487 st->Dvar1 = st->Dvar2 = FLOAT_ZERO;
488#endif
489
490 st->play_buf = (spx_int16_t*)speex_alloc((PLAYBACK_DELAY+1)*st->frame_size*sizeof(spx_int16_t));
491 st->play_buf_pos = PLAYBACK_DELAY*st->frame_size;
492 st->play_buf_started = 0;
493
494 return st;
495}
496
497/** Resets echo canceller state */
498void speex_echo_state_reset(SpeexEchoState *st)
499{
500 int i, M, N;
501 st->cancel_count=0;
502 st->screwed_up = 0;
503 N = st->window_size;
504 M = st->M;
505 for (i=0;i<N*M;i++)
506 st->W[i] = 0;
507#ifdef TWO_PATH
508 for (i=0;i<N*M;i++)
509 st->foreground[i] = 0;
510#endif
511 for (i=0;i<N*(M+1);i++)
512 st->X[i] = 0;
513 for (i=0;i<=st->frame_size;i++)
514 {
515 st->power[i] = 0;
516 st->power_1[i] = FLOAT_ONE;
517 st->Eh[i] = 0;
518 st->Yh[i] = 0;
519 }
520 for (i=0;i<st->frame_size;i++)
521 {
522 st->last_y[i] = 0;
523 }
524 for (i=0;i<N;i++)
525 {
526 st->E[i] = 0;
527 st->x[i] = 0;
528 }
529 st->notch_mem[0] = st->notch_mem[1] = 0;
530 st->memX=st->memD=st->memE=0;
531
532 st->saturated = 0;
533 st->adapted = 0;
534 st->sum_adapt = 0;
535 st->Pey = st->Pyy = FLOAT_ONE;
536#ifdef TWO_PATH
537 st->Davg1 = st->Davg2 = 0;
538 st->Dvar1 = st->Dvar2 = FLOAT_ZERO;
539#endif
540 for (i=0;i<3*st->frame_size;i++)
541 st->play_buf[i] = 0;
542 st->play_buf_pos = PLAYBACK_DELAY*st->frame_size;
543 st->play_buf_started = 0;
544
545}
546
547/** Destroys an echo canceller state */
548void speex_echo_state_destroy(SpeexEchoState *st)
549{
550 spx_fft_destroy(st->fft_table);
551
552 speex_free(st->e);
553 speex_free(st->x);
554 speex_free(st->input);
555 speex_free(st->y);
556 speex_free(st->last_y);
557 speex_free(st->Yf);
558 speex_free(st->Rf);
559 speex_free(st->Xf);
560 speex_free(st->Yh);
561 speex_free(st->Eh);
562
563 speex_free(st->X);
564 speex_free(st->Y);
565 speex_free(st->E);
566 speex_free(st->W);
567#ifdef TWO_PATH
568 speex_free(st->foreground);
569#endif
570 speex_free(st->PHI);
571 speex_free(st->power);
572 speex_free(st->power_1);
573 speex_free(st->window);
574 speex_free(st->prop);
575 speex_free(st->wtmp);
576#ifdef FIXED_POINT
577 speex_free(st->wtmp2);
578#endif
579 speex_free(st->play_buf);
580 speex_free(st);
581
582#ifdef DUMP_ECHO_CANCEL_DATA
583 fclose(rFile);
584 fclose(pFile);
585 fclose(oFile);
586 rFile = pFile = oFile = NULL;
587#endif
588}
589
590void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out)
591{
592 int i;
593 /*speex_warning_int("capture with fill level ", st->play_buf_pos/st->frame_size);*/
594 st->play_buf_started = 1;
595 if (st->play_buf_pos>=st->frame_size)
596 {
597 speex_echo_cancellation(st, rec, st->play_buf, out);
598 st->play_buf_pos -= st->frame_size;
599 for (i=0;i<st->play_buf_pos;i++)
600 st->play_buf[i] = st->play_buf[i+st->frame_size];
601 } else {
602 speex_warning("No playback frame available (your application is buggy and/or got xruns)");
603 if (st->play_buf_pos!=0)
604 {
605 speex_warning("internal playback buffer corruption?");
606 st->play_buf_pos = 0;
607 }
608 for (i=0;i<st->frame_size;i++)
609 out[i] = rec[i];
610 }
611}
612
613void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play)
614{
615 /*speex_warning_int("playback with fill level ", st->play_buf_pos/st->frame_size);*/
616 if (!st->play_buf_started)
617 {
618 speex_warning("discarded first playback frame");
619 return;
620 }
621 if (st->play_buf_pos<=PLAYBACK_DELAY*st->frame_size)
622 {
623 int i;
624 for (i=0;i<st->frame_size;i++)
625 st->play_buf[st->play_buf_pos+i] = play[i];
626 st->play_buf_pos += st->frame_size;
627 if (st->play_buf_pos <= (PLAYBACK_DELAY-1)*st->frame_size)
628 {
629 speex_warning("Auto-filling the buffer (your application is buggy and/or got xruns)");
630 for (i=0;i<st->frame_size;i++)
631 st->play_buf[st->play_buf_pos+i] = play[i];
632 st->play_buf_pos += st->frame_size;
633 }
634 } else {
635 speex_warning("Had to discard a playback frame (your application is buggy and/or got xruns)");
636 }
637}
638
639/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */
640void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout)
641{
642 speex_echo_cancellation(st, in, far_end, out);
643}
644
645/** Performs echo cancellation on a frame */
646void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out)
647{
648 int i,j;
649 int N,M;
650 spx_word32_t Syy,See,Sxx,Sdd, Sff;
651#ifdef TWO_PATH
652 spx_word32_t Dbf;
653 int update_foreground;
654#endif
655 spx_word32_t Sey;
656 spx_word16_t ss, ss_1;
657 spx_float_t Pey = FLOAT_ONE, Pyy=FLOAT_ONE;
658 spx_float_t alpha, alpha_1;
659 spx_word16_t RER;
660 spx_word32_t tmp32;
661
662 N = st->window_size;
663 M = st->M;
664 st->cancel_count++;
665#ifdef FIXED_POINT
666 ss=DIV32_16(11469,M);
667 ss_1 = SUB16(32767,ss);
668#else
669 ss=.35/M;
670 ss_1 = 1-ss;
671#endif
672
673 /* Apply a notch filter to make sure DC doesn't end up causing problems */
674 filter_dc_notch16(in, st->notch_radius, st->input, st->frame_size, st->notch_mem);
675 /* Copy input data to buffer and apply pre-emphasis */
676 for (i=0;i<st->frame_size;i++)
677 {
678 spx_word32_t tmp32;
679 tmp32 = SUB32(EXTEND32(far_end[i]), EXTEND32(MULT16_16_P15(st->preemph, st->memX)));
680#ifdef FIXED_POINT
681 /* If saturation occurs here, we need to freeze adaptation for M+1 frames (not just one) */
682 if (tmp32 > 32767)
683 {
684 tmp32 = 32767;
685 st->saturated = M+1;
686 }
687 if (tmp32 < -32767)
688 {
689 tmp32 = -32767;
690 st->saturated = M+1;
691 }
692#endif
693 st->x[i+st->frame_size] = EXTRACT16(tmp32);
694 st->memX = far_end[i];
695
696 tmp32 = SUB32(EXTEND32(st->input[i]), EXTEND32(MULT16_16_P15(st->preemph, st->memD)));
697#ifdef FIXED_POINT
698 if (tmp32 > 32767)
699 {
700 tmp32 = 32767;
701 if (st->saturated == 0)
702 st->saturated = 1;
703 }
704 if (tmp32 < -32767)
705 {
706 tmp32 = -32767;
707 if (st->saturated == 0)
708 st->saturated = 1;
709 }
710#endif
711 st->memD = st->input[i];
712 st->input[i] = tmp32;
713 }
714
715 /* Shift memory: this could be optimized eventually*/
716 for (j=M-1;j>=0;j--)
717 {
718 for (i=0;i<N;i++)
719 st->X[(j+1)*N+i] = st->X[j*N+i];
720 }
721
722 /* Convert x (far end) to frequency domain */
723 spx_fft(st->fft_table, st->x, &st->X[0]);
724 for (i=0;i<N;i++)
725 st->last_y[i] = st->x[i];
726 Sxx = mdf_inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size);
727 for (i=0;i<st->frame_size;i++)
728 st->x[i] = st->x[i+st->frame_size];
729 /* From here on, the top part of x is used as scratch space */
730
731#ifdef TWO_PATH
732 /* Compute foreground filter */
733 spectral_mul_accum16(st->X, st->foreground, st->Y, N, M);
734 spx_ifft(st->fft_table, st->Y, st->e);
735 for (i=0;i<st->frame_size;i++)
736 st->e[i] = SUB16(st->input[i], st->e[i+st->frame_size]);
737 Sff = mdf_inner_prod(st->e, st->e, st->frame_size);
738#endif
739
740 /* Adjust proportional adaption rate */
741 mdf_adjust_prop (st->W, N, M, st->prop);
742 /* Compute weight gradient */
743 if (st->saturated == 0)
744 {
745 for (j=M-1;j>=0;j--)
746 {
747 weighted_spectral_mul_conj(st->power_1, FLOAT_SHL(PSEUDOFLOAT(st->prop[j]),-15), &st->X[(j+1)*N], st->E, st->PHI, N);
748 for (i=0;i<N;i++)
749 st->W[j*N+i] = ADD32(st->W[j*N+i], st->PHI[i]);
750
751 }
752 } else {
753 st->saturated--;
754 }
755
756 /* Update weight to prevent circular convolution (MDF / AUMDF) */
757 for (j=0;j<M;j++)
758 {
759 /* This is a variant of the Alternatively Updated MDF (AUMDF) */
760 /* Remove the "if" to make this an MDF filter */
761 if (j==0 || st->cancel_count%(M-1) == j-1)
762 {
763#ifdef FIXED_POINT
764 for (i=0;i<N;i++)
765 st->wtmp2[i] = EXTRACT16(PSHR32(st->W[j*N+i],NORMALIZE_SCALEDOWN+16));
766 spx_ifft(st->fft_table, st->wtmp2, st->wtmp);
767 for (i=0;i<st->frame_size;i++)
768 {
769 st->wtmp[i]=0;
770 }
771 for (i=st->frame_size;i<N;i++)
772 {
773 st->wtmp[i]=SHL16(st->wtmp[i],NORMALIZE_SCALEUP);
774 }
775 spx_fft(st->fft_table, st->wtmp, st->wtmp2);
776 /* The "-1" in the shift is a sort of kludge that trades less efficient update speed for decrease noise */
777 for (i=0;i<N;i++)
778 st->W[j*N+i] -= SHL32(EXTEND32(st->wtmp2[i]),16+NORMALIZE_SCALEDOWN-NORMALIZE_SCALEUP-1);
779#else
780 spx_ifft(st->fft_table, &st->W[j*N], st->wtmp);
781 for (i=st->frame_size;i<N;i++)
782 {
783 st->wtmp[i]=0;
784 }
785 spx_fft(st->fft_table, st->wtmp, &st->W[j*N]);
786#endif
787 }
788 }
789
790 /* Compute filter response Y */
791 spectral_mul_accum(st->X, st->W, st->Y, N, M);
792 spx_ifft(st->fft_table, st->Y, st->y);
793
794#ifdef TWO_PATH
795 /* Difference in response, this is used to estimate the variance of our residual power estimate */
796 for (i=0;i<st->frame_size;i++)
797 st->e[i] = SUB16(st->e[i+st->frame_size], st->y[i+st->frame_size]);
798 Dbf = 10+mdf_inner_prod(st->e, st->e, st->frame_size);
799#endif
800
801 for (i=0;i<st->frame_size;i++)
802 st->e[i] = SUB16(st->input[i], st->y[i+st->frame_size]);
803 See = mdf_inner_prod(st->e, st->e, st->frame_size);
804#ifndef TWO_PATH
805 Sff = See;
806#endif
807
808#ifdef TWO_PATH
809 /* Logic for updating the foreground filter */
810
811 /* For two time windows, compute the mean of the energy difference, as well as the variance */
812 st->Davg1 = ADD32(MULT16_32_Q15(QCONST16(.6f,15),st->Davg1), MULT16_32_Q15(QCONST16(.4f,15),SUB32(Sff,See)));
813 st->Davg2 = ADD32(MULT16_32_Q15(QCONST16(.85f,15),st->Davg2), MULT16_32_Q15(QCONST16(.15f,15),SUB32(Sff,See)));
814 st->Dvar1 = FLOAT_ADD(FLOAT_MULT(VAR1_SMOOTH, st->Dvar1), FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.4f,15),Sff), MULT16_32_Q15(QCONST16(.4f,15),Dbf)));
815 st->Dvar2 = FLOAT_ADD(FLOAT_MULT(VAR2_SMOOTH, st->Dvar2), FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.15f,15),Sff), MULT16_32_Q15(QCONST16(.15f,15),Dbf)));
816
817 /* Equivalent float code:
818 st->Davg1 = .6*st->Davg1 + .4*(Sff-See);
819 st->Davg2 = .85*st->Davg2 + .15*(Sff-See);
820 st->Dvar1 = .36*st->Dvar1 + .16*Sff*Dbf;
821 st->Dvar2 = .7225*st->Dvar2 + .0225*Sff*Dbf;
822 */
823
824 update_foreground = 0;
825 /* Check if we have a statistically significant reduction in the residual echo */
826 /* Note that this is *not* Gaussian, so we need to be careful about the longer tail */
827 if (FLOAT_GT(FLOAT_MUL32U(SUB32(Sff,See),ABS32(SUB32(Sff,See))), FLOAT_MUL32U(Sff,Dbf)))
828 update_foreground = 1;
829 else if (FLOAT_GT(FLOAT_MUL32U(st->Davg1, ABS32(st->Davg1)), FLOAT_MULT(VAR1_UPDATE,(st->Dvar1))))
830 update_foreground = 1;
831 else if (FLOAT_GT(FLOAT_MUL32U(st->Davg2, ABS32(st->Davg2)), FLOAT_MULT(VAR2_UPDATE,(st->Dvar2))))
832 update_foreground = 1;
833
834 /* Do we update? */
835 if (update_foreground)
836 {
837 st->Davg1 = st->Davg2 = 0;
838 st->Dvar1 = st->Dvar2 = FLOAT_ZERO;
839 /* Copy background filter to foreground filter */
840 for (i=0;i<N*M;i++)
841 st->foreground[i] = EXTRACT16(PSHR32(st->W[i],16));
842 /* Apply a smooth transition so as to not introduce blocking artifacts */
843 for (i=0;i<st->frame_size;i++)
844 st->e[i+st->frame_size] = MULT16_16_Q15(st->window[i+st->frame_size],st->e[i+st->frame_size]) + MULT16_16_Q15(st->window[i],st->y[i+st->frame_size]);
845 } else {
846 int reset_background=0;
847 /* Otherwise, check if the background filter is significantly worse */
848 if (FLOAT_GT(FLOAT_MUL32U(NEG32(SUB32(Sff,See)),ABS32(SUB32(Sff,See))), FLOAT_MULT(VAR_BACKTRACK,FLOAT_MUL32U(Sff,Dbf))))
849 reset_background = 1;
850 if (FLOAT_GT(FLOAT_MUL32U(NEG32(st->Davg1), ABS32(st->Davg1)), FLOAT_MULT(VAR_BACKTRACK,st->Dvar1)))
851 reset_background = 1;
852 if (FLOAT_GT(FLOAT_MUL32U(NEG32(st->Davg2), ABS32(st->Davg2)), FLOAT_MULT(VAR_BACKTRACK,st->Dvar2)))
853 reset_background = 1;
854 if (reset_background)
855 {
856 /* Copy foreground filter to background filter */
857 for (i=0;i<N*M;i++)
858 st->W[i] = SHL32(EXTEND32(st->foreground[i]),16);
859 /* We also need to copy the output so as to get correct adaptation */
860 for (i=0;i<st->frame_size;i++)
861 st->y[i+st->frame_size] = st->e[i+st->frame_size];
862 for (i=0;i<st->frame_size;i++)
863 st->e[i] = SUB16(st->input[i], st->y[i+st->frame_size]);
864 See = Sff;
865 st->Davg1 = st->Davg2 = 0;
866 st->Dvar1 = st->Dvar2 = FLOAT_ZERO;
867 }
868 }
869#endif
870
871 /* Compute error signal (for the output with de-emphasis) */
872 for (i=0;i<st->frame_size;i++)
873 {
874 spx_word32_t tmp_out;
875#ifdef TWO_PATH
876 tmp_out = SUB32(EXTEND32(st->input[i]), EXTEND32(st->e[i+st->frame_size]));
877#else
878 tmp_out = SUB32(EXTEND32(st->input[i]), EXTEND32(st->y[i+st->frame_size]));
879#endif
880 /* Saturation */
881 if (tmp_out>32767)
882 tmp_out = 32767;
883 else if (tmp_out<-32768)
884 tmp_out = -32768;
885 tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE)));
886 /* This is an arbitrary test for saturation in the microphone signal */
887 if (in[i] <= -32000 || in[i] >= 32000)
888 {
889 tmp_out = 0;
890 if (st->saturated == 0)
891 st->saturated = 1;
892 }
893 out[i] = (spx_int16_t)tmp_out;
894 st->memE = tmp_out;
895 }
896
897#ifdef DUMP_ECHO_CANCEL_DATA
898 dump_audio(in, far_end, out, st->frame_size);
899#endif
900
901 /* Compute error signal (filter update version) */
902 for (i=0;i<st->frame_size;i++)
903 {
904 st->e[i+st->frame_size] = st->e[i];
905 st->e[i] = 0;
906 }
907
908 /* Compute a bunch of correlations */
909 Sey = mdf_inner_prod(st->e+st->frame_size, st->y+st->frame_size, st->frame_size);
910 Syy = mdf_inner_prod(st->y+st->frame_size, st->y+st->frame_size, st->frame_size);
911 Sdd = mdf_inner_prod(st->input, st->input, st->frame_size);
912
913 /*printf ("%f %f %f %f\n", Sff, See, Syy, Sdd, st->update_cond);*/
914
915 /* Do some sanity check */
916 if (!(Syy>=0 && Sxx>=0 && See >= 0)
917#ifndef FIXED_POINT
918 || !(Sff < N*1e9 && Syy < N*1e9 && Sxx < N*1e9)
919#endif
920 )
921 {
922 /* Things have gone really bad */
923 st->screwed_up += 50;
924 for (i=0;i<st->frame_size;i++)
925 out[i] = 0;
926 } else if (SHR32(Sff, 2) > ADD32(Sdd, SHR32(MULT16_16(N, 10000),6)))
927 {
928 /* AEC seems to add lots of echo instead of removing it, let's see if it will improve */
929 st->screwed_up++;
930 } else {
931 /* Everything's fine */
932 st->screwed_up=0;
933 }
934 if (st->screwed_up>=50)
935 {
936 speex_warning("The echo canceller started acting funny and got slapped (reset). It swears it will behave now.");
937 speex_echo_state_reset(st);
938 return;
939 }
940
941 /* Add a small noise floor to make sure not to have problems when dividing */
942 See = MAX32(See, SHR32(MULT16_16(N, 100),6));
943
944 /* Convert error to frequency domain */
945 spx_fft(st->fft_table, st->e, st->E);
946 for (i=0;i<st->frame_size;i++)
947 st->y[i] = 0;
948 spx_fft(st->fft_table, st->y, st->Y);
949
950 /* Compute power spectrum of far end (X), error (E) and filter response (Y) */
951 power_spectrum(st->E, st->Rf, N);
952 power_spectrum(st->Y, st->Yf, N);
953 power_spectrum(st->X, st->Xf, N);
954
955 /* Smooth far end energy estimate over time */
956 for (j=0;j<=st->frame_size;j++)
957 st->power[j] = MULT16_32_Q15(ss_1,st->power[j]) + 1 + MULT16_32_Q15(ss,st->Xf[j]);
958
959 /* Enable this to compute the power based only on the tail (would need to compute more
960 efficiently to make this really useful */
961 if (0)
962 {
963 float scale2 = .5f/M;
964 for (j=0;j<=st->frame_size;j++)
965 st->power[j] = 100;
966 for (i=0;i<M;i++)
967 {
968 power_spectrum(&st->X[i*N], st->Xf, N);
969 for (j=0;j<=st->frame_size;j++)
970 st->power[j] += scale2*st->Xf[j];
971 }
972 }
973
974 /* Compute filtered spectra and (cross-)correlations */
975 for (j=st->frame_size;j>=0;j--)
976 {
977 spx_float_t Eh, Yh;
978 Eh = PSEUDOFLOAT(st->Rf[j] - st->Eh[j]);
979 Yh = PSEUDOFLOAT(st->Yf[j] - st->Yh[j]);
980 Pey = FLOAT_ADD(Pey,FLOAT_MULT(Eh,Yh));
981 Pyy = FLOAT_ADD(Pyy,FLOAT_MULT(Yh,Yh));
982#ifdef FIXED_POINT
983 st->Eh[j] = MAC16_32_Q15(MULT16_32_Q15(SUB16(32767,st->spec_average),st->Eh[j]), st->spec_average, st->Rf[j]);
984 st->Yh[j] = MAC16_32_Q15(MULT16_32_Q15(SUB16(32767,st->spec_average),st->Yh[j]), st->spec_average, st->Yf[j]);
985#else
986 st->Eh[j] = (1-st->spec_average)*st->Eh[j] + st->spec_average*st->Rf[j];
987 st->Yh[j] = (1-st->spec_average)*st->Yh[j] + st->spec_average*st->Yf[j];
988#endif
989 }
990
991 Pyy = FLOAT_SQRT(Pyy);
992 Pey = FLOAT_DIVU(Pey,Pyy);
993
994 /* Compute correlation updatete rate */
995 tmp32 = MULT16_32_Q15(st->beta0,Syy);
996 if (tmp32 > MULT16_32_Q15(st->beta_max,See))
997 tmp32 = MULT16_32_Q15(st->beta_max,See);
998 alpha = FLOAT_DIV32(tmp32, See);
999 alpha_1 = FLOAT_SUB(FLOAT_ONE, alpha);
1000 /* Update correlations (recursive average) */
1001 st->Pey = FLOAT_ADD(FLOAT_MULT(alpha_1,st->Pey) , FLOAT_MULT(alpha,Pey));
1002 st->Pyy = FLOAT_ADD(FLOAT_MULT(alpha_1,st->Pyy) , FLOAT_MULT(alpha,Pyy));
1003 if (FLOAT_LT(st->Pyy, FLOAT_ONE))
1004 st->Pyy = FLOAT_ONE;
1005 /* We don't really hope to get better than 33 dB (MIN_LEAK-3dB) attenuation anyway */
1006 if (FLOAT_LT(st->Pey, FLOAT_MULT(MIN_LEAK,st->Pyy)))
1007 st->Pey = FLOAT_MULT(MIN_LEAK,st->Pyy);
1008 if (FLOAT_GT(st->Pey, st->Pyy))
1009 st->Pey = st->Pyy;
1010 /* leak_estimate is the linear regression result */
1011 st->leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(st->Pey, st->Pyy),14));
1012 /* This looks like a stupid bug, but it's right (because we convert from Q14 to Q15) */
1013 if (st->leak_estimate > 16383)
1014 st->leak_estimate = 32767;
1015 else
1016 st->leak_estimate = SHL16(st->leak_estimate,1);
1017 /*printf ("%f\n", st->leak_estimate);*/
1018
1019 /* Compute Residual to Error Ratio */
1020#ifdef FIXED_POINT
1021 tmp32 = MULT16_32_Q15(st->leak_estimate,Syy);
1022 tmp32 = ADD32(SHR32(Sxx,13), ADD32(tmp32, SHL32(tmp32,1)));
1023 /* Check for y in e (lower bound on RER) */
1024 {
1025 spx_float_t bound = PSEUDOFLOAT(Sey);
1026 bound = FLOAT_DIVU(FLOAT_MULT(bound, bound), PSEUDOFLOAT(ADD32(1,Syy)));
1027 if (FLOAT_GT(bound, PSEUDOFLOAT(See)))
1028 tmp32 = See;
1029 else if (tmp32 < FLOAT_EXTRACT32(bound))
1030 tmp32 = FLOAT_EXTRACT32(bound);
1031 }
1032 if (tmp32 > SHR32(See,1))
1033 tmp32 = SHR32(See,1);
1034 RER = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32,See),15));
1035#else
1036 RER = (.0001*Sxx + 3.*MULT16_32_Q15(st->leak_estimate,Syy)) / See;
1037 /* Check for y in e (lower bound on RER) */
1038 if (RER < Sey*Sey/(1+See*Syy))
1039 RER = Sey*Sey/(1+See*Syy);
1040 if (RER > .5)
1041 RER = .5;
1042#endif
1043
1044 /* We consider that the filter has had minimal adaptation if the following is true*/
1045 if (!st->adapted && st->sum_adapt > SHL32(EXTEND32(M),15) && MULT16_32_Q15(st->leak_estimate,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy))
1046 {
1047 st->adapted = 1;
1048 }
1049
1050 if (st->adapted)
1051 {
1052 /* Normal learning rate calculation once we're past the minimal adaptation phase */
1053 for (i=0;i<=st->frame_size;i++)
1054 {
1055 spx_word32_t r, e;
1056 /* Compute frequency-domain adaptation mask */
1057 r = MULT16_32_Q15(st->leak_estimate,SHL32(st->Yf[i],3));
1058 e = SHL32(st->Rf[i],3)+1;
1059#ifdef FIXED_POINT
1060 if (r>SHR32(e,1))
1061 r = SHR32(e,1);
1062#else
1063 if (r>.5*e)
1064 r = .5*e;
1065#endif
1066 r = MULT16_32_Q15(QCONST16(.7,15),r) + MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e)));
1067 /*st->power_1[i] = adapt_rate*r/(e*(1+st->power[i]));*/
1068 st->power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,st->power[i]+10)),WEIGHT_SHIFT+16);
1069 }
1070 } else {
1071 /* Temporary adaption rate if filter is not yet adapted enough */
1072 spx_word16_t adapt_rate=0;
1073
1074 if (Sxx > SHR32(MULT16_16(N, 1000),6))
1075 {
1076 tmp32 = MULT16_32_Q15(QCONST16(.25f, 15), Sxx);
1077#ifdef FIXED_POINT
1078 if (tmp32 > SHR32(See,2))
1079 tmp32 = SHR32(See,2);
1080#else
1081 if (tmp32 > .25*See)
1082 tmp32 = .25*See;
1083#endif
1084 adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32, See),15));
1085 }
1086 for (i=0;i<=st->frame_size;i++)
1087 st->power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(st->power[i],10)),WEIGHT_SHIFT+1);
1088
1089
1090 /* How much have we adapted so far? */
1091 st->sum_adapt = ADD32(st->sum_adapt,adapt_rate);
1092 }
1093
1094 /* Save residual echo so it can be used by the nonlinear processor */
1095 if (st->adapted)
1096 {
1097 /* If the filter is adapted, take the filtered echo */
1098 for (i=0;i<st->frame_size;i++)
1099 st->last_y[i] = st->last_y[st->frame_size+i];
1100 for (i=0;i<st->frame_size;i++)
1101 st->last_y[st->frame_size+i] = in[i]-out[i];
1102 } else {
1103 /* If filter isn't adapted yet, all we can do is take the far end signal directly */
1104 /* moved earlier: for (i=0;i<N;i++)
1105 st->last_y[i] = st->x[i];*/
1106 }
1107
1108}
1109
1110/* Compute spectrum of estimated echo for use in an echo post-filter */
1111void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *residual_echo, int len)
1112{
1113 int i;
1114 spx_word16_t leak2;
1115 int N;
1116
1117 N = st->window_size;
1118
1119 /* Apply hanning window (should pre-compute it)*/
1120 for (i=0;i<N;i++)
1121 st->y[i] = MULT16_16_Q15(st->window[i],st->last_y[i]);
1122
1123 /* Compute power spectrum of the echo */
1124 spx_fft(st->fft_table, st->y, st->Y);
1125 power_spectrum(st->Y, residual_echo, N);
1126
1127#ifdef FIXED_POINT
1128 if (st->leak_estimate > 16383)
1129 leak2 = 32767;
1130 else
1131 leak2 = SHL16(st->leak_estimate, 1);
1132#else
1133 if (st->leak_estimate>.5)
1134 leak2 = 1;
1135 else
1136 leak2 = 2*st->leak_estimate;
1137#endif
1138 /* Estimate residual echo */
1139 for (i=0;i<=st->frame_size;i++)
1140 residual_echo[i] = (spx_int32_t)MULT16_32_Q15(leak2,residual_echo[i]);
1141
1142}
1143
1144int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr)
1145{
1146 switch(request)
1147 {
1148
1149 case SPEEX_ECHO_GET_FRAME_SIZE:
1150 (*(int*)ptr) = st->frame_size;
1151 break;
1152 case SPEEX_ECHO_SET_SAMPLING_RATE:
1153 st->sampling_rate = (*(int*)ptr);
1154 st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate);
1155#ifdef FIXED_POINT
1156 st->beta0 = DIV32_16(SHL32(EXTEND32(st->frame_size), 16), st->sampling_rate);
1157 st->beta_max = DIV32_16(SHL32(EXTEND32(st->frame_size), 14), st->sampling_rate);
1158#else
1159 st->beta0 = (2.0f*st->frame_size)/st->sampling_rate;
1160 st->beta_max = (.5f*st->frame_size)/st->sampling_rate;
1161#endif
1162 if (st->sampling_rate<12000)
1163 st->notch_radius = QCONST16(.9, 15);
1164 else if (st->sampling_rate<24000)
1165 st->notch_radius = QCONST16(.982, 15);
1166 else
1167 st->notch_radius = QCONST16(.992, 15);
1168 break;
1169 case SPEEX_ECHO_GET_SAMPLING_RATE:
1170 (*(int*)ptr) = st->sampling_rate;
1171 break;
1172 default:
1173 speex_warning_int("Unknown speex_echo_ctl request: ", request);
1174 return -1;
1175 }
1176 return 0;
1177}
diff --git a/lib/rbcodec/codecs/libspeex/misc_bfin.h b/lib/rbcodec/codecs/libspeex/misc_bfin.h
new file mode 100644
index 0000000000..77b082c057
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/misc_bfin.h
@@ -0,0 +1,54 @@
1/* Copyright (C) 2005 Analog Devices */
2/**
3 @file misc_bfin.h
4 @author Jean-Marc Valin
5 @brief Various compatibility routines for Speex (Blackfin version)
6*/
7/*
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 - Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 - Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19 - Neither the name of the Xiph.org Foundation nor the names of its
20 contributors may be used to endorse or promote products derived from
21 this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#define OVERRIDE_SPEEX_MOVE
37void *speex_move (void *dest, void *src, int n)
38{
39 __asm__ __volatile__
40 (
41 "L0 = 0;\n\t"
42 "I0 = %0;\n\t"
43 "R0 = [I0++];\n\t"
44 "LOOP move%= LC0 = %2;\n\t"
45 "LOOP_BEGIN move%=;\n\t"
46 "[%1++] = R0 || R0 = [I0++];\n\t"
47 "LOOP_END move%=;\n\t"
48 "[%1++] = R0;\n\t"
49 : "=a" (src), "=a" (dest)
50 : "a" ((n>>2)-1), "0" (src), "1" (dest)
51 : "R0", "I0", "L0", "memory"
52 );
53 return dest;
54}
diff --git a/lib/rbcodec/codecs/libspeex/modes.c b/lib/rbcodec/codecs/libspeex/modes.c
new file mode 100644
index 0000000000..d1046f1cfb
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/modes.c
@@ -0,0 +1,484 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin
2 File: modes.c
3
4 Describes the different modes of the codec
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35#ifdef HAVE_CONFIG_H
36#include "config-speex.h"
37#endif
38
39#include "modes.h"
40#include "ltp.h"
41#include "quant_lsp.h"
42#include "cb_search.h"
43#include "sb_celp.h"
44#include "nb_celp.h"
45#include "vbr.h"
46#include "arch.h"
47#include <math.h>
48
49#ifndef NULL
50#define NULL 0
51#endif
52
53
54/* Extern declarations for all codebooks we use here */
55extern const signed char gain_cdbk_nb[];
56extern const signed char gain_cdbk_lbr[];
57extern const signed char exc_5_256_table[];
58extern const signed char exc_5_64_table[];
59extern const signed char exc_8_128_table[];
60extern const signed char exc_10_32_table[];
61extern const signed char exc_10_16_table[];
62extern const signed char exc_20_32_table[];
63
64
65/* Parameters for Long-Term Prediction (LTP)*/
66static const ltp_params ltp_params_nb = {
67 gain_cdbk_nb,
68 7,
69 7
70};
71
72/* Parameters for Long-Term Prediction (LTP)*/
73static const ltp_params ltp_params_vlbr = {
74 gain_cdbk_lbr,
75 5,
76 0
77};
78
79/* Parameters for Long-Term Prediction (LTP)*/
80static const ltp_params ltp_params_lbr = {
81 gain_cdbk_lbr,
82 5,
83 7
84};
85
86/* Parameters for Long-Term Prediction (LTP)*/
87static const ltp_params ltp_params_med = {
88 gain_cdbk_lbr,
89 5,
90 7
91};
92
93/* Split-VQ innovation parameters for very low bit-rate narrowband */
94static const split_cb_params split_cb_nb_vlbr = {
95 10, /*subvect_size*/
96 4, /*nb_subvect*/
97 exc_10_16_table, /*shape_cb*/
98 4, /*shape_bits*/
99 0,
100};
101
102/* Split-VQ innovation parameters for very low bit-rate narrowband */
103static const split_cb_params split_cb_nb_ulbr = {
104 20, /*subvect_size*/
105 2, /*nb_subvect*/
106 exc_20_32_table, /*shape_cb*/
107 5, /*shape_bits*/
108 0,
109};
110
111/* Split-VQ innovation parameters for low bit-rate narrowband */
112static const split_cb_params split_cb_nb_lbr = {
113 10, /*subvect_size*/
114 4, /*nb_subvect*/
115 exc_10_32_table, /*shape_cb*/
116 5, /*shape_bits*/
117 0,
118};
119
120
121/* Split-VQ innovation parameters narrowband */
122static const split_cb_params split_cb_nb = {
123 5, /*subvect_size*/
124 8, /*nb_subvect*/
125 exc_5_64_table, /*shape_cb*/
126 6, /*shape_bits*/
127 0,
128};
129
130/* Split-VQ innovation parameters narrowband */
131static const split_cb_params split_cb_nb_med = {
132 8, /*subvect_size*/
133 5, /*nb_subvect*/
134 exc_8_128_table, /*shape_cb*/
135 7, /*shape_bits*/
136 0,
137};
138
139/* Split-VQ innovation for low-band wideband */
140static const split_cb_params split_cb_sb = {
141 5, /*subvect_size*/
142 8, /*nb_subvect*/
143 exc_5_256_table, /*shape_cb*/
144 8, /*shape_bits*/
145 0,
146};
147
148
149
150/* 2150 bps "vocoder-like" mode for comfort noise */
151static const SpeexSubmode nb_submode1 = {
152 0,
153 1,
154 0,
155 0,
156#ifndef SPEEX_DISABLE_ENCODER
157 /* LSP quantization */
158 lsp_quant_lbr,
159 lsp_unquant_lbr,
160 /* No pitch quantization */
161 forced_pitch_quant,
162 forced_pitch_unquant,
163 NULL,
164 /* No innovation quantization (noise only) */
165 noise_codebook_quant,
166 noise_codebook_unquant,
167#else
168 /* LSP quantization */
169 NULL,
170 lsp_unquant_lbr,
171 /* No pitch quantization */
172 NULL,
173 forced_pitch_unquant,
174 NULL,
175 /* No innovation quantization (noise only) */
176 NULL,
177 noise_codebook_unquant,
178#endif
179 NULL,
180 -1,
181 43
182};
183
184/* 3.95 kbps very low bit-rate mode */
185static const SpeexSubmode nb_submode8 = {
186 0,
187 1,
188 0,
189 0,
190#ifndef SPEEX_DISABLE_ENCODER
191 /*LSP quantization*/
192 lsp_quant_lbr,
193 lsp_unquant_lbr,
194 /*No pitch quantization*/
195 forced_pitch_quant,
196 forced_pitch_unquant,
197 NULL,
198 /*Innovation quantization*/
199 split_cb_search_shape_sign,
200 split_cb_shape_sign_unquant,
201 &split_cb_nb_ulbr,
202#else
203 /*LSP quantization*/
204 NULL,
205 lsp_unquant_lbr,
206 /*No pitch quantization*/
207 NULL,
208 forced_pitch_unquant,
209 NULL,
210 /*Innovation quantization*/
211 NULL,
212 split_cb_shape_sign_unquant,
213 &split_cb_nb_ulbr,
214#endif
215 QCONST16(.5,15),
216 79
217};
218
219/* 5.95 kbps very low bit-rate mode */
220static const SpeexSubmode nb_submode2 = {
221 0,
222 0,
223 0,
224 0,
225#ifndef SPEEX_DISABLE_ENCODER
226 /*LSP quantization*/
227 lsp_quant_lbr,
228 lsp_unquant_lbr,
229 /*No pitch quantization*/
230 pitch_search_3tap,
231 pitch_unquant_3tap,
232 &ltp_params_vlbr,
233 /*Innovation quantization*/
234 split_cb_search_shape_sign,
235 split_cb_shape_sign_unquant,
236 &split_cb_nb_vlbr,
237#else
238 /*LSP quantization*/
239 NULL,
240 lsp_unquant_lbr,
241 /*No pitch quantization*/
242 NULL,
243 pitch_unquant_3tap,
244 &ltp_params_vlbr,
245 /*Innovation quantization*/
246 NULL,
247 split_cb_shape_sign_unquant,
248 &split_cb_nb_vlbr,
249#endif
250 QCONST16(.6,15),
251 119
252};
253
254/* 8 kbps low bit-rate mode */
255static const SpeexSubmode nb_submode3 = {
256 -1,
257 0,
258 1,
259 0,
260#ifndef SPEEX_DISABLE_ENCODER
261 /*LSP quantization*/
262 lsp_quant_lbr,
263 lsp_unquant_lbr,
264 /*Pitch quantization*/
265 pitch_search_3tap,
266 pitch_unquant_3tap,
267 &ltp_params_lbr,
268 /*Innovation quantization*/
269 split_cb_search_shape_sign,
270 split_cb_shape_sign_unquant,
271 &split_cb_nb_lbr,
272#else
273 /*LSP quantization*/
274 NULL,
275 lsp_unquant_lbr,
276 /*Pitch quantization*/
277 NULL,
278 pitch_unquant_3tap,
279 &ltp_params_lbr,
280 /*Innovation quantization*/
281 NULL,
282 split_cb_shape_sign_unquant,
283 &split_cb_nb_lbr,
284#endif
285 QCONST16(.55,15),
286 160
287};
288
289/* 11 kbps medium bit-rate mode */
290static const SpeexSubmode nb_submode4 = {
291 -1,
292 0,
293 1,
294 0,
295#ifndef SPEEX_DISABLE_ENCODER
296 /*LSP quantization*/
297 lsp_quant_lbr,
298 lsp_unquant_lbr,
299 /*Pitch quantization*/
300 pitch_search_3tap,
301 pitch_unquant_3tap,
302 &ltp_params_med,
303 /*Innovation quantization*/
304 split_cb_search_shape_sign,
305 split_cb_shape_sign_unquant,
306 &split_cb_nb_med,
307#else
308 /*LSP quantization*/
309 NULL,
310 lsp_unquant_lbr,
311 /*Pitch quantization*/
312 NULL,
313 pitch_unquant_3tap,
314 &ltp_params_med,
315 /*Innovation quantization*/
316 NULL,
317 split_cb_shape_sign_unquant,
318 &split_cb_nb_med,
319#endif
320 QCONST16(.45,15),
321 220
322};
323
324/* 15 kbps high bit-rate mode */
325static const SpeexSubmode nb_submode5 = {
326 -1,
327 0,
328 3,
329 0,
330#ifndef SPEEX_DISABLE_ENCODER
331 /*LSP quantization*/
332 lsp_quant_nb,
333 lsp_unquant_nb,
334 /*Pitch quantization*/
335 pitch_search_3tap,
336 pitch_unquant_3tap,
337 &ltp_params_nb,
338 /*Innovation quantization*/
339 split_cb_search_shape_sign,
340 split_cb_shape_sign_unquant,
341 &split_cb_nb,
342#else
343 /*LSP quantization*/
344 NULL,
345 lsp_unquant_nb,
346 /*Pitch quantization*/
347 NULL,
348 pitch_unquant_3tap,
349 &ltp_params_nb,
350 /*Innovation quantization*/
351 NULL,
352 split_cb_shape_sign_unquant,
353 &split_cb_nb,
354#endif
355 QCONST16(.3,15),
356 300
357};
358
359/* 18.2 high bit-rate mode */
360static const SpeexSubmode nb_submode6 = {
361 -1,
362 0,
363 3,
364 0,
365#ifndef SPEEX_DISABLE_ENCODER
366 /*LSP quantization*/
367 lsp_quant_nb,
368 lsp_unquant_nb,
369 /*Pitch quantization*/
370 pitch_search_3tap,
371 pitch_unquant_3tap,
372 &ltp_params_nb,
373 /*Innovation quantization*/
374 split_cb_search_shape_sign,
375 split_cb_shape_sign_unquant,
376 &split_cb_sb,
377#else
378 /*LSP quantization*/
379 NULL,
380 lsp_unquant_nb,
381 /*Pitch quantization*/
382 NULL,
383 pitch_unquant_3tap,
384 &ltp_params_nb,
385 /*Innovation quantization*/
386 NULL,
387 split_cb_shape_sign_unquant,
388 &split_cb_sb,
389#endif
390 QCONST16(.2,15),
391 364
392};
393
394/* 24.6 kbps high bit-rate mode */
395static const SpeexSubmode nb_submode7 = {
396 -1,
397 0,
398 3,
399 1,
400#ifndef SPEEX_DISABLE_ENCODER
401 /*LSP quantization*/
402 lsp_quant_nb,
403 lsp_unquant_nb,
404 /*Pitch quantization*/
405 pitch_search_3tap,
406 pitch_unquant_3tap,
407 &ltp_params_nb,
408 /*Innovation quantization*/
409 split_cb_search_shape_sign,
410 split_cb_shape_sign_unquant,
411 &split_cb_nb,
412#else
413 /*LSP quantization*/
414 NULL,
415 lsp_unquant_nb,
416 /*Pitch quantization*/
417 NULL,
418 pitch_unquant_3tap,
419 &ltp_params_nb,
420 /*Innovation quantization*/
421 NULL,
422 split_cb_shape_sign_unquant,
423 &split_cb_nb,
424#endif
425 QCONST16(.1,15),
426 492
427};
428
429
430/* Default mode for narrowband */
431static const SpeexNBMode nb_mode = {
432 160, /*frameSize*/
433 40, /*subframeSize*/
434 10, /*lpcSize*/
435 17, /*pitchStart*/
436 144, /*pitchEnd*/
437#ifdef FIXED_POINT
438 29491, 19661, /* gamma1, gamma2 */
439#else
440 0.9, 0.6, /* gamma1, gamma2 */
441#endif
442 QCONST16(.0002,15), /*lpc_floor*/
443 {NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7,
444 &nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
445 5,
446 {1, 8, 2, 3, 3, 4, 4, 5, 5, 6, 7}
447};
448
449
450/* Default mode for narrowband */
451const SpeexMode speex_nb_mode = {
452 &nb_mode,
453 nb_mode_query,
454 "narrowband",
455 0,
456 4,
457#ifndef SPEEX_DISABLE_ENCODER
458 &nb_encoder_init,
459 &nb_encoder_destroy,
460 &nb_encode,
461 &nb_decoder_init,
462 &nb_decoder_destroy,
463 &nb_decode,
464 &nb_encoder_ctl,
465 &nb_decoder_ctl,
466#else
467/* NULL,
468 NULL,
469 NULL, */
470 &nb_decoder_init,
471 &nb_decoder_destroy,
472 &nb_decode,
473/* NULL, */
474 &nb_decoder_ctl,
475#endif
476};
477
478
479
480int speex_mode_query(const SpeexMode *mode, int request, void *ptr)
481{
482 return mode->query(mode->mode, request, ptr);
483}
484
diff --git a/lib/rbcodec/codecs/libspeex/modes.h b/lib/rbcodec/codecs/libspeex/modes.h
new file mode 100644
index 0000000000..0fa1c3460e
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/modes.h
@@ -0,0 +1,161 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin */
2/**
3 @file modes.h
4 @brief Describes the different modes of the codec
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#ifndef MODES_H
37#define MODES_H
38
39#include "speex/speex.h"
40#include "speex/speex_bits.h"
41#include "arch.h"
42
43#define NB_SUBMODES 16
44#define NB_SUBMODE_BITS 4
45
46#define SB_SUBMODES 8
47#define SB_SUBMODE_BITS 3
48
49/* Used internally, NOT TO BE USED in applications */
50/** Used internally*/
51#define SPEEX_GET_PI_GAIN 100
52/** Used internally*/
53#define SPEEX_GET_EXC 101
54/** Used internally*/
55#define SPEEX_GET_INNOV 102
56/** Used internally*/
57#define SPEEX_GET_DTX_STATUS 103
58/** Used internally*/
59#define SPEEX_SET_INNOVATION_SAVE 104
60/** Used internally*/
61#define SPEEX_SET_WIDEBAND 105
62
63/** Used internally*/
64#define SPEEX_GET_STACK 106
65
66
67/** Quantizes LSPs */
68typedef void (*lsp_quant_func)(spx_lsp_t *, spx_lsp_t *, int, SpeexBits *);
69
70/** Decodes quantized LSPs */
71typedef void (*lsp_unquant_func)(spx_lsp_t *, int, SpeexBits *);
72
73
74/** Long-term predictor quantization */
75typedef int (*ltp_quant_func)(spx_word16_t *, spx_word16_t *, spx_coef_t *, spx_coef_t *,
76 spx_coef_t *, spx_sig_t *, const void *, int, int, spx_word16_t,
77 int, int, SpeexBits*, char *, spx_word16_t *, spx_word16_t *, int, int, int, spx_word32_t *);
78
79/** Long-term un-quantize */
80typedef void (*ltp_unquant_func)(spx_word16_t *, spx_word32_t *, int, int, spx_word16_t, const void *, int, int *,
81 spx_word16_t *, SpeexBits*, char*, int, int, spx_word16_t, int);
82
83
84/** Innovation quantization function */
85typedef void (*innovation_quant_func)(spx_word16_t *, spx_coef_t *, spx_coef_t *, spx_coef_t *, const void *, int, int,
86 spx_sig_t *, spx_word16_t *, SpeexBits *, char *, int, int);
87
88/** Innovation unquantization function */
89typedef void (*innovation_unquant_func)(spx_sig_t *, const void *, int, SpeexBits*, char *, spx_int32_t *);
90
91/** Description of a Speex sub-mode (wither narrowband or wideband */
92typedef struct SpeexSubmode {
93 int lbr_pitch; /**< Set to -1 for "normal" modes, otherwise encode pitch using a global pitch and allowing a +- lbr_pitch variation (for low not-rates)*/
94 int forced_pitch_gain; /**< Use the same (forced) pitch gain for all sub-frames */
95 int have_subframe_gain; /**< Number of bits to use as sub-frame innovation gain */
96 int double_codebook; /**< Apply innovation quantization twice for higher quality (and higher bit-rate)*/
97 /*LSP functions*/
98 lsp_quant_func lsp_quant; /**< LSP quantization function */
99 lsp_unquant_func lsp_unquant; /**< LSP unquantization function */
100
101 /*Long-term predictor functions*/
102 ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */
103 ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */
104 const void *ltp_params; /**< Pitch parameters (options) */
105
106 /*Quantization of innovation*/
107 innovation_quant_func innovation_quant; /**< Innovation quantization */
108 innovation_unquant_func innovation_unquant; /**< Innovation un-quantization */
109 const void *innovation_params; /**< Innovation quantization parameters*/
110
111 spx_word16_t comb_gain; /**< Gain of enhancer comb filter */
112
113 int bits_per_frame; /**< Number of bits per frame after encoding*/
114} SpeexSubmode;
115
116/** Struct defining the encoding/decoding mode*/
117typedef struct SpeexNBMode {
118 int frameSize; /**< Size of frames used for encoding */
119 int subframeSize; /**< Size of sub-frames used for encoding */
120 int lpcSize; /**< Order of LPC filter */
121 int pitchStart; /**< Smallest pitch value allowed */
122 int pitchEnd; /**< Largest pitch value allowed */
123
124 spx_word16_t gamma1; /**< Perceptual filter parameter #1 */
125 spx_word16_t gamma2; /**< Perceptual filter parameter #2 */
126 spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */
127
128 const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */
129 int defaultSubmode; /**< Default sub-mode to use when encoding */
130 int quality_map[11]; /**< Mode corresponding to each quality setting */
131} SpeexNBMode;
132
133
134/** Struct defining the encoding/decoding mode for SB-CELP (wideband) */
135typedef struct SpeexSBMode {
136 const SpeexMode *nb_mode; /**< Embedded narrowband mode */
137 int frameSize; /**< Size of frames used for encoding */
138 int subframeSize; /**< Size of sub-frames used for encoding */
139 int lpcSize; /**< Order of LPC filter */
140 spx_word16_t gamma1; /**< Perceptual filter parameter #1 */
141 spx_word16_t gamma2; /**< Perceptual filter parameter #1 */
142 spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */
143 spx_word16_t folding_gain;
144
145 const SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */
146 int defaultSubmode; /**< Default sub-mode to use when encoding */
147 int low_quality_map[11]; /**< Mode corresponding to each quality setting */
148 int quality_map[11]; /**< Mode corresponding to each quality setting */
149#ifndef DISABLE_VBR
150 const float (*vbr_thresh)[11];
151#endif
152 int nb_modes;
153} SpeexSBMode;
154
155int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits);
156int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out);
157
158int nb_mode_query(const void *mode, int request, void *ptr);
159int wb_mode_query(const void *mode, int request, void *ptr);
160
161#endif
diff --git a/lib/rbcodec/codecs/libspeex/modes_wb.c b/lib/rbcodec/codecs/libspeex/modes_wb.c
new file mode 100644
index 0000000000..93922afa2f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/modes_wb.c
@@ -0,0 +1,374 @@
1/* Copyright (C) 2002-2007 Jean-Marc Valin
2 File: modes.c
3
4 Describes the wideband modes of the codec
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35#ifdef HAVE_CONFIG_H
36#include "config-speex.h"
37#endif
38
39#include "modes.h"
40#include "ltp.h"
41#include "quant_lsp.h"
42#include "cb_search.h"
43#include "sb_celp.h"
44#include "nb_celp.h"
45#include "vbr.h"
46#include "arch.h"
47#include <math.h>
48#include "os_support.h"
49
50
51#ifndef NULL
52#define NULL 0
53#endif
54
55#ifndef ROCKBOX_VOICE_CODEC
56const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
57#else
58const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, NULL};
59#endif
60
61extern const signed char hexc_table[];
62extern const signed char hexc_10_32_table[];
63
64#ifndef DISABLE_WIDEBAND
65
66/* Split-VQ innovation for high-band wideband */
67static const split_cb_params split_cb_high = {
68 8, /*subvect_size*/
69 5, /*nb_subvect*/
70 hexc_table, /*shape_cb*/
71 7, /*shape_bits*/
72 1,
73};
74
75
76/* Split-VQ innovation for high-band wideband */
77static const split_cb_params split_cb_high_lbr = {
78 10, /*subvect_size*/
79 4, /*nb_subvect*/
80 hexc_10_32_table, /*shape_cb*/
81 5, /*shape_bits*/
82 0,
83};
84
85#endif
86
87
88static const SpeexSubmode wb_submode1 = {
89 0,
90 0,
91 1,
92 0,
93 /*LSP quantization*/
94#ifndef SPEEX_DISABLE_ENCODER
95 lsp_quant_high,
96 lsp_unquant_high,
97#else
98 NULL,
99 lsp_unquant_high,
100#endif
101 /*Pitch quantization*/
102 NULL,
103 NULL,
104 NULL,
105 /*No innovation quantization*/
106 NULL,
107 NULL,
108 NULL,
109 -1,
110 36
111};
112
113
114static const SpeexSubmode wb_submode2 = {
115 0,
116 0,
117 1,
118 0,
119#ifndef SPEEX_DISABLE_ENCODER
120 /*LSP quantization*/
121 lsp_quant_high,
122 lsp_unquant_high,
123 /*Pitch quantization*/
124 NULL,
125 NULL,
126 NULL,
127 /*Innovation quantization*/
128 split_cb_search_shape_sign,
129 split_cb_shape_sign_unquant,
130#else
131 /*LSP quantization*/
132 NULL,
133 lsp_unquant_high,
134 /*Pitch quantization*/
135 NULL,
136 NULL,
137 NULL,
138 /*Innovation quantization*/
139 NULL,
140 split_cb_shape_sign_unquant,
141#endif
142#ifdef DISABLE_WIDEBAND
143 NULL,
144#else
145 &split_cb_high_lbr,
146#endif
147 -1,
148 112
149};
150
151
152static const SpeexSubmode wb_submode3 = {
153 0,
154 0,
155 1,
156 0,
157#ifndef SPEEX_DISABLE_ENCODER
158 /*LSP quantization*/
159 lsp_quant_high,
160 lsp_unquant_high,
161 /*Pitch quantization*/
162 NULL,
163 NULL,
164 NULL,
165 /*Innovation quantization*/
166 split_cb_search_shape_sign,
167 split_cb_shape_sign_unquant,
168#else
169 /*LSP quantization*/
170 NULL,
171 lsp_unquant_high,
172 /*Pitch quantization*/
173 NULL,
174 NULL,
175 NULL,
176 /*Innovation quantization*/
177 NULL,
178 split_cb_shape_sign_unquant,
179#endif
180#ifdef DISABLE_WIDEBAND
181 NULL,
182#else
183 &split_cb_high,
184#endif
185 -1,
186 192
187};
188
189static const SpeexSubmode wb_submode4 = {
190 0,
191 0,
192 1,
193 1,
194#ifndef SPEEX_DISABLE_ENCODER
195 /*LSP quantization*/
196 lsp_quant_high,
197 lsp_unquant_high,
198 /*Pitch quantization*/
199 NULL,
200 NULL,
201 NULL,
202 /*Innovation quantization*/
203 split_cb_search_shape_sign,
204 split_cb_shape_sign_unquant,
205#else
206 /*LSP quantization*/
207 NULL,
208 lsp_unquant_high,
209 /*Pitch quantization*/
210 NULL,
211 NULL,
212 NULL,
213 /*Innovation quantization*/
214 NULL,
215 split_cb_shape_sign_unquant,
216#endif
217#ifdef DISABLE_WIDEBAND
218 NULL,
219#else
220 &split_cb_high,
221#endif
222 -1,
223 352
224};
225
226
227/* Split-band wideband CELP mode*/
228static const SpeexSBMode sb_wb_mode = {
229 &speex_nb_mode,
230 160, /*frameSize*/
231 40, /*subframeSize*/
232 8, /*lpcSize*/
233#ifdef FIXED_POINT
234 29491, 19661, /* gamma1, gamma2 */
235#else
236 0.9, 0.6, /* gamma1, gamma2 */
237#endif
238 QCONST16(.0002,15), /*lpc_floor*/
239 QCONST16(0.9f,15),
240 {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
241 3,
242 {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
243 {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
244#ifndef DISABLE_VBR
245 vbr_hb_thresh,
246#endif
247 5
248};
249
250
251const SpeexMode speex_wb_mode = {
252 &sb_wb_mode,
253 wb_mode_query,
254 "wideband (sub-band CELP)",
255 1,
256 4,
257#ifndef SPEEX_DISABLE_ENCODER
258 &sb_encoder_init,
259 &sb_encoder_destroy,
260 &sb_encode,
261 &sb_decoder_init,
262 &sb_decoder_destroy,
263 &sb_decode,
264 &sb_encoder_ctl,
265 &sb_decoder_ctl,
266#else
267/* NULL,
268 NULL,
269 NULL, */
270 &sb_decoder_init,
271 &sb_decoder_destroy,
272 &sb_decode,
273/* NULL, */
274 &sb_decoder_ctl,
275#endif
276};
277
278
279
280/* "Ultra-wideband" mode stuff */
281
282
283
284#ifndef ROCKBOX_VOICE_CODEC
285/* Split-band "ultra-wideband" (32 kbps) CELP mode*/
286static const SpeexSBMode sb_uwb_mode = {
287 &speex_wb_mode,
288 320, /*frameSize*/
289 80, /*subframeSize*/
290 8, /*lpcSize*/
291#ifdef FIXED_POINT
292 29491, 19661, /* gamma1, gamma2 */
293#else
294 0.9, 0.6, /* gamma1, gamma2 */
295#endif
296 QCONST16(.0002,15), /*lpc_floor*/
297 QCONST16(0.7f,15),
298 {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
299 1,
300 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
301 {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
302#ifndef DISABLE_VBR
303 vbr_uhb_thresh,
304#endif
305 2
306};
307#endif
308
309int wb_mode_query(const void *mode, int request, void *ptr)
310{
311 const SpeexSBMode *m = (const SpeexSBMode*)mode;
312
313 switch (request)
314 {
315 case SPEEX_MODE_FRAME_SIZE:
316 *((int*)ptr)=2*m->frameSize;
317 break;
318 case SPEEX_SUBMODE_BITS_PER_FRAME:
319 if (*((int*)ptr)==0)
320 *((int*)ptr) = SB_SUBMODE_BITS+1;
321 else if (m->submodes[*((int*)ptr)]==NULL)
322 *((int*)ptr) = -1;
323 else
324 *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
325 break;
326 default:
327 speex_warning_int("Unknown wb_mode_query request: ", request);
328 return -1;
329 }
330 return 0;
331}
332
333
334#ifndef ROCKBOX_VOICE_CODEC
335const SpeexMode speex_uwb_mode = {
336 &sb_uwb_mode,
337 wb_mode_query,
338 "ultra-wideband (sub-band CELP)",
339 2,
340 4,
341#ifndef SPEEX_DISABLE_ENCODER
342 &sb_encoder_init,
343 &sb_encoder_destroy,
344 &sb_encode,
345 &sb_decoder_init,
346 &sb_decoder_destroy,
347 &sb_decode,
348 &sb_encoder_ctl,
349 &sb_decoder_ctl,
350#else
351/* NULL,
352 NULL,
353 NULL, */
354 &sb_decoder_init,
355 &sb_decoder_destroy,
356 &sb_decode,
357/* NULL, */
358 &sb_decoder_ctl,
359#endif
360};
361#endif
362
363/* We have defined speex_lib_get_mode() as a macro in speex.h */
364#undef speex_lib_get_mode
365
366const SpeexMode * speex_lib_get_mode (int mode)
367{
368 if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL;
369
370 return speex_mode_list[mode];
371}
372
373
374
diff --git a/lib/rbcodec/codecs/libspeex/nb_celp.c b/lib/rbcodec/codecs/libspeex/nb_celp.c
new file mode 100644
index 0000000000..364f987472
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/nb_celp.c
@@ -0,0 +1,1917 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin
2 File: nb_celp.c
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#ifdef HAVE_CONFIG_H
33#include "config-speex.h"
34#endif
35
36#include <math.h>
37#include "nb_celp.h"
38#include "lpc.h"
39#include "lsp.h"
40#include "ltp.h"
41#include "quant_lsp.h"
42#include "cb_search.h"
43#include "filters.h"
44#include "stack_alloc.h"
45#include "vq.h"
46#include "speex/speex_bits.h"
47#include "vbr.h"
48#include "arch.h"
49#include "math_approx.h"
50#include "os_support.h"
51#include "speex/speex_callbacks.h"
52
53#ifdef VORBIS_PSYCHO
54#include "vorbis_psy.h"
55#endif
56
57#ifndef M_PI
58#define M_PI 3.14159265358979323846 /* pi */
59#endif
60
61#ifndef NULL
62#define NULL 0
63#endif
64
65#define SUBMODE(x) st->submodes[st->submodeID]->x
66
67/* Default size for the encoder and decoder stack (can be changed at compile time).
68 This does not apply when using variable-size arrays or alloca. */
69#ifndef NB_ENC_STACK
70#define NB_ENC_STACK (8000*sizeof(spx_sig_t))
71#endif
72
73#ifndef NB_DEC_STACK
74#define NB_DEC_STACK (4000*sizeof(spx_sig_t))
75#endif
76
77
78#ifdef FIXED_POINT
79const spx_word32_t ol_gain_table[32] ICONST_ATTR = {18900, 25150, 33468, 44536, 59265, 78865, 104946, 139653, 185838, 247297, 329081, 437913, 582736, 775454, 1031906, 1373169, 1827293, 2431601, 3235761, 4305867, 5729870, 7624808, 10146425, 13501971, 17967238, 23909222, 31816294, 42338330, 56340132, 74972501, 99766822, 132760927};
80const spx_word16_t exc_gain_quant_scal3_bound[7] ICONST_ATTR = {1841, 3883, 6051, 8062, 10444, 13580, 18560};
81const spx_word16_t exc_gain_quant_scal3[8] ICONST_ATTR = {1002, 2680, 5086, 7016, 9108, 11781, 15380, 21740};
82const spx_word16_t exc_gain_quant_scal1_bound[1] ICONST_ATTR = {14385};
83const spx_word16_t exc_gain_quant_scal1[2] ICONST_ATTR = {11546, 17224};
84
85#define LSP_MARGIN 16
86#define LSP_DELTA1 6553
87#define LSP_DELTA2 1638
88
89#else
90
91const float exc_gain_quant_scal3_bound[7]={0.112338f, 0.236980f, 0.369316f, 0.492054f, 0.637471f, 0.828874f, 1.132784f};
92const float exc_gain_quant_scal3[8]={0.061130f, 0.163546f, 0.310413f, 0.428220f, 0.555887f, 0.719055f, 0.938694f, 1.326874f};
93const float exc_gain_quant_scal1_bound[1]={0.87798f};
94const float exc_gain_quant_scal1[2]={0.70469f, 1.05127f};
95
96#define LSP_MARGIN .002f
97#define LSP_DELTA1 .2f
98#define LSP_DELTA2 .05f
99
100#endif
101
102#ifdef VORBIS_PSYCHO
103#define EXTRA_BUFFER 100
104#else
105#define EXTRA_BUFFER 0
106#endif
107
108
109#define sqr(x) ((x)*(x))
110
111extern const spx_word16_t lag_window[];
112extern const spx_word16_t lpc_window[];
113
114#ifndef SPEEX_DISABLE_ENCODER
115void *nb_encoder_init(const SpeexMode *m)
116{
117 EncState *st;
118 const SpeexNBMode *mode;
119 int i;
120
121 mode=(const SpeexNBMode *)m->mode;
122 st = (EncState*)speex_alloc(sizeof(EncState));
123 if (!st)
124 return NULL;
125#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
126 st->stack = NULL;
127#else
128 st->stack = (char*)speex_alloc_scratch(NB_ENC_STACK);
129#endif
130
131 st->mode=m;
132
133 st->frameSize = mode->frameSize;
134 st->nbSubframes=mode->frameSize/mode->subframeSize;
135 st->subframeSize=mode->subframeSize;
136 st->windowSize = st->frameSize+st->subframeSize;
137 st->lpcSize = mode->lpcSize;
138 st->gamma1=mode->gamma1;
139 st->gamma2=mode->gamma2;
140 st->min_pitch=mode->pitchStart;
141 st->max_pitch=mode->pitchEnd;
142 st->lpc_floor = mode->lpc_floor;
143
144 st->submodes=mode->submodes;
145 st->submodeID=st->submodeSelect=mode->defaultSubmode;
146 st->bounded_pitch = 1;
147
148 st->encode_submode = 1;
149
150#ifdef VORBIS_PSYCHO
151 st->psy = vorbis_psy_init(8000, 256);
152 st->curve = (float*)speex_alloc(128*sizeof(float));
153 st->old_curve = (float*)speex_alloc(128*sizeof(float));
154 st->psy_window = (float*)speex_alloc(256*sizeof(float));
155#endif
156
157 st->cumul_gain = 1024;
158
159 /* Allocating input buffer */
160 st->winBuf = (spx_word16_t*)speex_alloc((st->windowSize-st->frameSize)*sizeof(spx_word16_t));
161 /* Allocating excitation buffer */
162 st->excBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(spx_word16_t));
163 st->exc = st->excBuf + mode->pitchEnd + 2;
164 st->swBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(spx_word16_t));
165 st->sw = st->swBuf + mode->pitchEnd + 2;
166
167 st->window= lpc_window;
168
169 /* Create the window for autocorrelation (lag-windowing) */
170 st->lagWindow = lag_window;
171
172 st->old_lsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
173 st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
174 st->first = 1;
175 for (i=0;i<st->lpcSize;i++)
176 st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
177
178 st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
179 st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
180 st->mem_sw_whole = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
181 st->mem_exc = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
182 st->mem_exc2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
183
184 st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
185 st->innov_rms_save = NULL;
186
187 st->pitch = (int*)speex_alloc((st->nbSubframes)*sizeof(int));
188
189#ifndef DISABLE_VBR
190 st->vbr = (VBRState*)speex_alloc(sizeof(VBRState));
191 vbr_init(st->vbr);
192 st->vbr_quality = 8;
193 st->vbr_enabled = 0;
194 st->vbr_max = 0;
195 st->vad_enabled = 0;
196 st->dtx_enabled = 0;
197 st->dtx_count=0;
198 st->abr_enabled = 0;
199 st->abr_drift = 0;
200 st->abr_drift2 = 0;
201#endif /* #ifndef DISABLE_VBR */
202
203 st->plc_tuning = 2;
204 st->complexity=2;
205 st->sampling_rate=8000;
206 st->isWideband = 0;
207 st->highpass_enabled = 1;
208
209#ifdef ENABLE_VALGRIND
210 VALGRIND_MAKE_READABLE(st, NB_ENC_STACK);
211#endif
212 return st;
213}
214
215void nb_encoder_destroy(void *state)
216{
217 EncState *st=(EncState *)state;
218 /* Free all allocated memory */
219#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
220 speex_free_scratch(st->stack);
221#endif
222
223 speex_free (st->winBuf);
224 speex_free (st->excBuf);
225 speex_free (st->old_qlsp);
226 speex_free (st->swBuf);
227
228 speex_free (st->old_lsp);
229 speex_free (st->mem_sp);
230 speex_free (st->mem_sw);
231 speex_free (st->mem_sw_whole);
232 speex_free (st->mem_exc);
233 speex_free (st->mem_exc2);
234 speex_free (st->pi_gain);
235 speex_free (st->pitch);
236
237#ifndef DISABLE_VBR
238 vbr_destroy(st->vbr);
239 speex_free (st->vbr);
240#endif /* #ifndef DISABLE_VBR */
241
242#ifdef VORBIS_PSYCHO
243 vorbis_psy_destroy(st->psy);
244 speex_free (st->curve);
245 speex_free (st->old_curve);
246 speex_free (st->psy_window);
247#endif
248
249 /*Free state memory... should be last*/
250 speex_free(st);
251}
252
253int nb_encode(void *state, void *vin, SpeexBits *bits)
254{
255 EncState *st;
256 int i, sub, roots;
257 int ol_pitch;
258 spx_word16_t ol_pitch_coef;
259 spx_word32_t ol_gain;
260 VARDECL(spx_word16_t *ringing);
261 VARDECL(spx_word16_t *target);
262 VARDECL(spx_sig_t *innov);
263 VARDECL(spx_word32_t *exc32);
264 VARDECL(spx_mem_t *mem);
265 VARDECL(spx_coef_t *bw_lpc1);
266 VARDECL(spx_coef_t *bw_lpc2);
267 VARDECL(spx_coef_t *lpc);
268 VARDECL(spx_lsp_t *lsp);
269 VARDECL(spx_lsp_t *qlsp);
270 VARDECL(spx_lsp_t *interp_lsp);
271 VARDECL(spx_lsp_t *interp_qlsp);
272 VARDECL(spx_coef_t *interp_lpc);
273 VARDECL(spx_coef_t *interp_qlpc);
274 char *stack;
275 VARDECL(spx_word16_t *syn_resp);
276 VARDECL(spx_word16_t *real_exc);
277
278 spx_word32_t ener=0;
279 spx_word16_t fine_gain;
280 spx_word16_t *in = (spx_word16_t*)vin;
281
282 st=(EncState *)state;
283 stack=st->stack;
284
285 ALLOC(lpc, st->lpcSize, spx_coef_t);
286 ALLOC(bw_lpc1, st->lpcSize, spx_coef_t);
287 ALLOC(bw_lpc2, st->lpcSize, spx_coef_t);
288 ALLOC(lsp, st->lpcSize, spx_lsp_t);
289 ALLOC(qlsp, st->lpcSize, spx_lsp_t);
290 ALLOC(interp_lsp, st->lpcSize, spx_lsp_t);
291 ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
292 ALLOC(interp_lpc, st->lpcSize, spx_coef_t);
293 ALLOC(interp_qlpc, st->lpcSize, spx_coef_t);
294
295 /* Move signals 1 frame towards the past */
296 SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, st->max_pitch+2);
297 SPEEX_MOVE(st->swBuf, st->swBuf+st->frameSize, st->max_pitch+2);
298
299 if (st->highpass_enabled)
300 highpass(in, in, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_INPUT, st->mem_hp);
301
302 {
303 VARDECL(spx_word16_t *w_sig);
304 VARDECL(spx_word16_t *autocorr);
305 ALLOC(w_sig, st->windowSize, spx_word16_t);
306 ALLOC(autocorr, st->lpcSize+1, spx_word16_t);
307 /* Window for analysis */
308 for (i=0;i<st->windowSize-st->frameSize;i++)
309 w_sig[i] = EXTRACT16(SHR32(MULT16_16(st->winBuf[i],st->window[i]),SIG_SHIFT));
310 for (;i<st->windowSize;i++)
311 w_sig[i] = EXTRACT16(SHR32(MULT16_16(in[i-st->windowSize+st->frameSize],st->window[i]),SIG_SHIFT));
312 /* Compute auto-correlation */
313 _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize);
314 autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */
315
316 /* Lag windowing: equivalent to filtering in the power-spectrum domain */
317 for (i=0;i<st->lpcSize+1;i++)
318 autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]);
319
320 /* Levinson-Durbin */
321 _spx_lpc(lpc, autocorr, st->lpcSize);
322 /* LPC to LSPs (x-domain) transform */
323 roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack);
324 /* Check if we found all the roots */
325 if (roots!=st->lpcSize)
326 {
327 /*If we can't find all LSP's, do some damage control and use previous filter*/
328 for (i=0;i<st->lpcSize;i++)
329 {
330 lsp[i]=st->old_lsp[i];
331 }
332 }
333 }
334
335
336
337
338 /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */
339 {
340 int diff = st->windowSize-st->frameSize;
341 if (st->first)
342 for (i=0;i<st->lpcSize;i++)
343 interp_lsp[i] = lsp[i];
344 else
345 lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, st->nbSubframes, st->nbSubframes<<1);
346
347 lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);
348
349 /* Compute interpolated LPCs (unquantized) for whole frame*/
350 lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);
351
352
353 /*Open-loop pitch*/
354 if (!st->submodes[st->submodeID] || (st->complexity>2 && SUBMODE(have_subframe_gain)<3) || SUBMODE(forced_pitch_gain) || SUBMODE(lbr_pitch) != -1
355#ifndef DISABLE_VBR
356 || st->vbr_enabled || st->vad_enabled
357#endif
358 )
359 {
360 int nol_pitch[6];
361 spx_word16_t nol_pitch_coef[6];
362
363 bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);
364 bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
365
366 SPEEX_COPY(st->sw, st->winBuf, diff);
367 SPEEX_COPY(st->sw+diff, in, st->frameSize-diff);
368 filter_mem16(st->sw, bw_lpc1, bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole, stack);
369
370 open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize,
371 nol_pitch, nol_pitch_coef, 6, stack);
372 ol_pitch=nol_pitch[0];
373 ol_pitch_coef = nol_pitch_coef[0];
374 /*Try to remove pitch multiples*/
375 for (i=1;i<6;i++)
376 {
377#ifdef FIXED_POINT
378 if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],27853)) &&
379#else
380 if ((nol_pitch_coef[i]>.85*nol_pitch_coef[0]) &&
381#endif
382 (ABS(2*nol_pitch[i]-ol_pitch)<=2 || ABS(3*nol_pitch[i]-ol_pitch)<=3 ||
383 ABS(4*nol_pitch[i]-ol_pitch)<=4 || ABS(5*nol_pitch[i]-ol_pitch)<=5))
384 {
385 /*ol_pitch_coef=nol_pitch_coef[i];*/
386 ol_pitch = nol_pitch[i];
387 }
388 }
389 /*if (ol_pitch>50)
390 ol_pitch/=2;*/
391 /*ol_pitch_coef = sqrt(ol_pitch_coef);*/
392
393 } else {
394 ol_pitch=0;
395 ol_pitch_coef=0;
396 }
397
398 /*Compute "real" excitation*/
399 SPEEX_COPY(st->exc, st->winBuf, diff);
400 SPEEX_COPY(st->exc+diff, in, st->frameSize-diff);
401 fir_mem16(st->exc, interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc, stack);
402
403 /* Compute open-loop excitation gain */
404 {
405 spx_word16_t g = compute_rms16(st->exc, st->frameSize);
406 if (st->submodeID!=1 && ol_pitch>0)
407 ol_gain = MULT16_16(g, MULT16_16_Q14(QCONST16(1.1,14),
408 spx_sqrt(QCONST32(1.,28)-MULT16_32_Q15(QCONST16(.8,15),SHL32(MULT16_16(ol_pitch_coef,ol_pitch_coef),16)))));
409 else
410 ol_gain = SHL32(EXTEND32(g),SIG_SHIFT);
411 }
412 }
413
414#ifdef VORBIS_PSYCHO
415 SPEEX_MOVE(st->psy_window, st->psy_window+st->frameSize, 256-st->frameSize);
416 SPEEX_COPY(&st->psy_window[256-st->frameSize], in, st->frameSize);
417 compute_curve(st->psy, st->psy_window, st->curve);
418 /*print_vec(st->curve, 128, "curve");*/
419 if (st->first)
420 SPEEX_COPY(st->old_curve, st->curve, 128);
421#endif
422
423 /*VBR stuff*/
424#ifndef DISABLE_VBR
425 if (st->vbr && (st->vbr_enabled||st->vad_enabled))
426 {
427 float lsp_dist=0;
428 for (i=0;i<st->lpcSize;i++)
429 lsp_dist += (st->old_lsp[i] - lsp[i])*(st->old_lsp[i] - lsp[i]);
430 lsp_dist /= LSP_SCALING*LSP_SCALING;
431
432 if (st->abr_enabled)
433 {
434 float qual_change=0;
435 if (st->abr_drift2 * st->abr_drift > 0)
436 {
437 /* Only adapt if long-term and short-term drift are the same sign */
438 qual_change = -.00001*st->abr_drift/(1+st->abr_count);
439 if (qual_change>.05)
440 qual_change=.05;
441 if (qual_change<-.05)
442 qual_change=-.05;
443 }
444 st->vbr_quality += qual_change;
445 if (st->vbr_quality>10)
446 st->vbr_quality=10;
447 if (st->vbr_quality<0)
448 st->vbr_quality=0;
449 }
450
451 st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, GAIN_SCALING_1*ol_pitch_coef);
452 /*if (delta_qual<0)*/
453 /* delta_qual*=.1*(3+st->vbr_quality);*/
454 if (st->vbr_enabled)
455 {
456 spx_int32_t mode;
457 int choice=0;
458 float min_diff=100;
459 mode = 8;
460 while (mode)
461 {
462 int v1;
463 float thresh;
464 v1=(int)floor(st->vbr_quality);
465 if (v1==10)
466 thresh = vbr_nb_thresh[mode][v1];
467 else
468 thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1];
469 if (st->relative_quality > thresh &&
470 st->relative_quality-thresh<min_diff)
471 {
472 choice = mode;
473 min_diff = st->relative_quality-thresh;
474 }
475 mode--;
476 }
477 mode=choice;
478 if (mode==0)
479 {
480 if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)
481 {
482 mode=1;
483 st->dtx_count=1;
484 } else {
485 mode=0;
486 st->dtx_count++;
487 }
488 } else {
489 st->dtx_count=0;
490 }
491
492 speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);
493 if (st->vbr_max>0)
494 {
495 spx_int32_t rate;
496 speex_encoder_ctl(state, SPEEX_GET_BITRATE, &rate);
497 if (rate > st->vbr_max)
498 {
499 rate = st->vbr_max;
500 speex_encoder_ctl(state, SPEEX_SET_BITRATE, &rate);
501 }
502 }
503
504 if (st->abr_enabled)
505 {
506 spx_int32_t bitrate;
507 speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);
508 st->abr_drift+=(bitrate-st->abr_enabled);
509 st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);
510 st->abr_count += 1.0;
511 }
512
513 } else {
514 /*VAD only case*/
515 int mode;
516 if (st->relative_quality<2)
517 {
518 if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)
519 {
520 st->dtx_count=1;
521 mode=1;
522 } else {
523 mode=0;
524 st->dtx_count++;
525 }
526 } else {
527 st->dtx_count = 0;
528 mode=st->submodeSelect;
529 }
530 /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/
531 st->submodeID=mode;
532 }
533 } else {
534 st->relative_quality = -1;
535 }
536#endif /* #ifndef DISABLE_VBR */
537
538 if (st->encode_submode)
539 {
540 /* First, transmit a zero for narrowband */
541 speex_bits_pack(bits, 0, 1);
542
543 /* Transmit the sub-mode we use for this frame */
544 speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);
545
546 }
547
548 /* If null mode (no transmission), just set a couple things to zero*/
549 if (st->submodes[st->submodeID] == NULL)
550 {
551 for (i=0;i<st->frameSize;i++)
552 st->exc[i]=st->sw[i]=VERY_SMALL;
553
554 for (i=0;i<st->lpcSize;i++)
555 st->mem_sw[i]=0;
556 st->first=1;
557 st->bounded_pitch = 1;
558
559 SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize);
560
561 /* Clear memory (no need to really compute it) */
562 for (i=0;i<st->lpcSize;i++)
563 st->mem_sp[i] = 0;
564 return 0;
565
566 }
567
568 /* LSP Quantization */
569 if (st->first)
570 {
571 for (i=0;i<st->lpcSize;i++)
572 st->old_lsp[i] = lsp[i];
573 }
574
575
576 /*Quantize LSPs*/
577#if 1 /*0 for unquantized*/
578 SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits);
579#else
580 for (i=0;i<st->lpcSize;i++)
581 qlsp[i]=lsp[i];
582#endif
583
584 /*If we use low bit-rate pitch mode, transmit open-loop pitch*/
585 if (SUBMODE(lbr_pitch)!=-1)
586 {
587 speex_bits_pack(bits, ol_pitch-st->min_pitch, 7);
588 }
589
590 if (SUBMODE(forced_pitch_gain))
591 {
592 int quant;
593 /* This just damps the pitch a bit, because it tends to be too aggressive when forced */
594 ol_pitch_coef = MULT16_16_Q15(QCONST16(.9,15), ol_pitch_coef);
595#ifdef FIXED_POINT
596 quant = PSHR16(MULT16_16_16(15, ol_pitch_coef),GAIN_SHIFT);
597#else
598 quant = (int)floor(.5+15*ol_pitch_coef*GAIN_SCALING_1);
599#endif
600 if (quant>15)
601 quant=15;
602 if (quant<0)
603 quant=0;
604 speex_bits_pack(bits, quant, 4);
605 ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT));
606 }
607
608
609 /*Quantize and transmit open-loop excitation gain*/
610#ifdef FIXED_POINT
611 {
612 int qe = scal_quant32(ol_gain, ol_gain_table, 32);
613 /*ol_gain = exp(qe/3.5)*SIG_SCALING;*/
614 ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);
615 speex_bits_pack(bits, qe, 5);
616 }
617#else
618 {
619 int qe = (int)(floor(.5+3.5*log(ol_gain*1.0/SIG_SCALING)));
620 if (qe<0)
621 qe=0;
622 if (qe>31)
623 qe=31;
624 ol_gain = exp(qe/3.5)*SIG_SCALING;
625 speex_bits_pack(bits, qe, 5);
626 }
627#endif
628
629
630
631 /* Special case for first frame */
632 if (st->first)
633 {
634 for (i=0;i<st->lpcSize;i++)
635 st->old_qlsp[i] = qlsp[i];
636 }
637
638 /* Target signal */
639 ALLOC(target, st->subframeSize, spx_word16_t);
640 ALLOC(innov, st->subframeSize, spx_sig_t);
641 ALLOC(exc32, st->subframeSize, spx_word32_t);
642 ALLOC(ringing, st->subframeSize, spx_word16_t);
643 ALLOC(syn_resp, st->subframeSize, spx_word16_t);
644 ALLOC(real_exc, st->subframeSize, spx_word16_t);
645 ALLOC(mem, st->lpcSize, spx_mem_t);
646
647 /* Loop on sub-frames */
648 for (sub=0;sub<st->nbSubframes;sub++)
649 {
650 int offset;
651 spx_word16_t *sw;
652 spx_word16_t *exc;
653 int pitch;
654 int response_bound = st->subframeSize;
655
656 /* Offset relative to start of frame */
657 offset = st->subframeSize*sub;
658 /* Excitation */
659 exc=st->exc+offset;
660 /* Weighted signal */
661 sw=st->sw+offset;
662
663 /* LSP interpolation (quantized and unquantized) */
664 lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes);
665 lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
666
667 /* Make sure the filters are stable */
668 lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);
669 lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
670
671 /* Compute interpolated LPCs (quantized and unquantized) */
672 lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);
673
674 lsp_to_lpc(interp_qlsp, interp_qlpc, st->lpcSize, stack);
675
676 /* Compute analysis filter gain at w=pi (for use in SB-CELP) */
677 {
678 spx_word32_t pi_g=LPC_SCALING;
679 for (i=0;i<st->lpcSize;i+=2)
680 {
681 /*pi_g += -st->interp_qlpc[i] + st->interp_qlpc[i+1];*/
682 pi_g = ADD32(pi_g, SUB32(EXTEND32(interp_qlpc[i+1]),EXTEND32(interp_qlpc[i])));
683 }
684 st->pi_gain[sub] = pi_g;
685 }
686
687#ifdef VORBIS_PSYCHO
688 {
689 float curr_curve[128];
690 float fact = ((float)sub+1.0f)/st->nbSubframes;
691 for (i=0;i<128;i++)
692 curr_curve[i] = (1.0f-fact)*st->old_curve[i] + fact*st->curve[i];
693 curve_to_lpc(st->psy, curr_curve, bw_lpc1, bw_lpc2, 10);
694 }
695#else
696 /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */
697 bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);
698 if (st->gamma2>=0)
699 bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
700 else
701 {
702 for (i=0;i<st->lpcSize;i++)
703 bw_lpc2[i]=0;
704 }
705 /*print_vec(st->bw_lpc1, 10, "bw_lpc");*/
706#endif
707
708 /*FIXME: This will break if we change the window size */
709 speex_assert(st->windowSize-st->frameSize == st->subframeSize);
710 if (sub==0)
711 {
712 for (i=0;i<st->subframeSize;i++)
713 real_exc[i] = sw[i] = st->winBuf[i];
714 } else {
715 for (i=0;i<st->subframeSize;i++)
716 real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)];
717 }
718 fir_mem16(real_exc, interp_qlpc, real_exc, st->subframeSize, st->lpcSize, st->mem_exc2, stack);
719
720 if (st->complexity==0)
721 response_bound >>= 1;
722 compute_impulse_response(interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, response_bound, st->lpcSize, stack);
723 for (i=response_bound;i<st->subframeSize;i++)
724 syn_resp[i]=VERY_SMALL;
725
726 /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */
727 for (i=0;i<st->lpcSize;i++)
728 mem[i]=SHL32(st->mem_sp[i],1);
729 for (i=0;i<st->subframeSize;i++)
730 ringing[i] = VERY_SMALL;
731#ifdef SHORTCUTS2
732 iir_mem16(ringing, interp_qlpc, ringing, response_bound, st->lpcSize, mem, stack);
733 for (i=0;i<st->lpcSize;i++)
734 mem[i]=SHL32(st->mem_sw[i],1);
735 filter_mem16(ringing, st->bw_lpc1, st->bw_lpc2, ringing, response_bound, st->lpcSize, mem, stack);
736 SPEEX_MEMSET(&ringing[response_bound], 0, st->subframeSize-response_bound);
737#else
738 iir_mem16(ringing, interp_qlpc, ringing, st->subframeSize, st->lpcSize, mem, stack);
739 for (i=0;i<st->lpcSize;i++)
740 mem[i]=SHL32(st->mem_sw[i],1);
741 filter_mem16(ringing, bw_lpc1, bw_lpc2, ringing, st->subframeSize, st->lpcSize, mem, stack);
742#endif
743
744 /* Compute weighted signal */
745 for (i=0;i<st->lpcSize;i++)
746 mem[i]=st->mem_sw[i];
747 filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack);
748
749 if (st->complexity==0)
750 for (i=0;i<st->lpcSize;i++)
751 st->mem_sw[i]=mem[i];
752
753 /* Compute target signal (saturation prevents overflows on clipped input speech) */
754 for (i=0;i<st->subframeSize;i++)
755 target[i]=EXTRACT16(SATURATE(SUB32(sw[i],PSHR32(ringing[i],1)),32767));
756
757 /* Reset excitation */
758 SPEEX_MEMSET(exc, 0, st->subframeSize);
759
760 /* If we have a long-term predictor (otherwise, something's wrong) */
761 speex_assert (SUBMODE(ltp_quant));
762 {
763 int pit_min, pit_max;
764 /* Long-term prediction */
765 if (SUBMODE(lbr_pitch) != -1)
766 {
767 /* Low bit-rate pitch handling */
768 int margin;
769 margin = SUBMODE(lbr_pitch);
770 if (margin)
771 {
772 if (ol_pitch < st->min_pitch+margin-1)
773 ol_pitch=st->min_pitch+margin-1;
774 if (ol_pitch > st->max_pitch-margin)
775 ol_pitch=st->max_pitch-margin;
776 pit_min = ol_pitch-margin+1;
777 pit_max = ol_pitch+margin;
778 } else {
779 pit_min=pit_max=ol_pitch;
780 }
781 } else {
782 pit_min = st->min_pitch;
783 pit_max = st->max_pitch;
784 }
785
786 /* Force pitch to use only the current frame if needed */
787 if (st->bounded_pitch && pit_max>offset)
788 pit_max=offset;
789
790 /* Perform pitch search */
791 pitch = SUBMODE(ltp_quant)(target, sw, interp_qlpc, bw_lpc1, bw_lpc2,
792 exc32, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef,
793 st->lpcSize, st->subframeSize, bits, stack,
794 exc, syn_resp, st->complexity, 0, st->plc_tuning, &st->cumul_gain);
795
796 st->pitch[sub]=pitch;
797 }
798 /* Quantization of innovation */
799 SPEEX_MEMSET(innov, 0, st->subframeSize);
800
801 /* FIXME: Make sure this is save from overflows (so far so good) */
802 for (i=0;i<st->subframeSize;i++)
803 real_exc[i] = EXTRACT16(SUB32(EXTEND32(real_exc[i]), PSHR32(exc32[i],SIG_SHIFT-1)));
804
805 ener = SHL32(EXTEND32(compute_rms16(real_exc, st->subframeSize)),SIG_SHIFT);
806
807 /*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */
808#ifdef FIXED_POINT
809 {
810 spx_word32_t f = PDIV32(ener,PSHR32(ol_gain,SIG_SHIFT));
811 if (f<=32767)
812 fine_gain = f;
813 else
814 fine_gain = 32767;
815 }
816#else
817 fine_gain = PDIV32_16(ener,PSHR32(ol_gain,SIG_SHIFT));
818#endif
819 /* Calculate gain correction for the sub-frame (if any) */
820 if (SUBMODE(have_subframe_gain))
821 {
822 int qe;
823 if (SUBMODE(have_subframe_gain)==3)
824 {
825 qe = scal_quant(fine_gain, exc_gain_quant_scal3_bound, 8);
826 speex_bits_pack(bits, qe, 3);
827 ener=MULT16_32_Q14(exc_gain_quant_scal3[qe],ol_gain);
828 } else {
829 qe = scal_quant(fine_gain, exc_gain_quant_scal1_bound, 2);
830 speex_bits_pack(bits, qe, 1);
831 ener=MULT16_32_Q14(exc_gain_quant_scal1[qe],ol_gain);
832 }
833 } else {
834 ener=ol_gain;
835 }
836
837 /*printf ("%f %f\n", ener, ol_gain);*/
838
839 /* Normalize innovation */
840 signal_div(target, target, ener, st->subframeSize);
841
842 /* Quantize innovation */
843 speex_assert (SUBMODE(innovation_quant));
844 {
845 /* Codebook search */
846 SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2,
847 SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
848 innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook));
849
850 /* De-normalize innovation and update excitation */
851 signal_mul(innov, innov, ener, st->subframeSize);
852
853 for (i=0;i<st->subframeSize;i++)
854 exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));
855
856 /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */
857 if (SUBMODE(double_codebook)) {
858 char *tmp_stack=stack;
859 VARDECL(spx_sig_t *innov2);
860 ALLOC(innov2, st->subframeSize, spx_sig_t);
861 SPEEX_MEMSET(innov2, 0, st->subframeSize);
862 for (i=0;i<st->subframeSize;i++)
863 target[i]=MULT16_16_P13(QCONST16(2.2f,13), target[i]);
864 SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2,
865 SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
866 innov2, syn_resp, bits, stack, st->complexity, 0);
867 signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize);
868 for (i=0;i<st->subframeSize;i++)
869 innov[i] = ADD32(innov[i],innov2[i]);
870 stack = tmp_stack;
871 }
872 for (i=0;i<st->subframeSize;i++)
873 exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));
874 if (st->innov_rms_save)
875 {
876 st->innov_rms_save[sub] = compute_rms(innov, st->subframeSize);
877 }
878 }
879
880 /* Final signal synthesis from excitation */
881 iir_mem16(exc, interp_qlpc, sw, st->subframeSize, st->lpcSize, st->mem_sp, stack);
882
883 /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
884 if (st->complexity!=0)
885 filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack);
886
887 }
888
889 /* Store the LSPs for interpolation in the next frame */
890 if (st->submodeID>=1)
891 {
892 for (i=0;i<st->lpcSize;i++)
893 st->old_lsp[i] = lsp[i];
894 for (i=0;i<st->lpcSize;i++)
895 st->old_qlsp[i] = qlsp[i];
896 }
897
898#ifdef VORBIS_PSYCHO
899 if (st->submodeID>=1)
900 SPEEX_COPY(st->old_curve, st->curve, 128);
901#endif
902
903 if (st->submodeID==1)
904 {
905#ifndef DISABLE_VBR
906 if (st->dtx_count)
907 speex_bits_pack(bits, 15, 4);
908 else
909#endif
910 speex_bits_pack(bits, 0, 4);
911 }
912
913 /* The next frame will not be the first (Duh!) */
914 st->first = 0;
915 SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize);
916
917 if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0)
918 st->bounded_pitch = 1;
919 else
920 st->bounded_pitch = 0;
921
922 return 1;
923}
924#endif /* SPEEX_DISABLE_ENCODER */
925
926static DecState global_decstate IBSS_ATTR;
927
928void *nb_decoder_init(const SpeexMode *m)
929{
930 DecState *st = &global_decstate;
931 const SpeexNBMode *mode;
932 int i;
933
934 mode=(const SpeexNBMode*)m->mode;
935/*
936 st = (DecState *)speex_alloc(sizeof(DecState));
937 if (!st)
938 return NULL;
939*/
940 memset(st, 0, sizeof(*st));
941#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
942 st->stack = NULL;
943#else
944 st->stack = (char*)speex_alloc_scratch(NB_DEC_STACK);
945#endif
946
947 st->mode=m;
948
949
950 st->encode_submode = 1;
951
952 st->first=1;
953 /* Codec parameters, should eventually have several "modes"*/
954 st->frameSize = mode->frameSize;
955 st->nbSubframes=mode->frameSize/mode->subframeSize;
956 st->subframeSize=mode->subframeSize;
957 st->lpcSize = mode->lpcSize;
958 st->min_pitch=mode->pitchStart;
959 st->max_pitch=mode->pitchEnd;
960
961 st->submodes=mode->submodes;
962 st->submodeID=mode->defaultSubmode;
963
964 st->lpc_enh_enabled=1;
965
966 /* st->excBuf = (spx_word16_t*)speex_alloc((st->frameSize + 2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t)); */
967 st->exc = st->excBuf + 2*st->max_pitch + st->subframeSize + 6;
968 SPEEX_MEMSET(st->excBuf, 0, st->frameSize + st->max_pitch);
969
970 /* st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); */
971 /* st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); */
972 /* st->mem_sp = (spx_mem_t*)speex_alloc(st->lpcSize*sizeof(spx_mem_t)); */
973 /* st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); */
974 st->last_pitch = 40;
975 st->count_lost=0;
976 st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0;
977 st->pitch_gain_buf_idx = 0;
978 st->seed = 1000;
979
980 st->sampling_rate=8000;
981 st->last_ol_gain = 0;
982
983 st->user_callback.func = &speex_default_user_handler;
984 st->user_callback.data = NULL;
985 for (i=0;i<16;i++)
986 st->speex_callbacks[i].func = NULL;
987
988 st->voc_m1=st->voc_m2=st->voc_mean=0;
989 st->voc_offset=0;
990 st->dtx_enabled=0;
991 st->isWideband = 0;
992 st->highpass_enabled = 1;
993
994#ifdef CPU_COLDFIRE
995 coldfire_set_macsr(0); // Integer mode
996#endif
997#ifdef ENABLE_VALGRIND
998 VALGRIND_MAKE_READABLE(st, NB_DEC_STACK);
999#endif
1000 return st;
1001}
1002
1003void nb_decoder_destroy(void *state)
1004{
1005#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
1006 DecState *st;
1007 st=(DecState*)state;
1008 speex_free_scratch(st->stack);
1009#else
1010 (void)state;
1011#endif
1012/*
1013 speex_free (st->excBuf);
1014 speex_free (st->interp_qlpc);
1015 speex_free (st->old_qlsp);
1016 speex_free (st->mem_sp);
1017 speex_free (st->pi_gain);
1018
1019 speex_free(state);
1020*/
1021}
1022
1023#define median3(a, b, c) ((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a))))
1024
1025#ifdef FIXED_POINT
1026const spx_word16_t attenuation[10] = {32767, 31483, 27923, 22861, 17278, 12055, 7764, 4616, 2533, 1283};
1027#else
1028const spx_word16_t attenuation[10] = {1., 0.961, 0.852, 0.698, 0.527, 0.368, 0.237, 0.141, 0.077, 0.039};
1029
1030#endif
1031
1032#ifndef ROCKBOX_VOICE_CODEC
1033static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
1034{
1035 int i;
1036 int pitch_val;
1037 spx_word16_t pitch_gain;
1038 spx_word16_t fact;
1039 spx_word16_t gain_med;
1040 spx_word16_t innov_gain;
1041 spx_word16_t noise_gain;
1042
1043 if (st->count_lost<10)
1044 fact = attenuation[st->count_lost];
1045 else
1046 fact = 0;
1047
1048 gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]);
1049 if (gain_med < st->last_pitch_gain)
1050 st->last_pitch_gain = gain_med;
1051
1052#ifdef FIXED_POINT
1053 pitch_gain = st->last_pitch_gain;
1054 if (pitch_gain>54)
1055 pitch_gain = 54;
1056 pitch_gain = SHL16(pitch_gain, 9);
1057#else
1058 pitch_gain = GAIN_SCALING_1*st->last_pitch_gain;
1059 if (pitch_gain>.85)
1060 pitch_gain=.85;
1061#endif
1062 pitch_gain = MULT16_16_Q15(fact,pitch_gain) + VERY_SMALL;
1063 /* FIXME: This was rms of innovation (not exc) */
1064 innov_gain = compute_rms16(st->exc, st->frameSize);
1065 noise_gain = MULT16_16_Q15(innov_gain, MULT16_16_Q15(fact, SUB16(Q15ONE,MULT16_16_Q15(pitch_gain,pitch_gain))));
1066 /* Shift all buffers by one frame */
1067 SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12);
1068
1069
1070 pitch_val = st->last_pitch + SHR32((spx_int32_t)speex_rand(1+st->count_lost, &st->seed),SIG_SHIFT);
1071 if (pitch_val > st->max_pitch)
1072 pitch_val = st->max_pitch;
1073 if (pitch_val < st->min_pitch)
1074 pitch_val = st->min_pitch;
1075 for (i=0;i<st->frameSize;i++)
1076 {
1077 st->exc[i]= MULT16_16_Q15(pitch_gain, (st->exc[i-pitch_val]+VERY_SMALL)) +
1078 speex_rand(noise_gain, &st->seed);
1079 }
1080
1081 bw_lpc(QCONST16(.98,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize);
1082 iir_mem16(&st->exc[-st->subframeSize], st->interp_qlpc, out, st->frameSize,
1083 st->lpcSize, st->mem_sp, stack);
1084 highpass(out, out, st->frameSize, HIGHPASS_NARROWBAND|HIGHPASS_OUTPUT, st->mem_hp);
1085
1086 st->first = 0;
1087 st->count_lost++;
1088 st->pitch_gain_buf[st->pitch_gain_buf_idx++] = PSHR16(pitch_gain,9);
1089 if (st->pitch_gain_buf_idx > 2) /* rollover */
1090 st->pitch_gain_buf_idx = 0;
1091}
1092#endif
1093
1094/* Just so we don't need to carry the complete wideband mode information */
1095static const unsigned short wb_skip_table[8] = {0, 36, 112, 192, 352, 0, 0, 0};
1096
1097int nb_decode(void *state, SpeexBits *bits, void *vout)
1098{
1099 DecState *st;
1100 int i, sub;
1101 int pitch;
1102 spx_word16_t pitch_gain[3];
1103 spx_word32_t ol_gain=0;
1104 int ol_pitch=0;
1105 spx_word16_t ol_pitch_coef=0;
1106 int best_pitch=40;
1107 spx_word16_t best_pitch_gain=0;
1108 int wideband;
1109 int m;
1110 char *stack;
1111 VARDECL(spx_sig_t *innov);
1112 VARDECL(spx_word32_t *exc32);
1113 VARDECL(spx_coef_t *ak);
1114 VARDECL(spx_lsp_t *qlsp);
1115 spx_word16_t pitch_average=0;
1116
1117 spx_word16_t *out = (spx_word16_t*)vout;
1118 VARDECL(spx_lsp_t *interp_qlsp);
1119
1120 st=(DecState*)state;
1121 stack=st->stack;
1122
1123 /* Check if we're in DTX mode*/
1124 if (!bits && st->dtx_enabled)
1125 {
1126 st->submodeID=0;
1127 } else
1128 {
1129 /* If bits is NULL, consider the packet to be lost (what could we do anyway) */
1130#ifndef ROCKBOX_VOICE_CODEC
1131 if (!bits)
1132 {
1133 nb_decode_lost(st, out, stack);
1134 return 0;
1135 }
1136#endif
1137
1138 if (st->encode_submode)
1139 {
1140
1141 /* Search for next narrowband block (handle requests, skip wideband blocks) */
1142 do {
1143 if (speex_bits_remaining(bits)<5)
1144 return -1;
1145 wideband = speex_bits_unpack_unsigned(bits, 1);
1146 if (wideband) /* Skip wideband block (for compatibility) */
1147 {
1148 int submode;
1149 int advance;
1150 advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
1151 /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/
1152 advance = wb_skip_table[submode];
1153 if (advance < 0)
1154 {
1155 speex_notify("Invalid mode encountered. The stream is corrupted.");
1156 return -2;
1157 }
1158 advance -= (SB_SUBMODE_BITS+1);
1159 speex_bits_advance(bits, advance);
1160
1161 if (speex_bits_remaining(bits)<5)
1162 return -1;
1163 wideband = speex_bits_unpack_unsigned(bits, 1);
1164 if (wideband)
1165 {
1166 advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
1167 /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/
1168 advance = wb_skip_table[submode];
1169 if (advance < 0)
1170 {
1171 speex_notify("Invalid mode encountered. The stream is corrupted.");
1172 return -2;
1173 }
1174 advance -= (SB_SUBMODE_BITS+1);
1175 speex_bits_advance(bits, advance);
1176 wideband = speex_bits_unpack_unsigned(bits, 1);
1177 if (wideband)
1178 {
1179 speex_notify("More than two wideband layers found. The stream is corrupted.");
1180 return -2;
1181 }
1182
1183 }
1184 }
1185 if (speex_bits_remaining(bits)<4)
1186 return -1;
1187 /* FIXME: Check for overflow */
1188 m = speex_bits_unpack_unsigned(bits, 4);
1189 if (m==15) /* We found a terminator */
1190 {
1191 return -1;
1192 } else if (m==14) /* Speex in-band request */
1193 {
1194 int ret = speex_inband_handler(bits, st->speex_callbacks, state);
1195 if (ret)
1196 return ret;
1197 } else if (m==13) /* User in-band request */
1198 {
1199 int ret = st->user_callback.func(bits, state, st->user_callback.data);
1200 if (ret)
1201 return ret;
1202 } else if (m>8) /* Invalid mode */
1203 {
1204 speex_notify("Invalid mode encountered. The stream is corrupted.");
1205 return -2;
1206 }
1207
1208 } while (m>8);
1209
1210 /* Get the sub-mode that was used */
1211 st->submodeID = m;
1212 }
1213
1214 }
1215
1216 /* Shift all buffers by one frame */
1217 SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12);
1218
1219 /* If null mode (no transmission), just set a couple things to zero*/
1220 if (st->submodes[st->submodeID] == NULL)
1221 {
1222 VARDECL(spx_coef_t *lpc);
1223 ALLOC(lpc, st->lpcSize, spx_coef_t);
1224 bw_lpc(QCONST16(0.93f,15), st->interp_qlpc, lpc, st->lpcSize);
1225 {
1226 spx_word16_t innov_gain=0;
1227 /* FIXME: This was innov, not exc */
1228 innov_gain = compute_rms16(st->exc, st->frameSize);
1229 for (i=0;i<st->frameSize;i++)
1230 st->exc[i]=speex_rand(innov_gain, &st->seed);
1231 }
1232
1233
1234 st->first=1;
1235
1236 /* Final signal synthesis from excitation */
1237 iir_mem16(st->exc, lpc, out, st->frameSize, st->lpcSize, st->mem_sp, stack);
1238
1239 st->count_lost=0;
1240 return 0;
1241 }
1242
1243 ALLOC(qlsp, st->lpcSize, spx_lsp_t);
1244
1245 /* Unquantize LSPs */
1246 SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits);
1247
1248 /*Damp memory if a frame was lost and the LSP changed too much*/
1249 if (st->count_lost)
1250 {
1251 spx_word16_t fact;
1252 spx_word32_t lsp_dist=0;
1253 for (i=0;i<st->lpcSize;i++)
1254 lsp_dist = ADD32(lsp_dist, EXTEND32(ABS(st->old_qlsp[i] - qlsp[i])));
1255#ifdef FIXED_POINT
1256 fact = SHR16(19661,SHR32(lsp_dist,LSP_SHIFT+2));
1257#else
1258 fact = .6*exp(-.2*lsp_dist);
1259#endif
1260 for (i=0;i<st->lpcSize;i++)
1261 st->mem_sp[i] = MULT16_32_Q15(fact,st->mem_sp[i]);
1262 }
1263
1264
1265 /* Handle first frame and lost-packet case */
1266 if (st->first || st->count_lost)
1267 {
1268 for (i=0;i<st->lpcSize;i++)
1269 st->old_qlsp[i] = qlsp[i];
1270 }
1271
1272 /* Get open-loop pitch estimation for low bit-rate pitch coding */
1273 if (SUBMODE(lbr_pitch)!=-1)
1274 {
1275 ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);
1276 }
1277
1278 if (SUBMODE(forced_pitch_gain))
1279 {
1280 int quant;
1281 quant = speex_bits_unpack_unsigned(bits, 4);
1282 ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT));
1283 }
1284
1285 /* Get global excitation gain */
1286 {
1287 int qe;
1288 qe = speex_bits_unpack_unsigned(bits, 5);
1289#ifdef FIXED_POINT
1290 /* FIXME: Perhaps we could slightly lower the gain here when the output is going to saturate? */
1291 ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);
1292#else
1293 ol_gain = SIG_SCALING*exp(qe/3.5);
1294#endif
1295 }
1296
1297 ALLOC(ak, st->lpcSize, spx_coef_t);
1298 ALLOC(innov, st->subframeSize, spx_sig_t);
1299 ALLOC(exc32, st->subframeSize, spx_word32_t);
1300
1301 if (st->submodeID==1)
1302 {
1303 int extra;
1304 extra = speex_bits_unpack_unsigned(bits, 4);
1305
1306 if (extra==15)
1307 st->dtx_enabled=1;
1308 else
1309 st->dtx_enabled=0;
1310 }
1311 if (st->submodeID>1)
1312 st->dtx_enabled=0;
1313
1314 /*Loop on subframes */
1315 for (sub=0;sub<st->nbSubframes;sub++)
1316 {
1317 int offset;
1318 spx_word16_t *exc;
1319 spx_word16_t *innov_save = NULL;
1320 spx_word16_t tmp;
1321
1322 /* Offset relative to start of frame */
1323 offset = st->subframeSize*sub;
1324 /* Excitation */
1325 exc=st->exc+offset;
1326
1327 if (st->innov_save)
1328 innov_save = st->innov_save+offset;
1329
1330
1331 /* Reset excitation */
1332 SPEEX_MEMSET(exc, 0, st->subframeSize);
1333
1334 /*Adaptive codebook contribution*/
1335 speex_assert (SUBMODE(ltp_unquant));
1336 {
1337 int pit_min, pit_max;
1338 /* Handle pitch constraints if any */
1339 if (SUBMODE(lbr_pitch) != -1)
1340 {
1341 int margin;
1342 margin = SUBMODE(lbr_pitch);
1343 if (margin)
1344 {
1345/* GT - need optimization?
1346 if (ol_pitch < st->min_pitch+margin-1)
1347 ol_pitch=st->min_pitch+margin-1;
1348 if (ol_pitch > st->max_pitch-margin)
1349 ol_pitch=st->max_pitch-margin;
1350 pit_min = ol_pitch-margin+1;
1351 pit_max = ol_pitch+margin;
1352*/
1353 pit_min = ol_pitch-margin+1;
1354 if (pit_min < st->min_pitch)
1355 pit_min = st->min_pitch;
1356 pit_max = ol_pitch+margin;
1357 if (pit_max > st->max_pitch)
1358 pit_max = st->max_pitch;
1359 } else {
1360 pit_min = pit_max = ol_pitch;
1361 }
1362 } else {
1363 pit_min = st->min_pitch;
1364 pit_max = st->max_pitch;
1365 }
1366
1367
1368
1369 SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),
1370 st->subframeSize, &pitch, &pitch_gain[0], bits, stack,
1371 st->count_lost, offset, st->last_pitch_gain, 0);
1372
1373 /* Ensuring that things aren't blowing up as would happen if e.g. an encoder is
1374 crafting packets to make us produce NaNs and slow down the decoder (vague DoS threat).
1375 We can probably be even more aggressive and limit to 15000 or so. */
1376 sanitize_values32(exc32, NEG32(QCONST32(32000,SIG_SHIFT-1)), QCONST32(32000,SIG_SHIFT-1), st->subframeSize);
1377
1378 tmp = gain_3tap_to_1tap(pitch_gain);
1379
1380 pitch_average += tmp;
1381 if ((tmp>best_pitch_gain&&ABS(2*best_pitch-pitch)>=3&&ABS(3*best_pitch-pitch)>=4&&ABS(4*best_pitch-pitch)>=5)
1382 || (tmp>MULT16_16_Q15(QCONST16(.6,15),best_pitch_gain)&&(ABS(best_pitch-2*pitch)<3||ABS(best_pitch-3*pitch)<4||ABS(best_pitch-4*pitch)<5))
1383 || (MULT16_16_Q15(QCONST16(.67,15),tmp)>best_pitch_gain&&(ABS(2*best_pitch-pitch)<3||ABS(3*best_pitch-pitch)<4||ABS(4*best_pitch-pitch)<5)) )
1384 {
1385 best_pitch = pitch;
1386 if (tmp > best_pitch_gain)
1387 best_pitch_gain = tmp;
1388 }
1389 }
1390
1391 /* Unquantize the innovation */
1392 {
1393 int q_energy;
1394 spx_word32_t ener;
1395
1396 SPEEX_MEMSET(innov, 0, st->subframeSize);
1397
1398 /* Decode sub-frame gain correction */
1399 if (SUBMODE(have_subframe_gain)==3)
1400 {
1401 q_energy = speex_bits_unpack_unsigned(bits, 3);
1402 ener = MULT16_32_Q14(exc_gain_quant_scal3[q_energy],ol_gain);
1403 } else if (SUBMODE(have_subframe_gain)==1)
1404 {
1405 q_energy = speex_bits_unpack_unsigned(bits, 1);
1406 ener = MULT16_32_Q14(exc_gain_quant_scal1[q_energy],ol_gain);
1407 } else {
1408 ener = ol_gain;
1409 }
1410
1411 speex_assert (SUBMODE(innovation_unquant));
1412 {
1413 /*Fixed codebook contribution*/
1414 SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);
1415 /* De-normalize innovation and update excitation */
1416
1417 signal_mul(innov, innov, ener, st->subframeSize);
1418
1419 /* Decode second codebook (only for some modes) */
1420 if (SUBMODE(double_codebook))
1421 {
1422 char *tmp_stack=stack;
1423 VARDECL(spx_sig_t *innov2);
1424 ALLOC(innov2, st->subframeSize, spx_sig_t);
1425 SPEEX_MEMSET(innov2, 0, st->subframeSize);
1426 SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);
1427 signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize);
1428 for (i=0;i<st->subframeSize;i++)
1429 innov[i] = ADD32(innov[i], innov2[i]);
1430 stack = tmp_stack;
1431 }
1432 for (i=0;i<st->subframeSize;i++)
1433 exc[i]=EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));
1434 /*print_vec(exc, 40, "innov");*/
1435 if (innov_save)
1436 {
1437 for (i=0;i<st->subframeSize;i++)
1438 innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT));
1439 }
1440 }
1441
1442 /*Vocoder mode*/
1443 if (st->submodeID==1)
1444 {
1445 spx_word16_t g=ol_pitch_coef;
1446 g=MULT16_16_P14(QCONST16(1.5f,14),(g-QCONST16(.2f,6)));
1447 if (g<0)
1448 g=0;
1449 if (g>GAIN_SCALING)
1450 g=GAIN_SCALING;
1451
1452 SPEEX_MEMSET(exc, 0, st->subframeSize);
1453 while (st->voc_offset<st->subframeSize)
1454 {
1455 /* exc[st->voc_offset]= g*sqrt(2*ol_pitch)*ol_gain;
1456 Not quite sure why we need the factor of two in the sqrt */
1457 if (st->voc_offset>=0)
1458 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)));
1459 st->voc_offset+=ol_pitch;
1460 }
1461 st->voc_offset -= st->subframeSize;
1462
1463 for (i=0;i<st->subframeSize;i++)
1464 {
1465 spx_word16_t exci=exc[i];
1466 exc[i]= ADD16(ADD16(MULT16_16_Q15(QCONST16(.7f,15),exc[i]) , MULT16_16_Q15(QCONST16(.3f,15),st->voc_m1)),
1467 SUB16(MULT16_16_Q15(Q15_ONE-MULT16_16_16(QCONST16(.85f,9),g),EXTRACT16(PSHR32(innov[i],SIG_SHIFT))),
1468 MULT16_16_Q15(MULT16_16_16(QCONST16(.15f,9),g),EXTRACT16(PSHR32(st->voc_m2,SIG_SHIFT)))
1469 ));
1470 st->voc_m1 = exci;
1471 st->voc_m2=innov[i];
1472 st->voc_mean = EXTRACT16(PSHR32(ADD32(MULT16_16(QCONST16(.8f,15),st->voc_mean), MULT16_16(QCONST16(.2f,15),exc[i])), 15));
1473 exc[i]-=st->voc_mean;
1474 }
1475 }
1476
1477 }
1478 }
1479
1480 ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
1481
1482 if (st->lpc_enh_enabled && SUBMODE(comb_gain)>0 && !st->count_lost)
1483 {
1484 multicomb(st->exc-st->subframeSize, out, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);
1485 multicomb(st->exc+st->subframeSize, out+2*st->subframeSize, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);
1486 } else {
1487 SPEEX_COPY(out, &st->exc[-st->subframeSize], st->frameSize);
1488 }
1489
1490 /* If the last packet was lost, re-scale the excitation to obtain the same energy as encoded in ol_gain */
1491 if (st->count_lost)
1492 {
1493 spx_word16_t exc_ener;
1494 spx_word32_t gain32;
1495 spx_word16_t gain;
1496 exc_ener = compute_rms16 (st->exc, st->frameSize);
1497 gain32 = PDIV32(ol_gain, ADD16(exc_ener,1));
1498#ifdef FIXED_POINT
1499 if (gain32 > 32767)
1500 gain32 = 32767;
1501 gain = EXTRACT16(gain32);
1502#else
1503 if (gain32 > 2)
1504 gain32=2;
1505 gain = gain32;
1506#endif
1507 for (i=0;i<st->frameSize;i++)
1508 {
1509 st->exc[i] = MULT16_16_Q14(gain, st->exc[i]);
1510 out[i]=st->exc[i-st->subframeSize];
1511 }
1512 }
1513
1514 /*Loop on subframes */
1515 for (sub=0;sub<st->nbSubframes;sub++)
1516 {
1517 int offset;
1518 spx_word16_t *sp;
1519
1520 /* Offset relative to start of frame */
1521 offset = st->subframeSize*sub;
1522 /* Original signal */
1523 sp=out+offset;
1524
1525 /* LSP interpolation (quantized and unquantized) */
1526 lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
1527
1528 /* Make sure the LSP's are stable */
1529 lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
1530
1531 /* Compute interpolated LPCs (unquantized) */
1532 lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack);
1533
1534 /* Compute analysis filter at w=pi */
1535 {
1536 spx_word32_t pi_g=LPC_SCALING;
1537 for (i=0;i<st->lpcSize;i+=2)
1538 {
1539 /*pi_g += -st->interp_qlpc[i] + st->interp_qlpc[i+1];*/
1540 pi_g = ADD32(pi_g, SUB32(EXTEND32(ak[i+1]),EXTEND32(ak[i])));
1541 }
1542 st->pi_gain[sub] = pi_g;
1543 }
1544
1545 iir_mem16(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize,
1546 st->mem_sp, stack);
1547
1548 for (i=0;i<st->lpcSize;i++)
1549 st->interp_qlpc[i] = ak[i];
1550
1551 }
1552
1553 if (st->highpass_enabled)
1554 highpass(out, out, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_OUTPUT, st->mem_hp);
1555 /*for (i=0;i<st->frameSize;i++)
1556 printf ("%d\n", (int)st->frame[i]);*/
1557
1558 /* Tracking output level */
1559 st->level = 1+PSHR32(ol_gain,SIG_SHIFT);
1560 st->max_level = MAX16(MULT16_16_Q15(QCONST16(.99f,15), st->max_level), st->level);
1561 st->min_level = MIN16(ADD16(1,MULT16_16_Q14(QCONST16(1.01f,14), st->min_level)), st->level);
1562 if (st->max_level < st->min_level+1)
1563 st->max_level = st->min_level+1;
1564 /*printf ("%f %f %f %d\n", og, st->min_level, st->max_level, update);*/
1565
1566 /* Store the LSPs for interpolation in the next frame */
1567 for (i=0;i<st->lpcSize;i++)
1568 st->old_qlsp[i] = qlsp[i];
1569
1570 /* The next frame will not be the first (Duh!) */
1571 st->first = 0;
1572 st->count_lost=0;
1573 st->last_pitch = best_pitch;
1574#ifdef FIXED_POINT
1575 st->last_pitch_gain = PSHR16(pitch_average,2);
1576#else
1577 st->last_pitch_gain = .25*pitch_average;
1578#endif
1579 st->pitch_gain_buf[st->pitch_gain_buf_idx++] = st->last_pitch_gain;
1580 if (st->pitch_gain_buf_idx > 2) /* rollover */
1581 st->pitch_gain_buf_idx = 0;
1582
1583 st->last_ol_gain = ol_gain;
1584
1585 return 0;
1586}
1587
1588#ifndef SPEEX_DISABLE_ENCODER
1589int nb_encoder_ctl(void *state, int request, void *ptr)
1590{
1591 EncState *st;
1592 st=(EncState*)state;
1593 switch(request)
1594 {
1595 case SPEEX_GET_FRAME_SIZE:
1596 (*(spx_int32_t*)ptr) = st->frameSize;
1597 break;
1598 case SPEEX_SET_LOW_MODE:
1599 case SPEEX_SET_MODE:
1600 st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr);
1601 break;
1602 case SPEEX_GET_LOW_MODE:
1603 case SPEEX_GET_MODE:
1604 (*(spx_int32_t*)ptr) = st->submodeID;
1605 break;
1606#ifndef DISABLE_VBR
1607 case SPEEX_SET_VBR:
1608 st->vbr_enabled = (*(spx_int32_t*)ptr);
1609 break;
1610 case SPEEX_GET_VBR:
1611 (*(spx_int32_t*)ptr) = st->vbr_enabled;
1612 break;
1613 case SPEEX_SET_VAD:
1614 st->vad_enabled = (*(spx_int32_t*)ptr);
1615 break;
1616 case SPEEX_GET_VAD:
1617 (*(spx_int32_t*)ptr) = st->vad_enabled;
1618 break;
1619 case SPEEX_SET_DTX:
1620 st->dtx_enabled = (*(spx_int32_t*)ptr);
1621 break;
1622 case SPEEX_GET_DTX:
1623 (*(spx_int32_t*)ptr) = st->dtx_enabled;
1624 break;
1625 case SPEEX_SET_ABR:
1626 st->abr_enabled = (*(spx_int32_t*)ptr);
1627 st->vbr_enabled = st->abr_enabled!=0;
1628 if (st->vbr_enabled)
1629 {
1630 spx_int32_t i=10;
1631 spx_int32_t rate, target;
1632 float vbr_qual;
1633 target = (*(spx_int32_t*)ptr);
1634 while (i>=0)
1635 {
1636 speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
1637 speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
1638 if (rate <= target)
1639 break;
1640 i--;
1641 }
1642 vbr_qual=i;
1643 if (vbr_qual<0)
1644 vbr_qual=0;
1645 speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
1646 st->abr_count=0;
1647 st->abr_drift=0;
1648 st->abr_drift2=0;
1649 }
1650
1651 break;
1652 case SPEEX_GET_ABR:
1653 (*(spx_int32_t*)ptr) = st->abr_enabled;
1654 break;
1655#endif /* #ifndef DISABLE_VBR */
1656#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
1657 case SPEEX_SET_VBR_QUALITY:
1658 st->vbr_quality = (*(float*)ptr);
1659 break;
1660 case SPEEX_GET_VBR_QUALITY:
1661 (*(float*)ptr) = st->vbr_quality;
1662 break;
1663#endif /* !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
1664 case SPEEX_SET_QUALITY:
1665 {
1666 int quality = (*(spx_int32_t*)ptr);
1667 if (quality < 0)
1668 quality = 0;
1669 if (quality > 10)
1670 quality = 10;
1671 st->submodeSelect = st->submodeID = ((const SpeexNBMode*)(st->mode->mode))->quality_map[quality];
1672 }
1673 break;
1674 case SPEEX_SET_COMPLEXITY:
1675 st->complexity = (*(spx_int32_t*)ptr);
1676 if (st->complexity<0)
1677 st->complexity=0;
1678 break;
1679 case SPEEX_GET_COMPLEXITY:
1680 (*(spx_int32_t*)ptr) = st->complexity;
1681 break;
1682 case SPEEX_SET_BITRATE:
1683 {
1684 spx_int32_t i=10;
1685 spx_int32_t rate, target;
1686 target = (*(spx_int32_t*)ptr);
1687 while (i>=0)
1688 {
1689 speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
1690 speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
1691 if (rate <= target)
1692 break;
1693 i--;
1694 }
1695 }
1696 break;
1697 case SPEEX_GET_BITRATE:
1698 if (st->submodes[st->submodeID])
1699 (*(spx_int32_t*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize;
1700 else
1701 (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;
1702 break;
1703 case SPEEX_SET_SAMPLING_RATE:
1704 st->sampling_rate = (*(spx_int32_t*)ptr);
1705 break;
1706 case SPEEX_GET_SAMPLING_RATE:
1707 (*(spx_int32_t*)ptr)=st->sampling_rate;
1708 break;
1709 case SPEEX_RESET_STATE:
1710 {
1711 int i;
1712 st->bounded_pitch = 1;
1713 st->first = 1;
1714 for (i=0;i<st->lpcSize;i++)
1715 st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
1716 for (i=0;i<st->lpcSize;i++)
1717 st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0;
1718 for (i=0;i<st->frameSize+st->max_pitch+1;i++)
1719 st->excBuf[i]=st->swBuf[i]=0;
1720 for (i=0;i<st->windowSize-st->frameSize;i++)
1721 st->winBuf[i]=0;
1722 }
1723 break;
1724 case SPEEX_SET_SUBMODE_ENCODING:
1725 st->encode_submode = (*(spx_int32_t*)ptr);
1726 break;
1727 case SPEEX_GET_SUBMODE_ENCODING:
1728 (*(spx_int32_t*)ptr) = st->encode_submode;
1729 break;
1730 case SPEEX_GET_LOOKAHEAD:
1731 (*(spx_int32_t*)ptr)=(st->windowSize-st->frameSize);
1732 break;
1733 case SPEEX_SET_PLC_TUNING:
1734 st->plc_tuning = (*(spx_int32_t*)ptr);
1735 if (st->plc_tuning>100)
1736 st->plc_tuning=100;
1737 break;
1738 case SPEEX_GET_PLC_TUNING:
1739 (*(spx_int32_t*)ptr)=(st->plc_tuning);
1740 break;
1741#ifndef DISABLE_VBR
1742 case SPEEX_SET_VBR_MAX_BITRATE:
1743 st->vbr_max = (*(spx_int32_t*)ptr);
1744 break;
1745 case SPEEX_GET_VBR_MAX_BITRATE:
1746 (*(spx_int32_t*)ptr) = st->vbr_max;
1747 break;
1748#endif /* #ifndef DISABLE_VBR */
1749 case SPEEX_SET_HIGHPASS:
1750 st->highpass_enabled = (*(spx_int32_t*)ptr);
1751 break;
1752 case SPEEX_GET_HIGHPASS:
1753 (*(spx_int32_t*)ptr) = st->highpass_enabled;
1754 break;
1755
1756 /* This is all internal stuff past this point */
1757 case SPEEX_GET_PI_GAIN:
1758 {
1759 int i;
1760 spx_word32_t *g = (spx_word32_t*)ptr;
1761 for (i=0;i<st->nbSubframes;i++)
1762 g[i]=st->pi_gain[i];
1763 }
1764 break;
1765 case SPEEX_GET_EXC:
1766 {
1767 int i;
1768 for (i=0;i<st->nbSubframes;i++)
1769 ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize);
1770 }
1771 break;
1772#ifndef DISABLE_VBR
1773 case SPEEX_GET_RELATIVE_QUALITY:
1774 (*(float*)ptr)=st->relative_quality;
1775 break;
1776#endif /* #ifndef DISABLE_VBR */
1777 case SPEEX_SET_INNOVATION_SAVE:
1778 st->innov_rms_save = (spx_word16_t*)ptr;
1779 break;
1780 case SPEEX_SET_WIDEBAND:
1781 st->isWideband = *((spx_int32_t*)ptr);
1782 break;
1783 case SPEEX_GET_STACK:
1784 *((char**)ptr) = st->stack;
1785 break;
1786 default:
1787 speex_warning_int("Unknown nb_ctl request: ", request);
1788 return -1;
1789 }
1790 return 0;
1791}
1792#endif /* SPEEX_DISABLE_ENCODER */
1793
1794int nb_decoder_ctl(void *state, int request, void *ptr)
1795{
1796 DecState *st;
1797 st=(DecState*)state;
1798 switch(request)
1799 {
1800 case SPEEX_SET_LOW_MODE:
1801 case SPEEX_SET_MODE:
1802 st->submodeID = (*(spx_int32_t*)ptr);
1803 break;
1804 case SPEEX_GET_LOW_MODE:
1805 case SPEEX_GET_MODE:
1806 (*(spx_int32_t*)ptr) = st->submodeID;
1807 break;
1808 case SPEEX_SET_ENH:
1809 st->lpc_enh_enabled = *((spx_int32_t*)ptr);
1810 break;
1811 case SPEEX_GET_ENH:
1812 *((spx_int32_t*)ptr) = st->lpc_enh_enabled;
1813 break;
1814 case SPEEX_GET_FRAME_SIZE:
1815 (*(spx_int32_t*)ptr) = st->frameSize;
1816 break;
1817 case SPEEX_GET_BITRATE:
1818 if (st->submodes[st->submodeID])
1819 (*(spx_int32_t*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize;
1820 else
1821 (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;
1822 break;
1823 case SPEEX_SET_SAMPLING_RATE:
1824 st->sampling_rate = (*(spx_int32_t*)ptr);
1825 break;
1826 case SPEEX_GET_SAMPLING_RATE:
1827 (*(spx_int32_t*)ptr)=st->sampling_rate;
1828 break;
1829 case SPEEX_SET_HANDLER:
1830 {
1831 SpeexCallback *c = (SpeexCallback*)ptr;
1832 st->speex_callbacks[c->callback_id].func=c->func;
1833 st->speex_callbacks[c->callback_id].data=c->data;
1834 st->speex_callbacks[c->callback_id].callback_id=c->callback_id;
1835 }
1836 break;
1837 case SPEEX_SET_USER_HANDLER:
1838 {
1839 SpeexCallback *c = (SpeexCallback*)ptr;
1840 st->user_callback.func=c->func;
1841 st->user_callback.data=c->data;
1842 st->user_callback.callback_id=c->callback_id;
1843 }
1844 break;
1845 case SPEEX_RESET_STATE:
1846 {
1847 int i;
1848 for (i=0;i<st->lpcSize;i++)
1849 st->mem_sp[i]=0;
1850 for (i=0;i<st->frameSize + st->max_pitch + 1;i++)
1851 st->excBuf[i]=0;
1852 }
1853 break;
1854 case SPEEX_SET_SUBMODE_ENCODING:
1855 st->encode_submode = (*(spx_int32_t*)ptr);
1856 break;
1857 case SPEEX_GET_SUBMODE_ENCODING:
1858 (*(spx_int32_t*)ptr) = st->encode_submode;
1859 break;
1860 case SPEEX_GET_LOOKAHEAD:
1861 (*(spx_int32_t*)ptr)=st->subframeSize;
1862 break;
1863 case SPEEX_SET_HIGHPASS:
1864 st->highpass_enabled = (*(spx_int32_t*)ptr);
1865 break;
1866 case SPEEX_GET_HIGHPASS:
1867 (*(spx_int32_t*)ptr) = st->highpass_enabled;
1868 break;
1869 /* FIXME: Convert to fixed-point and re-enable even when float API is disabled */
1870#ifndef DISABLE_FLOAT_API
1871 case SPEEX_GET_ACTIVITY:
1872 {
1873 float ret;
1874 ret = log(st->level/st->min_level)/log(st->max_level/st->min_level);
1875 if (ret>1)
1876 ret = 1;
1877 /* Done in a strange way to catch NaNs as well */
1878 if (!(ret > 0))
1879 ret = 0;
1880 /*printf ("%f %f %f %f\n", st->level, st->min_level, st->max_level, ret);*/
1881 (*(spx_int32_t*)ptr) = (int)(100*ret);
1882 }
1883 break;
1884#endif
1885 case SPEEX_GET_PI_GAIN:
1886 {
1887 int i;
1888 spx_word32_t *g = (spx_word32_t*)ptr;
1889 for (i=0;i<st->nbSubframes;i++)
1890 g[i]=st->pi_gain[i];
1891 }
1892 break;
1893 case SPEEX_GET_EXC:
1894 {
1895 int i;
1896 for (i=0;i<st->nbSubframes;i++)
1897 ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize);
1898 }
1899 break;
1900 case SPEEX_GET_DTX_STATUS:
1901 *((spx_int32_t*)ptr) = st->dtx_enabled;
1902 break;
1903 case SPEEX_SET_INNOVATION_SAVE:
1904 st->innov_save = (spx_word16_t*)ptr;
1905 break;
1906 case SPEEX_SET_WIDEBAND:
1907 st->isWideband = *((spx_int32_t*)ptr);
1908 break;
1909 case SPEEX_GET_STACK:
1910 *((char**)ptr) = st->stack;
1911 break;
1912 default:
1913 speex_warning_int("Unknown nb_ctl request: ", request);
1914 return -1;
1915 }
1916 return 0;
1917}
diff --git a/lib/rbcodec/codecs/libspeex/nb_celp.h b/lib/rbcodec/codecs/libspeex/nb_celp.h
new file mode 100644
index 0000000000..30edbefaeb
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/nb_celp.h
@@ -0,0 +1,205 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin */
2/**
3 @file nb_celp.h
4 @brief Narrowband CELP encoder/decoder
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#ifndef NB_CELP_H
37#define NB_CELP_H
38
39#include "modes.h"
40#include "speex/speex_bits.h"
41#include "speex/speex_callbacks.h"
42#include "vbr.h"
43#include "filters.h"
44
45#ifdef VORBIS_PSYCHO
46#include "vorbis_psy.h"
47#endif
48
49/**Structure representing the full state of the narrowband encoder*/
50typedef struct EncState {
51 const SpeexMode *mode; /**< Mode corresponding to the state */
52 int first; /**< Is this the first frame? */
53 int frameSize; /**< Size of frames */
54 int subframeSize; /**< Size of sub-frames */
55 int nbSubframes; /**< Number of sub-frames */
56 int windowSize; /**< Analysis (LPC) window length */
57 int lpcSize; /**< LPC order */
58 int min_pitch; /**< Minimum pitch value allowed */
59 int max_pitch; /**< Maximum pitch value allowed */
60
61 spx_word32_t cumul_gain; /**< Product of previously used pitch gains (Q10) */
62 int bounded_pitch; /**< Next frame should not rely on previous frames for pitch */
63 int ol_pitch; /**< Open-loop pitch */
64 int ol_voiced; /**< Open-loop voiced/non-voiced decision */
65 int *pitch;
66
67#ifdef VORBIS_PSYCHO
68 VorbisPsy *psy;
69 float *psy_window;
70 float *curve;
71 float *old_curve;
72#endif
73
74 spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */
75 spx_word16_t gamma2; /**< Perceptual filter: A(z/gamma2) */
76 spx_word16_t lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/
77 char *stack; /**< Pseudo-stack allocation for temporary memory */
78 spx_word16_t *winBuf; /**< Input buffer (original signal) */
79 spx_word16_t *excBuf; /**< Excitation buffer */
80 spx_word16_t *exc; /**< Start of excitation frame */
81 spx_word16_t *swBuf; /**< Weighted signal buffer */
82 spx_word16_t *sw; /**< Start of weighted signal frame */
83 const spx_word16_t *window; /**< Temporary (Hanning) window */
84 const spx_word16_t *lagWindow; /**< Window applied to auto-correlation */
85 spx_lsp_t *old_lsp; /**< LSPs for previous frame */
86 spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */
87 spx_mem_t *mem_sp; /**< Filter memory for signal synthesis */
88 spx_mem_t *mem_sw; /**< Filter memory for perceptually-weighted signal */
89 spx_mem_t *mem_sw_whole; /**< Filter memory for perceptually-weighted signal (whole frame)*/
90 spx_mem_t *mem_exc; /**< Filter memory for excitation (whole frame) */
91 spx_mem_t *mem_exc2; /**< Filter memory for excitation (whole frame) */
92 spx_mem_t mem_hp[2]; /**< High-pass filter memory */
93 spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */
94 spx_word16_t *innov_rms_save; /**< If non-NULL, innovation RMS is copied here */
95
96#ifndef DISABLE_VBR
97 VBRState *vbr; /**< State of the VBR data */
98 float vbr_quality; /**< Quality setting for VBR encoding */
99 float relative_quality; /**< Relative quality that will be needed by VBR */
100 spx_int32_t vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */
101 spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode */
102 int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */
103 int dtx_enabled; /**< 1 for enabling DTX, 0 otherwise */
104 int dtx_count; /**< Number of consecutive DTX frames */
105 spx_int32_t abr_enabled; /**< ABR setting (in bps), 0 if off */
106 float abr_drift;
107 float abr_drift2;
108 float abr_count;
109#endif /* #ifndef DISABLE_VBR */
110
111 int complexity; /**< Complexity setting (0-10 from least complex to most complex) */
112 spx_int32_t sampling_rate;
113 int plc_tuning;
114 int encode_submode;
115 const SpeexSubmode * const *submodes; /**< Sub-mode data */
116 int submodeID; /**< Activated sub-mode */
117 int submodeSelect; /**< Mode chosen by the user (may differ from submodeID if VAD is on) */
118 int isWideband; /**< Is this used as part of the embedded wideband codec */
119 int highpass_enabled; /**< Is the input filter enabled */
120} EncState;
121
122/**Structure representing the full state of the narrowband decoder*/
123typedef struct DecState {
124 const SpeexMode *mode; /**< Mode corresponding to the state */
125 int first; /**< Is this the first frame? */
126 int count_lost; /**< Was the last frame lost? */
127 int frameSize; /**< Size of frames */
128 int subframeSize; /**< Size of sub-frames */
129 int nbSubframes; /**< Number of sub-frames */
130 int lpcSize; /**< LPC order */
131 int min_pitch; /**< Minimum pitch value allowed */
132 int max_pitch; /**< Maximum pitch value allowed */
133 spx_int32_t sampling_rate;
134
135 spx_word16_t last_ol_gain; /**< Open-loop gain for previous frame */
136
137 char *stack; /**< Pseudo-stack allocation for temporary memory */
138 /* Size calculated from maximum values of frameSize, max_pitch and
139 * subframeSize, being respectively 160, 144 and 40 */
140 spx_word16_t excBuf[500]; /**< Excitation buffer */
141 spx_word16_t *exc; /**< Start of excitation frame */
142 spx_lsp_t old_qlsp[10]; /**< Quantized LSPs for previous frame */
143 spx_coef_t interp_qlpc[10]; /**< Interpolated quantized LPCs */
144 spx_mem_t mem_sp[10]; /**< Filter memory for synthesis signal */
145 spx_mem_t mem_hp[2]; /**< High-pass filter memory */
146 spx_word32_t pi_gain[4]; /**< Gain of LPC filter at theta=pi (fe/2) */
147 spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */
148
149 spx_word16_t level;
150 spx_word16_t max_level;
151 spx_word16_t min_level;
152
153 /* This is used in packet loss concealment */
154 int last_pitch; /**< Pitch of last correctly decoded frame */
155 spx_word16_t last_pitch_gain; /**< Pitch gain of last correctly decoded frame */
156 spx_word16_t pitch_gain_buf[3]; /**< Pitch gain of last decoded frames */
157 int pitch_gain_buf_idx; /**< Tail of the buffer */
158 spx_int32_t seed; /** Seed used for random number generation */
159
160 int encode_submode;
161 const SpeexSubmode * const *submodes; /**< Sub-mode data */
162 int submodeID; /**< Activated sub-mode */
163 int lpc_enh_enabled; /**< 1 when LPC enhancer is on, 0 otherwise */
164 SpeexCallback speex_callbacks[SPEEX_MAX_CALLBACKS];
165
166 SpeexCallback user_callback;
167
168 /*Vocoder data*/
169 spx_word16_t voc_m1;
170 spx_word32_t voc_m2;
171 spx_word16_t voc_mean;
172 int voc_offset;
173
174 int dtx_enabled;
175 int isWideband; /**< Is this used as part of the embedded wideband codec */
176 int highpass_enabled; /**< Is the input filter enabled */
177} DecState;
178
179/** Initializes encoder state*/
180void *nb_encoder_init(const SpeexMode *m);
181
182/** De-allocates encoder state resources*/
183void nb_encoder_destroy(void *state);
184
185/** Encodes one frame*/
186int nb_encode(void *state, void *in, SpeexBits *bits);
187
188
189/** Initializes decoder state*/
190void *nb_decoder_init(const SpeexMode *m);
191
192/** De-allocates decoder state resources*/
193void nb_decoder_destroy(void *state);
194
195/** Decodes one frame*/
196int nb_decode(void *state, SpeexBits *bits, void *out);
197
198/** ioctl-like function for controlling a narrowband encoder */
199int nb_encoder_ctl(void *state, int request, void *ptr);
200
201/** ioctl-like function for controlling a narrowband decoder */
202int nb_decoder_ctl(void *state, int request, void *ptr);
203
204
205#endif
diff --git a/lib/rbcodec/codecs/libspeex/oggframing.c b/lib/rbcodec/codecs/libspeex/oggframing.c
new file mode 100644
index 0000000000..42d29502a8
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/oggframing.c
@@ -0,0 +1,909 @@
1/********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
12
13 function: code raw [Vorbis] packets into framed OggSquish stream and
14 decode Ogg streams back into raw packets
15 last mod: $Id$
16
17 note: The CRC code is directly derived from public domain code by
18 Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html
19 for details.
20
21 ********************************************************************/
22
23//#include "config-tremor.h"
24#include <string.h>
25#include "speex/ogg.h"
26#include "arch.h"
27
28/* A complete description of Ogg framing exists in docs/framing.html */
29
30int spx_ogg_page_version(spx_ogg_page *og){
31 return((int)(og->header[4]));
32}
33
34int spx_ogg_page_continued(spx_ogg_page *og){
35 return((int)(og->header[5]&0x01));
36}
37
38int spx_ogg_page_bos(spx_ogg_page *og){
39 return((int)(og->header[5]&0x02));
40}
41
42int spx_ogg_page_eos(spx_ogg_page *og){
43 return((int)(og->header[5]&0x04));
44}
45
46spx_ogg_int64_t spx_ogg_page_granulepos(spx_ogg_page *og){
47 unsigned char *page=og->header;
48 spx_ogg_int64_t granulepos=page[13]&(0xff);
49 granulepos= (granulepos<<8)|(page[12]&0xff);
50 granulepos= (granulepos<<8)|(page[11]&0xff);
51 granulepos= (granulepos<<8)|(page[10]&0xff);
52 granulepos= (granulepos<<8)|(page[9]&0xff);
53 granulepos= (granulepos<<8)|(page[8]&0xff);
54 granulepos= (granulepos<<8)|(page[7]&0xff);
55 granulepos= (granulepos<<8)|(page[6]&0xff);
56 return(granulepos);
57}
58
59int spx_ogg_page_serialno(spx_ogg_page *og){
60 return(og->header[14] |
61 (og->header[15]<<8) |
62 (og->header[16]<<16) |
63 (og->header[17]<<24));
64}
65
66long spx_ogg_page_pageno(spx_ogg_page *og){
67 return(og->header[18] |
68 (og->header[19]<<8) |
69 (og->header[20]<<16) |
70 (og->header[21]<<24));
71}
72
73
74
75/* returns the number of packets that are completed on this page (if
76 the leading packet is begun on a previous page, but ends on this
77 page, it's counted */
78
79/* NOTE:
80If a page consists of a packet begun on a previous page, and a new
81packet begun (but not completed) on this page, the return will be:
82 spx_ogg_page_packets(page) ==1,
83 spx_ogg_page_continued(page) !=0
84
85If a page happens to be a single packet that was begun on a
86previous page, and spans to the next page (in the case of a three or
87more page packet), the return will be:
88 spx_ogg_page_packets(page) ==0,
89 spx_ogg_page_continued(page) !=0
90*/
91
92int spx_ogg_page_packets(spx_ogg_page *og){
93 int i,n=og->header[26],count=0;
94 for(i=0;i<n;i++)
95 if(og->header[27+i]<255)count++;
96 return(count);
97}
98
99
100#if 0
101/* helper to initialize lookup for direct-table CRC (illustrative; we
102 use the static init below) */
103
104static spx_ogg_uint32_t _spx_ogg_crc_entry(unsigned long index){
105 int i;
106 unsigned long r;
107
108 r = index << 24;
109 for (i=0; i<8; i++)
110 if (r & 0x80000000UL)
111 r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator
112 polynomial, although we use an
113 unreflected alg and an init/final
114 of 0, not 0xffffffff */
115 else
116 r<<=1;
117 return (r & 0xffffffffUL);
118}
119#endif
120
121static const spx_ogg_uint32_t crc_lookup[256]={
122 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
123 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
124 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
125 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
126 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
127 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
128 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
129 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
130 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
131 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
132 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
133 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
134 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
135 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
136 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
137 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
138 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
139 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
140 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
141 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
142 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
143 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
144 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
145 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
146 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
147 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
148 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
149 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
150 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
151 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
152 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
153 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
154 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
155 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
156 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
157 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
158 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
159 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
160 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
161 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
162 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
163 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
164 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
165 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
166 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
167 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
168 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
169 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
170 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
171 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
172 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
173 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
174 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
175 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
176 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
177 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
178 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
179 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
180 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
181 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
182 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
183 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
184 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
185 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
186
187/* init the encode/decode logical stream state */
188
189int spx_ogg_stream_init(spx_ogg_stream_state *os,int serialno){
190 if(os){
191 memset(os,0,sizeof(*os));
192 os->body_storage=16*1024;
193 os->body_data=_spx_ogg_malloc(os->body_storage*sizeof(*os->body_data));
194
195 os->lacing_storage=1024;
196 os->lacing_vals=_spx_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
197 os->granule_vals=_spx_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals));
198
199 os->serialno=serialno;
200
201 return(0);
202 }
203 return(-1);
204}
205
206/* _clear does not free os, only the non-flat storage within */
207int spx_ogg_stream_clear(spx_ogg_stream_state *os){
208 if(os){
209 if(os->body_data)_spx_ogg_free(os->body_data);
210 if(os->lacing_vals)_spx_ogg_free(os->lacing_vals);
211 if(os->granule_vals)_spx_ogg_free(os->granule_vals);
212
213 memset(os,0,sizeof(*os));
214 }
215 return(0);
216}
217
218int spx_ogg_stream_destroy(spx_ogg_stream_state *os){
219 if(os){
220 spx_ogg_stream_clear(os);
221 _spx_ogg_free(os);
222 }
223 return(0);
224}
225
226/* Helpers for spx_ogg_stream_encode; this keeps the structure and
227 what's happening fairly clear */
228
229static void _os_body_expand(spx_ogg_stream_state *os,int needed){
230 if(os->body_storage<=os->body_fill+needed){
231 os->body_storage+=(needed+1024);
232 os->body_data=_spx_ogg_realloc(os->body_data,os->body_storage*sizeof(*os->body_data));
233 }
234}
235
236static void _os_lacing_expand(spx_ogg_stream_state *os,int needed){
237 if(os->lacing_storage<=os->lacing_fill+needed){
238 os->lacing_storage+=(needed+32);
239 os->lacing_vals=_spx_ogg_realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals));
240 os->granule_vals=_spx_ogg_realloc(os->granule_vals,os->lacing_storage*sizeof(*os->granule_vals));
241 }
242}
243
244/* checksum the page */
245/* Direct table CRC; note that this will be faster in the future if we
246 perform the checksum silmultaneously with other copies */
247
248void spx_ogg_page_checksum_set(spx_ogg_page *og){
249 if(og){
250 spx_ogg_uint32_t crc_reg=0;
251 int i;
252
253 /* safety; needed for API behavior, but not framing code */
254 og->header[22]=0;
255 og->header[23]=0;
256 og->header[24]=0;
257 og->header[25]=0;
258
259 for(i=0;i<og->header_len;i++)
260 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
261 for(i=0;i<og->body_len;i++)
262 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
263
264 og->header[22]=(unsigned char)(crc_reg&0xff);
265 og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
266 og->header[24]=(unsigned char)((crc_reg>>16)&0xff);
267 og->header[25]=(unsigned char)((crc_reg>>24)&0xff);
268 }
269}
270
271/* submit data to the internal buffer of the framing engine */
272int spx_ogg_stream_packetin(spx_ogg_stream_state *os,spx_ogg_packet *op){
273 int lacing_vals=op->bytes/255+1,i;
274
275 if(os->body_returned){
276 /* advance packet data according to the body_returned pointer. We
277 had to keep it around to return a pointer into the buffer last
278 call */
279
280 os->body_fill-=os->body_returned;
281 if(os->body_fill)
282 memmove(os->body_data,os->body_data+os->body_returned,
283 os->body_fill);
284 os->body_returned=0;
285 }
286
287 /* make sure we have the buffer storage */
288 _os_body_expand(os,op->bytes);
289 _os_lacing_expand(os,lacing_vals);
290
291 /* Copy in the submitted packet. Yes, the copy is a waste; this is
292 the liability of overly clean abstraction for the time being. It
293 will actually be fairly easy to eliminate the extra copy in the
294 future */
295
296 memcpy(os->body_data+os->body_fill,op->packet,op->bytes);
297 os->body_fill+=op->bytes;
298
299 /* Store lacing vals for this packet */
300 for(i=0;i<lacing_vals-1;i++){
301 os->lacing_vals[os->lacing_fill+i]=255;
302 os->granule_vals[os->lacing_fill+i]=os->granulepos;
303 }
304 os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255;
305 os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos;
306
307 /* flag the first segment as the beginning of the packet */
308 os->lacing_vals[os->lacing_fill]|= 0x100;
309
310 os->lacing_fill+=lacing_vals;
311
312 /* for the sake of completeness */
313 os->packetno++;
314
315 if(op->e_o_s)os->e_o_s=1;
316
317 return(0);
318}
319
320/* This will flush remaining packets into a page (returning nonzero),
321 even if there is not enough data to trigger a flush normally
322 (undersized page). If there are no packets or partial packets to
323 flush, spx_ogg_stream_flush returns 0. Note that spx_ogg_stream_flush will
324 try to flush a normal sized page like spx_ogg_stream_pageout; a call to
325 spx_ogg_stream_flush does not guarantee that all packets have flushed.
326 Only a return value of 0 from spx_ogg_stream_flush indicates all packet
327 data is flushed into pages.
328
329 since spx_ogg_stream_flush will flush the last page in a stream even if
330 it's undersized, you almost certainly want to use spx_ogg_stream_pageout
331 (and *not* spx_ogg_stream_flush) unless you specifically need to flush
332 an page regardless of size in the middle of a stream. */
333
334int spx_ogg_stream_flush(spx_ogg_stream_state *os,spx_ogg_page *og){
335 int i;
336 int vals=0;
337 int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
338 int bytes=0;
339 long acc=0;
340 spx_ogg_int64_t granule_pos=-1;
341
342 if(maxvals==0)return(0);
343
344 /* construct a page */
345 /* decide how many segments to include */
346
347 /* If this is the initial header case, the first page must only include
348 the initial header packet */
349 if(os->b_o_s==0){ /* 'initial header page' case */
350 granule_pos=0;
351 for(vals=0;vals<maxvals;vals++){
352 if((os->lacing_vals[vals]&0x0ff)<255){
353 vals++;
354 break;
355 }
356 }
357 }else{
358 for(vals=0;vals<maxvals;vals++){
359 if(acc>4096)break;
360 acc+=os->lacing_vals[vals]&0x0ff;
361 if((os->lacing_vals[vals]&0xff)<255)
362 granule_pos=os->granule_vals[vals];
363 }
364 }
365
366 /* construct the header in temp storage */
367 memcpy(os->header,"OggS",4);
368
369 /* stream structure version */
370 os->header[4]=0x00;
371
372 /* continued packet flag? */
373 os->header[5]=0x00;
374 if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
375 /* first page flag? */
376 if(os->b_o_s==0)os->header[5]|=0x02;
377 /* last page flag? */
378 if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04;
379 os->b_o_s=1;
380
381 /* 64 bits of PCM position */
382 for(i=6;i<14;i++){
383 os->header[i]=(unsigned char)(granule_pos&0xff);
384 granule_pos>>=8;
385 }
386
387 /* 32 bits of stream serial number */
388 {
389 long serialno=os->serialno;
390 for(i=14;i<18;i++){
391 os->header[i]=(unsigned char)(serialno&0xff);
392 serialno>>=8;
393 }
394 }
395
396 /* 32 bits of page counter (we have both counter and page header
397 because this val can roll over) */
398 if(os->pageno==-1)os->pageno=0; /* because someone called
399 stream_reset; this would be a
400 strange thing to do in an
401 encode stream, but it has
402 plausible uses */
403 {
404 long pageno=os->pageno++;
405 for(i=18;i<22;i++){
406 os->header[i]=(unsigned char)(pageno&0xff);
407 pageno>>=8;
408 }
409 }
410
411 /* zero for computation; filled in later */
412 os->header[22]=0;
413 os->header[23]=0;
414 os->header[24]=0;
415 os->header[25]=0;
416
417 /* segment table */
418 os->header[26]=(unsigned char)(vals&0xff);
419 for(i=0;i<vals;i++)
420 bytes+=os->header[i+27]=(unsigned char)(os->lacing_vals[i]&0xff);
421
422 /* set pointers in the spx_ogg_page struct */
423 og->header=os->header;
424 og->header_len=os->header_fill=vals+27;
425 og->body=os->body_data+os->body_returned;
426 og->body_len=bytes;
427
428 /* advance the lacing data and set the body_returned pointer */
429
430 os->lacing_fill-=vals;
431 memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
432 memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
433 os->body_returned+=bytes;
434
435 /* calculate the checksum */
436
437 spx_ogg_page_checksum_set(og);
438
439 /* done */
440 return(1);
441}
442
443
444/* This constructs pages from buffered packet segments. The pointers
445returned are to static buffers; do not free. The returned buffers are
446good only until the next call (using the same spx_ogg_stream_state) */
447
448int spx_ogg_stream_pageout(spx_ogg_stream_state *os, spx_ogg_page *og){
449
450 if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */
451 os->body_fill-os->body_returned > 4096 ||/* 'page nominal size' case */
452 os->lacing_fill>=255 || /* 'segment table full' case */
453 (os->lacing_fill&&!os->b_o_s)){ /* 'initial header page' case */
454
455 return(spx_ogg_stream_flush(os,og));
456 }
457
458 /* not enough data to construct a page and not end of stream */
459 return(0);
460}
461
462int spx_ogg_stream_eos(spx_ogg_stream_state *os){
463 return os->e_o_s;
464}
465
466/* DECODING PRIMITIVES: packet streaming layer **********************/
467
468/* This has two layers to place more of the multi-serialno and paging
469 control in the application's hands. First, we expose a data buffer
470 using spx_ogg_sync_buffer(). The app either copies into the
471 buffer, or passes it directly to read(), etc. We then call
472 spx_ogg_sync_wrote() to tell how many bytes we just added.
473
474 Pages are returned (pointers into the buffer in spx_ogg_sync_state)
475 by spx_ogg_sync_pageout(). The page is then submitted to
476 spx_ogg_stream_pagein() along with the appropriate
477 spx_ogg_stream_state* (ie, matching serialno). We then get raw
478 packets out calling spx_ogg_stream_packetout() with a
479 spx_ogg_stream_state. */
480
481/* initialize the struct to a known state */
482int spx_ogg_sync_init(spx_ogg_sync_state *oy){
483 if(oy){
484 memset(oy,0,sizeof(*oy));
485 }
486 return(0);
487}
488
489/* clear non-flat storage within */
490int spx_ogg_sync_clear(spx_ogg_sync_state *oy){
491 if(oy){
492 if(oy->data)_spx_ogg_free(oy->data);
493 spx_ogg_sync_init(oy);
494 }
495 return(0);
496}
497
498int spx_ogg_sync_destroy(spx_ogg_sync_state *oy){
499 if(oy){
500 spx_ogg_sync_clear(oy);
501 _spx_ogg_free(oy);
502 }
503 return(0);
504}
505void spx_ogg_alloc_buffer(spx_ogg_sync_state *oy, long size){
506 long newsize=size+oy->fill+size; /* an extra page to be nice */
507 if(oy->data){
508 oy->data=_spx_ogg_realloc(oy->data,newsize);
509 }else
510 oy->data=_spx_ogg_malloc(newsize);
511 oy->storage=newsize;
512 return;
513}
514
515char *spx_ogg_sync_buffer(spx_ogg_sync_state *oy, long size){
516
517 /* first, clear out any space that has been previously returned */
518 if(oy->returned){
519 oy->fill-=oy->returned;
520 if(oy->fill>0)
521 memmove(oy->data,oy->data+oy->returned,oy->fill);
522 oy->returned=0;
523 }
524
525 if(size>oy->storage-oy->fill){
526 /* We need to extend the internal buffer */
527 long newsize=size+oy->fill+4096; /* an extra page to be nice */
528 if(oy->data){
529 oy->data=_spx_ogg_realloc(oy->data,newsize);
530 }else
531 oy->data=_spx_ogg_malloc(newsize);
532 oy->storage=newsize;
533 }
534
535 /* expose a segment at least as large as requested at the fill mark */
536 return((char *)oy->data+oy->fill);
537}
538
539int spx_ogg_sync_wrote(spx_ogg_sync_state *oy, long bytes){
540 if(oy->fill+bytes>oy->storage)return(-1);
541 oy->fill+=bytes;
542 return(0);
543}
544
545/* sync the stream. This is meant to be useful for finding page
546 boundaries.
547
548 return values for this:
549 -n) skipped n bytes
550 0) page not ready; more data (no bytes skipped)
551 n) page synced at current location; page length n bytes
552
553*/
554
555long spx_ogg_sync_pageseek(spx_ogg_sync_state *oy,spx_ogg_page *og){
556 unsigned char *page=oy->data+oy->returned;
557 unsigned char *next;
558 long bytes=oy->fill-oy->returned;
559
560 if(oy->headerbytes==0){
561 int headerbytes,i;
562 if(bytes<27)return(0); /* not enough for a header */
563
564 /* verify capture pattern */
565 if(memcmp(page,"OggS",4))goto sync_fail;
566
567 headerbytes=page[26]+27;
568 if(bytes<headerbytes)return(0); /* not enough for header + seg table */
569
570 /* count up body length in the segment table */
571
572 for(i=0;i<page[26];i++)
573 oy->bodybytes+=page[27+i];
574 oy->headerbytes=headerbytes;
575 }
576
577 if(oy->bodybytes+oy->headerbytes>bytes)return(0);
578
579 /* The whole test page is buffered. Verify the checksum */
580 {
581 /* Grab the checksum bytes, set the header field to zero */
582 char chksum[4];
583 spx_ogg_page log;
584
585 memcpy(chksum,page+22,4);
586 memset(page+22,0,4);
587
588 /* set up a temp page struct and recompute the checksum */
589 log.header=page;
590 log.header_len=oy->headerbytes;
591 log.body=page+oy->headerbytes;
592 log.body_len=oy->bodybytes;
593 spx_ogg_page_checksum_set(&log);
594
595 /* Compare */
596 if(memcmp(chksum,page+22,4)){
597 /* D'oh. Mismatch! Corrupt page (or miscapture and not a page
598 at all) */
599 /* replace the computed checksum with the one actually read in */
600 memcpy(page+22,chksum,4);
601
602 /* Bad checksum. Lose sync */
603 goto sync_fail;
604 }
605 }
606
607 /* yes, have a whole page all ready to go */
608 {
609 unsigned char *page=oy->data+oy->returned;
610 long bytes;
611
612 if(og){
613 og->header=page;
614 og->header_len=oy->headerbytes;
615 og->body=page+oy->headerbytes;
616 og->body_len=oy->bodybytes;
617 }
618
619 oy->unsynced=0;
620 oy->returned+=(bytes=oy->headerbytes+oy->bodybytes);
621 oy->headerbytes=0;
622 oy->bodybytes=0;
623 return(bytes);
624 }
625
626 sync_fail:
627
628 oy->headerbytes=0;
629 oy->bodybytes=0;
630
631 /* search for possible capture */
632 next=memchr(page+1,'O',bytes-1);
633 if(!next)
634 next=oy->data+oy->fill;
635
636 oy->returned=next-oy->data;
637 return(-(next-page));
638}
639
640/* sync the stream and get a page. Keep trying until we find a page.
641 Supress 'sync errors' after reporting the first.
642
643 return values:
644 -1) recapture (hole in data)
645 0) need more data
646 1) page returned
647
648 Returns pointers into buffered data; invalidated by next call to
649 _stream, _clear, _init, or _buffer */
650
651int spx_ogg_sync_pageout(spx_ogg_sync_state *oy, spx_ogg_page *og){
652
653 /* all we need to do is verify a page at the head of the stream
654 buffer. If it doesn't verify, we look for the next potential
655 frame */
656
657 for(;;){
658 long ret=spx_ogg_sync_pageseek(oy,og);
659 if(ret>0){
660 /* have a page */
661 return(1);
662 }
663 if(ret==0){
664 /* need more data */
665 return(0);
666 }
667
668 /* head did not start a synced page... skipped some bytes */
669 if(!oy->unsynced){
670 oy->unsynced=1;
671 return(-1);
672 }
673
674 /* loop. keep looking */
675
676 }
677}
678
679/* add the incoming page to the stream state; we decompose the page
680 into packet segments here as well. */
681
682int spx_ogg_stream_pagein(spx_ogg_stream_state *os, spx_ogg_page *og){
683 unsigned char *header=og->header;
684 unsigned char *body=og->body;
685 long bodysize=og->body_len;
686 int segptr=0;
687
688 int version=spx_ogg_page_version(og);
689 int continued=spx_ogg_page_continued(og);
690 int bos=spx_ogg_page_bos(og);
691 int eos=spx_ogg_page_eos(og);
692 spx_ogg_int64_t granulepos=spx_ogg_page_granulepos(og);
693 int serialno=spx_ogg_page_serialno(og);
694 long pageno=spx_ogg_page_pageno(og);
695 int segments=header[26];
696
697 /* clean up 'returned data' */
698 {
699 long lr=os->lacing_returned;
700 long br=os->body_returned;
701
702 /* body data */
703 if(br){
704 os->body_fill-=br;
705 if(os->body_fill)
706 memmove(os->body_data,os->body_data+br,os->body_fill);
707 os->body_returned=0;
708 }
709
710 if(lr){
711 /* segment table */
712 if(os->lacing_fill-lr){
713 memmove(os->lacing_vals,os->lacing_vals+lr,
714 (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
715 memmove(os->granule_vals,os->granule_vals+lr,
716 (os->lacing_fill-lr)*sizeof(*os->granule_vals));
717 }
718 os->lacing_fill-=lr;
719 os->lacing_packet-=lr;
720 os->lacing_returned=0;
721 }
722 }
723
724 /* check the serial number */
725 if(serialno!=os->serialno)return(-1);
726 if(version>0)return(-1);
727
728 _os_lacing_expand(os,segments+1);
729
730 /* are we in sequence? */
731 if(pageno!=os->pageno){
732 int i;
733
734 /* unroll previous partial packet (if any) */
735 for(i=os->lacing_packet;i<os->lacing_fill;i++)
736 os->body_fill-=os->lacing_vals[i]&0xff;
737 os->lacing_fill=os->lacing_packet;
738
739 /* make a note of dropped data in segment table */
740 if(os->pageno!=-1){
741 os->lacing_vals[os->lacing_fill++]=0x400;
742 os->lacing_packet++;
743 }
744 }
745
746 /* are we a 'continued packet' page? If so, we may need to skip
747 some segments */
748 if(continued){
749 if(os->lacing_fill<1 ||
750 os->lacing_vals[os->lacing_fill-1]==0x400){
751 bos=0;
752 for(;segptr<segments;segptr++){
753 int val=header[27+segptr];
754 body+=val;
755 bodysize-=val;
756 if(val<255){
757 segptr++;
758 break;
759 }
760 }
761 }
762 }
763
764 if(bodysize){
765 _os_body_expand(os,bodysize);
766 memcpy(os->body_data+os->body_fill,body,bodysize);
767 os->body_fill+=bodysize;
768 }
769
770 {
771 int saved=-1;
772 while(segptr<segments){
773 int val=header[27+segptr];
774 os->lacing_vals[os->lacing_fill]=val;
775 os->granule_vals[os->lacing_fill]=-1;
776
777 if(bos){
778 os->lacing_vals[os->lacing_fill]|=0x100;
779 bos=0;
780 }
781
782 if(val<255)saved=os->lacing_fill;
783
784 os->lacing_fill++;
785 segptr++;
786
787 if(val<255)os->lacing_packet=os->lacing_fill;
788 }
789
790 /* set the granulepos on the last granuleval of the last full packet */
791 if(saved!=-1){
792 os->granule_vals[saved]=granulepos;
793 }
794
795 }
796
797 if(eos){
798 os->e_o_s=1;
799 if(os->lacing_fill>0)
800 os->lacing_vals[os->lacing_fill-1]|=0x200;
801 }
802
803 os->pageno=pageno+1;
804
805 return(0);
806}
807
808/* clear things to an initial state. Good to call, eg, before seeking */
809int spx_ogg_sync_reset(spx_ogg_sync_state *oy){
810 oy->fill=0;
811 oy->returned=0;
812 oy->unsynced=0;
813 oy->headerbytes=0;
814 oy->bodybytes=0;
815 return(0);
816}
817
818int spx_ogg_stream_reset(spx_ogg_stream_state *os){
819 os->body_fill=0;
820 os->body_returned=0;
821
822 os->lacing_fill=0;
823 os->lacing_packet=0;
824 os->lacing_returned=0;
825
826 os->header_fill=0;
827
828 os->e_o_s=0;
829 os->b_o_s=0;
830 os->pageno=-1;
831 os->packetno=0;
832 os->granulepos=0;
833
834 return(0);
835}
836
837int spx_ogg_stream_reset_serialno(spx_ogg_stream_state *os,int serialno){
838 spx_ogg_stream_reset(os);
839 os->serialno=serialno;
840 return(0);
841}
842
843static int _packetout(spx_ogg_stream_state *os,spx_ogg_packet *op,int adv){
844
845 /* The last part of decode. We have the stream broken into packet
846 segments. Now we need to group them into packets (or return the
847 out of sync markers) */
848
849 int ptr=os->lacing_returned;
850
851 if(os->lacing_packet<=ptr)return(0);
852
853 if(os->lacing_vals[ptr]&0x400){
854 /* we need to tell the codec there's a gap; it might need to
855 handle previous packet dependencies. */
856 os->lacing_returned++;
857 os->packetno++;
858 return(-1);
859 }
860
861 if(!op && !adv)return(1); /* just using peek as an inexpensive way
862 to ask if there's a whole packet
863 waiting */
864
865 /* Gather the whole packet. We'll have no holes or a partial packet */
866 {
867 int size=os->lacing_vals[ptr]&0xff;
868 int bytes=size;
869 int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */
870 int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */
871
872 while(size==255){
873 int val=os->lacing_vals[++ptr];
874 size=val&0xff;
875 if(val&0x200)eos=0x200;
876 bytes+=size;
877 }
878
879 if(op){
880 op->e_o_s=eos;
881 op->b_o_s=bos;
882 op->packet=os->body_data+os->body_returned;
883 op->packetno=os->packetno;
884 op->granulepos=os->granule_vals[ptr];
885 op->bytes=bytes;
886 }
887
888 if(adv){
889 os->body_returned+=bytes;
890 os->lacing_returned=ptr+1;
891 os->packetno++;
892 }
893 }
894 return(1);
895}
896
897int spx_ogg_stream_packetout(spx_ogg_stream_state *os,spx_ogg_packet *op){
898 return _packetout(os,op,1);
899}
900
901int spx_ogg_stream_packetpeek(spx_ogg_stream_state *os,spx_ogg_packet *op){
902 return _packetout(os,op,0);
903}
904
905void spx_ogg_packet_clear(spx_ogg_packet *op) {
906 _spx_ogg_free(op->packet);
907 memset(op, 0, sizeof(*op));
908}
909
diff --git a/lib/rbcodec/codecs/libspeex/os_support.h b/lib/rbcodec/codecs/libspeex/os_support.h
new file mode 100644
index 0000000000..71d24753c1
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/os_support.h
@@ -0,0 +1,165 @@
1/* Copyright (C) 2007 Jean-Marc Valin
2
3 File: os_support.h
4 This is the (tiny) OS abstraction layer. Aside from math.h, this is the
5 only place where system headers are allowed.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10
11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 3. The name of the author may not be used to endorse or promote products
19 derived from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.
32*/
33
34#ifndef OS_SUPPORT_H
35#define OS_SUPPORT_H
36
37#include "config-speex.h"
38#include "rockbox.h"
39
40#include <string.h>
41#include <stdio.h>
42#include <stdlib.h>
43
44/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free
45 NOTE: speex_alloc needs to CLEAR THE MEMORY */
46#ifndef OVERRIDE_SPEEX_ALLOC
47static inline void *speex_alloc (int size)
48{
49 /* WARNING: this is not equivalent to malloc(). If you want to use malloc()
50 or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise
51 you will experience strange bugs */
52 return calloc(size,1);
53}
54#endif
55
56/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
57#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH
58static inline void *speex_alloc_scratch (int size)
59{
60 /* Scratch space doesn't need to be cleared */
61 return calloc(size,1);
62}
63#endif
64
65/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */
66#ifndef OVERRIDE_SPEEX_REALLOC
67static inline void *speex_realloc (void *ptr, int size)
68{
69 return realloc(ptr, size);
70}
71#endif
72
73/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */
74#ifndef OVERRIDE_SPEEX_FREE
75static inline void speex_free (void *ptr)
76{
77 free(ptr);
78}
79#endif
80
81/** Same as speex_free, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
82#ifndef OVERRIDE_SPEEX_FREE_SCRATCH
83static inline void speex_free_scratch (void *ptr)
84{
85 free(ptr);
86}
87#endif
88
89/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking */
90#ifndef OVERRIDE_SPEEX_COPY
91#define SPEEX_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
92#endif
93
94/** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term
95 provides compile-time type checking */
96#ifndef OVERRIDE_SPEEX_MOVE
97#define SPEEX_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
98#endif
99
100/** Set n bytes of memory to value of c, starting at address s */
101#ifndef OVERRIDE_SPEEX_MEMSET
102#define SPEEX_MEMSET(dst, c, n) (memset((dst), (c), (n)*sizeof(*(dst))))
103#endif
104
105
106#ifndef OVERRIDE_SPEEX_FATAL
107static inline void _speex_fatal(const char *str, const char *file, int line)
108{
109 fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
110 exit(1);
111}
112#endif
113
114#ifndef OVERRIDE_SPEEX_WARNING
115static inline void speex_warning(const char *str)
116{
117#ifndef DISABLE_WARNINGS
118 fprintf (stderr, "warning: %s\n", str);
119#endif
120}
121#endif
122
123#ifndef OVERRIDE_SPEEX_WARNING_INT
124static inline void speex_warning_int(const char *str, int val)
125{
126#ifndef DISABLE_WARNINGS
127 fprintf (stderr, "warning: %s %d\n", str, val);
128#endif
129}
130#endif
131
132#ifndef OVERRIDE_SPEEX_NOTIFY
133static inline void speex_notify(const char *str)
134{
135#ifndef DISABLE_NOTIFICATIONS
136 fprintf (stderr, "notification: %s\n", str);
137#endif
138}
139#endif
140
141#ifndef OVERRIDE_SPEEX_PUTC
142/** Speex wrapper for putc */
143static inline void _speex_putc(int ch, void *file)
144{
145 FILE *f = (FILE *)file;
146 fprintf(f, "%c", ch);
147}
148#endif
149
150#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__);
151#define speex_assert(cond) {if (!(cond)) {speex_fatal("assertion failed: " #cond);}}
152
153#ifndef RELEASE
154static inline void print_vec(float *vec, int len, char *name)
155{
156 int i;
157 printf ("%s ", name);
158 for (i=0;i<len;i++)
159 printf (" %f", vec[i]);
160 printf ("\n");
161}
162#endif
163
164#endif
165
diff --git a/lib/rbcodec/codecs/libspeex/preprocess.c b/lib/rbcodec/codecs/libspeex/preprocess.c
new file mode 100644
index 0000000000..07a2ad3479
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/preprocess.c
@@ -0,0 +1,1185 @@
1/* Copyright (C) 2003 Epic Games (written by Jean-Marc Valin)
2 Copyright (C) 2004-2006 Epic Games
3
4 File: preprocess.c
5 Preprocessor with denoising based on the algorithm by Ephraim and Malah
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10
11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 3. The name of the author may not be used to endorse or promote products
19 derived from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.
32*/
33
34
35/*
36 Recommended papers:
37
38 Y. Ephraim and D. Malah, "Speech enhancement using minimum mean-square error
39 short-time spectral amplitude estimator". IEEE Transactions on Acoustics,
40 Speech and Signal Processing, vol. ASSP-32, no. 6, pp. 1109-1121, 1984.
41
42 Y. Ephraim and D. Malah, "Speech enhancement using minimum mean-square error
43 log-spectral amplitude estimator". IEEE Transactions on Acoustics, Speech and
44 Signal Processing, vol. ASSP-33, no. 2, pp. 443-445, 1985.
45
46 I. Cohen and B. Berdugo, "Speech enhancement for non-stationary noise environments".
47 Signal Processing, vol. 81, no. 2, pp. 2403-2418, 2001.
48
49 Stefan Gustafsson, Rainer Martin, Peter Jax, and Peter Vary. "A psychoacoustic
50 approach to combined acoustic echo cancellation and noise reduction". IEEE
51 Transactions on Speech and Audio Processing, 2002.
52
53 J.-M. Valin, J. Rouat, and F. Michaud, "Microphone array post-filter for separation
54 of simultaneous non-stationary sources". In Proceedings IEEE International
55 Conference on Acoustics, Speech, and Signal Processing, 2004.
56*/
57
58#ifdef HAVE_CONFIG_H
59#include "config-speex.h"
60#endif
61
62#include <math.h>
63#include "speex/speex_preprocess.h"
64#include "speex/speex_echo.h"
65#include "arch.h"
66#include "fftwrap.h"
67#include "filterbank.h"
68#include "math_approx.h"
69#include "os_support.h"
70
71#ifndef M_PI
72#define M_PI 3.14159263
73#endif
74
75#define LOUDNESS_EXP 5.f
76#define AMP_SCALE .001f
77#define AMP_SCALE_1 1000.f
78
79#define NB_BANDS 24
80
81#define SPEECH_PROB_START_DEFAULT QCONST16(0.35f,15)
82#define SPEECH_PROB_CONTINUE_DEFAULT QCONST16(0.20f,15)
83#define NOISE_SUPPRESS_DEFAULT -15
84#define ECHO_SUPPRESS_DEFAULT -40
85#define ECHO_SUPPRESS_ACTIVE_DEFAULT -15
86
87#ifndef NULL
88#define NULL 0
89#endif
90
91#define SQR(x) ((x)*(x))
92#define SQR16(x) (MULT16_16((x),(x)))
93#define SQR16_Q15(x) (MULT16_16_Q15((x),(x)))
94
95#ifdef FIXED_POINT
96static inline spx_word16_t DIV32_16_Q8(spx_word32_t a, spx_word32_t b)
97{
98 if (SHR32(a,7) >= b)
99 {
100 return 32767;
101 } else {
102 if (b>=QCONST32(1,23))
103 {
104 a = SHR32(a,8);
105 b = SHR32(b,8);
106 }
107 if (b>=QCONST32(1,19))
108 {
109 a = SHR32(a,4);
110 b = SHR32(b,4);
111 }
112 if (b>=QCONST32(1,15))
113 {
114 a = SHR32(a,4);
115 b = SHR32(b,4);
116 }
117 a = SHL32(a,8);
118 return PDIV32_16(a,b);
119 }
120
121}
122static inline spx_word16_t DIV32_16_Q15(spx_word32_t a, spx_word32_t b)
123{
124 if (SHR32(a,15) >= b)
125 {
126 return 32767;
127 } else {
128 if (b>=QCONST32(1,23))
129 {
130 a = SHR32(a,8);
131 b = SHR32(b,8);
132 }
133 if (b>=QCONST32(1,19))
134 {
135 a = SHR32(a,4);
136 b = SHR32(b,4);
137 }
138 if (b>=QCONST32(1,15))
139 {
140 a = SHR32(a,4);
141 b = SHR32(b,4);
142 }
143 a = SHL32(a,15)-a;
144 return DIV32_16(a,b);
145 }
146}
147#define SNR_SCALING 256.f
148#define SNR_SCALING_1 0.0039062f
149#define SNR_SHIFT 8
150
151#define FRAC_SCALING 32767.f
152#define FRAC_SCALING_1 3.0518e-05
153#define FRAC_SHIFT 1
154
155#define EXPIN_SCALING 2048.f
156#define EXPIN_SCALING_1 0.00048828f
157#define EXPIN_SHIFT 11
158#define EXPOUT_SCALING_1 1.5259e-05
159
160#define NOISE_SHIFT 7
161
162#else
163
164#define DIV32_16_Q8(a,b) ((a)/(b))
165#define DIV32_16_Q15(a,b) ((a)/(b))
166#define SNR_SCALING 1.f
167#define SNR_SCALING_1 1.f
168#define SNR_SHIFT 0
169#define FRAC_SCALING 1.f
170#define FRAC_SCALING_1 1.f
171#define FRAC_SHIFT 0
172#define NOISE_SHIFT 0
173
174#define EXPIN_SCALING 1.f
175#define EXPIN_SCALING_1 1.f
176#define EXPOUT_SCALING_1 1.f
177
178#endif
179
180/** Speex pre-processor state. */
181struct SpeexPreprocessState_ {
182 /* Basic info */
183 int frame_size; /**< Number of samples processed each time */
184 int ps_size; /**< Number of points in the power spectrum */
185 int sampling_rate; /**< Sampling rate of the input/output */
186 int nbands;
187 FilterBank *bank;
188
189 /* Parameters */
190 int denoise_enabled;
191 int vad_enabled;
192 int dereverb_enabled;
193 spx_word16_t reverb_decay;
194 spx_word16_t reverb_level;
195 spx_word16_t speech_prob_start;
196 spx_word16_t speech_prob_continue;
197 int noise_suppress;
198 int echo_suppress;
199 int echo_suppress_active;
200 SpeexEchoState *echo_state;
201
202 /* DSP-related arrays */
203 spx_word16_t *frame; /**< Processing frame (2*ps_size) */
204 spx_word16_t *ft; /**< Processing frame in freq domain (2*ps_size) */
205 spx_word32_t *ps; /**< Current power spectrum */
206 spx_word16_t *gain2; /**< Adjusted gains */
207 spx_word16_t *gain_floor; /**< Minimum gain allowed */
208 spx_word16_t *window; /**< Analysis/Synthesis window */
209 spx_word32_t *noise; /**< Noise estimate */
210 spx_word32_t *reverb_estimate; /**< Estimate of reverb energy */
211 spx_word32_t *old_ps; /**< Power spectrum for last frame */
212 spx_word16_t *gain; /**< Ephraim Malah gain */
213 spx_word16_t *prior; /**< A-priori SNR */
214 spx_word16_t *post; /**< A-posteriori SNR */
215
216 spx_word32_t *S; /**< Smoothed power spectrum */
217 spx_word32_t *Smin; /**< See Cohen paper */
218 spx_word32_t *Stmp; /**< See Cohen paper */
219 int *update_prob; /**< Probability of speech presence for noise update */
220
221 spx_word16_t *zeta; /**< Smoothed a priori SNR */
222 spx_word32_t *echo_noise;
223 spx_word32_t *residual_echo;
224
225 /* Misc */
226 spx_word16_t *inbuf; /**< Input buffer (overlapped analysis) */
227 spx_word16_t *outbuf; /**< Output buffer (for overlap and add) */
228
229 /* AGC stuff, only for floating point for now */
230#ifndef FIXED_POINT
231 int agc_enabled;
232 float agc_level;
233 float loudness_accum;
234 float *loudness_weight; /**< Perceptual loudness curve */
235 float loudness; /**< Loudness estimate */
236 float agc_gain; /**< Current AGC gain */
237 int nb_loudness_adapt; /**< Number of frames used for loudness adaptation so far */
238 float max_gain; /**< Maximum gain allowed */
239 float max_increase_step; /**< Maximum increase in gain from one frame to another */
240 float max_decrease_step; /**< Maximum decrease in gain from one frame to another */
241 float prev_loudness; /**< Loudness of previous frame */
242 float init_max; /**< Current gain limit during initialisation */
243#endif
244 int nb_adapt; /**< Number of frames used for adaptation so far */
245 int was_speech;
246 int min_count; /**< Number of frames processed so far */
247 void *fft_lookup; /**< Lookup table for the FFT */
248#ifdef FIXED_POINT
249 int frame_shift;
250#endif
251};
252
253
254static void conj_window(spx_word16_t *w, int len)
255{
256 int i;
257 for (i=0;i<len;i++)
258 {
259 spx_word16_t tmp;
260#ifdef FIXED_POINT
261 spx_word16_t x = DIV32_16(MULT16_16(32767,i),len);
262#else
263 spx_word16_t x = DIV32_16(MULT16_16(QCONST16(4.f,13),i),len);
264#endif
265 int inv=0;
266 if (x<QCONST16(1.f,13))
267 {
268 } else if (x<QCONST16(2.f,13))
269 {
270 x=QCONST16(2.f,13)-x;
271 inv=1;
272 } else if (x<QCONST16(3.f,13))
273 {
274 x=x-QCONST16(2.f,13);
275 inv=1;
276 } else {
277 x=QCONST16(2.f,13)-x+QCONST16(2.f,13); /* 4 - x */
278 }
279 x = MULT16_16_Q14(QCONST16(1.271903f,14), x);
280 tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(SHL32(EXTEND32(x),2))));
281 if (inv)
282 tmp=SUB16(Q15_ONE,tmp);
283 w[i]=spx_sqrt(SHL32(EXTEND32(tmp),15));
284 }
285}
286
287
288#ifdef FIXED_POINT
289/* This function approximates the gain function
290 y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x)
291 which multiplied by xi/(1+xi) is the optimal gain
292 in the loudness domain ( sqrt[amplitude] )
293 Input in Q11 format, output in Q15
294*/
295static inline spx_word32_t hypergeom_gain(spx_word32_t xx)
296{
297 int ind;
298 spx_word16_t frac;
299 /* Q13 table */
300 static const spx_word16_t table[21] = {
301 6730, 8357, 9868, 11267, 12563, 13770, 14898,
302 15959, 16961, 17911, 18816, 19682, 20512, 21311,
303 22082, 22827, 23549, 24250, 24931, 25594, 26241};
304 ind = SHR32(xx,10);
305 if (ind<0)
306 return Q15_ONE;
307 if (ind>19)
308 return ADD32(EXTEND32(Q15_ONE),EXTEND32(DIV32_16(QCONST32(.1296,23), SHR32(xx,EXPIN_SHIFT-SNR_SHIFT))));
309 frac = SHL32(xx-SHL32(ind,10),5);
310 return SHL32(DIV32_16(PSHR32(MULT16_16(Q15_ONE-frac,table[ind]) + MULT16_16(frac,table[ind+1]),7),(spx_sqrt(SHL32(xx,15)+6711))),7);
311}
312
313static inline spx_word16_t qcurve(spx_word16_t x)
314{
315 x = MAX16(x, 1);
316 return DIV32_16(SHL32(EXTEND32(32767),9),ADD16(512,MULT16_16_Q15(QCONST16(.60f,15),DIV32_16(32767,x))));
317}
318
319/* Compute the gain floor based on different floors for the background noise and residual echo */
320static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len)
321{
322 int i;
323
324 if (noise_suppress > effective_echo_suppress)
325 {
326 spx_word16_t noise_gain, gain_ratio;
327 noise_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),noise_suppress)),1)));
328 gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),effective_echo_suppress-noise_suppress)),1)));
329
330 /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */
331 for (i=0;i<len;i++)
332 gain_floor[i] = MULT16_16_Q15(noise_gain,
333 spx_sqrt(SHL32(EXTEND32(DIV32_16_Q15(PSHR32(noise[i],NOISE_SHIFT) + MULT16_32_Q15(gain_ratio,echo[i]),
334 (1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]) )),15)));
335 } else {
336 spx_word16_t echo_gain, gain_ratio;
337 echo_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),effective_echo_suppress)),1)));
338 gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),noise_suppress-effective_echo_suppress)),1)));
339
340 /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */
341 for (i=0;i<len;i++)
342 gain_floor[i] = MULT16_16_Q15(echo_gain,
343 spx_sqrt(SHL32(EXTEND32(DIV32_16_Q15(MULT16_32_Q15(gain_ratio,PSHR32(noise[i],NOISE_SHIFT)) + echo[i],
344 (1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]) )),15)));
345 }
346}
347
348#else
349/* This function approximates the gain function
350 y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x)
351 which multiplied by xi/(1+xi) is the optimal gain
352 in the loudness domain ( sqrt[amplitude] )
353*/
354static inline spx_word32_t hypergeom_gain(spx_word32_t xx)
355{
356 int ind;
357 float integer, frac;
358 float x;
359 static const float table[21] = {
360 0.82157f, 1.02017f, 1.20461f, 1.37534f, 1.53363f, 1.68092f, 1.81865f,
361 1.94811f, 2.07038f, 2.18638f, 2.29688f, 2.40255f, 2.50391f, 2.60144f,
362 2.69551f, 2.78647f, 2.87458f, 2.96015f, 3.04333f, 3.12431f, 3.20326f};
363 x = EXPIN_SCALING_1*xx;
364 integer = floor(2*x);
365 ind = (int)integer;
366 if (ind<0)
367 return FRAC_SCALING;
368 if (ind>19)
369 return FRAC_SCALING*(1+.1296/x);
370 frac = 2*x-integer;
371 return FRAC_SCALING*((1-frac)*table[ind] + frac*table[ind+1])/sqrt(x+.0001f);
372}
373
374static inline spx_word16_t qcurve(spx_word16_t x)
375{
376 return 1.f/(1.f+.15f/(SNR_SCALING_1*x));
377}
378
379static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len)
380{
381 int i;
382 float echo_floor;
383 float noise_floor;
384
385 noise_floor = exp(.2302585f*noise_suppress);
386 echo_floor = exp(.2302585f*effective_echo_suppress);
387
388 /* Compute the gain floor based on different floors for the background noise and residual echo */
389 for (i=0;i<len;i++)
390 gain_floor[i] = FRAC_SCALING*sqrt(noise_floor*PSHR32(noise[i],NOISE_SHIFT) + echo_floor*echo[i])/sqrt(1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]);
391}
392
393#endif
394SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate)
395{
396 int i;
397 int N, N3, N4, M;
398
399 SpeexPreprocessState *st = (SpeexPreprocessState *)speex_alloc(sizeof(SpeexPreprocessState));
400 st->frame_size = frame_size;
401
402 /* Round ps_size down to the nearest power of two */
403#if 0
404 i=1;
405 st->ps_size = st->frame_size;
406 while(1)
407 {
408 if (st->ps_size & ~i)
409 {
410 st->ps_size &= ~i;
411 i<<=1;
412 } else {
413 break;
414 }
415 }
416
417
418 if (st->ps_size < 3*st->frame_size/4)
419 st->ps_size = st->ps_size * 3 / 2;
420#else
421 st->ps_size = st->frame_size;
422#endif
423
424 N = st->ps_size;
425 N3 = 2*N - st->frame_size;
426 N4 = st->frame_size - N3;
427
428 st->sampling_rate = sampling_rate;
429 st->denoise_enabled = 1;
430 st->vad_enabled = 0;
431 st->dereverb_enabled = 0;
432 st->reverb_decay = 0;
433 st->reverb_level = 0;
434 st->noise_suppress = NOISE_SUPPRESS_DEFAULT;
435 st->echo_suppress = ECHO_SUPPRESS_DEFAULT;
436 st->echo_suppress_active = ECHO_SUPPRESS_ACTIVE_DEFAULT;
437
438 st->speech_prob_start = SPEECH_PROB_START_DEFAULT;
439 st->speech_prob_continue = SPEECH_PROB_CONTINUE_DEFAULT;
440
441 st->echo_state = NULL;
442
443 st->nbands = NB_BANDS;
444 M = st->nbands;
445 st->bank = filterbank_new(M, sampling_rate, N, 1);
446
447 st->frame = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t));
448 st->window = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t));
449 st->ft = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t));
450
451 st->ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));
452 st->noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));
453 st->echo_noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));
454 st->residual_echo = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));
455 st->reverb_estimate = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));
456 st->old_ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t));
457 st->prior = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));
458 st->post = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));
459 st->gain = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));
460 st->gain2 = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));
461 st->gain_floor = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));
462 st->zeta = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t));
463
464 st->S = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t));
465 st->Smin = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t));
466 st->Stmp = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t));
467 st->update_prob = (int*)speex_alloc(N*sizeof(int));
468
469 st->inbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t));
470 st->outbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t));
471
472 conj_window(st->window, 2*N3);
473 for (i=2*N3;i<2*st->ps_size;i++)
474 st->window[i]=Q15_ONE;
475
476 if (N4>0)
477 {
478 for (i=N3-1;i>=0;i--)
479 {
480 st->window[i+N3+N4]=st->window[i+N3];
481 st->window[i+N3]=1;
482 }
483 }
484 for (i=0;i<N+M;i++)
485 {
486 st->noise[i]=QCONST32(1.f,NOISE_SHIFT);
487 st->reverb_estimate[i]=0;
488 st->old_ps[i]=1;
489 st->gain[i]=Q15_ONE;
490 st->post[i]=SHL16(1, SNR_SHIFT);
491 st->prior[i]=SHL16(1, SNR_SHIFT);
492 }
493
494 for (i=0;i<N;i++)
495 st->update_prob[i] = 1;
496 for (i=0;i<N3;i++)
497 {
498 st->inbuf[i]=0;
499 st->outbuf[i]=0;
500 }
501#ifndef FIXED_POINT
502 st->agc_enabled = 0;
503 st->agc_level = 8000;
504 st->loudness_weight = (float*)speex_alloc(N*sizeof(float));
505 for (i=0;i<N;i++)
506 {
507 float ff=((float)i)*.5*sampling_rate/((float)N);
508 /*st->loudness_weight[i] = .5f*(1.f/(1.f+ff/8000.f))+1.f*exp(-.5f*(ff-3800.f)*(ff-3800.f)/9e5f);*/
509 st->loudness_weight[i] = .35f-.35f*ff/16000.f+.73f*exp(-.5f*(ff-3800)*(ff-3800)/9e5f);
510 if (st->loudness_weight[i]<.01f)
511 st->loudness_weight[i]=.01f;
512 st->loudness_weight[i] *= st->loudness_weight[i];
513 }
514 /*st->loudness = pow(AMP_SCALE*st->agc_level,LOUDNESS_EXP);*/
515 st->loudness = 1e-15;
516 st->agc_gain = 1;
517 st->nb_loudness_adapt = 0;
518 st->max_gain = 30;
519 st->max_increase_step = exp(0.11513f * 12.*st->frame_size / st->sampling_rate);
520 st->max_decrease_step = exp(-0.11513f * 40.*st->frame_size / st->sampling_rate);
521 st->prev_loudness = 1;
522 st->init_max = 1;
523#endif
524 st->was_speech = 0;
525
526 st->fft_lookup = spx_fft_init(2*N);
527
528 st->nb_adapt=0;
529 st->min_count=0;
530 return st;
531}
532
533void speex_preprocess_state_destroy(SpeexPreprocessState *st)
534{
535 speex_free(st->frame);
536 speex_free(st->ft);
537 speex_free(st->ps);
538 speex_free(st->gain2);
539 speex_free(st->gain_floor);
540 speex_free(st->window);
541 speex_free(st->noise);
542 speex_free(st->reverb_estimate);
543 speex_free(st->old_ps);
544 speex_free(st->gain);
545 speex_free(st->prior);
546 speex_free(st->post);
547#ifndef FIXED_POINT
548 speex_free(st->loudness_weight);
549#endif
550 speex_free(st->echo_noise);
551 speex_free(st->residual_echo);
552
553 speex_free(st->S);
554 speex_free(st->Smin);
555 speex_free(st->Stmp);
556 speex_free(st->update_prob);
557 speex_free(st->zeta);
558
559 speex_free(st->inbuf);
560 speex_free(st->outbuf);
561
562 spx_fft_destroy(st->fft_lookup);
563 filterbank_destroy(st->bank);
564 speex_free(st);
565}
566
567/* FIXME: The AGC doesn't work yet with fixed-point*/
568#ifndef FIXED_POINT
569static void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx_word16_t *ft)
570{
571 int i;
572 int N = st->ps_size;
573 float target_gain;
574 float loudness=1.f;
575 float rate;
576
577 for (i=2;i<N;i++)
578 {
579 loudness += 2.f*N*st->ps[i]* st->loudness_weight[i];
580 }
581 loudness=sqrt(loudness);
582 /*if (loudness < 2*pow(st->loudness, 1.0/LOUDNESS_EXP) &&
583 loudness*2 > pow(st->loudness, 1.0/LOUDNESS_EXP))*/
584 if (Pframe>.3f)
585 {
586 st->nb_loudness_adapt++;
587 /*rate=2.0f*Pframe*Pframe/(1+st->nb_loudness_adapt);*/
588 rate = .03*Pframe*Pframe;
589 st->loudness = (1-rate)*st->loudness + (rate)*pow(AMP_SCALE*loudness, LOUDNESS_EXP);
590 st->loudness_accum = (1-rate)*st->loudness_accum + rate;
591 if (st->init_max < st->max_gain && st->nb_adapt > 20)
592 st->init_max *= 1.f + .1f*Pframe*Pframe;
593 }
594 /*printf ("%f %f %f %f\n", Pframe, loudness, pow(st->loudness, 1.0f/LOUDNESS_EXP), st->loudness2);*/
595
596 target_gain = AMP_SCALE*st->agc_level*pow(st->loudness/(1e-4+st->loudness_accum), -1.0f/LOUDNESS_EXP);
597
598 if ((Pframe>.5 && st->nb_adapt > 20) || target_gain < st->agc_gain)
599 {
600 if (target_gain > st->max_increase_step*st->agc_gain)
601 target_gain = st->max_increase_step*st->agc_gain;
602 if (target_gain < st->max_decrease_step*st->agc_gain && loudness < 10*st->prev_loudness)
603 target_gain = st->max_decrease_step*st->agc_gain;
604 if (target_gain > st->max_gain)
605 target_gain = st->max_gain;
606 if (target_gain > st->init_max)
607 target_gain = st->init_max;
608
609 st->agc_gain = target_gain;
610 }
611 /*fprintf (stderr, "%f %f %f\n", loudness, (float)AMP_SCALE_1*pow(st->loudness, 1.0f/LOUDNESS_EXP), st->agc_gain);*/
612
613 for (i=0;i<2*N;i++)
614 ft[i] *= st->agc_gain;
615 st->prev_loudness = loudness;
616}
617#endif
618
619static void preprocess_analysis(SpeexPreprocessState *st, spx_int16_t *x)
620{
621 int i;
622 int N = st->ps_size;
623 int N3 = 2*N - st->frame_size;
624 int N4 = st->frame_size - N3;
625 spx_word32_t *ps=st->ps;
626
627 /* 'Build' input frame */
628 for (i=0;i<N3;i++)
629 st->frame[i]=st->inbuf[i];
630 for (i=0;i<st->frame_size;i++)
631 st->frame[N3+i]=x[i];
632
633 /* Update inbuf */
634 for (i=0;i<N3;i++)
635 st->inbuf[i]=x[N4+i];
636
637 /* Windowing */
638 for (i=0;i<2*N;i++)
639 st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]);
640
641#ifdef FIXED_POINT
642 {
643 spx_word16_t max_val=0;
644 for (i=0;i<2*N;i++)
645 max_val = MAX16(max_val, ABS16(st->frame[i]));
646 st->frame_shift = 14-spx_ilog2(EXTEND32(max_val));
647 for (i=0;i<2*N;i++)
648 st->frame[i] = SHL16(st->frame[i], st->frame_shift);
649 }
650#endif
651
652 /* Perform FFT */
653 spx_fft(st->fft_lookup, st->frame, st->ft);
654
655 /* Power spectrum */
656 ps[0]=MULT16_16(st->ft[0],st->ft[0]);
657 for (i=1;i<N;i++)
658 ps[i]=MULT16_16(st->ft[2*i-1],st->ft[2*i-1]) + MULT16_16(st->ft[2*i],st->ft[2*i]);
659 for (i=0;i<N;i++)
660 st->ps[i] = PSHR32(st->ps[i], 2*st->frame_shift);
661
662 filterbank_compute_bank32(st->bank, ps, ps+N);
663}
664
665static void update_noise_prob(SpeexPreprocessState *st)
666{
667 int i;
668 int min_range;
669 int N = st->ps_size;
670
671 for (i=1;i<N-1;i++)
672 st->S[i] = MULT16_32_Q15(QCONST16(.8f,15),st->S[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i-1])
673 + MULT16_32_Q15(QCONST16(.1f,15),st->ps[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i+1]);
674 st->S[0] = MULT16_32_Q15(QCONST16(.8f,15),st->S[0]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[0]);
675 st->S[N-1] = MULT16_32_Q15(QCONST16(.8f,15),st->S[N-1]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[N-1]);
676
677 if (st->nb_adapt==1)
678 {
679 for (i=0;i<N;i++)
680 st->Smin[i] = st->Stmp[i] = 0;
681 }
682
683 if (st->nb_adapt < 100)
684 min_range = 15;
685 else if (st->nb_adapt < 1000)
686 min_range = 50;
687 else if (st->nb_adapt < 10000)
688 min_range = 150;
689 else
690 min_range = 300;
691 if (st->min_count > min_range)
692 {
693 st->min_count = 0;
694 for (i=0;i<N;i++)
695 {
696 st->Smin[i] = MIN32(st->Stmp[i], st->S[i]);
697 st->Stmp[i] = st->S[i];
698 }
699 } else {
700 for (i=0;i<N;i++)
701 {
702 st->Smin[i] = MIN32(st->Smin[i], st->S[i]);
703 st->Stmp[i] = MIN32(st->Stmp[i], st->S[i]);
704 }
705 }
706 for (i=0;i<N;i++)
707 {
708 if (MULT16_32_Q15(QCONST16(.4f,15),st->S[i]) > ADD32(st->Smin[i],EXTEND32(20)))
709 st->update_prob[i] = 1;
710 else
711 st->update_prob[i] = 0;
712 /*fprintf (stderr, "%f ", st->S[i]/st->Smin[i]);*/
713 /*fprintf (stderr, "%f ", st->update_prob[i]);*/
714 }
715
716}
717
718#define NOISE_OVERCOMPENS 1.
719
720void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len);
721
722int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo)
723{
724 return speex_preprocess_run(st, x);
725}
726
727int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x)
728{
729 int i;
730 int M;
731 int N = st->ps_size;
732 int N3 = 2*N - st->frame_size;
733 int N4 = st->frame_size - N3;
734 spx_word32_t *ps=st->ps;
735 spx_word32_t Zframe;
736 spx_word16_t Pframe;
737 spx_word16_t beta, beta_1;
738 spx_word16_t effective_echo_suppress;
739
740 st->nb_adapt++;
741 if (st->nb_adapt>20000)
742 st->nb_adapt = 20000;
743 st->min_count++;
744
745 beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt));
746 beta_1 = Q15_ONE-beta;
747 M = st->nbands;
748 /* Deal with residual echo if provided */
749 if (st->echo_state)
750 {
751 speex_echo_get_residual(st->echo_state, st->residual_echo, N);
752#ifndef FIXED_POINT
753 /* If there are NaNs or ridiculous values, it'll show up in the DC and we just reset everything to zero */
754 if (!(st->residual_echo[0] >=0 && st->residual_echo[0]<N*1e9f))
755 {
756 for (i=0;i<N;i++)
757 st->residual_echo[i] = 0;
758 }
759#endif
760 for (i=0;i<N;i++)
761 st->echo_noise[i] = MAX32(MULT16_32_Q15(QCONST16(.6f,15),st->echo_noise[i]), st->residual_echo[i]);
762 filterbank_compute_bank32(st->bank, st->echo_noise, st->echo_noise+N);
763 } else {
764 for (i=0;i<N+M;i++)
765 st->echo_noise[i] = 0;
766 }
767 preprocess_analysis(st, x);
768
769 update_noise_prob(st);
770
771 /* Noise estimation always updated for the 10 first frames */
772 /*if (st->nb_adapt<10)
773 {
774 for (i=1;i<N-1;i++)
775 st->update_prob[i] = 0;
776 }
777 */
778
779 /* Update the noise estimate for the frequencies where it can be */
780 for (i=0;i<N;i++)
781 {
782 if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i], NOISE_SHIFT))
783 st->noise[i] = MAX32(EXTEND32(0),MULT16_32_Q15(beta_1,st->noise[i]) + MULT16_32_Q15(beta,SHL32(st->ps[i],NOISE_SHIFT)));
784 }
785 filterbank_compute_bank32(st->bank, st->noise, st->noise+N);
786
787 /* Special case for first frame */
788 if (st->nb_adapt==1)
789 for (i=0;i<N+M;i++)
790 st->old_ps[i] = ps[i];
791
792 /* Compute a posteriori SNR */
793 for (i=0;i<N+M;i++)
794 {
795 spx_word16_t gamma;
796
797 /* Total noise estimate including residual echo and reverberation */
798 spx_word32_t tot_noise = ADD32(ADD32(ADD32(EXTEND32(1), PSHR32(st->noise[i],NOISE_SHIFT)) , st->echo_noise[i]) , st->reverb_estimate[i]);
799
800 /* A posteriori SNR = ps/noise - 1*/
801 st->post[i] = SUB16(DIV32_16_Q8(ps[i],tot_noise), QCONST16(1.f,SNR_SHIFT));
802 st->post[i]=MIN16(st->post[i], QCONST16(100.f,SNR_SHIFT));
803
804 /* Computing update gamma = .1 + .9*(old/(old+noise))^2 */
805 gamma = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.89f,15),SQR16_Q15(DIV32_16_Q15(st->old_ps[i],ADD32(st->old_ps[i],tot_noise))));
806
807 /* A priori SNR update = gamma*max(0,post) + (1-gamma)*old/noise */
808 st->prior[i] = EXTRACT16(PSHR32(ADD32(MULT16_16(gamma,MAX16(0,st->post[i])), MULT16_16(Q15_ONE-gamma,DIV32_16_Q8(st->old_ps[i],tot_noise))), 15));
809 st->prior[i]=MIN16(st->prior[i], QCONST16(100.f,SNR_SHIFT));
810 }
811
812 /*print_vec(st->post, N+M, "");*/
813
814 /* Recursive average of the a priori SNR. A bit smoothed for the psd components */
815 st->zeta[0] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[0]), MULT16_16(QCONST16(.3f,15),st->prior[0])),15);
816 for (i=1;i<N-1;i++)
817 st->zeta[i] = PSHR32(ADD32(ADD32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.15f,15),st->prior[i])),
818 MULT16_16(QCONST16(.075f,15),st->prior[i-1])), MULT16_16(QCONST16(.075f,15),st->prior[i+1])),15);
819 for (i=N-1;i<N+M;i++)
820 st->zeta[i] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.3f,15),st->prior[i])),15);
821
822 /* Speech probability of presence for the entire frame is based on the average filterbank a priori SNR */
823 Zframe = 0;
824 for (i=N;i<N+M;i++)
825 Zframe = ADD32(Zframe, EXTEND32(st->zeta[i]));
826 Pframe = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.899f,15),qcurve(DIV32_16(Zframe,st->nbands)));
827
828 effective_echo_suppress = EXTRACT16(PSHR32(ADD32(MULT16_16(SUB16(Q15_ONE,Pframe), st->echo_suppress), MULT16_16(Pframe, st->echo_suppress_active)),15));
829
830 compute_gain_floor(st->noise_suppress, effective_echo_suppress, st->noise+N, st->echo_noise+N, st->gain_floor+N, M);
831
832 /* Compute Ephraim & Malah gain speech probability of presence for each critical band (Bark scale)
833 Technically this is actually wrong because the EM gaim assumes a slightly different probability
834 distribution */
835 for (i=N;i<N+M;i++)
836 {
837 /* See EM and Cohen papers*/
838 spx_word32_t theta;
839 /* Gain from hypergeometric function */
840 spx_word32_t MM;
841 /* Weiner filter gain */
842 spx_word16_t prior_ratio;
843 /* a priority probability of speech presence based on Bark sub-band alone */
844 spx_word16_t P1;
845 /* Speech absence a priori probability (considering sub-band and frame) */
846 spx_word16_t q;
847#ifdef FIXED_POINT
848 spx_word16_t tmp;
849#endif
850
851 prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT)));
852 theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT));
853
854 MM = hypergeom_gain(theta);
855 /* Gain with bound */
856 st->gain[i] = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM)));
857 /* Save old Bark power spectrum */
858 st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]);
859
860 P1 = QCONST16(.199f,15)+MULT16_16_Q15(QCONST16(.8f,15),qcurve (st->zeta[i]));
861 q = Q15_ONE-MULT16_16_Q15(Pframe,P1);
862#ifdef FIXED_POINT
863 theta = MIN32(theta, EXTEND32(32767));
864/*Q8*/tmp = MULT16_16_Q15((SHL32(1,SNR_SHIFT)+st->prior[i]),EXTRACT16(MIN32(Q15ONE,SHR32(spx_exp(-EXTRACT16(theta)),1))));
865 tmp = MIN16(QCONST16(3.,SNR_SHIFT), tmp); /* Prevent overflows in the next line*/
866/*Q8*/tmp = EXTRACT16(PSHR32(MULT16_16(PDIV32_16(SHL32(EXTEND32(q),8),(Q15_ONE-q)),tmp),8));
867 st->gain2[i]=DIV32_16(SHL32(EXTEND32(32767),SNR_SHIFT), ADD16(256,tmp));
868#else
869 st->gain2[i]=1/(1.f + (q/(1.f-q))*(1+st->prior[i])*exp(-theta));
870#endif
871 }
872 /* Convert the EM gains and speech prob to linear frequency */
873 filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2);
874 filterbank_compute_psd16(st->bank,st->gain+N, st->gain);
875
876 /* Use 1 for linear gain resolution (best) or 0 for Bark gain resolution (faster) */
877 if (1)
878 {
879 filterbank_compute_psd16(st->bank,st->gain_floor+N, st->gain_floor);
880
881 /* Compute gain according to the Ephraim-Malah algorithm -- linear frequency */
882 for (i=0;i<N;i++)
883 {
884 spx_word32_t MM;
885 spx_word32_t theta;
886 spx_word16_t prior_ratio;
887 spx_word16_t tmp;
888 spx_word16_t p;
889 spx_word16_t g;
890
891 /* Wiener filter gain */
892 prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT)));
893 theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT));
894
895 /* Optimal estimator for loudness domain */
896 MM = hypergeom_gain(theta);
897 /* EM gain with bound */
898 g = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM)));
899 /* Interpolated speech probability of presence */
900 p = st->gain2[i];
901
902 /* Constrain the gain to be close to the Bark scale gain */
903 if (MULT16_16_Q15(QCONST16(.333f,15),g) > st->gain[i])
904 g = MULT16_16(3,st->gain[i]);
905 st->gain[i] = g;
906
907 /* Save old power spectrum */
908 st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]);
909
910 /* Apply gain floor */
911 if (st->gain[i] < st->gain_floor[i])
912 st->gain[i] = st->gain_floor[i];
913
914 /* Exponential decay model for reverberation (unused) */
915 /*st->reverb_estimate[i] = st->reverb_decay*st->reverb_estimate[i] + st->reverb_decay*st->reverb_level*st->gain[i]*st->gain[i]*st->ps[i];*/
916
917 /* Take into account speech probability of presence (loudness domain MMSE estimator) */
918 /* gain2 = [p*sqrt(gain)+(1-p)*sqrt(gain _floor) ]^2 */
919 tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15)));
920 st->gain2[i]=SQR16_Q15(tmp);
921
922 /* Use this if you want a log-domain MMSE estimator instead */
923 /*st->gain2[i] = pow(st->gain[i], p) * pow(st->gain_floor[i],1.f-p);*/
924 }
925 } else {
926 for (i=N;i<N+M;i++)
927 {
928 spx_word16_t tmp;
929 spx_word16_t p = st->gain2[i];
930 st->gain[i] = MAX16(st->gain[i], st->gain_floor[i]);
931 tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15)));
932 st->gain2[i]=SQR16_Q15(tmp);
933 }
934 filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2);
935 }
936
937 /* If noise suppression is off, don't apply the gain (but then why call this in the first place!) */
938 if (!st->denoise_enabled)
939 {
940 for (i=0;i<N+M;i++)
941 st->gain2[i]=Q15_ONE;
942 }
943
944 /* Apply computed gain */
945 for (i=1;i<N;i++)
946 {
947 st->ft[2*i-1] = MULT16_16_P15(st->gain2[i],st->ft[2*i-1]);
948 st->ft[2*i] = MULT16_16_P15(st->gain2[i],st->ft[2*i]);
949 }
950 st->ft[0] = MULT16_16_P15(st->gain2[0],st->ft[0]);
951 st->ft[2*N-1] = MULT16_16_P15(st->gain2[N-1],st->ft[2*N-1]);
952
953 /*FIXME: This *will* not work for fixed-point */
954#ifndef FIXED_POINT
955 if (st->agc_enabled)
956 speex_compute_agc(st, Pframe, st->ft);
957#endif
958
959 /* Inverse FFT with 1/N scaling */
960 spx_ifft(st->fft_lookup, st->ft, st->frame);
961 /* Scale back to original (lower) amplitude */
962 for (i=0;i<2*N;i++)
963 st->frame[i] = PSHR16(st->frame[i], st->frame_shift);
964
965 /*FIXME: This *will* not work for fixed-point */
966#ifndef FIXED_POINT
967 if (st->agc_enabled)
968 {
969 float max_sample=0;
970 for (i=0;i<2*N;i++)
971 if (fabs(st->frame[i])>max_sample)
972 max_sample = fabs(st->frame[i]);
973 if (max_sample>28000.f)
974 {
975 float damp = 28000.f/max_sample;
976 for (i=0;i<2*N;i++)
977 st->frame[i] *= damp;
978 }
979 }
980#endif
981
982 /* Synthesis window (for WOLA) */
983 for (i=0;i<2*N;i++)
984 st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]);
985
986 /* Perform overlap and add */
987 for (i=0;i<N3;i++)
988 x[i] = st->outbuf[i] + st->frame[i];
989 for (i=0;i<N4;i++)
990 x[N3+i] = st->frame[N3+i];
991
992 /* Update outbuf */
993 for (i=0;i<N3;i++)
994 st->outbuf[i] = st->frame[st->frame_size+i];
995
996 /* FIXME: This VAD is a kludge */
997 if (st->vad_enabled)
998 {
999 if (Pframe > st->speech_prob_start || (st->was_speech && Pframe > st->speech_prob_continue))
1000 {
1001 st->was_speech=1;
1002 return 1;
1003 } else
1004 {
1005 st->was_speech=0;
1006 return 0;
1007 }
1008 } else {
1009 return 1;
1010 }
1011}
1012
1013void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x)
1014{
1015 int i;
1016 int N = st->ps_size;
1017 int N3 = 2*N - st->frame_size;
1018 int M;
1019 spx_word32_t *ps=st->ps;
1020
1021 M = st->nbands;
1022 st->min_count++;
1023
1024 preprocess_analysis(st, x);
1025
1026 update_noise_prob(st);
1027
1028 for (i=1;i<N-1;i++)
1029 {
1030 if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i],NOISE_SHIFT))
1031 {
1032 st->noise[i] = MULT16_32_Q15(QCONST16(.95f,15),st->noise[i]) + MULT16_32_Q15(QCONST16(.05f,15),SHL32(st->ps[i],NOISE_SHIFT));
1033 }
1034 }
1035
1036 for (i=0;i<N3;i++)
1037 st->outbuf[i] = MULT16_16_Q15(x[st->frame_size-N3+i],st->window[st->frame_size+i]);
1038
1039 /* Save old power spectrum */
1040 for (i=0;i<N+M;i++)
1041 st->old_ps[i] = ps[i];
1042
1043 for (i=0;i<N;i++)
1044 st->reverb_estimate[i] = MULT16_32_Q15(st->reverb_decay, st->reverb_estimate[i]);
1045}
1046
1047
1048int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr)
1049{
1050 int i;
1051 SpeexPreprocessState *st;
1052 st=(SpeexPreprocessState*)state;
1053 switch(request)
1054 {
1055 case SPEEX_PREPROCESS_SET_DENOISE:
1056 st->denoise_enabled = (*(spx_int32_t*)ptr);
1057 break;
1058 case SPEEX_PREPROCESS_GET_DENOISE:
1059 (*(spx_int32_t*)ptr) = st->denoise_enabled;
1060 break;
1061#ifndef FIXED_POINT
1062 case SPEEX_PREPROCESS_SET_AGC:
1063 st->agc_enabled = (*(spx_int32_t*)ptr);
1064 break;
1065 case SPEEX_PREPROCESS_GET_AGC:
1066 (*(spx_int32_t*)ptr) = st->agc_enabled;
1067 break;
1068#ifndef DISABLE_FLOAT_API
1069 case SPEEX_PREPROCESS_SET_AGC_LEVEL:
1070 st->agc_level = (*(float*)ptr);
1071 if (st->agc_level<1)
1072 st->agc_level=1;
1073 if (st->agc_level>32768)
1074 st->agc_level=32768;
1075 break;
1076 case SPEEX_PREPROCESS_GET_AGC_LEVEL:
1077 (*(float*)ptr) = st->agc_level;
1078 break;
1079#endif /* #ifndef DISABLE_FLOAT_API */
1080 case SPEEX_PREPROCESS_SET_AGC_INCREMENT:
1081 st->max_increase_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate);
1082 break;
1083 case SPEEX_PREPROCESS_GET_AGC_INCREMENT:
1084 (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_increase_step)*st->sampling_rate/st->frame_size);
1085 break;
1086 case SPEEX_PREPROCESS_SET_AGC_DECREMENT:
1087 st->max_decrease_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate);
1088 break;
1089 case SPEEX_PREPROCESS_GET_AGC_DECREMENT:
1090 (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_decrease_step)*st->sampling_rate/st->frame_size);
1091 break;
1092 case SPEEX_PREPROCESS_SET_AGC_MAX_GAIN:
1093 st->max_gain = exp(0.11513f * (*(spx_int32_t*)ptr));
1094 break;
1095 case SPEEX_PREPROCESS_GET_AGC_MAX_GAIN:
1096 (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_gain));
1097 break;
1098#endif
1099 case SPEEX_PREPROCESS_SET_VAD:
1100 speex_warning("The VAD has been replaced by a hack pending a complete rewrite");
1101 st->vad_enabled = (*(spx_int32_t*)ptr);
1102 break;
1103 case SPEEX_PREPROCESS_GET_VAD:
1104 (*(spx_int32_t*)ptr) = st->vad_enabled;
1105 break;
1106
1107 case SPEEX_PREPROCESS_SET_DEREVERB:
1108 st->dereverb_enabled = (*(spx_int32_t*)ptr);
1109 for (i=0;i<st->ps_size;i++)
1110 st->reverb_estimate[i]=0;
1111 break;
1112 case SPEEX_PREPROCESS_GET_DEREVERB:
1113 (*(spx_int32_t*)ptr) = st->dereverb_enabled;
1114 break;
1115
1116 case SPEEX_PREPROCESS_SET_DEREVERB_LEVEL:
1117 /* FIXME: Re-enable when de-reverberation is actually enabled again */
1118 /*st->reverb_level = (*(float*)ptr);*/
1119 break;
1120 case SPEEX_PREPROCESS_GET_DEREVERB_LEVEL:
1121 /* FIXME: Re-enable when de-reverberation is actually enabled again */
1122 /*(*(float*)ptr) = st->reverb_level;*/
1123 break;
1124
1125 case SPEEX_PREPROCESS_SET_DEREVERB_DECAY:
1126 /* FIXME: Re-enable when de-reverberation is actually enabled again */
1127 /*st->reverb_decay = (*(float*)ptr);*/
1128 break;
1129 case SPEEX_PREPROCESS_GET_DEREVERB_DECAY:
1130 /* FIXME: Re-enable when de-reverberation is actually enabled again */
1131 /*(*(float*)ptr) = st->reverb_decay;*/
1132 break;
1133
1134 case SPEEX_PREPROCESS_SET_PROB_START:
1135 *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr));
1136 st->speech_prob_start = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100);
1137 break;
1138 case SPEEX_PREPROCESS_GET_PROB_START:
1139 (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100);
1140 break;
1141
1142 case SPEEX_PREPROCESS_SET_PROB_CONTINUE:
1143 *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr));
1144 st->speech_prob_continue = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100);
1145 break;
1146 case SPEEX_PREPROCESS_GET_PROB_CONTINUE:
1147 (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_continue, 100);
1148 break;
1149
1150 case SPEEX_PREPROCESS_SET_NOISE_SUPPRESS:
1151 st->noise_suppress = -ABS(*(spx_int32_t*)ptr);
1152 break;
1153 case SPEEX_PREPROCESS_GET_NOISE_SUPPRESS:
1154 (*(spx_int32_t*)ptr) = st->noise_suppress;
1155 break;
1156 case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS:
1157 st->echo_suppress = -ABS(*(spx_int32_t*)ptr);
1158 break;
1159 case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS:
1160 (*(spx_int32_t*)ptr) = st->echo_suppress;
1161 break;
1162 case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE:
1163 st->echo_suppress_active = -ABS(*(spx_int32_t*)ptr);
1164 break;
1165 case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE:
1166 (*(spx_int32_t*)ptr) = st->echo_suppress_active;
1167 break;
1168 case SPEEX_PREPROCESS_SET_ECHO_STATE:
1169 st->echo_state = (SpeexEchoState*)ptr;
1170 break;
1171 case SPEEX_PREPROCESS_GET_ECHO_STATE:
1172 ptr = (void*)st->echo_state;
1173 break;
1174#ifndef FIXED_POINT
1175 case SPEEX_PREPROCESS_GET_AGC_LOUDNESS:
1176 (*(spx_int32_t*)ptr) = pow(st->loudness, 1.0/LOUDNESS_EXP);
1177 break;
1178#endif
1179
1180 default:
1181 speex_warning_int("Unknown speex_preprocess_ctl request: ", request);
1182 return -1;
1183 }
1184 return 0;
1185}
diff --git a/lib/rbcodec/codecs/libspeex/pseudofloat.h b/lib/rbcodec/codecs/libspeex/pseudofloat.h
new file mode 100644
index 0000000000..448dd61ffe
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/pseudofloat.h
@@ -0,0 +1,382 @@
1/* Copyright (C) 2005 Jean-Marc Valin */
2/**
3 @file pseudofloat.h
4 @brief Pseudo-floating point
5 * This header file provides a lightweight floating point type for
6 * use on fixed-point platforms when a large dynamic range is
7 * required. The new type is not compatible with the 32-bit IEEE format,
8 * it is not even remotely as accurate as 32-bit floats, and is not
9 * even guaranteed to produce even remotely correct results for code
10 * other than Speex. It makes all kinds of shortcuts that are acceptable
11 * for Speex, but may not be acceptable for your application. You're
12 * quite welcome to reuse this code and improve it, but don't assume
13 * it works out of the box. Most likely, it doesn't.
14 */
15/*
16 Redistribution and use in source and binary forms, with or without
17 modification, are permitted provided that the following conditions
18 are met:
19
20 - Redistributions of source code must retain the above copyright
21 notice, this list of conditions and the following disclaimer.
22
23 - Redistributions in binary form must reproduce the above copyright
24 notice, this list of conditions and the following disclaimer in the
25 documentation and/or other materials provided with the distribution.
26
27 - Neither the name of the Xiph.org Foundation nor the names of its
28 contributors may be used to endorse or promote products derived from
29 this software without specific prior written permission.
30
31 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
35 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
36 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
37 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
38 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42*/
43
44#ifndef PSEUDOFLOAT_H
45#define PSEUDOFLOAT_H
46
47#include "arch.h"
48#include "os_support.h"
49#include "math_approx.h"
50#include <math.h>
51
52#ifdef FIXED_POINT
53
54typedef struct {
55 spx_int16_t m;
56 spx_int16_t e;
57} spx_float_t;
58
59static const spx_float_t FLOAT_ZERO = {0,0};
60static const spx_float_t FLOAT_ONE = {16384,-14};
61static const spx_float_t FLOAT_HALF = {16384,-15};
62
63#ifdef MIN
64#undef MIN
65#endif
66#define MIN(a,b) ((a)<(b)?(a):(b))
67static inline spx_float_t PSEUDOFLOAT(spx_int32_t x)
68{
69 int e=0;
70 int sign=0;
71 if (x<0)
72 {
73 sign = 1;
74 x = -x;
75 }
76 if (x==0)
77 {
78 spx_float_t r = {0,0};
79 return r;
80 }
81 e = spx_ilog2(ABS32(x))-14;
82 x = VSHR32(x, e);
83 if (sign)
84 {
85 spx_float_t r;
86 r.m = -x;
87 r.e = e;
88 return r;
89 }
90 else
91 {
92 spx_float_t r;
93 r.m = x;
94 r.e = e;
95 return r;
96 }
97}
98
99
100static inline spx_float_t FLOAT_ADD(spx_float_t a, spx_float_t b)
101{
102 spx_float_t r;
103 if (a.m==0)
104 return b;
105 else if (b.m==0)
106 return a;
107 if ((a).e > (b).e)
108 {
109 r.m = ((a).m>>1) + ((b).m>>MIN(15,(a).e-(b).e+1));
110 r.e = (a).e+1;
111 }
112 else
113 {
114 r.m = ((b).m>>1) + ((a).m>>MIN(15,(b).e-(a).e+1));
115 r.e = (b).e+1;
116 }
117 if (r.m>0)
118 {
119 if (r.m<16384)
120 {
121 r.m<<=1;
122 r.e-=1;
123 }
124 } else {
125 if (r.m>-16384)
126 {
127 r.m<<=1;
128 r.e-=1;
129 }
130 }
131 /*printf ("%f + %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/
132 return r;
133}
134
135static inline spx_float_t FLOAT_SUB(spx_float_t a, spx_float_t b)
136{
137 spx_float_t r;
138 if (a.m==0)
139 return b;
140 else if (b.m==0)
141 return a;
142 if ((a).e > (b).e)
143 {
144 r.m = ((a).m>>1) - ((b).m>>MIN(15,(a).e-(b).e+1));
145 r.e = (a).e+1;
146 }
147 else
148 {
149 r.m = ((a).m>>MIN(15,(b).e-(a).e+1)) - ((b).m>>1);
150 r.e = (b).e+1;
151 }
152 if (r.m>0)
153 {
154 if (r.m<16384)
155 {
156 r.m<<=1;
157 r.e-=1;
158 }
159 } else {
160 if (r.m>-16384)
161 {
162 r.m<<=1;
163 r.e-=1;
164 }
165 }
166 /*printf ("%f + %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/
167 return r;
168}
169
170static inline int FLOAT_LT(spx_float_t a, spx_float_t b)
171{
172 if (a.m==0)
173 return b.m>0;
174 else if (b.m==0)
175 return a.m<0;
176 if ((a).e > (b).e)
177 return ((a).m>>1) < ((b).m>>MIN(15,(a).e-(b).e+1));
178 else
179 return ((b).m>>1) > ((a).m>>MIN(15,(b).e-(a).e+1));
180
181}
182
183static inline int FLOAT_GT(spx_float_t a, spx_float_t b)
184{
185 return FLOAT_LT(b,a);
186}
187
188static inline spx_float_t FLOAT_MULT(spx_float_t a, spx_float_t b)
189{
190 spx_float_t r;
191 r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15);
192 r.e = (a).e+(b).e+15;
193 if (r.m>0)
194 {
195 if (r.m<16384)
196 {
197 r.m<<=1;
198 r.e-=1;
199 }
200 } else {
201 if (r.m>-16384)
202 {
203 r.m<<=1;
204 r.e-=1;
205 }
206 }
207 /*printf ("%f * %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/
208 return r;
209}
210
211static inline spx_float_t FLOAT_AMULT(spx_float_t a, spx_float_t b)
212{
213 spx_float_t r;
214 r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15);
215 r.e = (a).e+(b).e+15;
216 return r;
217}
218
219
220static inline spx_float_t FLOAT_SHL(spx_float_t a, int b)
221{
222 spx_float_t r;
223 r.m = a.m;
224 r.e = a.e+b;
225 return r;
226}
227
228static inline spx_int16_t FLOAT_EXTRACT16(spx_float_t a)
229{
230 if (a.e<0)
231 return EXTRACT16((EXTEND32(a.m)+(EXTEND32(1)<<(-a.e-1)))>>-a.e);
232 else
233 return a.m<<a.e;
234}
235
236static inline spx_int32_t FLOAT_EXTRACT32(spx_float_t a)
237{
238 if (a.e<0)
239 return (EXTEND32(a.m)+(EXTEND32(1)<<(-a.e-1)))>>-a.e;
240 else
241 return EXTEND32(a.m)<<a.e;
242}
243
244static inline spx_int32_t FLOAT_MUL32(spx_float_t a, spx_word32_t b)
245{
246 return VSHR32(MULT16_32_Q15(a.m, b),-a.e-15);
247}
248
249static inline spx_float_t FLOAT_MUL32U(spx_word32_t a, spx_word32_t b)
250{
251 int e1, e2;
252 spx_float_t r;
253 if (a==0 || b==0)
254 {
255 return FLOAT_ZERO;
256 }
257 e1 = spx_ilog2(ABS32(a));
258 a = VSHR32(a, e1-14);
259 e2 = spx_ilog2(ABS32(b));
260 b = VSHR32(b, e2-14);
261 r.m = MULT16_16_Q15(a,b);
262 r.e = e1+e2-13;
263 return r;
264}
265
266/* Do NOT attempt to divide by a negative number */
267static inline spx_float_t FLOAT_DIV32_FLOAT(spx_word32_t a, spx_float_t b)
268{
269 int e=0;
270 spx_float_t r;
271 if (a==0)
272 {
273 return FLOAT_ZERO;
274 }
275 e = spx_ilog2(ABS32(a))-spx_ilog2(b.m-1)-15;
276 a = VSHR32(a, e);
277 if (ABS32(a)>=SHL32(EXTEND32(b.m-1),15))
278 {
279 a >>= 1;
280 e++;
281 }
282 r.m = DIV32_16(a,b.m);
283 r.e = e-b.e;
284 return r;
285}
286
287
288/* Do NOT attempt to divide by a negative number */
289static inline spx_float_t FLOAT_DIV32(spx_word32_t a, spx_word32_t b)
290{
291 int e0=0,e=0;
292 spx_float_t r;
293 if (a==0)
294 {
295 return FLOAT_ZERO;
296 }
297 if (b>32767)
298 {
299 e0 = spx_ilog2(b)-14;
300 b = VSHR32(b, e0);
301 e0 = -e0;
302 }
303 e = spx_ilog2(ABS32(a))-spx_ilog2(b-1)-15;
304 a = VSHR32(a, e);
305 if (ABS32(a)>=SHL32(EXTEND32(b-1),15))
306 {
307 a >>= 1;
308 e++;
309 }
310 e += e0;
311 r.m = DIV32_16(a,b);
312 r.e = e;
313 return r;
314}
315
316/* Do NOT attempt to divide by a negative number */
317static inline spx_float_t FLOAT_DIVU(spx_float_t a, spx_float_t b)
318{
319 int e=0;
320 spx_int32_t num;
321 spx_float_t r;
322 if (b.m<=0)
323 {
324 speex_warning_int("Attempted to divide by", b.m);
325 return FLOAT_ONE;
326 }
327 num = a.m;
328 a.m = ABS16(a.m);
329 while (a.m >= b.m)
330 {
331 e++;
332 a.m >>= 1;
333 }
334 num = num << (15-e);
335 r.m = DIV32_16(num,b.m);
336 r.e = a.e-b.e-15+e;
337 return r;
338}
339
340static inline spx_float_t FLOAT_SQRT(spx_float_t a)
341{
342 spx_float_t r;
343 spx_int32_t m;
344 m = SHL32(EXTEND32(a.m), 14);
345 r.e = a.e - 14;
346 if (r.e & 1)
347 {
348 r.e -= 1;
349 m <<= 1;
350 }
351 r.e >>= 1;
352 r.m = spx_sqrt(m);
353 return r;
354}
355
356#else
357
358#define spx_float_t float
359#define FLOAT_ZERO 0.f
360#define FLOAT_ONE 1.f
361#define FLOAT_HALF 0.5f
362#define PSEUDOFLOAT(x) (x)
363#define FLOAT_MULT(a,b) ((a)*(b))
364#define FLOAT_AMULT(a,b) ((a)*(b))
365#define FLOAT_MUL32(a,b) ((a)*(b))
366#define FLOAT_DIV32(a,b) ((a)/(b))
367#define FLOAT_EXTRACT16(a) (a)
368#define FLOAT_EXTRACT32(a) (a)
369#define FLOAT_ADD(a,b) ((a)+(b))
370#define FLOAT_SUB(a,b) ((a)-(b))
371#define REALFLOAT(x) (x)
372#define FLOAT_DIV32_FLOAT(a,b) ((a)/(b))
373#define FLOAT_MUL32U(a,b) ((a)*(b))
374#define FLOAT_SHL(a,b) (a)
375#define FLOAT_LT(a,b) ((a)<(b))
376#define FLOAT_GT(a,b) ((a)>(b))
377#define FLOAT_DIVU(a,b) ((a)/(b))
378#define FLOAT_SQRT(a) (spx_sqrt(a))
379
380#endif
381
382#endif
diff --git a/lib/rbcodec/codecs/libspeex/quant_lsp.c b/lib/rbcodec/codecs/libspeex/quant_lsp.c
new file mode 100644
index 0000000000..9b9104c842
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/quant_lsp.c
@@ -0,0 +1,391 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: quant_lsp.c
3 LSP vector quantization
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#ifdef HAVE_CONFIG_H
34#include "config-speex.h"
35#endif
36
37#include "quant_lsp.h"
38#include "os_support.h"
39#include <math.h>
40#ifndef M_PI
41#define M_PI 3.14159265358979323846
42#endif
43
44#include "arch.h"
45
46#ifdef BFIN_ASM
47#include "quant_lsp_bfin.h"
48#endif
49
50#ifdef FIXED_POINT
51
52#define LSP_LINEAR(i) (SHL16(i+1,11))
53#define LSP_LINEAR_HIGH(i) (ADD16(MULT16_16_16(i,2560),6144))
54#define LSP_DIV_256(x) (SHL16((spx_word16_t)x, 5))
55#define LSP_DIV_512(x) (SHL16((spx_word16_t)x, 4))
56#define LSP_DIV_1024(x) (SHL16((spx_word16_t)x, 3))
57#define LSP_PI 25736
58
59#else
60
61#define LSP_LINEAR(i) (.25*(i)+.25)
62#define LSP_LINEAR_HIGH(i) (.3125*(i)+.75)
63#define LSP_SCALE 256.
64#define LSP_DIV_256(x) (0.0039062*(x))
65#define LSP_DIV_512(x) (0.0019531*(x))
66#define LSP_DIV_1024(x) (0.00097656*(x))
67#define LSP_PI M_PI
68
69#endif
70
71#ifndef SPEEX_DISABLE_ENCODER
72static void compute_quant_weights(spx_lsp_t *qlsp, spx_word16_t *quant_weight, int order)
73{
74 int i;
75 spx_word16_t tmp1, tmp2;
76 for (i=0;i<order;i++)
77 {
78 if (i==0)
79 tmp1 = qlsp[i];
80 else
81 tmp1 = qlsp[i]-qlsp[i-1];
82 if (i==order-1)
83 tmp2 = LSP_PI-qlsp[i];
84 else
85 tmp2 = qlsp[i+1]-qlsp[i];
86 if (tmp2<tmp1)
87 tmp1 = tmp2;
88#ifdef FIXED_POINT
89 quant_weight[i] = DIV32_16(81920,ADD16(300,tmp1));
90#else
91 quant_weight[i] = 10/(.04+tmp1);
92#endif
93 }
94
95}
96
97/* Note: x is modified*/
98#ifndef OVERRIDE_LSP_QUANT
99static int lsp_quant(spx_word16_t *x, const signed char *cdbk, int nbVec, int nbDim)
100{
101 int i,j;
102 spx_word32_t dist;
103 spx_word16_t tmp;
104 spx_word32_t best_dist=VERY_LARGE32;
105 int best_id=0;
106 const signed char *ptr=cdbk;
107 for (i=0;i<nbVec;i++)
108 {
109 dist=0;
110 for (j=0;j<nbDim;j++)
111 {
112 tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));
113 dist=MAC16_16(dist,tmp,tmp);
114 }
115 if (dist<best_dist)
116 {
117 best_dist=dist;
118 best_id=i;
119 }
120 }
121
122 for (j=0;j<nbDim;j++)
123 x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
124
125 return best_id;
126}
127#endif
128
129/* Note: x is modified*/
130#ifndef OVERRIDE_LSP_WEIGHT_QUANT
131static int lsp_weight_quant(spx_word16_t *x, spx_word16_t *weight, const signed char *cdbk, int nbVec, int nbDim)
132{
133 int i,j;
134 spx_word32_t dist;
135 spx_word16_t tmp;
136 spx_word32_t best_dist=VERY_LARGE32;
137 int best_id=0;
138 const signed char *ptr=cdbk;
139 for (i=0;i<nbVec;i++)
140 {
141 dist=0;
142 for (j=0;j<nbDim;j++)
143 {
144 tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));
145 dist=MAC16_32_Q15(dist,weight[j],MULT16_16(tmp,tmp));
146 }
147 if (dist<best_dist)
148 {
149 best_dist=dist;
150 best_id=i;
151 }
152 }
153
154 for (j=0;j<nbDim;j++)
155 x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
156 return best_id;
157}
158#endif
159
160void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
161{
162 int i;
163 int id;
164 spx_word16_t quant_weight[10];
165
166 for (i=0;i<order;i++)
167 qlsp[i]=lsp[i];
168
169 compute_quant_weights(qlsp, quant_weight, order);
170
171 for (i=0;i<order;i++)
172 qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));
173
174#ifndef FIXED_POINT
175 for (i=0;i<order;i++)
176 qlsp[i] = LSP_SCALE*qlsp[i];
177#endif
178 id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
179 speex_bits_pack(bits, id, 6);
180
181 for (i=0;i<order;i++)
182 qlsp[i]*=2;
183
184 id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
185 speex_bits_pack(bits, id, 6);
186
187 for (i=0;i<5;i++)
188 qlsp[i]*=2;
189
190 id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5);
191 speex_bits_pack(bits, id, 6);
192
193 id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
194 speex_bits_pack(bits, id, 6);
195
196 for (i=5;i<10;i++)
197 qlsp[i]*=2;
198
199 id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5);
200 speex_bits_pack(bits, id, 6);
201
202#ifdef FIXED_POINT
203 for (i=0;i<order;i++)
204 qlsp[i]=PSHR16(qlsp[i],2);
205#else
206 for (i=0;i<order;i++)
207 qlsp[i]=qlsp[i] * .00097656;
208#endif
209
210 for (i=0;i<order;i++)
211 qlsp[i]=lsp[i]-qlsp[i];
212}
213#endif /* SPEEX_DISABLE_ENCODER */
214
215void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits)
216{
217 int i, id;
218 for (i=0;i<order;i++)
219 lsp[i]=LSP_LINEAR(i);
220
221
222 id=speex_bits_unpack_unsigned(bits, 6);
223 for (i=0;i<10;i++)
224 lsp[i] = ADD32(lsp[i], LSP_DIV_256(cdbk_nb[id*10+i]));
225
226 id=speex_bits_unpack_unsigned(bits, 6);
227 for (i=0;i<5;i++)
228 lsp[i] = ADD16(lsp[i], LSP_DIV_512(cdbk_nb_low1[id*5+i]));
229
230 id=speex_bits_unpack_unsigned(bits, 6);
231 for (i=0;i<5;i++)
232 lsp[i] = ADD32(lsp[i], LSP_DIV_1024(cdbk_nb_low2[id*5+i]));
233
234 id=speex_bits_unpack_unsigned(bits, 6);
235 for (i=0;i<5;i++)
236 lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_512(cdbk_nb_high1[id*5+i]));
237
238 id=speex_bits_unpack_unsigned(bits, 6);
239 for (i=0;i<5;i++)
240 lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_1024(cdbk_nb_high2[id*5+i]));
241}
242
243
244#ifndef SPEEX_DISABLE_ENCODER
245void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
246{
247 int i;
248 int id;
249 spx_word16_t quant_weight[10];
250
251 for (i=0;i<order;i++)
252 qlsp[i]=lsp[i];
253
254 compute_quant_weights(qlsp, quant_weight, order);
255
256 for (i=0;i<order;i++)
257 qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));
258#ifndef FIXED_POINT
259 for (i=0;i<order;i++)
260 qlsp[i]=qlsp[i]*LSP_SCALE;
261#endif
262 id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
263 speex_bits_pack(bits, id, 6);
264
265 for (i=0;i<order;i++)
266 qlsp[i]*=2;
267
268 id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
269 speex_bits_pack(bits, id, 6);
270
271 id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
272 speex_bits_pack(bits, id, 6);
273
274#ifdef FIXED_POINT
275 for (i=0;i<order;i++)
276 qlsp[i] = PSHR16(qlsp[i],1);
277#else
278 for (i=0;i<order;i++)
279 qlsp[i] = qlsp[i]*0.0019531;
280#endif
281
282 for (i=0;i<order;i++)
283 qlsp[i]=lsp[i]-qlsp[i];
284}
285#endif /* SPEEX_DISABLE_ENCODER */
286
287void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)
288{
289 int i, id;
290 for (i=0;i<order;i++)
291 lsp[i]=LSP_LINEAR(i);
292
293
294 id=speex_bits_unpack_unsigned(bits, 6);
295 for (i=0;i<10;i++)
296 lsp[i] += LSP_DIV_256(cdbk_nb[id*10+i]);
297
298 id=speex_bits_unpack_unsigned(bits, 6);
299 for (i=0;i<5;i++)
300 lsp[i] += LSP_DIV_512(cdbk_nb_low1[id*5+i]);
301
302 id=speex_bits_unpack_unsigned(bits, 6);
303 for (i=0;i<5;i++)
304 lsp[i+5] += LSP_DIV_512(cdbk_nb_high1[id*5+i]);
305
306}
307
308
309#ifdef DISABLE_WIDEBAND
310void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
311{
312 speex_fatal("Wideband and Ultra-wideband are disabled");
313}
314void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
315{
316 speex_fatal("Wideband and Ultra-wideband are disabled");
317}
318#else
319extern const signed char high_lsp_cdbk[];
320extern const signed char high_lsp_cdbk2[];
321
322
323#ifndef SPEEX_DISABLE_ENCODER
324void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
325{
326 int i;
327 int id;
328 spx_word16_t quant_weight[10];
329
330 for (i=0;i<order;i++)
331 qlsp[i]=lsp[i];
332
333 compute_quant_weights(qlsp, quant_weight, order);
334
335 /* quant_weight[0] = 10/(qlsp[1]-qlsp[0]);
336 quant_weight[order-1] = 10/(qlsp[order-1]-qlsp[order-2]);
337 for (i=1;i<order-1;i++)
338 {
339 tmp1 = 10/(qlsp[i]-qlsp[i-1]);
340 tmp2 = 10/(qlsp[i+1]-qlsp[i]);
341 quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
342 }*/
343
344 for (i=0;i<order;i++)
345 qlsp[i]=SUB16(qlsp[i],LSP_LINEAR_HIGH(i));
346#ifndef FIXED_POINT
347 for (i=0;i<order;i++)
348 qlsp[i] = qlsp[i]*LSP_SCALE;
349#endif
350 id = lsp_quant(qlsp, high_lsp_cdbk, 64, order);
351 speex_bits_pack(bits, id, 6);
352
353 for (i=0;i<order;i++)
354 qlsp[i]*=2;
355
356 id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order);
357 speex_bits_pack(bits, id, 6);
358
359#ifdef FIXED_POINT
360 for (i=0;i<order;i++)
361 qlsp[i] = PSHR16(qlsp[i],1);
362#else
363 for (i=0;i<order;i++)
364 qlsp[i] = qlsp[i]*0.0019531;
365#endif
366
367 for (i=0;i<order;i++)
368 qlsp[i]=lsp[i]-qlsp[i];
369}
370#endif /* SPEEX_DISABLE_ENCODER */
371
372void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
373{
374
375 int i, id;
376 for (i=0;i<order;i++)
377 lsp[i]=LSP_LINEAR_HIGH(i);
378
379
380 id=speex_bits_unpack_unsigned(bits, 6);
381 for (i=0;i<order;i++)
382 lsp[i] += LSP_DIV_256(high_lsp_cdbk[id*order+i]);
383
384
385 id=speex_bits_unpack_unsigned(bits, 6);
386 for (i=0;i<order;i++)
387 lsp[i] += LSP_DIV_512(high_lsp_cdbk2[id*order+i]);
388}
389
390#endif
391
diff --git a/lib/rbcodec/codecs/libspeex/quant_lsp.h b/lib/rbcodec/codecs/libspeex/quant_lsp.h
new file mode 100644
index 0000000000..0fc206be6f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/quant_lsp.h
@@ -0,0 +1,74 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file quant_lsp.h
4 @brief LSP vector quantization
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef QUANT_LSP_H
36#define QUANT_LSP_H
37
38#include "speex/speex_bits.h"
39#include "arch.h"
40
41#define MAX_LSP_SIZE 20
42
43#define NB_CDBK_SIZE 64
44#define NB_CDBK_SIZE_LOW1 64
45#define NB_CDBK_SIZE_LOW2 64
46#define NB_CDBK_SIZE_HIGH1 64
47#define NB_CDBK_SIZE_HIGH2 64
48
49/*Narrowband codebooks*/
50extern const signed char cdbk_nb[];
51extern const signed char cdbk_nb_low1[];
52extern const signed char cdbk_nb_low2[];
53extern const signed char cdbk_nb_high1[];
54extern const signed char cdbk_nb_high2[];
55
56/* Quantizes narrowband LSPs with 30 bits */
57void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
58
59/* Decodes quantized narrowband LSPs */
60void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits);
61
62/* Quantizes low bit-rate narrowband LSPs with 18 bits */
63void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
64
65/* Decodes quantized low bit-rate narrowband LSPs */
66void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits);
67
68/* Quantizes high-band LSPs with 12 bits */
69void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
70
71/* Decodes high-band LSPs */
72void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits);
73
74#endif
diff --git a/lib/rbcodec/codecs/libspeex/quant_lsp_bfin.h b/lib/rbcodec/codecs/libspeex/quant_lsp_bfin.h
new file mode 100644
index 0000000000..917047bb56
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/quant_lsp_bfin.h
@@ -0,0 +1,165 @@
1/* Copyright (C) 2006 David Rowe */
2/**
3 @file quant_lsp_bfin.h
4 @author David Rowe
5 @brief Various compatibility routines for Speex (Blackfin version)
6*/
7/*
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 - Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 - Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19 - Neither the name of the Xiph.org Foundation nor the names of its
20 contributors may be used to endorse or promote products derived from
21 this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#define OVERRIDE_LSP_QUANT
37#ifdef OVERRIDE_LSP_QUANT
38
39/*
40 Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
41 well tell you all the magic resgister constraints used below
42 for gcc in-line asm.
43*/
44
45static int lsp_quant(
46 spx_word16_t *x,
47 const signed char *cdbk,
48 int nbVec,
49 int nbDim
50)
51{
52 int j;
53 spx_word32_t best_dist=1<<30;
54 int best_id=0;
55
56 __asm__ __volatile__
57 (
58" %0 = 1 (X);\n\t" /* %0: best_dist */
59" %0 <<= 30;\n\t"
60" %1 = 0 (X);\n\t" /* %1: best_i */
61" P2 = %3\n\t" /* P2: ptr to cdbk */
62" R5 = 0;\n\t" /* R5: best cb entry */
63
64" R0 = %5;\n\t" /* set up circ addr */
65" R0 <<= 1;\n\t"
66" L0 = R0;\n\t"
67" I0 = %2;\n\t" /* %2: &x[0] */
68" B0 = %2;\n\t"
69
70" R2.L = W [I0++];\n\t"
71" LSETUP (lq1, lq2) LC0 = %4;\n\t"
72"lq1: R3 = 0;\n\t" /* R3: dist */
73" LSETUP (lq3, lq4) LC1 = %5;\n\t"
74"lq3: R1 = B [P2++] (X);\n\t"
75" R1 <<= 5;\n\t"
76" R0.L = R2.L - R1.L || R2.L = W [I0++];\n\t"
77" R0 = R0.L*R0.L;\n\t"
78"lq4: R3 = R3 + R0;\n\t"
79
80" cc =R3<%0;\n\t"
81" if cc %0=R3;\n\t"
82" if cc %1=R5;\n\t"
83"lq2: R5 += 1;\n\t"
84" L0 = 0;\n\t"
85 : "=&d" (best_dist), "=&d" (best_id)
86 : "a" (x), "b" (cdbk), "a" (nbVec), "a" (nbDim)
87 : "I0", "P2", "R0", "R1", "R2", "R3", "R5", "L0", "B0", "A0"
88 );
89
90 for (j=0;j<nbDim;j++) {
91 x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
92 }
93 return best_id;
94}
95#endif
96
97#define OVERRIDE_LSP_WEIGHT_QUANT
98#ifdef OVERRIDE_LSP_WEIGHT_QUANT
99
100/*
101 Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
102 well tell you all the magic resgister constraints used below
103 for gcc in-line asm.
104*/
105
106static int lsp_weight_quant(
107 spx_word16_t *x,
108 spx_word16_t *weight,
109 const signed char *cdbk,
110 int nbVec,
111 int nbDim
112)
113{
114 int j;
115 spx_word32_t best_dist=1<<30;
116 int best_id=0;
117
118 __asm__ __volatile__
119 (
120" %0 = 1 (X);\n\t" /* %0: best_dist */
121" %0 <<= 30;\n\t"
122" %1 = 0 (X);\n\t" /* %1: best_i */
123" P2 = %4\n\t" /* P2: ptr to cdbk */
124" R5 = 0;\n\t" /* R5: best cb entry */
125
126" R0 = %6;\n\t" /* set up circ addr */
127" R0 <<= 1;\n\t"
128" L0 = R0;\n\t"
129" L1 = R0;\n\t"
130" I0 = %2;\n\t" /* %2: &x[0] */
131" I1 = %3;\n\t" /* %3: &weight[0] */
132" B0 = %2;\n\t"
133" B1 = %3;\n\t"
134
135" LSETUP (lwq1, lwq2) LC0 = %5;\n\t"
136"lwq1: R3 = 0 (X);\n\t" /* R3: dist */
137" LSETUP (lwq3, lwq4) LC1 = %6;\n\t"
138"lwq3: R0.L = W [I0++] || R2.L = W [I1++];\n\t"
139" R1 = B [P2++] (X);\n\t"
140" R1 <<= 5;\n\t"
141" R0.L = R0.L - R1.L;\n\t"
142" R0 = R0.L*R0.L;\n\t"
143" A1 = R2.L*R0.L (M,IS);\n\t"
144" A1 = A1 >>> 16;\n\t"
145" R1 = (A1 += R2.L*R0.H) (IS);\n\t"
146"lwq4: R3 = R3 + R1;\n\t"
147
148" cc =R3<%0;\n\t"
149" if cc %0=R3;\n\t"
150" if cc %1=R5;\n\t"
151"lwq2: R5 += 1;\n\t"
152" L0 = 0;\n\t"
153" L1 = 0;\n\t"
154 : "=&d" (best_dist), "=&d" (best_id)
155 : "a" (x), "a" (weight), "b" (cdbk), "a" (nbVec), "a" (nbDim)
156 : "I0", "I1", "P2", "R0", "R1", "R2", "R3", "R5", "A1",
157 "L0", "L1", "B0", "B1"
158 );
159
160 for (j=0;j<nbDim;j++) {
161 x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
162 }
163 return best_id;
164}
165#endif
diff --git a/lib/rbcodec/codecs/libspeex/resample.c b/lib/rbcodec/codecs/libspeex/resample.c
new file mode 100644
index 0000000000..65dfef28a3
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/resample.c
@@ -0,0 +1,1140 @@
1/* Copyright (C) 2007 Jean-Marc Valin
2
3 File: resample.c
4 Arbitrary resampling code
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are
8 met:
9
10 1. Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 3. The name of the author may not be used to endorse or promote products
18 derived from this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31*/
32
33/*
34 The design goals of this code are:
35 - Very fast algorithm
36 - SIMD-friendly algorithm
37 - Low memory requirement
38 - Good *perceptual* quality (and not best SNR)
39
40 Warning: This resampler is relatively new. Although I think I got rid of
41 all the major bugs and I don't expect the API to change anymore, there
42 may be something I've missed. So use with caution.
43
44 This algorithm is based on this original resampling algorithm:
45 Smith, Julius O. Digital Audio Resampling Home Page
46 Center for Computer Research in Music and Acoustics (CCRMA),
47 Stanford University, 2007.
48 Web published at http://www-ccrma.stanford.edu/~jos/resample/.
49
50 There is one main difference, though. This resampler uses cubic
51 interpolation instead of linear interpolation in the above paper. This
52 makes the table much smaller and makes it possible to compute that table
53 on a per-stream basis. In turn, being able to tweak the table for each
54 stream makes it possible to both reduce complexity on simple ratios
55 (e.g. 2/3), and get rid of the rounding operations in the inner loop.
56 The latter both reduces CPU time and makes the algorithm more SIMD-friendly.
57*/
58
59#ifdef HAVE_CONFIG_H
60#include "config-speex.h"
61#endif
62
63#ifdef OUTSIDE_SPEEX
64#include <stdlib.h>
65static void *speex_alloc (int size) {return calloc(size,1);}
66static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);}
67static void speex_free (void *ptr) {free(ptr);}
68#include "speex_resampler.h"
69#include "arch.h"
70#else /* OUTSIDE_SPEEX */
71
72#include "speex/speex_resampler.h"
73#include "arch.h"
74#include "os_support.h"
75#endif /* OUTSIDE_SPEEX */
76
77#include <math.h>
78
79#ifndef M_PI
80#define M_PI 3.14159263
81#endif
82
83#ifdef FIXED_POINT
84#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x)))
85#else
86#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x))))
87#endif
88
89/*#define float double*/
90#define FILTER_SIZE 64
91#define OVERSAMPLE 8
92
93#define IMAX(a,b) ((a) > (b) ? (a) : (b))
94#define IMIN(a,b) ((a) < (b) ? (a) : (b))
95
96#ifndef NULL
97#define NULL 0
98#endif
99
100typedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t , const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *);
101
102struct SpeexResamplerState_ {
103 spx_uint32_t in_rate;
104 spx_uint32_t out_rate;
105 spx_uint32_t num_rate;
106 spx_uint32_t den_rate;
107
108 int quality;
109 spx_uint32_t nb_channels;
110 spx_uint32_t filt_len;
111 spx_uint32_t mem_alloc_size;
112 int int_advance;
113 int frac_advance;
114 float cutoff;
115 spx_uint32_t oversample;
116 int initialised;
117 int started;
118
119 /* These are per-channel */
120 spx_int32_t *last_sample;
121 spx_uint32_t *samp_frac_num;
122 spx_uint32_t *magic_samples;
123
124 spx_word16_t *mem;
125 spx_word16_t *sinc_table;
126 spx_uint32_t sinc_table_length;
127 resampler_basic_func resampler_ptr;
128
129 int in_stride;
130 int out_stride;
131} ;
132
133static double kaiser12_table[68] = {
134 0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076,
135 0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014,
136 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601,
137 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014,
138 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490,
139 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546,
140 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178,
141 0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947,
142 0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058,
143 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438,
144 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734,
145 0.00001000, 0.00000000};
146/*
147static double kaiser12_table[36] = {
148 0.99440475, 1.00000000, 0.99440475, 0.97779076, 0.95066529, 0.91384741,
149 0.86843014, 0.81573067, 0.75723148, 0.69451601, 0.62920216, 0.56287762,
150 0.49704014, 0.43304576, 0.37206735, 0.31506490, 0.26276832, 0.21567274,
151 0.17404546, 0.13794294, 0.10723616, 0.08164178, 0.06075685, 0.04409466,
152 0.03111947, 0.02127838, 0.01402878, 0.00886058, 0.00531256, 0.00298291,
153 0.00153438, 0.00069463, 0.00025272, 0.0000527734, 0.00000500, 0.00000000};
154*/
155static double kaiser10_table[36] = {
156 0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446,
157 0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347,
158 0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962,
159 0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451,
160 0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739,
161 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000};
162
163static double kaiser8_table[36] = {
164 0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200,
165 0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126,
166 0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272,
167 0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758,
168 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490,
169 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000};
170
171static double kaiser6_table[36] = {
172 0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003,
173 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565,
174 0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561,
175 0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058,
176 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600,
177 0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000};
178
179struct FuncDef {
180 double *table;
181 int oversample;
182};
183
184static struct FuncDef _KAISER12 = {kaiser12_table, 64};
185#define KAISER12 (&_KAISER12)
186/*static struct FuncDef _KAISER12 = {kaiser12_table, 32};
187#define KAISER12 (&_KAISER12)*/
188static struct FuncDef _KAISER10 = {kaiser10_table, 32};
189#define KAISER10 (&_KAISER10)
190static struct FuncDef _KAISER8 = {kaiser8_table, 32};
191#define KAISER8 (&_KAISER8)
192static struct FuncDef _KAISER6 = {kaiser6_table, 32};
193#define KAISER6 (&_KAISER6)
194
195struct QualityMapping {
196 int base_length;
197 int oversample;
198 float downsample_bandwidth;
199 float upsample_bandwidth;
200 struct FuncDef *window_func;
201};
202
203
204/* This table maps conversion quality to internal parameters. There are two
205 reasons that explain why the up-sampling bandwidth is larger than the
206 down-sampling bandwidth:
207 1) When up-sampling, we can assume that the spectrum is already attenuated
208 close to the Nyquist rate (from an A/D or a previous resampling filter)
209 2) Any aliasing that occurs very close to the Nyquist rate will be masked
210 by the sinusoids/noise just below the Nyquist rate (guaranteed only for
211 up-sampling).
212*/
213static const struct QualityMapping quality_map[11] = {
214 { 8, 4, 0.830f, 0.860f, KAISER6 }, /* Q0 */
215 { 16, 4, 0.850f, 0.880f, KAISER6 }, /* Q1 */
216 { 32, 4, 0.882f, 0.910f, KAISER6 }, /* Q2 */ /* 82.3% cutoff ( ~60 dB stop) 6 */
217 { 48, 8, 0.895f, 0.917f, KAISER8 }, /* Q3 */ /* 84.9% cutoff ( ~80 dB stop) 8 */
218 { 64, 8, 0.921f, 0.940f, KAISER8 }, /* Q4 */ /* 88.7% cutoff ( ~80 dB stop) 8 */
219 { 80, 16, 0.922f, 0.940f, KAISER10}, /* Q5 */ /* 89.1% cutoff (~100 dB stop) 10 */
220 { 96, 16, 0.940f, 0.945f, KAISER10}, /* Q6 */ /* 91.5% cutoff (~100 dB stop) 10 */
221 {128, 16, 0.950f, 0.950f, KAISER10}, /* Q7 */ /* 93.1% cutoff (~100 dB stop) 10 */
222 {160, 16, 0.960f, 0.960f, KAISER10}, /* Q8 */ /* 94.5% cutoff (~100 dB stop) 10 */
223 {192, 32, 0.968f, 0.968f, KAISER12}, /* Q9 */ /* 95.5% cutoff (~100 dB stop) 10 */
224 {256, 32, 0.975f, 0.975f, KAISER12}, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */
225};
226/*8,24,40,56,80,104,128,160,200,256,320*/
227static double compute_func(float x, struct FuncDef *func)
228{
229 float y, frac;
230 double interp[4];
231 int ind;
232 y = x*func->oversample;
233 ind = (int)floor(y);
234 frac = (y-ind);
235 /* CSE with handle the repeated powers */
236 interp[3] = -0.1666666667*frac + 0.1666666667*(frac*frac*frac);
237 interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac);
238 /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/
239 interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac);
240 /* Just to make sure we don't have rounding problems */
241 interp[1] = 1.f-interp[3]-interp[2]-interp[0];
242
243 /*sum = frac*accum[1] + (1-frac)*accum[2];*/
244 return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3];
245}
246
247#if 0
248#include <stdio.h>
249int main(int argc, char **argv)
250{
251 int i;
252 for (i=0;i<256;i++)
253 {
254 printf ("%f\n", compute_func(i/256., KAISER12));
255 }
256 return 0;
257}
258#endif
259
260#ifdef FIXED_POINT
261/* The slow way of computing a sinc for the table. Should improve that some day */
262static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func)
263{
264 /*fprintf (stderr, "%f ", x);*/
265 float xx = x * cutoff;
266 if (fabs(x)<1e-6f)
267 return WORD2INT(32768.*cutoff);
268 else if (fabs(x) > .5f*N)
269 return 0;
270 /*FIXME: Can it really be any slower than this? */
271 return WORD2INT(32768.*cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func));
272}
273#else
274/* The slow way of computing a sinc for the table. Should improve that some day */
275static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func)
276{
277 /*fprintf (stderr, "%f ", x);*/
278 float xx = x * cutoff;
279 if (fabs(x)<1e-6)
280 return cutoff;
281 else if (fabs(x) > .5*N)
282 return 0;
283 /*FIXME: Can it really be any slower than this? */
284 return cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func);
285}
286#endif
287
288#ifdef FIXED_POINT
289static void cubic_coef(spx_word16_t x, spx_word16_t interp[4])
290{
291 /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation
292 but I know it's MMSE-optimal on a sinc */
293 spx_word16_t x2, x3;
294 x2 = MULT16_16_P15(x, x);
295 x3 = MULT16_16_P15(x, x2);
296 interp[0] = PSHR32(MULT16_16(QCONST16(-0.16667f, 15),x) + MULT16_16(QCONST16(0.16667f, 15),x3),15);
297 interp[1] = EXTRACT16(EXTEND32(x) + SHR32(SUB32(EXTEND32(x2),EXTEND32(x3)),1));
298 interp[3] = PSHR32(MULT16_16(QCONST16(-0.33333f, 15),x) + MULT16_16(QCONST16(.5f,15),x2) - MULT16_16(QCONST16(0.16667f, 15),x3),15);
299 /* Just to make sure we don't have rounding problems */
300 interp[2] = Q15_ONE-interp[0]-interp[1]-interp[3];
301 if (interp[2]<32767)
302 interp[2]+=1;
303}
304#else
305static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4])
306{
307 /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation
308 but I know it's MMSE-optimal on a sinc */
309 interp[0] = -0.16667f*frac + 0.16667f*frac*frac*frac;
310 interp[1] = frac + 0.5f*frac*frac - 0.5f*frac*frac*frac;
311 /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/
312 interp[3] = -0.33333f*frac + 0.5f*frac*frac - 0.16667f*frac*frac*frac;
313 /* Just to make sure we don't have rounding problems */
314 interp[2] = 1.-interp[0]-interp[1]-interp[3];
315}
316#endif
317
318static int resampler_basic_direct_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
319{
320 int N = st->filt_len;
321 int out_sample = 0;
322 spx_word16_t *mem;
323 int last_sample = st->last_sample[channel_index];
324 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
325 mem = st->mem + channel_index * st->mem_alloc_size;
326 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
327 {
328 int j;
329 spx_word32_t sum=0;
330
331 /* We already have all the filter coefficients pre-computed in the table */
332 const spx_word16_t *ptr;
333 /* Do the memory part */
334 for (j=0;last_sample-N+1+j < 0;j++)
335 {
336 sum += MULT16_16(mem[last_sample+j],st->sinc_table[samp_frac_num*st->filt_len+j]);
337 }
338
339 /* Do the new part */
340 if (in != NULL)
341 {
342 ptr = in+st->in_stride*(last_sample-N+1+j);
343 for (;j<N;j++)
344 {
345 sum += MULT16_16(*ptr,st->sinc_table[samp_frac_num*st->filt_len+j]);
346 ptr += st->in_stride;
347 }
348 }
349
350 *out = PSHR32(sum,15);
351 out += st->out_stride;
352 out_sample++;
353 last_sample += st->int_advance;
354 samp_frac_num += st->frac_advance;
355 if (samp_frac_num >= st->den_rate)
356 {
357 samp_frac_num -= st->den_rate;
358 last_sample++;
359 }
360 }
361 st->last_sample[channel_index] = last_sample;
362 st->samp_frac_num[channel_index] = samp_frac_num;
363 return out_sample;
364}
365
366#ifdef FIXED_POINT
367#else
368/* This is the same as the previous function, except with a double-precision accumulator */
369static int resampler_basic_direct_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
370{
371 int N = st->filt_len;
372 int out_sample = 0;
373 spx_word16_t *mem;
374 int last_sample = st->last_sample[channel_index];
375 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
376 mem = st->mem + channel_index * st->mem_alloc_size;
377 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
378 {
379 int j;
380 double sum=0;
381
382 /* We already have all the filter coefficients pre-computed in the table */
383 const spx_word16_t *ptr;
384 /* Do the memory part */
385 for (j=0;last_sample-N+1+j < 0;j++)
386 {
387 sum += MULT16_16(mem[last_sample+j],(double)st->sinc_table[samp_frac_num*st->filt_len+j]);
388 }
389
390 /* Do the new part */
391 if (in != NULL)
392 {
393 ptr = in+st->in_stride*(last_sample-N+1+j);
394 for (;j<N;j++)
395 {
396 sum += MULT16_16(*ptr,(double)st->sinc_table[samp_frac_num*st->filt_len+j]);
397 ptr += st->in_stride;
398 }
399 }
400
401 *out = sum;
402 out += st->out_stride;
403 out_sample++;
404 last_sample += st->int_advance;
405 samp_frac_num += st->frac_advance;
406 if (samp_frac_num >= st->den_rate)
407 {
408 samp_frac_num -= st->den_rate;
409 last_sample++;
410 }
411 }
412 st->last_sample[channel_index] = last_sample;
413 st->samp_frac_num[channel_index] = samp_frac_num;
414 return out_sample;
415}
416#endif
417
418static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
419{
420 int N = st->filt_len;
421 int out_sample = 0;
422 spx_word16_t *mem;
423 int last_sample = st->last_sample[channel_index];
424 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
425 mem = st->mem + channel_index * st->mem_alloc_size;
426 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
427 {
428 int j;
429 spx_word32_t sum=0;
430
431 /* We need to interpolate the sinc filter */
432 spx_word32_t accum[4] = {0.f,0.f, 0.f, 0.f};
433 spx_word16_t interp[4];
434 const spx_word16_t *ptr;
435 int offset;
436 spx_word16_t frac;
437 offset = samp_frac_num*st->oversample/st->den_rate;
438#ifdef FIXED_POINT
439 frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);
440#else
441 frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;
442#endif
443 /* This code is written like this to make it easy to optimise with SIMD.
444 For most DSPs, it would be best to split the loops in two because most DSPs
445 have only two accumulators */
446 for (j=0;last_sample-N+1+j < 0;j++)
447 {
448 spx_word16_t curr_mem = mem[last_sample+j];
449 accum[0] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
450 accum[1] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
451 accum[2] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset]);
452 accum[3] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
453 }
454
455 if (in != NULL)
456 {
457 ptr = in+st->in_stride*(last_sample-N+1+j);
458 /* Do the new part */
459 for (;j<N;j++)
460 {
461 spx_word16_t curr_in = *ptr;
462 ptr += st->in_stride;
463 accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
464 accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
465 accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);
466 accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
467 }
468 }
469 cubic_coef(frac, interp);
470 sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]);
471
472 *out = PSHR32(sum,15);
473 out += st->out_stride;
474 out_sample++;
475 last_sample += st->int_advance;
476 samp_frac_num += st->frac_advance;
477 if (samp_frac_num >= st->den_rate)
478 {
479 samp_frac_num -= st->den_rate;
480 last_sample++;
481 }
482 }
483 st->last_sample[channel_index] = last_sample;
484 st->samp_frac_num[channel_index] = samp_frac_num;
485 return out_sample;
486}
487
488#ifdef FIXED_POINT
489#else
490/* This is the same as the previous function, except with a double-precision accumulator */
491static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
492{
493 int N = st->filt_len;
494 int out_sample = 0;
495 spx_word16_t *mem;
496 int last_sample = st->last_sample[channel_index];
497 spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
498 mem = st->mem + channel_index * st->mem_alloc_size;
499 while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
500 {
501 int j;
502 spx_word32_t sum=0;
503
504 /* We need to interpolate the sinc filter */
505 double accum[4] = {0.f,0.f, 0.f, 0.f};
506 float interp[4];
507 const spx_word16_t *ptr;
508 float alpha = ((float)samp_frac_num)/st->den_rate;
509 int offset = samp_frac_num*st->oversample/st->den_rate;
510 float frac = alpha*st->oversample - offset;
511 /* This code is written like this to make it easy to optimise with SIMD.
512 For most DSPs, it would be best to split the loops in two because most DSPs
513 have only two accumulators */
514 for (j=0;last_sample-N+1+j < 0;j++)
515 {
516 double curr_mem = mem[last_sample+j];
517 accum[0] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
518 accum[1] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
519 accum[2] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset]);
520 accum[3] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
521 }
522 if (in != NULL)
523 {
524 ptr = in+st->in_stride*(last_sample-N+1+j);
525 /* Do the new part */
526 for (;j<N;j++)
527 {
528 double curr_in = *ptr;
529 ptr += st->in_stride;
530 accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);
531 accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);
532 accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);
533 accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);
534 }
535 }
536 cubic_coef(frac, interp);
537 sum = interp[0]*accum[0] + interp[1]*accum[1] + interp[2]*accum[2] + interp[3]*accum[3];
538
539 *out = PSHR32(sum,15);
540 out += st->out_stride;
541 out_sample++;
542 last_sample += st->int_advance;
543 samp_frac_num += st->frac_advance;
544 if (samp_frac_num >= st->den_rate)
545 {
546 samp_frac_num -= st->den_rate;
547 last_sample++;
548 }
549 }
550 st->last_sample[channel_index] = last_sample;
551 st->samp_frac_num[channel_index] = samp_frac_num;
552 return out_sample;
553}
554#endif
555
556static void update_filter(SpeexResamplerState *st)
557{
558 spx_uint32_t old_length;
559
560 old_length = st->filt_len;
561 st->oversample = quality_map[st->quality].oversample;
562 st->filt_len = quality_map[st->quality].base_length;
563
564 if (st->num_rate > st->den_rate)
565 {
566 /* down-sampling */
567 st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate;
568 /* FIXME: divide the numerator and denominator by a certain amount if they're too large */
569 st->filt_len = st->filt_len*st->num_rate / st->den_rate;
570 /* Round down to make sure we have a multiple of 4 */
571 st->filt_len &= (~0x3);
572 if (2*st->den_rate < st->num_rate)
573 st->oversample >>= 1;
574 if (4*st->den_rate < st->num_rate)
575 st->oversample >>= 1;
576 if (8*st->den_rate < st->num_rate)
577 st->oversample >>= 1;
578 if (16*st->den_rate < st->num_rate)
579 st->oversample >>= 1;
580 if (st->oversample < 1)
581 st->oversample = 1;
582 } else {
583 /* up-sampling */
584 st->cutoff = quality_map[st->quality].upsample_bandwidth;
585 }
586
587 /* Choose the resampling type that requires the least amount of memory */
588 if (st->den_rate <= st->oversample)
589 {
590 spx_uint32_t i;
591 if (!st->sinc_table)
592 st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t));
593 else if (st->sinc_table_length < st->filt_len*st->den_rate)
594 {
595 st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t));
596 st->sinc_table_length = st->filt_len*st->den_rate;
597 }
598 for (i=0;i<st->den_rate;i++)
599 {
600 spx_int32_t j;
601 for (j=0;j<st->filt_len;j++)
602 {
603 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);
604 }
605 }
606#ifdef FIXED_POINT
607 st->resampler_ptr = resampler_basic_direct_single;
608#else
609 if (st->quality>8)
610 st->resampler_ptr = resampler_basic_direct_double;
611 else
612 st->resampler_ptr = resampler_basic_direct_single;
613#endif
614 /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/
615 } else {
616 spx_int32_t i;
617 if (!st->sinc_table)
618 st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t));
619 else if (st->sinc_table_length < st->filt_len*st->oversample+8)
620 {
621 st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t));
622 st->sinc_table_length = st->filt_len*st->oversample+8;
623 }
624 for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++)
625 st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len, quality_map[st->quality].window_func);
626#ifdef FIXED_POINT
627 st->resampler_ptr = resampler_basic_interpolate_single;
628#else
629 if (st->quality>8)
630 st->resampler_ptr = resampler_basic_interpolate_double;
631 else
632 st->resampler_ptr = resampler_basic_interpolate_single;
633#endif
634 /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/
635 }
636 st->int_advance = st->num_rate/st->den_rate;
637 st->frac_advance = st->num_rate%st->den_rate;
638
639
640 /* Here's the place where we update the filter memory to take into account
641 the change in filter length. It's probably the messiest part of the code
642 due to handling of lots of corner cases. */
643 if (!st->mem)
644 {
645 spx_uint32_t i;
646 st->mem = (spx_word16_t*)speex_alloc(st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t));
647 for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
648 st->mem[i] = 0;
649 st->mem_alloc_size = st->filt_len-1;
650 /*speex_warning("init filter");*/
651 } else if (!st->started)
652 {
653 spx_uint32_t i;
654 st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t));
655 for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
656 st->mem[i] = 0;
657 st->mem_alloc_size = st->filt_len-1;
658 /*speex_warning("reinit filter");*/
659 } else if (st->filt_len > old_length)
660 {
661 spx_int32_t i;
662 /* Increase the filter length */
663 /*speex_warning("increase filter size");*/
664 int old_alloc_size = st->mem_alloc_size;
665 if (st->filt_len-1 > st->mem_alloc_size)
666 {
667 st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t));
668 st->mem_alloc_size = st->filt_len-1;
669 }
670 for (i=st->nb_channels-1;i>=0;i--)
671 {
672 spx_int32_t j;
673 spx_uint32_t olen = old_length;
674 /*if (st->magic_samples[i])*/
675 {
676 /* Try and remove the magic samples as if nothing had happened */
677
678 /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */
679 olen = old_length + 2*st->magic_samples[i];
680 for (j=old_length-2+st->magic_samples[i];j>=0;j--)
681 st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j];
682 for (j=0;j<st->magic_samples[i];j++)
683 st->mem[i*st->mem_alloc_size+j] = 0;
684 st->magic_samples[i] = 0;
685 }
686 if (st->filt_len > olen)
687 {
688 /* If the new filter length is still bigger than the "augmented" length */
689 /* Copy data going backward */
690 for (j=0;j<olen-1;j++)
691 st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)];
692 /* Then put zeros for lack of anything better */
693 for (;j<st->filt_len-1;j++)
694 st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0;
695 /* Adjust last_sample */
696 st->last_sample[i] += (st->filt_len - olen)/2;
697 } else {
698 /* Put back some of the magic! */
699 st->magic_samples[i] = (olen - st->filt_len)/2;
700 for (j=0;j<st->filt_len-1+st->magic_samples[i];j++)
701 st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];
702 }
703 }
704 } else if (st->filt_len < old_length)
705 {
706 spx_uint32_t i;
707 /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic"
708 samples so they can be used directly as input the next time(s) */
709 for (i=0;i<st->nb_channels;i++)
710 {
711 spx_uint32_t j;
712 spx_uint32_t old_magic = st->magic_samples[i];
713 st->magic_samples[i] = (old_length - st->filt_len)/2;
714 /* We must copy some of the memory that's no longer used */
715 /* Copy data going backward */
716 for (j=0;j<st->filt_len-1+st->magic_samples[i]+old_magic;j++)
717 st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];
718 st->magic_samples[i] += old_magic;
719 }
720 }
721
722}
723
724SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)
725{
726 return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err);
727}
728
729SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)
730{
731 spx_uint32_t i;
732 SpeexResamplerState *st;
733 if (quality > 10 || quality < 0)
734 {
735 if (err)
736 *err = RESAMPLER_ERR_INVALID_ARG;
737 return NULL;
738 }
739 st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState));
740 st->initialised = 0;
741 st->started = 0;
742 st->in_rate = 0;
743 st->out_rate = 0;
744 st->num_rate = 0;
745 st->den_rate = 0;
746 st->quality = -1;
747 st->sinc_table_length = 0;
748 st->mem_alloc_size = 0;
749 st->filt_len = 0;
750 st->mem = 0;
751 st->resampler_ptr = 0;
752
753 st->cutoff = 1.f;
754 st->nb_channels = nb_channels;
755 st->in_stride = 1;
756 st->out_stride = 1;
757
758 /* Per channel data */
759 st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(int));
760 st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int));
761 st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int));
762 for (i=0;i<nb_channels;i++)
763 {
764 st->last_sample[i] = 0;
765 st->magic_samples[i] = 0;
766 st->samp_frac_num[i] = 0;
767 }
768
769 speex_resampler_set_quality(st, quality);
770 speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate);
771
772
773 update_filter(st);
774
775 st->initialised = 1;
776 if (err)
777 *err = RESAMPLER_ERR_SUCCESS;
778
779 return st;
780}
781
782void speex_resampler_destroy(SpeexResamplerState *st)
783{
784 speex_free(st->mem);
785 speex_free(st->sinc_table);
786 speex_free(st->last_sample);
787 speex_free(st->magic_samples);
788 speex_free(st->samp_frac_num);
789 speex_free(st);
790}
791
792
793
794static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
795{
796 int j=0;
797 int N = st->filt_len;
798 int out_sample = 0;
799 spx_word16_t *mem;
800 spx_uint32_t tmp_out_len = 0;
801 mem = st->mem + channel_index * st->mem_alloc_size;
802 st->started = 1;
803
804 /* Handle the case where we have samples left from a reduction in filter length */
805 if (st->magic_samples[channel_index])
806 {
807 int istride_save;
808 spx_uint32_t tmp_in_len;
809 spx_uint32_t tmp_magic;
810
811 istride_save = st->in_stride;
812 tmp_in_len = st->magic_samples[channel_index];
813 tmp_out_len = *out_len;
814 /* magic_samples needs to be set to zero to avoid infinite recursion */
815 tmp_magic = st->magic_samples[channel_index];
816 st->magic_samples[channel_index] = 0;
817 st->in_stride = 1;
818 speex_resampler_process_native(st, channel_index, mem+N-1, &tmp_in_len, out, &tmp_out_len);
819 st->in_stride = istride_save;
820 /*speex_warning_int("extra samples:", tmp_out_len);*/
821 /* If we couldn't process all "magic" input samples, save the rest for next time */
822 if (tmp_in_len < tmp_magic)
823 {
824 spx_uint32_t i;
825 st->magic_samples[channel_index] = tmp_magic-tmp_in_len;
826 for (i=0;i<st->magic_samples[channel_index];i++)
827 mem[N-1+i]=mem[N-1+i+tmp_in_len];
828 }
829 out += tmp_out_len*st->out_stride;
830 *out_len -= tmp_out_len;
831 }
832
833 /* Call the right resampler through the function ptr */
834 out_sample = st->resampler_ptr(st, channel_index, in, in_len, out, out_len);
835
836 if (st->last_sample[channel_index] < (spx_int32_t)*in_len)
837 *in_len = st->last_sample[channel_index];
838 *out_len = out_sample+tmp_out_len;
839 st->last_sample[channel_index] -= *in_len;
840
841 for (j=0;j<N-1-(spx_int32_t)*in_len;j++)
842 mem[j] = mem[j+*in_len];
843 for (;j<N-1;j++)
844 mem[j] = in[st->in_stride*(j+*in_len-N+1)];
845
846 return RESAMPLER_ERR_SUCCESS;
847}
848
849#define FIXED_STACK_ALLOC 1024
850
851#ifdef FIXED_POINT
852int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
853{
854 spx_uint32_t i;
855 int istride_save, ostride_save;
856#ifdef VAR_ARRAYS
857 spx_word16_t x[*in_len];
858 spx_word16_t y[*out_len];
859 /*VARDECL(spx_word16_t *x);
860 VARDECL(spx_word16_t *y);
861 ALLOC(x, *in_len, spx_word16_t);
862 ALLOC(y, *out_len, spx_word16_t);*/
863 istride_save = st->in_stride;
864 ostride_save = st->out_stride;
865 for (i=0;i<*in_len;i++)
866 x[i] = WORD2INT(in[i*st->in_stride]);
867 st->in_stride = st->out_stride = 1;
868 speex_resampler_process_native(st, channel_index, x, in_len, y, out_len);
869 st->in_stride = istride_save;
870 st->out_stride = ostride_save;
871 for (i=0;i<*out_len;i++)
872 out[i*st->out_stride] = y[i];
873#else
874 spx_word16_t x[FIXED_STACK_ALLOC];
875 spx_word16_t y[FIXED_STACK_ALLOC];
876 spx_uint32_t ilen=*in_len, olen=*out_len;
877 istride_save = st->in_stride;
878 ostride_save = st->out_stride;
879 while (ilen && olen)
880 {
881 spx_uint32_t ichunk, ochunk;
882 ichunk = ilen;
883 ochunk = olen;
884 if (ichunk>FIXED_STACK_ALLOC)
885 ichunk=FIXED_STACK_ALLOC;
886 if (ochunk>FIXED_STACK_ALLOC)
887 ochunk=FIXED_STACK_ALLOC;
888 for (i=0;i<ichunk;i++)
889 x[i] = WORD2INT(in[i*st->in_stride]);
890 st->in_stride = st->out_stride = 1;
891 speex_resampler_process_native(st, channel_index, x, &ichunk, y, &ochunk);
892 st->in_stride = istride_save;
893 st->out_stride = ostride_save;
894 for (i=0;i<ochunk;i++)
895 out[i*st->out_stride] = y[i];
896 out += ochunk;
897 in += ichunk;
898 ilen -= ichunk;
899 olen -= ochunk;
900 }
901 *in_len -= ilen;
902 *out_len -= olen;
903#endif
904 return RESAMPLER_ERR_SUCCESS;
905}
906int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
907{
908 return speex_resampler_process_native(st, channel_index, in, in_len, out, out_len);
909}
910#else
911int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
912{
913 return speex_resampler_process_native(st, channel_index, in, in_len, out, out_len);
914}
915int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
916{
917 spx_uint32_t i;
918 int istride_save, ostride_save;
919#ifdef VAR_ARRAYS
920 spx_word16_t x[*in_len];
921 spx_word16_t y[*out_len];
922 /*VARDECL(spx_word16_t *x);
923 VARDECL(spx_word16_t *y);
924 ALLOC(x, *in_len, spx_word16_t);
925 ALLOC(y, *out_len, spx_word16_t);*/
926 istride_save = st->in_stride;
927 ostride_save = st->out_stride;
928 for (i=0;i<*in_len;i++)
929 x[i] = in[i*st->in_stride];
930 st->in_stride = st->out_stride = 1;
931 speex_resampler_process_native(st, channel_index, x, in_len, y, out_len);
932 st->in_stride = istride_save;
933 st->out_stride = ostride_save;
934 for (i=0;i<*out_len;i++)
935 out[i*st->out_stride] = WORD2INT(y[i]);
936#else
937 spx_word16_t x[FIXED_STACK_ALLOC];
938 spx_word16_t y[FIXED_STACK_ALLOC];
939 spx_uint32_t ilen=*in_len, olen=*out_len;
940 istride_save = st->in_stride;
941 ostride_save = st->out_stride;
942 while (ilen && olen)
943 {
944 spx_uint32_t ichunk, ochunk;
945 ichunk = ilen;
946 ochunk = olen;
947 if (ichunk>FIXED_STACK_ALLOC)
948 ichunk=FIXED_STACK_ALLOC;
949 if (ochunk>FIXED_STACK_ALLOC)
950 ochunk=FIXED_STACK_ALLOC;
951 for (i=0;i<ichunk;i++)
952 x[i] = in[i*st->in_stride];
953 st->in_stride = st->out_stride = 1;
954 speex_resampler_process_native(st, channel_index, x, &ichunk, y, &ochunk);
955 st->in_stride = istride_save;
956 st->out_stride = ostride_save;
957 for (i=0;i<ochunk;i++)
958 out[i*st->out_stride] = WORD2INT(y[i]);
959 out += ochunk;
960 in += ichunk;
961 ilen -= ichunk;
962 olen -= ochunk;
963 }
964 *in_len -= ilen;
965 *out_len -= olen;
966#endif
967 return RESAMPLER_ERR_SUCCESS;
968}
969#endif
970
971int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
972{
973 spx_uint32_t i;
974 int istride_save, ostride_save;
975 spx_uint32_t bak_len = *out_len;
976 istride_save = st->in_stride;
977 ostride_save = st->out_stride;
978 st->in_stride = st->out_stride = st->nb_channels;
979 for (i=0;i<st->nb_channels;i++)
980 {
981 *out_len = bak_len;
982 if (in != NULL)
983 speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len);
984 else
985 speex_resampler_process_float(st, i, NULL, in_len, out+i, out_len);
986 }
987 st->in_stride = istride_save;
988 st->out_stride = ostride_save;
989 return RESAMPLER_ERR_SUCCESS;
990}
991
992
993int 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)
994{
995 spx_uint32_t i;
996 int istride_save, ostride_save;
997 spx_uint32_t bak_len = *out_len;
998 istride_save = st->in_stride;
999 ostride_save = st->out_stride;
1000 st->in_stride = st->out_stride = st->nb_channels;
1001 for (i=0;i<st->nb_channels;i++)
1002 {
1003 *out_len = bak_len;
1004 if (in != NULL)
1005 speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len);
1006 else
1007 speex_resampler_process_int(st, i, NULL, in_len, out+i, out_len);
1008 }
1009 st->in_stride = istride_save;
1010 st->out_stride = ostride_save;
1011 return RESAMPLER_ERR_SUCCESS;
1012}
1013
1014int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate)
1015{
1016 return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);
1017}
1018
1019void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate)
1020{
1021 *in_rate = st->in_rate;
1022 *out_rate = st->out_rate;
1023}
1024
1025int 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)
1026{
1027 spx_uint32_t fact;
1028 spx_uint32_t old_den;
1029 spx_uint32_t i;
1030 if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)
1031 return RESAMPLER_ERR_SUCCESS;
1032
1033 old_den = st->den_rate;
1034 st->in_rate = in_rate;
1035 st->out_rate = out_rate;
1036 st->num_rate = ratio_num;
1037 st->den_rate = ratio_den;
1038 /* FIXME: This is terribly inefficient, but who cares (at least for now)? */
1039 for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++)
1040 {
1041 while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))
1042 {
1043 st->num_rate /= fact;
1044 st->den_rate /= fact;
1045 }
1046 }
1047
1048 if (old_den > 0)
1049 {
1050 for (i=0;i<st->nb_channels;i++)
1051 {
1052 st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den;
1053 /* Safety net */
1054 if (st->samp_frac_num[i] >= st->den_rate)
1055 st->samp_frac_num[i] = st->den_rate-1;
1056 }
1057 }
1058
1059 if (st->initialised)
1060 update_filter(st);
1061 return RESAMPLER_ERR_SUCCESS;
1062}
1063
1064void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den)
1065{
1066 *ratio_num = st->num_rate;
1067 *ratio_den = st->den_rate;
1068}
1069
1070int speex_resampler_set_quality(SpeexResamplerState *st, int quality)
1071{
1072 if (quality > 10 || quality < 0)
1073 return RESAMPLER_ERR_INVALID_ARG;
1074 if (st->quality == quality)
1075 return RESAMPLER_ERR_SUCCESS;
1076 st->quality = quality;
1077 if (st->initialised)
1078 update_filter(st);
1079 return RESAMPLER_ERR_SUCCESS;
1080}
1081
1082void speex_resampler_get_quality(SpeexResamplerState *st, int *quality)
1083{
1084 *quality = st->quality;
1085}
1086
1087void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride)
1088{
1089 st->in_stride = stride;
1090}
1091
1092void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride)
1093{
1094 *stride = st->in_stride;
1095}
1096
1097void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride)
1098{
1099 st->out_stride = stride;
1100}
1101
1102void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride)
1103{
1104 *stride = st->out_stride;
1105}
1106
1107int speex_resampler_skip_zeros(SpeexResamplerState *st)
1108{
1109 spx_uint32_t i;
1110 for (i=0;i<st->nb_channels;i++)
1111 st->last_sample[i] = st->filt_len/2;
1112 return RESAMPLER_ERR_SUCCESS;
1113}
1114
1115int speex_resampler_reset_mem(SpeexResamplerState *st)
1116{
1117 spx_uint32_t i;
1118 for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
1119 st->mem[i] = 0;
1120 return RESAMPLER_ERR_SUCCESS;
1121}
1122
1123const char *speex_resampler_strerror(int err)
1124{
1125 switch (err)
1126 {
1127 case RESAMPLER_ERR_SUCCESS:
1128 return "Success.";
1129 case RESAMPLER_ERR_ALLOC_FAILED:
1130 return "Memory allocation failed.";
1131 case RESAMPLER_ERR_BAD_STATE:
1132 return "Bad resampler state.";
1133 case RESAMPLER_ERR_INVALID_ARG:
1134 return "Invalid argument.";
1135 case RESAMPLER_ERR_PTR_OVERLAP:
1136 return "Input and output buffers overlap.";
1137 default:
1138 return "Unknown error. Bad error code or strange version mismatch.";
1139 }
1140}
diff --git a/lib/rbcodec/codecs/libspeex/rockbox.h b/lib/rbcodec/codecs/libspeex/rockbox.h
new file mode 100644
index 0000000000..459c8b532f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/rockbox.h
@@ -0,0 +1,119 @@
1/**************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 Dan Everton
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ***************************************************************************/
20
21#ifndef SPEEX_ROCKBOX_H
22#define SPEEX_ROCKBOX_H
23
24/* We don't want all this stuff if we're building encoder */
25#ifndef ROCKBOX_VOICE_ENCODER
26
27#include "codeclib.h"
28#include "debug.h"
29
30#if !defined(ROCKBOX_VOICE_CODEC)
31
32#if defined(DEBUG) || defined(SIMULATOR)
33#undef DEBUGF
34#define DEBUGF ci->debugf
35#endif
36
37
38#ifdef ROCKBOX_HAS_LOGF
39#undef LOGF
40#define LOGF ci->logf
41#endif
42
43#endif /* ROCKBOX_VOICE_CODEC */
44
45#define OVERRIDE_SPEEX_ALLOC 1
46static inline void *speex_alloc (int size)
47{
48 return codec_calloc(size, 1);
49}
50
51#define OVERRIDE_SPEEX_ALLOC_SCRATCH 1
52static inline void *speex_alloc_scratch (int size)
53{
54 return codec_calloc(size,1);
55}
56
57#define OVERRIDE_SPEEX_REALLOC 1
58static inline void *speex_realloc (void *ptr, int size)
59{
60 return codec_realloc(ptr, size);
61}
62
63#define OVERRIDE_SPEEX_FREE 1
64static inline void speex_free (void *ptr)
65{
66 codec_free(ptr);
67}
68
69#define OVERRIDE_SPEEX_FREE_SCRATCH 1
70static inline void speex_free_scratch (void *ptr)
71{
72 codec_free(ptr);
73}
74
75#define OVERRIDE_SPEEX_FATAL 1
76static inline void _speex_fatal(const char *str, const char *file, int line)
77{
78 (void)str;
79 (void)file;
80 (void)line;
81 DEBUGF("Fatal error: %s\n", str);
82 //exit(1);
83}
84
85#define OVERRIDE_SPEEX_WARNING 1
86static inline void speex_warning(const char *str)
87{
88 (void)str;
89 DEBUGF("warning: %s\n", str);
90}
91
92#define OVERRIDE_SPEEX_WARNING_INT 1
93static inline void speex_warning_int(const char *str, int val)
94{
95 (void)str;
96 (void)val;
97 DEBUGF("warning: %s %d\n", str, val);
98}
99
100#define OVERRIDE_SPEEX_NOTIFY 1
101static inline void speex_notify(const char *str)
102{
103 (void)str;
104 DEBUGF("notice: %s\n", str);
105}
106
107#define OVERRIDE_SPEEX_PUTC 1
108static inline void _speex_putc(int ch, void *file)
109{
110 (void)ch;
111 (void)file;
112 //FILE *f = (FILE *)file;
113 //printf("%c", ch);
114}
115
116#endif /* ROCKBOX_VOICE_ENCODER */
117
118#endif
119
diff --git a/lib/rbcodec/codecs/libspeex/sb_celp.c b/lib/rbcodec/codecs/libspeex/sb_celp.c
new file mode 100644
index 0000000000..b28744812f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/sb_celp.c
@@ -0,0 +1,1510 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin
2 File: sb_celp.c
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#ifdef HAVE_CONFIG_H
33#include "config-speex.h"
34#endif
35
36#include <math.h>
37#include "sb_celp.h"
38#include "filters.h"
39#include "lpc.h"
40#include "lsp.h"
41#include "stack_alloc.h"
42#include "cb_search.h"
43#include "quant_lsp.h"
44#include "vq.h"
45#include "ltp.h"
46#include "arch.h"
47#include "math_approx.h"
48#include "os_support.h"
49
50#ifndef NULL
51#define NULL 0
52#endif
53
54/* Default size for the encoder and decoder stack (can be changed at compile time).
55 This does not apply when using variable-size arrays or alloca. */
56#ifndef SB_ENC_STACK
57#define SB_ENC_STACK (10000*sizeof(spx_sig_t))
58#endif
59
60#ifndef SB_DEC_STACK
61#define SB_DEC_STACK (6000*sizeof(spx_sig_t))
62#endif
63
64
65#ifdef DISABLE_WIDEBAND
66void *sb_encoder_init(const SpeexMode *m)
67{
68 speex_fatal("Wideband and Ultra-wideband are disabled");
69 return NULL;
70}
71void sb_encoder_destroy(void *state)
72{
73 speex_fatal("Wideband and Ultra-wideband are disabled");
74}
75int sb_encode(void *state, void *vin, SpeexBits *bits)
76{
77 speex_fatal("Wideband and Ultra-wideband are disabled");
78 return -2;
79}
80void *sb_decoder_init(const SpeexMode *m)
81{
82 speex_fatal("Wideband and Ultra-wideband are disabled");
83 return NULL;
84}
85void sb_decoder_destroy(void *state)
86{
87 speex_fatal("Wideband and Ultra-wideband are disabled");
88}
89int sb_decode(void *state, SpeexBits *bits, void *vout)
90{
91 speex_fatal("Wideband and Ultra-wideband are disabled");
92 return -2;
93}
94int sb_encoder_ctl(void *state, int request, void *ptr)
95{
96 speex_fatal("Wideband and Ultra-wideband are disabled");
97 return -2;
98}
99int sb_decoder_ctl(void *state, int request, void *ptr)
100{
101 speex_fatal("Wideband and Ultra-wideband are disabled");
102 return -2;
103}
104#else
105
106
107#ifndef M_PI
108#define M_PI 3.14159265358979323846 /* pi */
109#endif
110
111#define sqr(x) ((x)*(x))
112
113#define SUBMODE(x) st->submodes[st->submodeID]->x
114
115#ifdef FIXED_POINT
116static const spx_word16_t gc_quant_bound[16] ICONST_ATTR = {125, 164, 215, 282, 370, 484, 635, 832, 1090, 1428, 1871, 2452, 3213, 4210, 5516, 7228};
117static const spx_word16_t fold_quant_bound[32] ICONST_ATTR = {
118 39, 44, 50, 57, 64, 73, 83, 94,
119 106, 120, 136, 154, 175, 198, 225, 255,
120 288, 327, 370, 420, 476, 539, 611, 692,
121 784, 889, 1007, 1141, 1293, 1465, 1660, 1881};
122#define LSP_MARGIN 410
123#define LSP_DELTA1 6553
124#define LSP_DELTA2 1638
125
126#else
127
128static const spx_word16_t gc_quant_bound[16] = {
129 0.97979, 1.28384, 1.68223, 2.20426, 2.88829, 3.78458, 4.95900, 6.49787,
130 8.51428, 11.15642, 14.61846, 19.15484, 25.09895, 32.88761, 43.09325, 56.46588};
131static const spx_word16_t fold_quant_bound[32] = {
132 0.30498, 0.34559, 0.39161, 0.44375, 0.50283, 0.56979, 0.64565, 0.73162,
133 0.82903, 0.93942, 1.06450, 1.20624, 1.36685, 1.54884, 1.75506, 1.98875,
134 2.25355, 2.55360, 2.89361, 3.27889, 3.71547, 4.21018, 4.77076, 5.40598,
135 6.12577, 6.94141, 7.86565, 8.91295, 10.09969, 11.44445, 12.96826, 14.69497};
136
137#define LSP_MARGIN .05
138#define LSP_DELTA1 .2
139#define LSP_DELTA2 .05
140
141#endif
142
143#define QMF_ORDER 64
144
145#ifdef FIXED_POINT
146static const spx_word16_t h0[64] ICONST_ATTR = {2, -7, -7, 18, 15, -39, -25, 75, 35, -130, -41, 212, 38, -327, -17, 483, -32, -689, 124, 956, -283, -1307, 543, 1780, -973, -2467, 1733, 3633, -3339, -6409, 9059, 30153, 30153, 9059, -6409, -3339, 3633, 1733, -2467, -973, 1780, 543, -1307, -283, 956, 124, -689, -32, 483, -17, -327, 38, 212, -41, -130, 35, 75, -25, -39, 15, 18, -7, -7, 2};
147
148#else
149static const float h0[64] = {
150 3.596189e-05f, -0.0001123515f,
151 -0.0001104587f, 0.0002790277f,
152 0.0002298438f, -0.0005953563f,
153 -0.0003823631f, 0.00113826f,
154 0.0005308539f, -0.001986177f,
155 -0.0006243724f, 0.003235877f,
156 0.0005743159f, -0.004989147f,
157 -0.0002584767f, 0.007367171f,
158 -0.0004857935f, -0.01050689f,
159 0.001894714f, 0.01459396f,
160 -0.004313674f, -0.01994365f,
161 0.00828756f, 0.02716055f,
162 -0.01485397f, -0.03764973f,
163 0.026447f, 0.05543245f,
164 -0.05095487f, -0.09779096f,
165 0.1382363f, 0.4600981f,
166 0.4600981f, 0.1382363f,
167 -0.09779096f, -0.05095487f,
168 0.05543245f, 0.026447f,
169 -0.03764973f, -0.01485397f,
170 0.02716055f, 0.00828756f,
171 -0.01994365f, -0.004313674f,
172 0.01459396f, 0.001894714f,
173 -0.01050689f, -0.0004857935f,
174 0.007367171f, -0.0002584767f,
175 -0.004989147f, 0.0005743159f,
176 0.003235877f, -0.0006243724f,
177 -0.001986177f, 0.0005308539f,
178 0.00113826f, -0.0003823631f,
179 -0.0005953563f, 0.0002298438f,
180 0.0002790277f, -0.0001104587f,
181 -0.0001123515f, 3.596189e-05f
182};
183
184#endif
185
186extern const spx_word16_t lag_window[];
187extern const spx_word16_t lpc_window[];
188
189#ifndef SPEEX_DISABLE_ENCODER
190void *sb_encoder_init(const SpeexMode *m)
191{
192 int i;
193 spx_int32_t tmp;
194 SBEncState *st;
195 const SpeexSBMode *mode;
196
197 st = (SBEncState*)speex_alloc(sizeof(SBEncState));
198 if (!st)
199 return NULL;
200 st->mode = m;
201 mode = (const SpeexSBMode*)m->mode;
202
203
204 st->st_low = speex_encoder_init(mode->nb_mode);
205#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
206 st->stack = NULL;
207#else
208 /*st->stack = (char*)speex_alloc_scratch(SB_ENC_STACK);*/
209 speex_encoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);
210#endif
211
212 st->full_frame_size = 2*mode->frameSize;
213 st->frame_size = mode->frameSize;
214 st->subframeSize = mode->subframeSize;
215 st->nbSubframes = mode->frameSize/mode->subframeSize;
216 st->windowSize = st->frame_size+st->subframeSize;
217 st->lpcSize=mode->lpcSize;
218
219 st->encode_submode = 1;
220 st->submodes=mode->submodes;
221 st->submodeSelect = st->submodeID=mode->defaultSubmode;
222
223 tmp=9;
224 speex_encoder_ctl(st->st_low, SPEEX_SET_QUALITY, &tmp);
225 tmp=1;
226 speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp);
227
228 st->lpc_floor = mode->lpc_floor;
229 st->gamma1=mode->gamma1;
230 st->gamma2=mode->gamma2;
231 st->first=1;
232
233 st->high=(spx_word16_t*)speex_alloc((st->windowSize-st->frame_size)*sizeof(spx_word16_t));
234
235 st->h0_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
236 st->h1_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
237
238 st->window= lpc_window;
239
240 st->lagWindow = lag_window;
241
242 st->old_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
243 st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
244 st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t));
245 st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
246 st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t));
247 st->innov_rms_save = NULL;
248
249 st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
250 st->mem_sp2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
251 st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
252
253 for (i=0;i<st->lpcSize;i++)
254 st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
255
256#ifndef DISABLE_VBR
257 st->vbr_quality = 8;
258 st->vbr_enabled = 0;
259 st->vbr_max = 0;
260 st->vbr_max_high = 20000; /* We just need a big value here */
261 st->vad_enabled = 0;
262 st->abr_enabled = 0;
263 st->relative_quality=0;
264#endif /* #ifndef DISABLE_VBR */
265
266 st->complexity=2;
267 speex_encoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
268 st->sampling_rate*=2;
269#ifdef ENABLE_VALGRIND
270 VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
271#endif
272 return st;
273}
274
275void sb_encoder_destroy(void *state)
276{
277 SBEncState *st=(SBEncState*)state;
278
279 speex_encoder_destroy(st->st_low);
280#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
281 /*speex_free_scratch(st->stack);*/
282#endif
283
284 speex_free(st->high);
285
286 speex_free(st->h0_mem);
287 speex_free(st->h1_mem);
288
289 speex_free(st->old_lsp);
290 speex_free(st->old_qlsp);
291 speex_free(st->interp_qlpc);
292 speex_free(st->pi_gain);
293 speex_free(st->exc_rms);
294
295 speex_free(st->mem_sp);
296 speex_free(st->mem_sp2);
297 speex_free(st->mem_sw);
298
299
300 speex_free(st);
301}
302
303
304int sb_encode(void *state, void *vin, SpeexBits *bits)
305{
306 SBEncState *st;
307 int i, roots, sub;
308 char *stack;
309 VARDECL(spx_mem_t *mem);
310 VARDECL(spx_sig_t *innov);
311 VARDECL(spx_word16_t *target);
312 VARDECL(spx_word16_t *syn_resp);
313 VARDECL(spx_word32_t *low_pi_gain);
314 spx_word16_t *low;
315 spx_word16_t *high;
316 VARDECL(spx_word16_t *low_exc_rms);
317 VARDECL(spx_word16_t *low_innov_rms);
318 const SpeexSBMode *mode;
319 spx_int32_t dtx;
320 spx_word16_t *in = (spx_word16_t*)vin;
321 spx_word16_t e_low=0, e_high=0;
322 VARDECL(spx_coef_t *lpc);
323 VARDECL(spx_coef_t *interp_lpc);
324 VARDECL(spx_coef_t *bw_lpc1);
325 VARDECL(spx_coef_t *bw_lpc2);
326 VARDECL(spx_lsp_t *lsp);
327 VARDECL(spx_lsp_t *qlsp);
328 VARDECL(spx_lsp_t *interp_lsp);
329 VARDECL(spx_lsp_t *interp_qlsp);
330
331 st = (SBEncState*)state;
332 stack=st->stack;
333 mode = (const SpeexSBMode*)(st->mode->mode);
334 low = in;
335 high = in+st->frame_size;
336
337 /* High-band buffering / sync with low band */
338 /* Compute the two sub-bands by filtering with QMF h0*/
339 qmf_decomp(in, h0, low, high, st->full_frame_size, QMF_ORDER, st->h0_mem, stack);
340
341#ifndef DISABLE_VBR
342 if (st->vbr_enabled || st->vad_enabled)
343 {
344 /* Need to compute things here before the signal is trashed by the encoder */
345 /*FIXME: Are the two signals (low, high) in sync? */
346 e_low = compute_rms16(low, st->frame_size);
347 e_high = compute_rms16(high, st->frame_size);
348 }
349#endif /* #ifndef DISABLE_VBR */
350
351 ALLOC(low_innov_rms, st->nbSubframes, spx_word16_t);
352 speex_encoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_rms);
353 /* Encode the narrowband part*/
354 speex_encode_native(st->st_low, low, bits);
355
356 high = high - (st->windowSize-st->frame_size);
357 SPEEX_COPY(high, st->high, st->windowSize-st->frame_size);
358 SPEEX_COPY(st->high, &high[st->frame_size], st->windowSize-st->frame_size);
359
360
361 ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);
362 ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t);
363 speex_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
364 speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms);
365
366 speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx);
367
368 if (dtx==0)
369 dtx=1;
370 else
371 dtx=0;
372
373 ALLOC(lpc, st->lpcSize, spx_coef_t);
374 ALLOC(interp_lpc, st->lpcSize, spx_coef_t);
375 ALLOC(bw_lpc1, st->lpcSize, spx_coef_t);
376 ALLOC(bw_lpc2, st->lpcSize, spx_coef_t);
377
378 ALLOC(lsp, st->lpcSize, spx_lsp_t);
379 ALLOC(qlsp, st->lpcSize, spx_lsp_t);
380 ALLOC(interp_lsp, st->lpcSize, spx_lsp_t);
381 ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
382
383 {
384 VARDECL(spx_word16_t *autocorr);
385 VARDECL(spx_word16_t *w_sig);
386 ALLOC(autocorr, st->lpcSize+1, spx_word16_t);
387 ALLOC(w_sig, st->windowSize, spx_word16_t);
388 /* Window for analysis */
389 /* FIXME: This is a kludge */
390 if (st->subframeSize==80)
391 {
392 for (i=0;i<st->windowSize;i++)
393 w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i>>1]),SIG_SHIFT));
394 } else {
395 for (i=0;i<st->windowSize;i++)
396 w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i]),SIG_SHIFT));
397 }
398 /* Compute auto-correlation */
399 _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize);
400 autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */
401
402 /* Lag windowing: equivalent to filtering in the power-spectrum domain */
403 for (i=0;i<st->lpcSize+1;i++)
404 autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]);
405
406 /* Levinson-Durbin */
407 _spx_lpc(lpc, autocorr, st->lpcSize);
408 }
409
410 /* LPC to LSPs (x-domain) transform */
411 roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack);
412 if (roots!=st->lpcSize)
413 {
414 roots = lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA2, stack);
415 if (roots!=st->lpcSize) {
416 /*If we can't find all LSP's, do some damage control and use a flat filter*/
417 for (i=0;i<st->lpcSize;i++)
418 {
419 lsp[i]=st->old_lsp[i];
420 }
421 }
422 }
423
424#ifndef DISABLE_VBR
425 /* VBR code */
426 if ((st->vbr_enabled || st->vad_enabled) && !dtx)
427 {
428 float ratio;
429 if (st->abr_enabled)
430 {
431 float qual_change=0;
432 if (st->abr_drift2 * st->abr_drift > 0)
433 {
434 /* Only adapt if long-term and short-term drift are the same sign */
435 qual_change = -.00001*st->abr_drift/(1+st->abr_count);
436 if (qual_change>.1)
437 qual_change=.1;
438 if (qual_change<-.1)
439 qual_change=-.1;
440 }
441 st->vbr_quality += qual_change;
442 if (st->vbr_quality>10)
443 st->vbr_quality=10;
444 if (st->vbr_quality<0)
445 st->vbr_quality=0;
446 }
447
448
449 ratio = 2*log((1.f+e_high)/(1.f+e_low));
450
451 speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality);
452 if (ratio<-4)
453 ratio=-4;
454 if (ratio>2)
455 ratio=2;
456 /*if (ratio>-2)*/
457 if (st->vbr_enabled)
458 {
459 spx_int32_t modeid;
460 modeid = mode->nb_modes-1;
461 st->relative_quality+=1.0*(ratio+2);
462 if (st->relative_quality<-1)
463 st->relative_quality=-1;
464 while (modeid)
465 {
466 int v1;
467 float thresh;
468 v1=(int)floor(st->vbr_quality);
469 if (v1==10)
470 thresh = mode->vbr_thresh[modeid][v1];
471 else
472 thresh = (st->vbr_quality-v1) * mode->vbr_thresh[modeid][v1+1] +
473 (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1];
474 if (st->relative_quality >= thresh && st->sampling_rate*st->submodes[modeid]->bits_per_frame/st->full_frame_size <= st->vbr_max_high)
475 break;
476 modeid--;
477 }
478 speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid);
479 if (st->abr_enabled)
480 {
481 spx_int32_t bitrate;
482 speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);
483 st->abr_drift+=(bitrate-st->abr_enabled);
484 st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);
485 st->abr_count += 1.0;
486 }
487
488 } else {
489 /* VAD only */
490 int modeid;
491 if (st->relative_quality<2.0)
492 modeid=1;
493 else
494 modeid=st->submodeSelect;
495 /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/
496 st->submodeID=modeid;
497
498 }
499 /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/
500 }
501#endif /* #ifndef DISABLE_VBR */
502
503 if (st->encode_submode)
504 {
505 speex_bits_pack(bits, 1, 1);
506 if (dtx)
507 speex_bits_pack(bits, 0, SB_SUBMODE_BITS);
508 else
509 speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS);
510 }
511
512 /* If null mode (no transmission), just set a couple things to zero*/
513 if (dtx || st->submodes[st->submodeID] == NULL)
514 {
515 for (i=0;i<st->frame_size;i++)
516 high[i]=VERY_SMALL;
517
518 for (i=0;i<st->lpcSize;i++)
519 st->mem_sw[i]=0;
520 st->first=1;
521
522 /* Final signal synthesis from excitation */
523 iir_mem16(high, st->interp_qlpc, high, st->frame_size, st->lpcSize, st->mem_sp, stack);
524
525 if (dtx)
526 return 0;
527 else
528 return 1;
529 }
530
531
532 /* LSP quantization */
533 SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits);
534
535 if (st->first)
536 {
537 for (i=0;i<st->lpcSize;i++)
538 st->old_lsp[i] = lsp[i];
539 for (i=0;i<st->lpcSize;i++)
540 st->old_qlsp[i] = qlsp[i];
541 }
542
543 ALLOC(mem, st->lpcSize, spx_mem_t);
544 ALLOC(syn_resp, st->subframeSize, spx_word16_t);
545 ALLOC(innov, st->subframeSize, spx_sig_t);
546 ALLOC(target, st->subframeSize, spx_word16_t);
547
548 for (sub=0;sub<st->nbSubframes;sub++)
549 {
550 VARDECL(spx_word16_t *exc);
551 VARDECL(spx_word16_t *res);
552 VARDECL(spx_word16_t *sw);
553 spx_word16_t *sp;
554 spx_word16_t filter_ratio; /*Q7*/
555 int offset;
556 spx_word32_t rl, rh; /*Q13*/
557 spx_word16_t eh=0;
558
559 offset = st->subframeSize*sub;
560 sp=high+offset;
561 ALLOC(exc, st->subframeSize, spx_word16_t);
562 ALLOC(res, st->subframeSize, spx_word16_t);
563 ALLOC(sw, st->subframeSize, spx_word16_t);
564
565 /* LSP interpolation (quantized and unquantized) */
566 lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes);
567 lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
568
569 lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);
570 lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
571
572 lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);
573 lsp_to_lpc(interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
574
575 bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);
576 bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
577
578 /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band
579 filters */
580 st->pi_gain[sub]=LPC_SCALING;
581 rh = LPC_SCALING;
582 for (i=0;i<st->lpcSize;i+=2)
583 {
584 rh += st->interp_qlpc[i+1] - st->interp_qlpc[i];
585 st->pi_gain[sub] += st->interp_qlpc[i] + st->interp_qlpc[i+1];
586 }
587
588 rl = low_pi_gain[sub];
589#ifdef FIXED_POINT
590 filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767));
591#else
592 filter_ratio=(rl+.01)/(rh+.01);
593#endif
594
595 /* Compute "real excitation" */
596 fir_mem16(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2, stack);
597 /* Compute energy of low-band and high-band excitation */
598
599 eh = compute_rms16(exc, st->subframeSize);
600
601 if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */
602 spx_word32_t g; /*Q7*/
603 spx_word16_t el; /*Q0*/
604 el = low_innov_rms[sub];
605
606 /* Gain to use if we want to use the low-band excitation for high-band */
607 g=PDIV32(MULT16_16(filter_ratio,eh),EXTEND32(ADD16(1,el)));
608
609#if 0
610 {
611 char *tmp_stack=stack;
612 float *tmp_sig;
613 float g2;
614 ALLOC(tmp_sig, st->subframeSize, spx_sig_t);
615 for (i=0;i<st->lpcSize;i++)
616 mem[i]=st->mem_sp[i];
617 iir_mem2(st->low_innov+offset, st->interp_qlpc, tmp_sig, st->subframeSize, st->lpcSize, mem);
618 g2 = compute_rms(sp, st->subframeSize)/(.01+compute_rms(tmp_sig, st->subframeSize));
619 /*fprintf (stderr, "gains: %f %f\n", g, g2);*/
620 g = g2;
621 stack = tmp_stack;
622 }
623#endif
624
625 /*print_vec(&g, 1, "gain factor");*/
626 /* Gain quantization */
627 {
628 int quant = scal_quant(g, fold_quant_bound, 32);
629 /*speex_warning_int("tata", quant);*/
630 if (quant<0)
631 quant=0;
632 if (quant>31)
633 quant=31;
634 speex_bits_pack(bits, quant, 5);
635 }
636 if (st->innov_rms_save)
637 {
638 st->innov_rms_save[sub] = eh;
639 }
640 st->exc_rms[sub] = eh;
641 } else {
642 spx_word16_t gc; /*Q7*/
643 spx_word32_t scale; /*Q14*/
644 spx_word16_t el; /*Q0*/
645 el = low_exc_rms[sub]; /*Q0*/
646
647 gc = PDIV32_16(MULT16_16(filter_ratio,1+eh),1+el);
648
649 /* This is a kludge that cleans up a historical bug */
650 if (st->subframeSize==80)
651 gc = MULT16_16_P15(QCONST16(0.70711f,15),gc);
652 /*printf ("%f %f %f %f\n", el, eh, filter_ratio, gc);*/
653 {
654 int qgc = scal_quant(gc, gc_quant_bound, 16);
655 speex_bits_pack(bits, qgc, 4);
656 gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]);
657 }
658 if (st->subframeSize==80)
659 gc = MULT16_16_P14(QCONST16(1.4142f,14), gc);
660
661 scale = SHL32(MULT16_16(PDIV32_16(SHL32(EXTEND32(gc),SIG_SHIFT-6),filter_ratio),(1+el)),6);
662
663 compute_impulse_response(st->interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack);
664
665
666 /* Reset excitation */
667 for (i=0;i<st->subframeSize;i++)
668 res[i]=VERY_SMALL;
669
670 /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */
671 for (i=0;i<st->lpcSize;i++)
672 mem[i]=st->mem_sp[i];
673 iir_mem16(res, st->interp_qlpc, res, st->subframeSize, st->lpcSize, mem, stack);
674
675 for (i=0;i<st->lpcSize;i++)
676 mem[i]=st->mem_sw[i];
677 filter_mem16(res, bw_lpc1, bw_lpc2, res, st->subframeSize, st->lpcSize, mem, stack);
678
679 /* Compute weighted signal */
680 for (i=0;i<st->lpcSize;i++)
681 mem[i]=st->mem_sw[i];
682 filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack);
683
684 /* Compute target signal */
685 for (i=0;i<st->subframeSize;i++)
686 target[i]=SUB16(sw[i],res[i]);
687
688 signal_div(target, target, scale, st->subframeSize);
689
690 /* Reset excitation */
691 SPEEX_MEMSET(innov, 0, st->subframeSize);
692
693 /*print_vec(target, st->subframeSize, "\ntarget");*/
694 SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2,
695 SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
696 innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook));
697 /*print_vec(target, st->subframeSize, "after");*/
698
699 signal_mul(innov, innov, scale, st->subframeSize);
700
701 if (SUBMODE(double_codebook)) {
702 char *tmp_stack=stack;
703 VARDECL(spx_sig_t *innov2);
704 ALLOC(innov2, st->subframeSize, spx_sig_t);
705 SPEEX_MEMSET(innov2, 0, st->subframeSize);
706 for (i=0;i<st->subframeSize;i++)
707 target[i]=MULT16_16_P13(QCONST16(2.5f,13), target[i]);
708
709 SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2,
710 SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
711 innov2, syn_resp, bits, stack, st->complexity, 0);
712 signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize);
713
714 for (i=0;i<st->subframeSize;i++)
715 innov[i] = ADD32(innov[i],innov2[i]);
716 stack = tmp_stack;
717 }
718 for (i=0;i<st->subframeSize;i++)
719 exc[i] = PSHR32(innov[i],SIG_SHIFT);
720
721 if (st->innov_rms_save)
722 {
723 st->innov_rms_save[sub] = MULT16_16_Q15(QCONST16(.70711f, 15), compute_rms(innov, st->subframeSize));
724 }
725 st->exc_rms[sub] = compute_rms16(exc, st->subframeSize);
726
727
728 }
729
730
731 /*Keep the previous memory*/
732 for (i=0;i<st->lpcSize;i++)
733 mem[i]=st->mem_sp[i];
734 /* Final signal synthesis from excitation */
735 iir_mem16(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp, stack);
736
737 /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
738 filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack);
739 }
740
741 for (i=0;i<st->lpcSize;i++)
742 st->old_lsp[i] = lsp[i];
743 for (i=0;i<st->lpcSize;i++)
744 st->old_qlsp[i] = qlsp[i];
745
746 st->first=0;
747
748 return 1;
749}
750#endif /* SPEEX_DISABLE_ENCODER */
751
752
753
754static SBDecState global_decstate_wb IBSS_ATTR;
755/* Do not include this for voice codec, files will never be UWB */
756#ifndef ROCKBOX_VOICE_CODEC
757static SBDecState global_decstate_uwb IBSS_ATTR;
758#endif
759
760void *sb_decoder_init(const SpeexMode *m)
761{
762 spx_int32_t tmp;
763 SBDecState *st;
764 const SpeexSBMode *mode;
765/*
766 st = (SBDecState*)speex_alloc(sizeof(SBDecState));
767 if (!st)
768 return NULL;
769*/
770#ifndef ROCKBOX_VOICE_CODEC
771 if (m->modeID == SPEEX_MODEID_UWB)
772 st = &global_decstate_uwb;
773 else
774#endif
775 st = &global_decstate_wb;
776 memset(st, 0, sizeof(*st));
777 st->mode = m;
778 mode=(const SpeexSBMode*)m->mode;
779 st->encode_submode = 1;
780
781 st->st_low = speex_decoder_init(mode->nb_mode);
782#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
783 st->stack = NULL;
784#else
785 /*st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK);*/
786 speex_decoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);
787#endif
788
789 st->full_frame_size = 2*mode->frameSize;
790 st->frame_size = mode->frameSize;
791 st->subframeSize = mode->subframeSize;
792 st->nbSubframes = mode->frameSize/mode->subframeSize;
793 st->lpcSize=mode->lpcSize;
794 speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
795 st->sampling_rate*=2;
796 tmp=1;
797 speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp);
798
799 st->submodes=mode->submodes;
800 st->submodeID=mode->defaultSubmode;
801
802 st->first=1;
803
804 /* st->g0_mem = (spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t)); */
805 /* st->g1_mem = (spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t)); */
806
807 /* st->excBuf = (spx_word16_t*)speex_alloc((st->subframeSize)*sizeof(spx_word16_t)); */
808
809 /* st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); */
810 /* st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); */
811
812 /* st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); */
813 /*st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t)); */
814 /* st->mem_sp = (spx_mem_t*)speex_alloc((2*st->lpcSize)*sizeof(spx_mem_t)); */
815
816 st->innov_save = NULL;
817
818
819 st->lpc_enh_enabled=0;
820 st->seed = 1000;
821
822#ifdef ENABLE_VALGRIND
823 VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
824#endif
825 return st;
826}
827
828void sb_decoder_destroy(void *state)
829{
830 SBDecState *st;
831 st = (SBDecState*)state;
832 speex_decoder_destroy(st->st_low);
833#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
834 /*speex_free_scratch(st->stack);*/
835#endif
836/*
837 speex_free(st->g0_mem);
838 speex_free(st->g1_mem);
839 speex_free(st->excBuf);
840 speex_free(st->old_qlsp);
841 speex_free(st->interp_qlpc);
842 speex_free(st->pi_gain);
843 speex_free(st->exc_rms);
844 speex_free(st->mem_sp);
845
846 speex_free(state);
847*/
848}
849
850#ifndef ROCKBOX_VOICE_CODEC
851static void sb_decode_lost(SBDecState *st, spx_word16_t *out, int dtx, char *stack)
852{
853 int i;
854 int saved_modeid=0;
855
856 if (dtx)
857 {
858 saved_modeid=st->submodeID;
859 st->submodeID=1;
860 } else {
861 bw_lpc(QCONST16(0.99f,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize);
862 }
863
864 st->first=1;
865
866
867 /* Final signal synthesis from excitation */
868 if (!dtx)
869 {
870 st->last_ener = MULT16_16_Q15(QCONST16(.9f,15),st->last_ener);
871 }
872 for (i=0;i<st->frame_size;i++)
873 out[i+st->frame_size] = speex_rand(st->last_ener, &st->seed);
874
875 iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize,
876 st->mem_sp, stack);
877
878
879 /* Reconstruct the original */
880 qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
881 if (dtx)
882 {
883 st->submodeID=saved_modeid;
884 }
885
886 return;
887}
888#endif
889
890int sb_decode(void *state, SpeexBits *bits, void *vout)
891{
892 int i, sub;
893 SBDecState *st;
894 int wideband;
895 int ret;
896 char *stack;
897 VARDECL(spx_word32_t *low_pi_gain);
898 VARDECL(spx_word16_t *low_exc_rms);
899 VARDECL(spx_coef_t *ak);
900 VARDECL(spx_lsp_t *qlsp);
901 VARDECL(spx_lsp_t *interp_qlsp);
902 spx_int32_t dtx;
903 const SpeexSBMode *mode;
904 spx_word16_t *out = (spx_word16_t*)vout;
905 spx_word16_t *low_innov_alias;
906 spx_word32_t exc_ener_sum = 0;
907
908 st = (SBDecState*)state;
909 stack=st->stack;
910 mode = (const SpeexSBMode*)(st->mode->mode);
911
912 low_innov_alias = out+st->frame_size;
913 speex_decoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_alias);
914 /* Decode the low-band */
915 ret = speex_decode_native(st->st_low, bits, out);
916
917 speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx);
918
919 /* If error decoding the narrowband part, propagate error */
920 if (ret!=0)
921 {
922 return ret;
923 }
924
925#ifndef ROCKBOX_VOICE_CODEC
926 if (!bits)
927 {
928 sb_decode_lost(st, out, dtx, stack);
929 return 0;
930 }
931#endif
932
933 if (st->encode_submode)
934 {
935
936 /*Check "wideband bit"*/
937 if (speex_bits_remaining(bits)>0)
938 wideband = speex_bits_peek(bits);
939 else
940 wideband = 0;
941 if (wideband)
942 {
943 /*Regular wideband frame, read the submode*/
944 wideband = speex_bits_unpack_unsigned(bits, 1);
945 st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
946 } else
947 {
948 /*Was a narrowband frame, set "null submode"*/
949 st->submodeID = 0;
950 }
951 if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL)
952 {
953 speex_notify("Invalid mode encountered. The stream is corrupted.");
954 return -2;
955 }
956 }
957
958 /* If null mode (no transmission), just set a couple things to zero*/
959 if (st->submodes[st->submodeID] == NULL)
960 {
961#ifndef ROCKBOX_VOICE_CODEC
962 if (dtx)
963 {
964 sb_decode_lost(st, out, 1, stack);
965 return 0;
966 }
967#endif
968
969 for (i=0;i<st->frame_size;i++)
970 out[st->frame_size+i]=VERY_SMALL;
971
972 st->first=1;
973
974 /* Final signal synthesis from excitation */
975 iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize, st->mem_sp, stack);
976
977 qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
978
979 return 0;
980
981 }
982
983 ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);
984 ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t);
985 speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
986 speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms);
987
988 ALLOC(qlsp, st->lpcSize, spx_lsp_t);
989 ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
990 SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits);
991
992 if (st->first)
993 {
994 for (i=0;i<st->lpcSize;i++)
995 st->old_qlsp[i] = qlsp[i];
996 }
997
998 ALLOC(ak, st->lpcSize, spx_coef_t);
999
1000 for (sub=0;sub<st->nbSubframes;sub++)
1001 {
1002 VARDECL(spx_word32_t *exc);
1003 spx_word16_t *innov_save=NULL;
1004 spx_word16_t *sp;
1005 spx_word16_t filter_ratio;
1006 spx_word16_t el=0;
1007 int offset;
1008 spx_word32_t rl=0,rh=0;
1009
1010 offset = st->subframeSize*sub;
1011 sp=out+st->frame_size+offset;
1012 ALLOC(exc, st->subframeSize, spx_word32_t);
1013 /* Pointer for saving innovation */
1014 if (st->innov_save)
1015 {
1016 innov_save = st->innov_save+2*offset;
1017 SPEEX_MEMSET(innov_save, 0, 2*st->subframeSize);
1018 }
1019
1020 /* LSP interpolation */
1021 lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
1022
1023 lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
1024
1025 /* LSP to LPC */
1026 lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack);
1027
1028 /* Calculate reponse ratio between the low and high filter in the middle
1029 of the band (4000 Hz) */
1030
1031 st->pi_gain[sub]=LPC_SCALING;
1032 rh = LPC_SCALING;
1033 for (i=0;i<st->lpcSize;i+=2)
1034 {
1035 rh += ak[i+1] - ak[i];
1036 st->pi_gain[sub] += ak[i] + ak[i+1];
1037 }
1038
1039 rl = low_pi_gain[sub];
1040#ifdef FIXED_POINT
1041 filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767));
1042#else
1043 filter_ratio=(rl+.01)/(rh+.01);
1044#endif
1045
1046 SPEEX_MEMSET(exc, 0, st->subframeSize);
1047 if (!SUBMODE(innovation_unquant))
1048 {
1049 spx_word32_t g;
1050 int quant;
1051
1052 quant = speex_bits_unpack_unsigned(bits, 5);
1053 g= spx_exp(MULT16_16(QCONST16(.125f,11),(quant-10)));
1054
1055 g = PDIV32(g, filter_ratio);
1056
1057 for (i=0;i<st->subframeSize;i+=2)
1058 {
1059 exc[i]=SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i]),SHL32(g,6)),SIG_SHIFT);
1060 exc[i+1]=NEG32(SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i+1]),SHL32(g,6)),SIG_SHIFT));
1061 }
1062
1063 } else {
1064 spx_word16_t gc;
1065 spx_word32_t scale;
1066 int qgc = speex_bits_unpack_unsigned(bits, 4);
1067
1068 el = low_exc_rms[sub];
1069 gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]);
1070
1071 if (st->subframeSize==80)
1072 gc = MULT16_16_P14(QCONST16(1.4142f,14),gc);
1073
1074 scale = SHL32(PDIV32(SHL32(MULT16_16(gc, el),3), filter_ratio),SIG_SHIFT-3);
1075 SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize,
1076 bits, stack, &st->seed);
1077
1078 signal_mul(exc,exc,scale,st->subframeSize);
1079
1080 if (SUBMODE(double_codebook)) {
1081 char *tmp_stack=stack;
1082 VARDECL(spx_sig_t *innov2);
1083 ALLOC(innov2, st->subframeSize, spx_sig_t);
1084 SPEEX_MEMSET(innov2, 0, st->subframeSize);
1085 SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize,
1086 bits, stack, &st->seed);
1087 signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize);
1088 for (i=0;i<st->subframeSize;i++)
1089 exc[i] = ADD32(exc[i],innov2[i]);
1090 stack = tmp_stack;
1091 }
1092
1093 }
1094
1095 if (st->innov_save)
1096 {
1097 for (i=0;i<st->subframeSize;i++)
1098 innov_save[2*i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT));
1099 }
1100
1101 iir_mem16(st->excBuf, st->interp_qlpc, sp, st->subframeSize, st->lpcSize,
1102 st->mem_sp, stack);
1103 for (i=0;i<st->subframeSize;i++)
1104 st->excBuf[i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT));
1105 for (i=0;i<st->lpcSize;i++)
1106 st->interp_qlpc[i] = ak[i];
1107 st->exc_rms[sub] = compute_rms16(st->excBuf, st->subframeSize);
1108 exc_ener_sum = ADD32(exc_ener_sum, DIV32(MULT16_16(st->exc_rms[sub],st->exc_rms[sub]), st->nbSubframes));
1109 }
1110 st->last_ener = spx_sqrt(exc_ener_sum);
1111
1112 qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
1113 for (i=0;i<st->lpcSize;i++)
1114 st->old_qlsp[i] = qlsp[i];
1115
1116 st->first=0;
1117
1118 return 0;
1119}
1120
1121#ifndef SPEEX_DISABLE_ENCODER
1122int sb_encoder_ctl(void *state, int request, void *ptr)
1123{
1124 SBEncState *st;
1125 st=(SBEncState*)state;
1126 switch(request)
1127 {
1128 case SPEEX_GET_FRAME_SIZE:
1129 (*(spx_int32_t*)ptr) = st->full_frame_size;
1130 break;
1131 case SPEEX_SET_HIGH_MODE:
1132 st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr);
1133 break;
1134 case SPEEX_SET_LOW_MODE:
1135 speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
1136 break;
1137 case SPEEX_SET_DTX:
1138 speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr);
1139 break;
1140 case SPEEX_GET_DTX:
1141 speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr);
1142 break;
1143 case SPEEX_GET_LOW_MODE:
1144 speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
1145 break;
1146 case SPEEX_SET_MODE:
1147 speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr);
1148 break;
1149#ifndef DISABLE_VBR
1150 case SPEEX_SET_VBR:
1151 st->vbr_enabled = (*(spx_int32_t*)ptr);
1152 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr);
1153 break;
1154 case SPEEX_GET_VBR:
1155 (*(spx_int32_t*)ptr) = st->vbr_enabled;
1156 break;
1157 case SPEEX_SET_VAD:
1158 st->vad_enabled = (*(spx_int32_t*)ptr);
1159 speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr);
1160 break;
1161 case SPEEX_GET_VAD:
1162 (*(spx_int32_t*)ptr) = st->vad_enabled;
1163 break;
1164#endif /* #ifndef DISABLE_VBR */
1165#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
1166 case SPEEX_SET_VBR_QUALITY:
1167 {
1168 spx_int32_t q;
1169 float qual = (*(float*)ptr)+.6;
1170 st->vbr_quality = (*(float*)ptr);
1171 if (qual>10)
1172 qual=10;
1173 q=(int)floor(.5+*(float*)ptr);
1174 if (q>10)
1175 q=10;
1176 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual);
1177 speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q);
1178 break;
1179 }
1180 case SPEEX_GET_VBR_QUALITY:
1181 (*(float*)ptr) = st->vbr_quality;
1182 break;
1183#endif /* #if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
1184#ifndef DISABLE_VBR
1185 case SPEEX_SET_ABR:
1186 st->abr_enabled = (*(spx_int32_t*)ptr);
1187 st->vbr_enabled = st->abr_enabled!=0;
1188 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled);
1189 if (st->vbr_enabled)
1190 {
1191 spx_int32_t i=10, rate, target;
1192 float vbr_qual;
1193 target = (*(spx_int32_t*)ptr);
1194 while (i>=0)
1195 {
1196 speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
1197 speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
1198 if (rate <= target)
1199 break;
1200 i--;
1201 }
1202 vbr_qual=i;
1203 if (vbr_qual<0)
1204 vbr_qual=0;
1205 speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
1206 st->abr_count=0;
1207 st->abr_drift=0;
1208 st->abr_drift2=0;
1209 }
1210
1211 break;
1212 case SPEEX_GET_ABR:
1213 (*(spx_int32_t*)ptr) = st->abr_enabled;
1214 break;
1215#endif /* #ifndef DISABLE_VBR */
1216
1217 case SPEEX_SET_QUALITY:
1218 {
1219 spx_int32_t nb_qual;
1220 int quality = (*(spx_int32_t*)ptr);
1221 if (quality < 0)
1222 quality = 0;
1223 if (quality > 10)
1224 quality = 10;
1225 st->submodeSelect = st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];
1226 nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
1227 speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
1228 }
1229 break;
1230 case SPEEX_SET_COMPLEXITY:
1231 speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr);
1232 st->complexity = (*(spx_int32_t*)ptr);
1233 if (st->complexity<1)
1234 st->complexity=1;
1235 break;
1236 case SPEEX_GET_COMPLEXITY:
1237 (*(spx_int32_t*)ptr) = st->complexity;
1238 break;
1239 case SPEEX_SET_BITRATE:
1240 {
1241 spx_int32_t i=10;
1242 spx_int32_t rate, target;
1243 target = (*(spx_int32_t*)ptr);
1244 while (i>=0)
1245 {
1246 speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
1247 speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
1248 if (rate <= target)
1249 break;
1250 i--;
1251 }
1252 }
1253 break;
1254 case SPEEX_GET_BITRATE:
1255 speex_encoder_ctl(st->st_low, request, ptr);
1256 /*fprintf (stderr, "before: %d\n", (*(int*)ptr));*/
1257 if (st->submodes[st->submodeID])
1258 (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
1259 else
1260 (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
1261 /*fprintf (stderr, "after: %d\n", (*(int*)ptr));*/
1262 break;
1263 case SPEEX_SET_SAMPLING_RATE:
1264 {
1265 spx_int32_t tmp=(*(spx_int32_t*)ptr);
1266 st->sampling_rate = tmp;
1267 tmp>>=1;
1268 speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
1269 }
1270 break;
1271 case SPEEX_GET_SAMPLING_RATE:
1272 (*(spx_int32_t*)ptr)=st->sampling_rate;
1273 break;
1274 case SPEEX_RESET_STATE:
1275 {
1276 int i;
1277 st->first = 1;
1278 for (i=0;i<st->lpcSize;i++)
1279 st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
1280 for (i=0;i<st->lpcSize;i++)
1281 st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0;
1282 for (i=0;i<QMF_ORDER;i++)
1283 st->h0_mem[i]=st->h1_mem[i]=0;
1284 }
1285 break;
1286 case SPEEX_SET_SUBMODE_ENCODING:
1287 st->encode_submode = (*(spx_int32_t*)ptr);
1288 speex_encoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr);
1289 break;
1290 case SPEEX_GET_SUBMODE_ENCODING:
1291 (*(spx_int32_t*)ptr) = st->encode_submode;
1292 break;
1293 case SPEEX_GET_LOOKAHEAD:
1294 speex_encoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);
1295 (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr) + QMF_ORDER - 1;
1296 break;
1297 case SPEEX_SET_PLC_TUNING:
1298 speex_encoder_ctl(st->st_low, SPEEX_SET_PLC_TUNING, ptr);
1299 break;
1300 case SPEEX_GET_PLC_TUNING:
1301 speex_encoder_ctl(st->st_low, SPEEX_GET_PLC_TUNING, ptr);
1302 break;
1303#ifndef DISABLE_VBR
1304 case SPEEX_SET_VBR_MAX_BITRATE:
1305 {
1306 st->vbr_max = (*(spx_int32_t*)ptr);
1307 if (SPEEX_SET_VBR_MAX_BITRATE<1)
1308 {
1309 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &st->vbr_max);
1310 st->vbr_max_high = 17600;
1311 } else {
1312 spx_int32_t low_rate;
1313 if (st->vbr_max >= 42200)
1314 {
1315 st->vbr_max_high = 17600;
1316 } else if (st->vbr_max >= 27800)
1317 {
1318 st->vbr_max_high = 9600;
1319 } else if (st->vbr_max > 20600)
1320 {
1321 st->vbr_max_high = 5600;
1322 } else {
1323 st->vbr_max_high = 1800;
1324 }
1325 if (st->subframeSize==80)
1326 st->vbr_max_high = 1800;
1327 low_rate = st->vbr_max - st->vbr_max_high;
1328 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &low_rate);
1329 }
1330 }
1331 break;
1332 case SPEEX_GET_VBR_MAX_BITRATE:
1333 (*(spx_int32_t*)ptr) = st->vbr_max;
1334 break;
1335#endif /* #ifndef DISABLE_VBR */
1336 case SPEEX_SET_HIGHPASS:
1337 speex_encoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);
1338 break;
1339 case SPEEX_GET_HIGHPASS:
1340 speex_encoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);
1341 break;
1342
1343
1344 /* This is all internal stuff past this point */
1345 case SPEEX_GET_PI_GAIN:
1346 {
1347 int i;
1348 spx_word32_t *g = (spx_word32_t*)ptr;
1349 for (i=0;i<st->nbSubframes;i++)
1350 g[i]=st->pi_gain[i];
1351 }
1352 break;
1353 case SPEEX_GET_EXC:
1354 {
1355 int i;
1356 for (i=0;i<st->nbSubframes;i++)
1357 ((spx_word16_t*)ptr)[i] = st->exc_rms[i];
1358 }
1359 break;
1360#ifndef DISABLE_VBR
1361 case SPEEX_GET_RELATIVE_QUALITY:
1362 (*(float*)ptr)=st->relative_quality;
1363 break;
1364#endif /* #ifndef DISABLE_VBR */
1365 case SPEEX_SET_INNOVATION_SAVE:
1366 st->innov_rms_save = (spx_word16_t*)ptr;
1367 break;
1368 case SPEEX_SET_WIDEBAND:
1369 speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);
1370 break;
1371 case SPEEX_GET_STACK:
1372 *((char**)ptr) = st->stack;
1373 break;
1374 default:
1375 speex_warning_int("Unknown nb_ctl request: ", request);
1376 return -1;
1377 }
1378 return 0;
1379}
1380#endif /* SPEEX_DISABLE_ENCODER */
1381
1382int sb_decoder_ctl(void *state, int request, void *ptr)
1383{
1384 SBDecState *st;
1385 st=(SBDecState*)state;
1386 switch(request)
1387 {
1388 case SPEEX_SET_HIGH_MODE:
1389 st->submodeID = (*(spx_int32_t*)ptr);
1390 break;
1391 case SPEEX_SET_LOW_MODE:
1392 speex_decoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
1393 break;
1394 case SPEEX_GET_LOW_MODE:
1395 speex_decoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
1396 break;
1397 case SPEEX_GET_FRAME_SIZE:
1398 (*(spx_int32_t*)ptr) = st->full_frame_size;
1399 break;
1400 case SPEEX_SET_ENH:
1401 speex_decoder_ctl(st->st_low, request, ptr);
1402 st->lpc_enh_enabled = *((spx_int32_t*)ptr);
1403 break;
1404 case SPEEX_GET_ENH:
1405 *((spx_int32_t*)ptr) = st->lpc_enh_enabled;
1406 break;
1407 case SPEEX_SET_MODE:
1408 case SPEEX_SET_QUALITY:
1409 {
1410 spx_int32_t nb_qual;
1411 int quality = (*(spx_int32_t*)ptr);
1412 if (quality < 0)
1413 quality = 0;
1414 if (quality > 10)
1415 quality = 10;
1416 st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];
1417 nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
1418 speex_decoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
1419 }
1420 break;
1421 case SPEEX_GET_BITRATE:
1422 speex_decoder_ctl(st->st_low, request, ptr);
1423 if (st->submodes[st->submodeID])
1424 (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
1425 else
1426 (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
1427 break;
1428 case SPEEX_SET_SAMPLING_RATE:
1429 {
1430 spx_int32_t tmp=(*(spx_int32_t*)ptr);
1431 st->sampling_rate = tmp;
1432 tmp>>=1;
1433 speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
1434 }
1435 break;
1436 case SPEEX_GET_SAMPLING_RATE:
1437 (*(spx_int32_t*)ptr)=st->sampling_rate;
1438 break;
1439 case SPEEX_SET_HANDLER:
1440 speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr);
1441 break;
1442 case SPEEX_SET_USER_HANDLER:
1443 speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr);
1444 break;
1445 case SPEEX_RESET_STATE:
1446 {
1447 int i;
1448 for (i=0;i<2*st->lpcSize;i++)
1449 st->mem_sp[i]=0;
1450 for (i=0;i<QMF_ORDER;i++)
1451 st->g0_mem[i]=st->g1_mem[i]=0;
1452 st->last_ener=0;
1453 }
1454 break;
1455 case SPEEX_SET_SUBMODE_ENCODING:
1456 st->encode_submode = (*(spx_int32_t*)ptr);
1457 speex_decoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr);
1458 break;
1459 case SPEEX_GET_SUBMODE_ENCODING:
1460 (*(spx_int32_t*)ptr) = st->encode_submode;
1461 break;
1462 case SPEEX_GET_LOOKAHEAD:
1463 speex_decoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);
1464 (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr);
1465 break;
1466 case SPEEX_SET_HIGHPASS:
1467 speex_decoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);
1468 break;
1469 case SPEEX_GET_HIGHPASS:
1470 speex_decoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);
1471 break;
1472 case SPEEX_GET_ACTIVITY:
1473 speex_decoder_ctl(st->st_low, SPEEX_GET_ACTIVITY, ptr);
1474 break;
1475 case SPEEX_GET_PI_GAIN:
1476 {
1477 int i;
1478 spx_word32_t *g = (spx_word32_t*)ptr;
1479 for (i=0;i<st->nbSubframes;i++)
1480 g[i]=st->pi_gain[i];
1481 }
1482 break;
1483 case SPEEX_GET_EXC:
1484 {
1485 int i;
1486 for (i=0;i<st->nbSubframes;i++)
1487 ((spx_word16_t*)ptr)[i] = st->exc_rms[i];
1488 }
1489 break;
1490 case SPEEX_GET_DTX_STATUS:
1491 speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr);
1492 break;
1493 case SPEEX_SET_INNOVATION_SAVE:
1494 st->innov_save = (spx_word16_t*)ptr;
1495 break;
1496 case SPEEX_SET_WIDEBAND:
1497 speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);
1498 break;
1499 case SPEEX_GET_STACK:
1500 *((char**)ptr) = st->stack;
1501 break;
1502 default:
1503 speex_warning_int("Unknown nb_ctl request: ", request);
1504 return -1;
1505 }
1506 return 0;
1507}
1508
1509#endif
1510
diff --git a/lib/rbcodec/codecs/libspeex/sb_celp.h b/lib/rbcodec/codecs/libspeex/sb_celp.h
new file mode 100644
index 0000000000..5a65d1ff8d
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/sb_celp.h
@@ -0,0 +1,160 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin */
2/**
3 @file sb_celp.h
4 @brief Sub-band CELP mode used for wideband encoding
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#ifndef SB_CELP_H
37#define SB_CELP_H
38
39#include "modes.h"
40#include "speex/speex_bits.h"
41#include "nb_celp.h"
42
43/**Structure representing the full state of the sub-band encoder*/
44typedef struct SBEncState {
45 const SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */
46 void *st_low; /**< State of the low-band (narrowband) encoder */
47 int full_frame_size; /**< Length of full-band frames*/
48 int frame_size; /**< Length of high-band frames*/
49 int subframeSize; /**< Length of high-band sub-frames*/
50 int nbSubframes; /**< Number of high-band sub-frames*/
51 int windowSize; /**< Length of high-band LPC window*/
52 int lpcSize; /**< Order of high-band LPC analysis */
53 int first; /**< First frame? */
54 spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */
55 spx_word16_t gamma1; /**< Perceptual weighting coef 1 */
56 spx_word16_t gamma2; /**< Perceptual weighting coef 2 */
57
58 char *stack; /**< Temporary allocation stack */
59 spx_word16_t *high; /**< High-band signal (buffer) */
60 spx_word16_t *h0_mem, *h1_mem;
61
62 const spx_word16_t *window; /**< LPC analysis window */
63 const spx_word16_t *lagWindow; /**< Auto-correlation window */
64 spx_lsp_t *old_lsp; /**< LSPs of previous frame */
65 spx_lsp_t *old_qlsp; /**< Quantized LSPs of previous frame */
66 spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */
67
68 spx_mem_t *mem_sp; /**< Synthesis signal memory */
69 spx_mem_t *mem_sp2;
70 spx_mem_t *mem_sw; /**< Perceptual signal memory */
71 spx_word32_t *pi_gain;
72 spx_word16_t *exc_rms;
73 spx_word16_t *innov_rms_save; /**< If non-NULL, innovation is copied here */
74
75#ifndef DISABLE_VBR
76 float vbr_quality; /**< Quality setting for VBR encoding */
77 int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */
78 spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode (total) */
79 spx_int32_t vbr_max_high; /**< Max bit-rate allowed in VBR mode for the high-band */
80 spx_int32_t abr_enabled; /**< ABR setting (in bps), 0 if off */
81 float abr_drift;
82 float abr_drift2;
83 float abr_count;
84 int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */
85 float relative_quality;
86#endif /* #ifndef DISABLE_VBR */
87
88 int encode_submode;
89 const SpeexSubmode * const *submodes;
90 int submodeID;
91 int submodeSelect;
92 int complexity;
93 spx_int32_t sampling_rate;
94
95} SBEncState;
96
97
98/**Structure representing the full state of the sub-band decoder*/
99typedef struct SBDecState {
100 const SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */
101 void *st_low; /**< State of the low-band (narrowband) encoder */
102 int full_frame_size;
103 int frame_size;
104 int subframeSize;
105 int nbSubframes;
106 int lpcSize;
107 int first;
108 spx_int32_t sampling_rate;
109 int lpc_enh_enabled;
110
111 char *stack;
112 spx_word16_t g0_mem[64], g1_mem[64];
113
114/* Voice codec files will be WB mode, which has sub frame size of 40 */
115#ifndef ROCKBOX_VOICE_CODEC
116 spx_word16_t excBuf[80];
117#else
118 spx_word16_t excBuf[40];
119#endif
120 spx_lsp_t old_qlsp[8];
121 spx_coef_t interp_qlpc[8];
122
123 spx_mem_t mem_sp[16];
124 spx_word32_t pi_gain[4];
125 spx_word16_t exc_rms[4];
126 spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */
127
128 spx_word16_t last_ener;
129 spx_int32_t seed;
130
131 int encode_submode;
132 const SpeexSubmode * const *submodes;
133 int submodeID;
134} SBDecState;
135
136
137/**Initializes encoder state*/
138void *sb_encoder_init(const SpeexMode *m);
139
140/**De-allocates encoder state resources*/
141void sb_encoder_destroy(void *state);
142
143/**Encodes one frame*/
144int sb_encode(void *state, void *in, SpeexBits *bits);
145
146
147/**Initializes decoder state*/
148void *sb_decoder_init(const SpeexMode *m);
149
150/**De-allocates decoder state resources*/
151void sb_decoder_destroy(void *state);
152
153/**Decodes one frame*/
154int sb_decode(void *state, SpeexBits *bits, void *out);
155
156int sb_encoder_ctl(void *state, int request, void *ptr);
157
158int sb_decoder_ctl(void *state, int request, void *ptr);
159
160#endif
diff --git a/lib/rbcodec/codecs/libspeex/smallft.c b/lib/rbcodec/codecs/libspeex/smallft.c
new file mode 100644
index 0000000000..6e3a927b5f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/smallft.c
@@ -0,0 +1,1261 @@
1/********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
9 * by the XIPHOPHORUS Company http://www.xiph.org/ *
10 * *
11 ********************************************************************
12
13 function: *unnormalized* fft transform
14 last mod: $Id$
15
16 ********************************************************************/
17
18/* FFT implementation from OggSquish, minus cosine transforms,
19 * minus all but radix 2/4 case. In Vorbis we only need this
20 * cut-down version.
21 *
22 * To do more than just power-of-two sized vectors, see the full
23 * version I wrote for NetLib.
24 *
25 * Note that the packing is a little strange; rather than the FFT r/i
26 * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1,
27 * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the
28 * FORTRAN version
29 */
30
31#ifdef HAVE_CONFIG_H
32#include "config-speex.h"
33#endif
34
35#include <math.h>
36#include "smallft.h"
37#include "arch.h"
38#include "os_support.h"
39
40static void drfti1(int n, float *wa, int *ifac){
41 static int ntryh[4] = { 4,2,3,5 };
42 static float tpi = 6.28318530717958648f;
43 float arg,argh,argld,fi;
44 int ntry=0,i,j=-1;
45 int k1, l1, l2, ib;
46 int ld, ii, ip, is, nq, nr;
47 int ido, ipm, nfm1;
48 int nl=n;
49 int nf=0;
50
51 L101:
52 j++;
53 if (j < 4)
54 ntry=ntryh[j];
55 else
56 ntry+=2;
57
58 L104:
59 nq=nl/ntry;
60 nr=nl-ntry*nq;
61 if (nr!=0) goto L101;
62
63 nf++;
64 ifac[nf+1]=ntry;
65 nl=nq;
66 if(ntry!=2)goto L107;
67 if(nf==1)goto L107;
68
69 for (i=1;i<nf;i++){
70 ib=nf-i+1;
71 ifac[ib+1]=ifac[ib];
72 }
73 ifac[2] = 2;
74
75 L107:
76 if(nl!=1)goto L104;
77 ifac[0]=n;
78 ifac[1]=nf;
79 argh=tpi/n;
80 is=0;
81 nfm1=nf-1;
82 l1=1;
83
84 if(nfm1==0)return;
85
86 for (k1=0;k1<nfm1;k1++){
87 ip=ifac[k1+2];
88 ld=0;
89 l2=l1*ip;
90 ido=n/l2;
91 ipm=ip-1;
92
93 for (j=0;j<ipm;j++){
94 ld+=l1;
95 i=is;
96 argld=(float)ld*argh;
97 fi=0.f;
98 for (ii=2;ii<ido;ii+=2){
99 fi+=1.f;
100 arg=fi*argld;
101 wa[i++]=cos(arg);
102 wa[i++]=sin(arg);
103 }
104 is+=ido;
105 }
106 l1=l2;
107 }
108}
109
110static void fdrffti(int n, float *wsave, int *ifac){
111
112 if (n == 1) return;
113 drfti1(n, wsave+n, ifac);
114}
115
116static void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){
117 int i,k;
118 float ti2,tr2;
119 int t0,t1,t2,t3,t4,t5,t6;
120
121 t1=0;
122 t0=(t2=l1*ido);
123 t3=ido<<1;
124 for(k=0;k<l1;k++){
125 ch[t1<<1]=cc[t1]+cc[t2];
126 ch[(t1<<1)+t3-1]=cc[t1]-cc[t2];
127 t1+=ido;
128 t2+=ido;
129 }
130
131 if(ido<2)return;
132 if(ido==2)goto L105;
133
134 t1=0;
135 t2=t0;
136 for(k=0;k<l1;k++){
137 t3=t2;
138 t4=(t1<<1)+(ido<<1);
139 t5=t1;
140 t6=t1+t1;
141 for(i=2;i<ido;i+=2){
142 t3+=2;
143 t4-=2;
144 t5+=2;
145 t6+=2;
146 tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
147 ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
148 ch[t6]=cc[t5]+ti2;
149 ch[t4]=ti2-cc[t5];
150 ch[t6-1]=cc[t5-1]+tr2;
151 ch[t4-1]=cc[t5-1]-tr2;
152 }
153 t1+=ido;
154 t2+=ido;
155 }
156
157 if(ido%2==1)return;
158
159 L105:
160 t3=(t2=(t1=ido)-1);
161 t2+=t0;
162 for(k=0;k<l1;k++){
163 ch[t1]=-cc[t2];
164 ch[t1-1]=cc[t3];
165 t1+=ido<<1;
166 t2+=ido;
167 t3+=ido;
168 }
169}
170
171static void dradf4(int ido,int l1,float *cc,float *ch,float *wa1,
172 float *wa2,float *wa3){
173 static float hsqt2 = .70710678118654752f;
174 int i,k,t0,t1,t2,t3,t4,t5,t6;
175 float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
176 t0=l1*ido;
177
178 t1=t0;
179 t4=t1<<1;
180 t2=t1+(t1<<1);
181 t3=0;
182
183 for(k=0;k<l1;k++){
184 tr1=cc[t1]+cc[t2];
185 tr2=cc[t3]+cc[t4];
186
187 ch[t5=t3<<2]=tr1+tr2;
188 ch[(ido<<2)+t5-1]=tr2-tr1;
189 ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4];
190 ch[t5]=cc[t2]-cc[t1];
191
192 t1+=ido;
193 t2+=ido;
194 t3+=ido;
195 t4+=ido;
196 }
197
198 if(ido<2)return;
199 if(ido==2)goto L105;
200
201
202 t1=0;
203 for(k=0;k<l1;k++){
204 t2=t1;
205 t4=t1<<2;
206 t5=(t6=ido<<1)+t4;
207 for(i=2;i<ido;i+=2){
208 t3=(t2+=2);
209 t4+=2;
210 t5-=2;
211
212 t3+=t0;
213 cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
214 ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
215 t3+=t0;
216 cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3];
217 ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1];
218 t3+=t0;
219 cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3];
220 ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1];
221
222 tr1=cr2+cr4;
223 tr4=cr4-cr2;
224 ti1=ci2+ci4;
225 ti4=ci2-ci4;
226
227 ti2=cc[t2]+ci3;
228 ti3=cc[t2]-ci3;
229 tr2=cc[t2-1]+cr3;
230 tr3=cc[t2-1]-cr3;
231
232 ch[t4-1]=tr1+tr2;
233 ch[t4]=ti1+ti2;
234
235 ch[t5-1]=tr3-ti4;
236 ch[t5]=tr4-ti3;
237
238 ch[t4+t6-1]=ti4+tr3;
239 ch[t4+t6]=tr4+ti3;
240
241 ch[t5+t6-1]=tr2-tr1;
242 ch[t5+t6]=ti1-ti2;
243 }
244 t1+=ido;
245 }
246 if(ido&1)return;
247
248 L105:
249
250 t2=(t1=t0+ido-1)+(t0<<1);
251 t3=ido<<2;
252 t4=ido;
253 t5=ido<<1;
254 t6=ido;
255
256 for(k=0;k<l1;k++){
257 ti1=-hsqt2*(cc[t1]+cc[t2]);
258 tr1=hsqt2*(cc[t1]-cc[t2]);
259
260 ch[t4-1]=tr1+cc[t6-1];
261 ch[t4+t5-1]=cc[t6-1]-tr1;
262
263 ch[t4]=ti1-cc[t1+t0];
264 ch[t4+t5]=ti1+cc[t1+t0];
265
266 t1+=ido;
267 t2+=ido;
268 t4+=t3;
269 t6+=ido;
270 }
271}
272
273static void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
274 float *c2,float *ch,float *ch2,float *wa){
275
276 static float tpi=6.283185307179586f;
277 int idij,ipph,i,j,k,l,ic,ik,is;
278 int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
279 float dc2,ai1,ai2,ar1,ar2,ds2;
280 int nbd;
281 float dcp,arg,dsp,ar1h,ar2h;
282 int idp2,ipp2;
283
284 arg=tpi/(float)ip;
285 dcp=cos(arg);
286 dsp=sin(arg);
287 ipph=(ip+1)>>1;
288 ipp2=ip;
289 idp2=ido;
290 nbd=(ido-1)>>1;
291 t0=l1*ido;
292 t10=ip*ido;
293
294 if(ido==1)goto L119;
295 for(ik=0;ik<idl1;ik++)ch2[ik]=c2[ik];
296
297 t1=0;
298 for(j=1;j<ip;j++){
299 t1+=t0;
300 t2=t1;
301 for(k=0;k<l1;k++){
302 ch[t2]=c1[t2];
303 t2+=ido;
304 }
305 }
306
307 is=-ido;
308 t1=0;
309 if(nbd>l1){
310 for(j=1;j<ip;j++){
311 t1+=t0;
312 is+=ido;
313 t2= -ido+t1;
314 for(k=0;k<l1;k++){
315 idij=is-1;
316 t2+=ido;
317 t3=t2;
318 for(i=2;i<ido;i+=2){
319 idij+=2;
320 t3+=2;
321 ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
322 ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
323 }
324 }
325 }
326 }else{
327
328 for(j=1;j<ip;j++){
329 is+=ido;
330 idij=is-1;
331 t1+=t0;
332 t2=t1;
333 for(i=2;i<ido;i+=2){
334 idij+=2;
335 t2+=2;
336 t3=t2;
337 for(k=0;k<l1;k++){
338 ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
339 ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
340 t3+=ido;
341 }
342 }
343 }
344 }
345
346 t1=0;
347 t2=ipp2*t0;
348 if(nbd<l1){
349 for(j=1;j<ipph;j++){
350 t1+=t0;
351 t2-=t0;
352 t3=t1;
353 t4=t2;
354 for(i=2;i<ido;i+=2){
355 t3+=2;
356 t4+=2;
357 t5=t3-ido;
358 t6=t4-ido;
359 for(k=0;k<l1;k++){
360 t5+=ido;
361 t6+=ido;
362 c1[t5-1]=ch[t5-1]+ch[t6-1];
363 c1[t6-1]=ch[t5]-ch[t6];
364 c1[t5]=ch[t5]+ch[t6];
365 c1[t6]=ch[t6-1]-ch[t5-1];
366 }
367 }
368 }
369 }else{
370 for(j=1;j<ipph;j++){
371 t1+=t0;
372 t2-=t0;
373 t3=t1;
374 t4=t2;
375 for(k=0;k<l1;k++){
376 t5=t3;
377 t6=t4;
378 for(i=2;i<ido;i+=2){
379 t5+=2;
380 t6+=2;
381 c1[t5-1]=ch[t5-1]+ch[t6-1];
382 c1[t6-1]=ch[t5]-ch[t6];
383 c1[t5]=ch[t5]+ch[t6];
384 c1[t6]=ch[t6-1]-ch[t5-1];
385 }
386 t3+=ido;
387 t4+=ido;
388 }
389 }
390 }
391
392L119:
393 for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
394
395 t1=0;
396 t2=ipp2*idl1;
397 for(j=1;j<ipph;j++){
398 t1+=t0;
399 t2-=t0;
400 t3=t1-ido;
401 t4=t2-ido;
402 for(k=0;k<l1;k++){
403 t3+=ido;
404 t4+=ido;
405 c1[t3]=ch[t3]+ch[t4];
406 c1[t4]=ch[t4]-ch[t3];
407 }
408 }
409
410 ar1=1.f;
411 ai1=0.f;
412 t1=0;
413 t2=ipp2*idl1;
414 t3=(ip-1)*idl1;
415 for(l=1;l<ipph;l++){
416 t1+=idl1;
417 t2-=idl1;
418 ar1h=dcp*ar1-dsp*ai1;
419 ai1=dcp*ai1+dsp*ar1;
420 ar1=ar1h;
421 t4=t1;
422 t5=t2;
423 t6=t3;
424 t7=idl1;
425
426 for(ik=0;ik<idl1;ik++){
427 ch2[t4++]=c2[ik]+ar1*c2[t7++];
428 ch2[t5++]=ai1*c2[t6++];
429 }
430
431 dc2=ar1;
432 ds2=ai1;
433 ar2=ar1;
434 ai2=ai1;
435
436 t4=idl1;
437 t5=(ipp2-1)*idl1;
438 for(j=2;j<ipph;j++){
439 t4+=idl1;
440 t5-=idl1;
441
442 ar2h=dc2*ar2-ds2*ai2;
443 ai2=dc2*ai2+ds2*ar2;
444 ar2=ar2h;
445
446 t6=t1;
447 t7=t2;
448 t8=t4;
449 t9=t5;
450 for(ik=0;ik<idl1;ik++){
451 ch2[t6++]+=ar2*c2[t8++];
452 ch2[t7++]+=ai2*c2[t9++];
453 }
454 }
455 }
456
457 t1=0;
458 for(j=1;j<ipph;j++){
459 t1+=idl1;
460 t2=t1;
461 for(ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++];
462 }
463
464 if(ido<l1)goto L132;
465
466 t1=0;
467 t2=0;
468 for(k=0;k<l1;k++){
469 t3=t1;
470 t4=t2;
471 for(i=0;i<ido;i++)cc[t4++]=ch[t3++];
472 t1+=ido;
473 t2+=t10;
474 }
475
476 goto L135;
477
478 L132:
479 for(i=0;i<ido;i++){
480 t1=i;
481 t2=i;
482 for(k=0;k<l1;k++){
483 cc[t2]=ch[t1];
484 t1+=ido;
485 t2+=t10;
486 }
487 }
488
489 L135:
490 t1=0;
491 t2=ido<<1;
492 t3=0;
493 t4=ipp2*t0;
494 for(j=1;j<ipph;j++){
495
496 t1+=t2;
497 t3+=t0;
498 t4-=t0;
499
500 t5=t1;
501 t6=t3;
502 t7=t4;
503
504 for(k=0;k<l1;k++){
505 cc[t5-1]=ch[t6];
506 cc[t5]=ch[t7];
507 t5+=t10;
508 t6+=ido;
509 t7+=ido;
510 }
511 }
512
513 if(ido==1)return;
514 if(nbd<l1)goto L141;
515
516 t1=-ido;
517 t3=0;
518 t4=0;
519 t5=ipp2*t0;
520 for(j=1;j<ipph;j++){
521 t1+=t2;
522 t3+=t2;
523 t4+=t0;
524 t5-=t0;
525 t6=t1;
526 t7=t3;
527 t8=t4;
528 t9=t5;
529 for(k=0;k<l1;k++){
530 for(i=2;i<ido;i+=2){
531 ic=idp2-i;
532 cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1];
533 cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1];
534 cc[i+t7]=ch[i+t8]+ch[i+t9];
535 cc[ic+t6]=ch[i+t9]-ch[i+t8];
536 }
537 t6+=t10;
538 t7+=t10;
539 t8+=ido;
540 t9+=ido;
541 }
542 }
543 return;
544
545 L141:
546
547 t1=-ido;
548 t3=0;
549 t4=0;
550 t5=ipp2*t0;
551 for(j=1;j<ipph;j++){
552 t1+=t2;
553 t3+=t2;
554 t4+=t0;
555 t5-=t0;
556 for(i=2;i<ido;i+=2){
557 t6=idp2+t1-i;
558 t7=i+t3;
559 t8=i+t4;
560 t9=i+t5;
561 for(k=0;k<l1;k++){
562 cc[t7-1]=ch[t8-1]+ch[t9-1];
563 cc[t6-1]=ch[t8-1]-ch[t9-1];
564 cc[t7]=ch[t8]+ch[t9];
565 cc[t6]=ch[t9]-ch[t8];
566 t6+=t10;
567 t7+=t10;
568 t8+=ido;
569 t9+=ido;
570 }
571 }
572 }
573}
574
575static void drftf1(int n,float *c,float *ch,float *wa,int *ifac){
576 int i,k1,l1,l2;
577 int na,kh,nf;
578 int ip,iw,ido,idl1,ix2,ix3;
579
580 nf=ifac[1];
581 na=1;
582 l2=n;
583 iw=n;
584
585 for(k1=0;k1<nf;k1++){
586 kh=nf-k1;
587 ip=ifac[kh+1];
588 l1=l2/ip;
589 ido=n/l2;
590 idl1=ido*l1;
591 iw-=(ip-1)*ido;
592 na=1-na;
593
594 if(ip!=4)goto L102;
595
596 ix2=iw+ido;
597 ix3=ix2+ido;
598 if(na!=0)
599 dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
600 else
601 dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
602 goto L110;
603
604 L102:
605 if(ip!=2)goto L104;
606 if(na!=0)goto L103;
607
608 dradf2(ido,l1,c,ch,wa+iw-1);
609 goto L110;
610
611 L103:
612 dradf2(ido,l1,ch,c,wa+iw-1);
613 goto L110;
614
615 L104:
616 if(ido==1)na=1-na;
617 if(na!=0)goto L109;
618
619 dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
620 na=1;
621 goto L110;
622
623 L109:
624 dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
625 na=0;
626
627 L110:
628 l2=l1;
629 }
630
631 if(na==1)return;
632
633 for(i=0;i<n;i++)c[i]=ch[i];
634}
635
636static void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){
637 int i,k,t0,t1,t2,t3,t4,t5,t6;
638 float ti2,tr2;
639
640 t0=l1*ido;
641
642 t1=0;
643 t2=0;
644 t3=(ido<<1)-1;
645 for(k=0;k<l1;k++){
646 ch[t1]=cc[t2]+cc[t3+t2];
647 ch[t1+t0]=cc[t2]-cc[t3+t2];
648 t2=(t1+=ido)<<1;
649 }
650
651 if(ido<2)return;
652 if(ido==2)goto L105;
653
654 t1=0;
655 t2=0;
656 for(k=0;k<l1;k++){
657 t3=t1;
658 t5=(t4=t2)+(ido<<1);
659 t6=t0+t1;
660 for(i=2;i<ido;i+=2){
661 t3+=2;
662 t4+=2;
663 t5-=2;
664 t6+=2;
665 ch[t3-1]=cc[t4-1]+cc[t5-1];
666 tr2=cc[t4-1]-cc[t5-1];
667 ch[t3]=cc[t4]-cc[t5];
668 ti2=cc[t4]+cc[t5];
669 ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2;
670 ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2;
671 }
672 t2=(t1+=ido)<<1;
673 }
674
675 if(ido%2==1)return;
676
677L105:
678 t1=ido-1;
679 t2=ido-1;
680 for(k=0;k<l1;k++){
681 ch[t1]=cc[t2]+cc[t2];
682 ch[t1+t0]=-(cc[t2+1]+cc[t2+1]);
683 t1+=ido;
684 t2+=ido<<1;
685 }
686}
687
688static void dradb3(int ido,int l1,float *cc,float *ch,float *wa1,
689 float *wa2){
690 static float taur = -.5f;
691 static float taui = .8660254037844386f;
692 int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
693 float ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2;
694 t0=l1*ido;
695
696 t1=0;
697 t2=t0<<1;
698 t3=ido<<1;
699 t4=ido+(ido<<1);
700 t5=0;
701 for(k=0;k<l1;k++){
702 tr2=cc[t3-1]+cc[t3-1];
703 cr2=cc[t5]+(taur*tr2);
704 ch[t1]=cc[t5]+tr2;
705 ci3=taui*(cc[t3]+cc[t3]);
706 ch[t1+t0]=cr2-ci3;
707 ch[t1+t2]=cr2+ci3;
708 t1+=ido;
709 t3+=t4;
710 t5+=t4;
711 }
712
713 if(ido==1)return;
714
715 t1=0;
716 t3=ido<<1;
717 for(k=0;k<l1;k++){
718 t7=t1+(t1<<1);
719 t6=(t5=t7+t3);
720 t8=t1;
721 t10=(t9=t1+t0)+t0;
722
723 for(i=2;i<ido;i+=2){
724 t5+=2;
725 t6-=2;
726 t7+=2;
727 t8+=2;
728 t9+=2;
729 t10+=2;
730 tr2=cc[t5-1]+cc[t6-1];
731 cr2=cc[t7-1]+(taur*tr2);
732 ch[t8-1]=cc[t7-1]+tr2;
733 ti2=cc[t5]-cc[t6];
734 ci2=cc[t7]+(taur*ti2);
735 ch[t8]=cc[t7]+ti2;
736 cr3=taui*(cc[t5-1]-cc[t6-1]);
737 ci3=taui*(cc[t5]+cc[t6]);
738 dr2=cr2-ci3;
739 dr3=cr2+ci3;
740 di2=ci2+cr3;
741 di3=ci2-cr3;
742 ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2;
743 ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2;
744 ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3;
745 ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3;
746 }
747 t1+=ido;
748 }
749}
750
751static void dradb4(int ido,int l1,float *cc,float *ch,float *wa1,
752 float *wa2,float *wa3){
753 static float sqrt2=1.414213562373095f;
754 int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8;
755 float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
756 t0=l1*ido;
757
758 t1=0;
759 t2=ido<<2;
760 t3=0;
761 t6=ido<<1;
762 for(k=0;k<l1;k++){
763 t4=t3+t6;
764 t5=t1;
765 tr3=cc[t4-1]+cc[t4-1];
766 tr4=cc[t4]+cc[t4];
767 tr1=cc[t3]-cc[(t4+=t6)-1];
768 tr2=cc[t3]+cc[t4-1];
769 ch[t5]=tr2+tr3;
770 ch[t5+=t0]=tr1-tr4;
771 ch[t5+=t0]=tr2-tr3;
772 ch[t5+=t0]=tr1+tr4;
773 t1+=ido;
774 t3+=t2;
775 }
776
777 if(ido<2)return;
778 if(ido==2)goto L105;
779
780 t1=0;
781 for(k=0;k<l1;k++){
782 t5=(t4=(t3=(t2=t1<<2)+t6))+t6;
783 t7=t1;
784 for(i=2;i<ido;i+=2){
785 t2+=2;
786 t3+=2;
787 t4-=2;
788 t5-=2;
789 t7+=2;
790 ti1=cc[t2]+cc[t5];
791 ti2=cc[t2]-cc[t5];
792 ti3=cc[t3]-cc[t4];
793 tr4=cc[t3]+cc[t4];
794 tr1=cc[t2-1]-cc[t5-1];
795 tr2=cc[t2-1]+cc[t5-1];
796 ti4=cc[t3-1]-cc[t4-1];
797 tr3=cc[t3-1]+cc[t4-1];
798 ch[t7-1]=tr2+tr3;
799 cr3=tr2-tr3;
800 ch[t7]=ti2+ti3;
801 ci3=ti2-ti3;
802 cr2=tr1-tr4;
803 cr4=tr1+tr4;
804 ci2=ti1+ti4;
805 ci4=ti1-ti4;
806
807 ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2;
808 ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2;
809 ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3;
810 ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3;
811 ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4;
812 ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4;
813 }
814 t1+=ido;
815 }
816
817 if(ido%2 == 1)return;
818
819 L105:
820
821 t1=ido;
822 t2=ido<<2;
823 t3=ido-1;
824 t4=ido+(ido<<1);
825 for(k=0;k<l1;k++){
826 t5=t3;
827 ti1=cc[t1]+cc[t4];
828 ti2=cc[t4]-cc[t1];
829 tr1=cc[t1-1]-cc[t4-1];
830 tr2=cc[t1-1]+cc[t4-1];
831 ch[t5]=tr2+tr2;
832 ch[t5+=t0]=sqrt2*(tr1-ti1);
833 ch[t5+=t0]=ti2+ti2;
834 ch[t5+=t0]=-sqrt2*(tr1+ti1);
835
836 t3+=ido;
837 t1+=t2;
838 t4+=t2;
839 }
840}
841
842static void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
843 float *c2,float *ch,float *ch2,float *wa){
844 static float tpi=6.283185307179586f;
845 int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,
846 t11,t12;
847 float dc2,ai1,ai2,ar1,ar2,ds2;
848 int nbd;
849 float dcp,arg,dsp,ar1h,ar2h;
850 int ipp2;
851
852 t10=ip*ido;
853 t0=l1*ido;
854 arg=tpi/(float)ip;
855 dcp=cos(arg);
856 dsp=sin(arg);
857 nbd=(ido-1)>>1;
858 ipp2=ip;
859 ipph=(ip+1)>>1;
860 if(ido<l1)goto L103;
861
862 t1=0;
863 t2=0;
864 for(k=0;k<l1;k++){
865 t3=t1;
866 t4=t2;
867 for(i=0;i<ido;i++){
868 ch[t3]=cc[t4];
869 t3++;
870 t4++;
871 }
872 t1+=ido;
873 t2+=t10;
874 }
875 goto L106;
876
877 L103:
878 t1=0;
879 for(i=0;i<ido;i++){
880 t2=t1;
881 t3=t1;
882 for(k=0;k<l1;k++){
883 ch[t2]=cc[t3];
884 t2+=ido;
885 t3+=t10;
886 }
887 t1++;
888 }
889
890 L106:
891 t1=0;
892 t2=ipp2*t0;
893 t7=(t5=ido<<1);
894 for(j=1;j<ipph;j++){
895 t1+=t0;
896 t2-=t0;
897 t3=t1;
898 t4=t2;
899 t6=t5;
900 for(k=0;k<l1;k++){
901 ch[t3]=cc[t6-1]+cc[t6-1];
902 ch[t4]=cc[t6]+cc[t6];
903 t3+=ido;
904 t4+=ido;
905 t6+=t10;
906 }
907 t5+=t7;
908 }
909
910 if (ido == 1)goto L116;
911 if(nbd<l1)goto L112;
912
913 t1=0;
914 t2=ipp2*t0;
915 t7=0;
916 for(j=1;j<ipph;j++){
917 t1+=t0;
918 t2-=t0;
919 t3=t1;
920 t4=t2;
921
922 t7+=(ido<<1);
923 t8=t7;
924 for(k=0;k<l1;k++){
925 t5=t3;
926 t6=t4;
927 t9=t8;
928 t11=t8;
929 for(i=2;i<ido;i+=2){
930 t5+=2;
931 t6+=2;
932 t9+=2;
933 t11-=2;
934 ch[t5-1]=cc[t9-1]+cc[t11-1];
935 ch[t6-1]=cc[t9-1]-cc[t11-1];
936 ch[t5]=cc[t9]-cc[t11];
937 ch[t6]=cc[t9]+cc[t11];
938 }
939 t3+=ido;
940 t4+=ido;
941 t8+=t10;
942 }
943 }
944 goto L116;
945
946 L112:
947 t1=0;
948 t2=ipp2*t0;
949 t7=0;
950 for(j=1;j<ipph;j++){
951 t1+=t0;
952 t2-=t0;
953 t3=t1;
954 t4=t2;
955 t7+=(ido<<1);
956 t8=t7;
957 t9=t7;
958 for(i=2;i<ido;i+=2){
959 t3+=2;
960 t4+=2;
961 t8+=2;
962 t9-=2;
963 t5=t3;
964 t6=t4;
965 t11=t8;
966 t12=t9;
967 for(k=0;k<l1;k++){
968 ch[t5-1]=cc[t11-1]+cc[t12-1];
969 ch[t6-1]=cc[t11-1]-cc[t12-1];
970 ch[t5]=cc[t11]-cc[t12];
971 ch[t6]=cc[t11]+cc[t12];
972 t5+=ido;
973 t6+=ido;
974 t11+=t10;
975 t12+=t10;
976 }
977 }
978 }
979
980L116:
981 ar1=1.f;
982 ai1=0.f;
983 t1=0;
984 t9=(t2=ipp2*idl1);
985 t3=(ip-1)*idl1;
986 for(l=1;l<ipph;l++){
987 t1+=idl1;
988 t2-=idl1;
989
990 ar1h=dcp*ar1-dsp*ai1;
991 ai1=dcp*ai1+dsp*ar1;
992 ar1=ar1h;
993 t4=t1;
994 t5=t2;
995 t6=0;
996 t7=idl1;
997 t8=t3;
998 for(ik=0;ik<idl1;ik++){
999 c2[t4++]=ch2[t6++]+ar1*ch2[t7++];
1000 c2[t5++]=ai1*ch2[t8++];
1001 }
1002 dc2=ar1;
1003 ds2=ai1;
1004 ar2=ar1;
1005 ai2=ai1;
1006
1007 t6=idl1;
1008 t7=t9-idl1;
1009 for(j=2;j<ipph;j++){
1010 t6+=idl1;
1011 t7-=idl1;
1012 ar2h=dc2*ar2-ds2*ai2;
1013 ai2=dc2*ai2+ds2*ar2;
1014 ar2=ar2h;
1015 t4=t1;
1016 t5=t2;
1017 t11=t6;
1018 t12=t7;
1019 for(ik=0;ik<idl1;ik++){
1020 c2[t4++]+=ar2*ch2[t11++];
1021 c2[t5++]+=ai2*ch2[t12++];
1022 }
1023 }
1024 }
1025
1026 t1=0;
1027 for(j=1;j<ipph;j++){
1028 t1+=idl1;
1029 t2=t1;
1030 for(ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++];
1031 }
1032
1033 t1=0;
1034 t2=ipp2*t0;
1035 for(j=1;j<ipph;j++){
1036 t1+=t0;
1037 t2-=t0;
1038 t3=t1;
1039 t4=t2;
1040 for(k=0;k<l1;k++){
1041 ch[t3]=c1[t3]-c1[t4];
1042 ch[t4]=c1[t3]+c1[t4];
1043 t3+=ido;
1044 t4+=ido;
1045 }
1046 }
1047
1048 if(ido==1)goto L132;
1049 if(nbd<l1)goto L128;
1050
1051 t1=0;
1052 t2=ipp2*t0;
1053 for(j=1;j<ipph;j++){
1054 t1+=t0;
1055 t2-=t0;
1056 t3=t1;
1057 t4=t2;
1058 for(k=0;k<l1;k++){
1059 t5=t3;
1060 t6=t4;
1061 for(i=2;i<ido;i+=2){
1062 t5+=2;
1063 t6+=2;
1064 ch[t5-1]=c1[t5-1]-c1[t6];
1065 ch[t6-1]=c1[t5-1]+c1[t6];
1066 ch[t5]=c1[t5]+c1[t6-1];
1067 ch[t6]=c1[t5]-c1[t6-1];
1068 }
1069 t3+=ido;
1070 t4+=ido;
1071 }
1072 }
1073 goto L132;
1074
1075 L128:
1076 t1=0;
1077 t2=ipp2*t0;
1078 for(j=1;j<ipph;j++){
1079 t1+=t0;
1080 t2-=t0;
1081 t3=t1;
1082 t4=t2;
1083 for(i=2;i<ido;i+=2){
1084 t3+=2;
1085 t4+=2;
1086 t5=t3;
1087 t6=t4;
1088 for(k=0;k<l1;k++){
1089 ch[t5-1]=c1[t5-1]-c1[t6];
1090 ch[t6-1]=c1[t5-1]+c1[t6];
1091 ch[t5]=c1[t5]+c1[t6-1];
1092 ch[t6]=c1[t5]-c1[t6-1];
1093 t5+=ido;
1094 t6+=ido;
1095 }
1096 }
1097 }
1098
1099L132:
1100 if(ido==1)return;
1101
1102 for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
1103
1104 t1=0;
1105 for(j=1;j<ip;j++){
1106 t2=(t1+=t0);
1107 for(k=0;k<l1;k++){
1108 c1[t2]=ch[t2];
1109 t2+=ido;
1110 }
1111 }
1112
1113 if(nbd>l1)goto L139;
1114
1115 is= -ido-1;
1116 t1=0;
1117 for(j=1;j<ip;j++){
1118 is+=ido;
1119 t1+=t0;
1120 idij=is;
1121 t2=t1;
1122 for(i=2;i<ido;i+=2){
1123 t2+=2;
1124 idij+=2;
1125 t3=t2;
1126 for(k=0;k<l1;k++){
1127 c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
1128 c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
1129 t3+=ido;
1130 }
1131 }
1132 }
1133 return;
1134
1135 L139:
1136 is= -ido-1;
1137 t1=0;
1138 for(j=1;j<ip;j++){
1139 is+=ido;
1140 t1+=t0;
1141 t2=t1;
1142 for(k=0;k<l1;k++){
1143 idij=is;
1144 t3=t2;
1145 for(i=2;i<ido;i+=2){
1146 idij+=2;
1147 t3+=2;
1148 c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
1149 c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
1150 }
1151 t2+=ido;
1152 }
1153 }
1154}
1155
1156static void drftb1(int n, float *c, float *ch, float *wa, int *ifac){
1157 int i,k1,l1,l2;
1158 int na;
1159 int nf,ip,iw,ix2,ix3,ido,idl1;
1160
1161 nf=ifac[1];
1162 na=0;
1163 l1=1;
1164 iw=1;
1165
1166 for(k1=0;k1<nf;k1++){
1167 ip=ifac[k1 + 2];
1168 l2=ip*l1;
1169 ido=n/l2;
1170 idl1=ido*l1;
1171 if(ip!=4)goto L103;
1172 ix2=iw+ido;
1173 ix3=ix2+ido;
1174
1175 if(na!=0)
1176 dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
1177 else
1178 dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
1179 na=1-na;
1180 goto L115;
1181
1182 L103:
1183 if(ip!=2)goto L106;
1184
1185 if(na!=0)
1186 dradb2(ido,l1,ch,c,wa+iw-1);
1187 else
1188 dradb2(ido,l1,c,ch,wa+iw-1);
1189 na=1-na;
1190 goto L115;
1191
1192 L106:
1193 if(ip!=3)goto L109;
1194
1195 ix2=iw+ido;
1196 if(na!=0)
1197 dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1);
1198 else
1199 dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1);
1200 na=1-na;
1201 goto L115;
1202
1203 L109:
1204/* The radix five case can be translated later..... */
1205/* if(ip!=5)goto L112;
1206
1207 ix2=iw+ido;
1208 ix3=ix2+ido;
1209 ix4=ix3+ido;
1210 if(na!=0)
1211 dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
1212 else
1213 dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
1214 na=1-na;
1215 goto L115;
1216
1217 L112:*/
1218 if(na!=0)
1219 dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
1220 else
1221 dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
1222 if(ido==1)na=1-na;
1223
1224 L115:
1225 l1=l2;
1226 iw+=(ip-1)*ido;
1227 }
1228
1229 if(na==0)return;
1230
1231 for(i=0;i<n;i++)c[i]=ch[i];
1232}
1233
1234void spx_drft_forward(struct drft_lookup *l,float *data){
1235 if(l->n==1)return;
1236 drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);
1237}
1238
1239void spx_drft_backward(struct drft_lookup *l,float *data){
1240 if (l->n==1)return;
1241 drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);
1242}
1243
1244void spx_drft_init(struct drft_lookup *l,int n)
1245{
1246 l->n=n;
1247 l->trigcache=(float*)speex_alloc(3*n*sizeof(*l->trigcache));
1248 l->splitcache=(int*)speex_alloc(32*sizeof(*l->splitcache));
1249 fdrffti(n, l->trigcache, l->splitcache);
1250}
1251
1252void spx_drft_clear(struct drft_lookup *l)
1253{
1254 if(l)
1255 {
1256 if(l->trigcache)
1257 speex_free(l->trigcache);
1258 if(l->splitcache)
1259 speex_free(l->splitcache);
1260 }
1261}
diff --git a/lib/rbcodec/codecs/libspeex/smallft.h b/lib/rbcodec/codecs/libspeex/smallft.h
new file mode 100644
index 0000000000..4ef9e58c7d
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/smallft.h
@@ -0,0 +1,46 @@
1/********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
9 * by the XIPHOPHORUS Company http://www.xiph.org/ *
10 * *
11 ********************************************************************
12
13 function: fft transform
14 last mod: $Id$
15
16 ********************************************************************/
17/**
18 @file smallft.h
19 @brief Discrete Rotational Fourier Transform (DRFT)
20*/
21
22#ifndef _V_SMFT_H_
23#define _V_SMFT_H_
24
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/** Discrete Rotational Fourier Transform lookup */
31struct drft_lookup{
32 int n;
33 float *trigcache;
34 int *splitcache;
35};
36
37extern void spx_drft_forward(struct drft_lookup *l,float *data);
38extern void spx_drft_backward(struct drft_lookup *l,float *data);
39extern void spx_drft_init(struct drft_lookup *l,int n);
40extern void spx_drft_clear(struct drft_lookup *l);
41
42#ifdef __cplusplus
43}
44#endif
45
46#endif
diff --git a/lib/rbcodec/codecs/libspeex/speex.c b/lib/rbcodec/codecs/libspeex/speex.c
new file mode 100644
index 0000000000..0dcfb3f7f6
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex.c
@@ -0,0 +1,252 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: speex.c
3
4 Basic Speex functions
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35#ifdef HAVE_CONFIG_H
36#include "config-speex.h"
37#endif
38
39#include "modes.h"
40#include <math.h>
41#include "os_support.h"
42
43#ifndef NULL
44#define NULL 0
45#endif
46
47#define MAX_IN_SAMPLES 640
48
49#ifndef SPEEX_DISABLE_ENCODER
50void *speex_encoder_init(const SpeexMode *mode)
51{
52 return mode->enc_init(mode);
53}
54#endif
55
56void *speex_decoder_init(const SpeexMode *mode)
57{
58 return mode->dec_init(mode);
59}
60
61#ifndef SPEEX_DISABLE_ENCODER
62void speex_encoder_destroy(void *state)
63{
64 (*((SpeexMode**)state))->enc_destroy(state);
65}
66#endif
67
68void speex_decoder_destroy(void *state)
69{
70 (*((SpeexMode**)state))->dec_destroy(state);
71}
72
73#ifndef SPEEX_DISABLE_ENCODER
74int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits)
75{
76 return (*((SpeexMode**)state))->enc(state, in, bits);
77}
78#endif
79
80int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out)
81{
82 return (*((SpeexMode**)state))->dec(state, bits, out);
83}
84
85
86
87#ifdef FIXED_POINT
88
89#ifndef SPEEX_DISABLE_ENCODER
90#ifndef DISABLE_FLOAT_API
91int speex_encode(void *state, float *in, SpeexBits *bits)
92{
93 int i;
94 spx_int32_t N;
95 spx_int16_t short_in[MAX_IN_SAMPLES];
96 speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
97 for (i=0;i<N;i++)
98 {
99 if (in[i]>32767.f)
100 short_in[i] = 32767;
101 else if (in[i]<-32768.f)
102 short_in[i] = -32768;
103 else
104 short_in[i] = (spx_int16_t)floor(.5+in[i]);
105 }
106 return (*((SpeexMode**)state))->enc(state, short_in, bits);
107}
108#endif /* #ifndef DISABLE_FLOAT_API */
109
110int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
111{
112 SpeexMode *mode;
113 mode = *(SpeexMode**)state;
114 return (mode)->enc(state, in, bits);
115}
116#endif /* SPEEX_DISABLE_ENCODER */
117
118#ifndef DISABLE_FLOAT_API
119int speex_decode(void *state, SpeexBits *bits, float *out)
120{
121 int i, ret;
122 spx_int32_t N;
123 spx_int16_t short_out[MAX_IN_SAMPLES];
124 speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
125 ret = (*((SpeexMode**)state))->dec(state, bits, short_out);
126 for (i=0;i<N;i++)
127 out[i] = short_out[i];
128 return ret;
129}
130#endif /* #ifndef DISABLE_FLOAT_API */
131
132int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
133{
134 SpeexMode *mode = *(SpeexMode**)state;
135 return (mode)->dec(state, bits, out);
136}
137
138#else
139
140int speex_encode(void *state, float *in, SpeexBits *bits)
141{
142 return (*((SpeexMode**)state))->enc(state, in, bits);
143}
144
145int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
146{
147 int i;
148 spx_int32_t N;
149 float float_in[MAX_IN_SAMPLES];
150 speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
151 for (i=0;i<N;i++)
152 float_in[i] = in[i];
153 return (*((SpeexMode**)state))->enc(state, float_in, bits);
154}
155
156int speex_decode(void *state, SpeexBits *bits, float *out)
157{
158 return (*((SpeexMode**)state))->dec(state, bits, out);
159}
160
161int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
162{
163 int i;
164 spx_int32_t N;
165 float float_out[MAX_IN_SAMPLES];
166 int ret;
167 speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
168 ret = (*((SpeexMode**)state))->dec(state, bits, float_out);
169 for (i=0;i<N;i++)
170 {
171 if (float_out[i]>32767.f)
172 out[i] = 32767;
173 else if (float_out[i]<-32768.f)
174 out[i] = -32768;
175 else
176 out[i] = (spx_int16_t)floor(.5+float_out[i]);
177 }
178 return ret;
179}
180#endif
181
182#ifndef SPEEX_DISABLE_ENCODER
183int speex_encoder_ctl(void *state, int request, void *ptr)
184{
185 return (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
186}
187#endif
188
189int speex_decoder_ctl(void *state, int request, void *ptr)
190{
191 return (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
192}
193
194int nb_mode_query(const void *mode, int request, void *ptr)
195{
196 const SpeexNBMode *m = (const SpeexNBMode*)mode;
197
198 switch (request)
199 {
200 case SPEEX_MODE_FRAME_SIZE:
201 *((int*)ptr)=m->frameSize;
202 break;
203 case SPEEX_SUBMODE_BITS_PER_FRAME:
204 if (*((int*)ptr)==0)
205 *((int*)ptr) = NB_SUBMODE_BITS+1;
206 else if (m->submodes[*((int*)ptr)]==NULL)
207 *((int*)ptr) = -1;
208 else
209 *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
210 break;
211 default:
212 speex_warning_int("Unknown nb_mode_query request: ", request);
213 return -1;
214 }
215 return 0;
216}
217
218
219
220int speex_lib_ctl(int request, void *ptr)
221{
222 switch (request)
223 {
224 case SPEEX_LIB_GET_MAJOR_VERSION:
225 *((int*)ptr) = SPEEX_MAJOR_VERSION;
226 break;
227 case SPEEX_LIB_GET_MINOR_VERSION:
228 *((int*)ptr) = SPEEX_MINOR_VERSION;
229 break;
230 case SPEEX_LIB_GET_MICRO_VERSION:
231 *((int*)ptr) = SPEEX_MICRO_VERSION;
232 break;
233 case SPEEX_LIB_GET_EXTRA_VERSION:
234 *((const char**)ptr) = SPEEX_EXTRA_VERSION;
235 break;
236 case SPEEX_LIB_GET_VERSION_STRING:
237 *((const char**)ptr) = SPEEX_VERSION;
238 break;
239 /*case SPEEX_LIB_SET_ALLOC_FUNC:
240 break;
241 case SPEEX_LIB_GET_ALLOC_FUNC:
242 break;
243 case SPEEX_LIB_SET_FREE_FUNC:
244 break;
245 case SPEEX_LIB_GET_FREE_FUNC:
246 break;*/
247 default:
248 speex_warning_int("Unknown wb_mode_query request: ", request);
249 return -1;
250 }
251 return 0;
252}
diff --git a/lib/rbcodec/codecs/libspeex/speex/ogg.h b/lib/rbcodec/codecs/libspeex/speex/ogg.h
new file mode 100644
index 0000000000..8898b99582
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/ogg.h
@@ -0,0 +1,216 @@
1/********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
12
13 function: toplevel libogg include
14 last mod: $Id$
15
16 ********************************************************************/
17#ifndef _OGG_H
18#define _OGG_H
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24#include "codeclib.h"
25
26typedef short spx_ogg_int16_t;
27typedef unsigned short spx_ogg_uint16_t;
28typedef int spx_ogg_int32_t;
29typedef unsigned int spx_ogg_uint32_t;
30typedef long long spx_ogg_int64_t;
31
32
33#define _spx_ogg_malloc codec_malloc
34#define _spx_ogg_calloc codec_calloc
35#define _spx_ogg_realloc codec_realloc
36#define _spx_ogg_free codec_free
37
38
39typedef struct {
40 long endbyte;
41 int endbit;
42
43 unsigned char *buffer;
44 unsigned char *ptr;
45 long storage;
46} oggpack_buffer;
47
48/* spx_ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
49
50typedef struct {
51 unsigned char *header;
52 long header_len;
53 unsigned char *body;
54 long body_len;
55} spx_ogg_page;
56
57/* spx_ogg_stream_state contains the current encode/decode state of a logical
58 Ogg bitstream **********************************************************/
59
60typedef struct {
61 unsigned char *body_data; /* bytes from packet bodies */
62 long body_storage; /* storage elements allocated */
63 long body_fill; /* elements stored; fill mark */
64 long body_returned; /* elements of fill returned */
65
66
67 int *lacing_vals; /* The values that will go to the segment table */
68 spx_ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
69 this way, but it is simple coupled to the
70 lacing fifo */
71 long lacing_storage;
72 long lacing_fill;
73 long lacing_packet;
74 long lacing_returned;
75
76 unsigned char header[282]; /* working space for header encode */
77 int header_fill;
78
79 int e_o_s; /* set when we have buffered the last packet in the
80 logical bitstream */
81 int b_o_s; /* set after we've written the initial page
82 of a logical bitstream */
83 long serialno;
84 long pageno;
85 spx_ogg_int64_t packetno; /* sequence number for decode; the framing
86 knows where there's a hole in the data,
87 but we need coupling so that the codec
88 (which is in a seperate abstraction
89 layer) also knows about the gap */
90 spx_ogg_int64_t granulepos;
91
92} spx_ogg_stream_state;
93
94/* spx_ogg_packet is used to encapsulate the data and metadata belonging
95 to a single raw Ogg/Vorbis packet *************************************/
96
97typedef struct {
98 unsigned char *packet;
99 long bytes;
100 long b_o_s;
101 long e_o_s;
102
103 spx_ogg_int64_t granulepos;
104
105 spx_ogg_int64_t packetno; /* sequence number for decode; the framing
106 knows where there's a hole in the data,
107 but we need coupling so that the codec
108 (which is in a seperate abstraction
109 layer) also knows about the gap */
110} spx_ogg_packet;
111
112typedef struct {
113 unsigned char *data;
114 int storage;
115 int fill;
116 int returned;
117
118 int unsynced;
119 int headerbytes;
120 int bodybytes;
121} spx_ogg_sync_state;
122
123/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
124
125extern void oggpack_writeinit(oggpack_buffer *b);
126extern void oggpack_writetrunc(oggpack_buffer *b,long bits);
127extern void oggpack_writealign(oggpack_buffer *b);
128extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
129extern void oggpack_reset(oggpack_buffer *b);
130extern void oggpack_writeclear(oggpack_buffer *b);
131extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
132extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
133extern long oggpack_look(oggpack_buffer *b,int bits);
134extern long oggpack_look1(oggpack_buffer *b);
135extern void oggpack_adv(oggpack_buffer *b,int bits);
136extern void oggpack_adv1(oggpack_buffer *b);
137extern long oggpack_read(oggpack_buffer *b,int bits);
138extern long oggpack_read1(oggpack_buffer *b);
139extern long oggpack_bytes(oggpack_buffer *b);
140extern long oggpack_bits(oggpack_buffer *b);
141extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
142
143extern void oggpackB_writeinit(oggpack_buffer *b);
144extern void oggpackB_writetrunc(oggpack_buffer *b,long bits);
145extern void oggpackB_writealign(oggpack_buffer *b);
146extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
147extern void oggpackB_reset(oggpack_buffer *b);
148extern void oggpackB_writeclear(oggpack_buffer *b);
149extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
150extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
151extern long oggpackB_look(oggpack_buffer *b,int bits);
152extern long oggpackB_look1(oggpack_buffer *b);
153extern void oggpackB_adv(oggpack_buffer *b,int bits);
154extern void oggpackB_adv1(oggpack_buffer *b);
155extern long oggpackB_read(oggpack_buffer *b,int bits);
156extern long oggpackB_read1(oggpack_buffer *b);
157extern long oggpackB_bytes(oggpack_buffer *b);
158extern long oggpackB_bits(oggpack_buffer *b);
159extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
160
161/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
162
163extern int spx_ogg_stream_packetin(spx_ogg_stream_state *os, spx_ogg_packet *op);
164extern int spx_ogg_stream_pageout(spx_ogg_stream_state *os, spx_ogg_page *og);
165extern int spx_ogg_stream_flush(spx_ogg_stream_state *os, spx_ogg_page *og);
166
167/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
168
169extern int spx_ogg_sync_init(spx_ogg_sync_state *oy);
170extern int spx_ogg_sync_clear(spx_ogg_sync_state *oy);
171extern int spx_ogg_sync_reset(spx_ogg_sync_state *oy);
172extern int spx_ogg_sync_destroy(spx_ogg_sync_state *oy);
173
174extern void spx_ogg_alloc_buffer(spx_ogg_sync_state *oy, long size);
175extern char *spx_ogg_sync_buffer(spx_ogg_sync_state *oy, long size);
176extern int spx_ogg_sync_wrote(spx_ogg_sync_state *oy, long bytes);
177extern long spx_ogg_sync_pageseek(spx_ogg_sync_state *oy,spx_ogg_page *og);
178extern int spx_ogg_sync_pageout(spx_ogg_sync_state *oy, spx_ogg_page *og);
179extern int spx_ogg_stream_pagein(spx_ogg_stream_state *os, spx_ogg_page *og);
180extern int spx_ogg_stream_packetout(spx_ogg_stream_state *os,spx_ogg_packet *op);
181extern int spx_ogg_stream_packetpeek(spx_ogg_stream_state *os,spx_ogg_packet *op);
182
183/* Ogg BITSTREAM PRIMITIVES: general ***************************/
184
185extern int spx_ogg_stream_init(spx_ogg_stream_state *os,int serialno);
186extern int spx_ogg_stream_clear(spx_ogg_stream_state *os);
187extern int spx_ogg_stream_reset(spx_ogg_stream_state *os);
188extern int spx_ogg_stream_reset_serialno(spx_ogg_stream_state *os,int serialno);
189extern int spx_ogg_stream_destroy(spx_ogg_stream_state *os);
190extern int spx_ogg_stream_eos(spx_ogg_stream_state *os);
191
192extern void spx_ogg_page_checksum_set(spx_ogg_page *og);
193
194extern int spx_ogg_page_version(spx_ogg_page *og);
195extern int spx_ogg_page_continued(spx_ogg_page *og);
196extern int spx_ogg_page_bos(spx_ogg_page *og);
197extern int spx_ogg_page_eos(spx_ogg_page *og);
198extern spx_ogg_int64_t spx_ogg_page_granulepos(spx_ogg_page *og);
199extern int spx_ogg_page_serialno(spx_ogg_page *og);
200extern long spx_ogg_page_pageno(spx_ogg_page *og);
201extern int spx_ogg_page_packets(spx_ogg_page *og);
202
203extern void spx_ogg_packet_clear(spx_ogg_packet *op);
204
205
206#ifdef __cplusplus
207}
208#endif
209
210#endif /* _OGG_H */
211
212
213
214
215
216
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex.h b/lib/rbcodec/codecs/libspeex/speex/speex.h
new file mode 100644
index 0000000000..086d492670
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex.h
@@ -0,0 +1,428 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin*/
2/**
3 @file speex.h
4 @brief Describes the different modes of the codec
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#ifndef SPEEX_H
37#define SPEEX_H
38/** @defgroup Codec Speex encoder and decoder
39 * This is the Speex codec itself.
40 * @{
41 */
42
43#include "speex_bits.h"
44#include "speex_types.h"
45
46#ifdef __cplusplus
47extern "C" {
48#endif
49
50/* Values allowed for *ctl() requests */
51
52/** Set enhancement on/off (decoder only) */
53#define SPEEX_SET_ENH 0
54/** Get enhancement state (decoder only) */
55#define SPEEX_GET_ENH 1
56
57/*Would be SPEEX_SET_FRAME_SIZE, but it's (currently) invalid*/
58/** Obtain frame size used by encoder/decoder */
59#define SPEEX_GET_FRAME_SIZE 3
60
61/** Set quality value */
62#define SPEEX_SET_QUALITY 4
63/** Get current quality setting */
64/* #define SPEEX_GET_QUALITY 5 -- Doesn't make much sense, does it? */
65
66/** Set sub-mode to use */
67#define SPEEX_SET_MODE 6
68/** Get current sub-mode in use */
69#define SPEEX_GET_MODE 7
70
71/** Set low-band sub-mode to use (wideband only)*/
72#define SPEEX_SET_LOW_MODE 8
73/** Get current low-band mode in use (wideband only)*/
74#define SPEEX_GET_LOW_MODE 9
75
76/** Set high-band sub-mode to use (wideband only)*/
77#define SPEEX_SET_HIGH_MODE 10
78/** Get current high-band mode in use (wideband only)*/
79#define SPEEX_GET_HIGH_MODE 11
80
81/** Set VBR on (1) or off (0) */
82#define SPEEX_SET_VBR 12
83/** Get VBR status (1 for on, 0 for off) */
84#define SPEEX_GET_VBR 13
85
86/** Set quality value for VBR encoding (0-10) */
87#define SPEEX_SET_VBR_QUALITY 14
88/** Get current quality value for VBR encoding (0-10) */
89#define SPEEX_GET_VBR_QUALITY 15
90
91/** Set complexity of the encoder (0-10) */
92#define SPEEX_SET_COMPLEXITY 16
93/** Get current complexity of the encoder (0-10) */
94#define SPEEX_GET_COMPLEXITY 17
95
96/** Set bit-rate used by the encoder (or lower) */
97#define SPEEX_SET_BITRATE 18
98/** Get current bit-rate used by the encoder or decoder */
99#define SPEEX_GET_BITRATE 19
100
101/** Define a handler function for in-band Speex request*/
102#define SPEEX_SET_HANDLER 20
103
104/** Define a handler function for in-band user-defined request*/
105#define SPEEX_SET_USER_HANDLER 22
106
107/** Set sampling rate used in bit-rate computation */
108#define SPEEX_SET_SAMPLING_RATE 24
109/** Get sampling rate used in bit-rate computation */
110#define SPEEX_GET_SAMPLING_RATE 25
111
112/** Reset the encoder/decoder memories to zero*/
113#define SPEEX_RESET_STATE 26
114
115/** Get VBR info (mostly used internally) */
116#define SPEEX_GET_RELATIVE_QUALITY 29
117
118/** Set VAD status (1 for on, 0 for off) */
119#define SPEEX_SET_VAD 30
120
121/** Get VAD status (1 for on, 0 for off) */
122#define SPEEX_GET_VAD 31
123
124/** Set Average Bit-Rate (ABR) to n bits per seconds */
125#define SPEEX_SET_ABR 32
126/** Get Average Bit-Rate (ABR) setting (in bps) */
127#define SPEEX_GET_ABR 33
128
129/** Set DTX status (1 for on, 0 for off) */
130#define SPEEX_SET_DTX 34
131/** Get DTX status (1 for on, 0 for off) */
132#define SPEEX_GET_DTX 35
133
134/** Set submode encoding in each frame (1 for yes, 0 for no, setting to no breaks the standard) */
135#define SPEEX_SET_SUBMODE_ENCODING 36
136/** Get submode encoding in each frame */
137#define SPEEX_GET_SUBMODE_ENCODING 37
138
139/*#define SPEEX_SET_LOOKAHEAD 38*/
140/** Returns the lookahead used by Speex */
141#define SPEEX_GET_LOOKAHEAD 39
142
143/** Sets tuning for packet-loss concealment (expected loss rate) */
144#define SPEEX_SET_PLC_TUNING 40
145/** Gets tuning for PLC */
146#define SPEEX_GET_PLC_TUNING 41
147
148/** Sets the max bit-rate allowed in VBR mode */
149#define SPEEX_SET_VBR_MAX_BITRATE 42
150/** Gets the max bit-rate allowed in VBR mode */
151#define SPEEX_GET_VBR_MAX_BITRATE 43
152
153/** Turn on/off input/output high-pass filtering */
154#define SPEEX_SET_HIGHPASS 44
155/** Get status of input/output high-pass filtering */
156#define SPEEX_GET_HIGHPASS 45
157
158/** Get "activity level" of the last decoded frame, i.e.
159 how much damage we cause if we remove the frame */
160#define SPEEX_GET_ACTIVITY 47
161
162
163/* Preserving compatibility:*/
164/** Equivalent to SPEEX_SET_ENH */
165#define SPEEX_SET_PF 0
166/** Equivalent to SPEEX_GET_ENH */
167#define SPEEX_GET_PF 1
168
169
170
171
172/* Values allowed for mode queries */
173/** Query the frame size of a mode */
174#define SPEEX_MODE_FRAME_SIZE 0
175
176/** Query the size of an encoded frame for a particular sub-mode */
177#define SPEEX_SUBMODE_BITS_PER_FRAME 1
178
179
180
181/** Get major Speex version */
182#define SPEEX_LIB_GET_MAJOR_VERSION 1
183/** Get minor Speex version */
184#define SPEEX_LIB_GET_MINOR_VERSION 3
185/** Get micro Speex version */
186#define SPEEX_LIB_GET_MICRO_VERSION 5
187/** Get extra Speex version */
188#define SPEEX_LIB_GET_EXTRA_VERSION 7
189/** Get Speex version string */
190#define SPEEX_LIB_GET_VERSION_STRING 9
191
192/*#define SPEEX_LIB_SET_ALLOC_FUNC 10
193#define SPEEX_LIB_GET_ALLOC_FUNC 11
194#define SPEEX_LIB_SET_FREE_FUNC 12
195#define SPEEX_LIB_GET_FREE_FUNC 13
196
197#define SPEEX_LIB_SET_WARNING_FUNC 14
198#define SPEEX_LIB_GET_WARNING_FUNC 15
199#define SPEEX_LIB_SET_ERROR_FUNC 16
200#define SPEEX_LIB_GET_ERROR_FUNC 17
201*/
202
203/** Number of defined modes in Speex */
204#define SPEEX_NB_MODES 3
205
206/** modeID for the defined narrowband mode */
207#define SPEEX_MODEID_NB 0
208
209/** modeID for the defined wideband mode */
210#define SPEEX_MODEID_WB 1
211
212/** modeID for the defined ultra-wideband mode */
213#define SPEEX_MODEID_UWB 2
214
215struct SpeexMode;
216
217
218/* Prototypes for mode function pointers */
219
220/** Encoder state initialization function */
221typedef void *(*encoder_init_func)(const struct SpeexMode *mode);
222
223/** Encoder state destruction function */
224typedef void (*encoder_destroy_func)(void *st);
225
226/** Main encoding function */
227typedef int (*encode_func)(void *state, void *in, SpeexBits *bits);
228
229/** Function for controlling the encoder options */
230typedef int (*encoder_ctl_func)(void *state, int request, void *ptr);
231
232/** Decoder state initialization function */
233typedef void *(*decoder_init_func)(const struct SpeexMode *mode);
234
235/** Decoder state destruction function */
236typedef void (*decoder_destroy_func)(void *st);
237
238/** Main decoding function */
239typedef int (*decode_func)(void *state, SpeexBits *bits, void *out);
240
241/** Function for controlling the decoder options */
242typedef int (*decoder_ctl_func)(void *state, int request, void *ptr);
243
244
245/** Query function for a mode */
246typedef int (*mode_query_func)(const void *mode, int request, void *ptr);
247
248/** Struct defining a Speex mode */
249typedef struct SpeexMode {
250 /** Pointer to the low-level mode data */
251 const void *mode;
252
253 /** Pointer to the mode query function */
254 mode_query_func query;
255
256 /** The name of the mode (you should not rely on this to identify the mode)*/
257 const char *modeName;
258
259 /**ID of the mode*/
260 int modeID;
261
262 /**Version number of the bitstream (incremented every time we break
263 bitstream compatibility*/
264 int bitstream_version;
265
266#ifndef SPEEX_DISABLE_ENCODER
267 /** Pointer to encoder initialization function */
268 encoder_init_func enc_init;
269
270 /** Pointer to encoder destruction function */
271 encoder_destroy_func enc_destroy;
272
273 /** Pointer to frame encoding function */
274 encode_func enc;
275#endif
276
277 /** Pointer to decoder initialization function */
278 decoder_init_func dec_init;
279
280 /** Pointer to decoder destruction function */
281 decoder_destroy_func dec_destroy;
282
283 /** Pointer to frame decoding function */
284 decode_func dec;
285
286#ifndef SPEEX_DISABLE_ENCODER
287 /** ioctl-like requests for encoder */
288 encoder_ctl_func enc_ctl;
289#endif
290
291 /** ioctl-like requests for decoder */
292 decoder_ctl_func dec_ctl;
293
294} SpeexMode;
295
296/**
297 * Returns a handle to a newly created Speex encoder state structure. For now,
298 * the "mode" argument can be &nb_mode or &wb_mode . In the future, more modes
299 * may be added. Note that for now if you have more than one channels to
300 * encode, you need one state per channel.
301 *
302 * @param mode The mode to use (either speex_nb_mode or speex_wb.mode)
303 * @return A newly created encoder state or NULL if state allocation fails
304 */
305void *speex_encoder_init(const SpeexMode *mode);
306
307/** Frees all resources associated to an existing Speex encoder state.
308 * @param state Encoder state to be destroyed */
309void speex_encoder_destroy(void *state);
310
311/** Uses an existing encoder state to encode one frame of speech pointed to by
312 "in". The encoded bit-stream is saved in "bits".
313 @param state Encoder state
314 @param in Frame that will be encoded with a +-2^15 range. This data MAY be
315 overwritten by the encoder and should be considered uninitialised
316 after the call.
317 @param bits Bit-stream where the data will be written
318 @return 0 if frame needs not be transmitted (DTX only), 1 otherwise
319 */
320int speex_encode(void *state, float *in, SpeexBits *bits);
321
322/** Uses an existing encoder state to encode one frame of speech pointed to by
323 "in". The encoded bit-stream is saved in "bits".
324 @param state Encoder state
325 @param in Frame that will be encoded with a +-2^15 range
326 @param bits Bit-stream where the data will be written
327 @return 0 if frame needs not be transmitted (DTX only), 1 otherwise
328 */
329int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits);
330
331/** Used like the ioctl function to control the encoder parameters
332 *
333 * @param state Encoder state
334 * @param request ioctl-type request (one of the SPEEX_* macros)
335 * @param ptr Data exchanged to-from function
336 * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
337 */
338int speex_encoder_ctl(void *state, int request, void *ptr);
339
340
341/** Returns a handle to a newly created decoder state structure. For now,
342 * the mode argument can be &nb_mode or &wb_mode . In the future, more modes
343 * may be added. Note that for now if you have more than one channels to
344 * decode, you need one state per channel.
345 *
346 * @param mode Speex mode (one of speex_nb_mode or speex_wb_mode)
347 * @return A newly created decoder state or NULL if state allocation fails
348 */
349void *speex_decoder_init(const SpeexMode *mode);
350
351/** Frees all resources associated to an existing decoder state.
352 *
353 * @param state State to be destroyed
354 */
355void speex_decoder_destroy(void *state);
356
357/** Uses an existing decoder state to decode one frame of speech from
358 * bit-stream bits. The output speech is saved written to out.
359 *
360 * @param state Decoder state
361 * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost)
362 * @param out Where to write the decoded frame
363 * @return return status (0 for no error, -1 for end of stream, -2 corrupt stream)
364 */
365int speex_decode(void *state, SpeexBits *bits, float *out);
366
367/** Uses an existing decoder state to decode one frame of speech from
368 * bit-stream bits. The output speech is saved written to out.
369 *
370 * @param state Decoder state
371 * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost)
372 * @param out Where to write the decoded frame
373 * @return return status (0 for no error, -1 for end of stream, -2 corrupt stream)
374 */
375int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out);
376
377/** Used like the ioctl function to control the encoder parameters
378 *
379 * @param state Decoder state
380 * @param request ioctl-type request (one of the SPEEX_* macros)
381 * @param ptr Data exchanged to-from function
382 * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
383 */
384int speex_decoder_ctl(void *state, int request, void *ptr);
385
386
387/** Query function for mode information
388 *
389 * @param mode Speex mode
390 * @param request ioctl-type request (one of the SPEEX_* macros)
391 * @param ptr Data exchanged to-from function
392 * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
393 */
394int speex_mode_query(const SpeexMode *mode, int request, void *ptr);
395
396/** Functions for controlling the behavior of libspeex
397 * @param request ioctl-type request (one of the SPEEX_LIB_* macros)
398 * @param ptr Data exchanged to-from function
399 * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
400 */
401int speex_lib_ctl(int request, void *ptr);
402
403/** Default narrowband mode */
404extern const SpeexMode speex_nb_mode;
405
406/** Default wideband mode */
407extern const SpeexMode speex_wb_mode;
408
409/** Default "ultra-wideband" mode */
410extern const SpeexMode speex_uwb_mode;
411
412/** List of all modes available */
413extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES];
414
415/** Obtain one of the modes available */
416const SpeexMode * speex_lib_get_mode (int mode);
417
418#ifndef WIN32
419/* We actually override the function in the narrowband case so that we can avoid linking in the wideband stuff */
420#define speex_lib_get_mode(mode) ((mode)==SPEEX_MODEID_NB ? &speex_nb_mode : speex_lib_get_mode (mode))
421#endif
422
423#ifdef __cplusplus
424}
425#endif
426
427/** @}*/
428#endif
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex_bits.h b/lib/rbcodec/codecs/libspeex/speex/speex_bits.h
new file mode 100644
index 0000000000..fee2893380
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex_bits.h
@@ -0,0 +1,184 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file speex_bits.h
4 @brief Handles bit packing/unpacking
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#ifndef BITS_H
37#define BITS_H
38/** @defgroup SpeexBits SpeexBits: Bit-stream manipulations
39 * This is the structure that holds the bit-stream when encoding or decoding
40 * with Speex. It allows some manipulations as well.
41 * @{
42 */
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48/** Bit-packing data structure representing (part of) a bit-stream. */
49typedef struct SpeexBits {
50 char *chars; /**< "raw" data */
51 int nbBits; /**< Total number of bits stored in the stream*/
52 int charPtr; /**< Position of the byte "cursor" */
53 int bitPtr; /**< Position of the bit "cursor" within the current char */
54 int owner; /**< Does the struct "own" the "raw" buffer (member "chars") */
55 int overflow;/**< Set to one if we try to read past the valid data */
56 int buf_size;/**< Allocated size for buffer */
57 int reserved1; /**< Reserved for future use */
58 void *reserved2; /**< Reserved for future use */
59} SpeexBits;
60
61/** Initializes and allocates resources for a SpeexBits struct */
62void speex_bits_init(SpeexBits *bits);
63
64/** Initializes SpeexBits struct using a pre-allocated buffer*/
65/* Rockbox: unused
66void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size);
67*/
68
69/** Sets the bits in a SpeexBits struct to use data from an existing buffer (for decoding without copying data) */
70void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size);
71
72/** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/
73void speex_bits_destroy(SpeexBits *bits);
74
75/** Resets bits to initial value (just after initialization, erasing content)*/
76void speex_bits_reset(SpeexBits *bits);
77
78/** Rewind the bit-stream to the beginning (ready for read) without erasing the content */
79/* Rockbox: unused
80void speex_bits_rewind(SpeexBits *bits);
81*/
82
83/** Initializes the bit-stream from the data in an area of memory */
84void speex_bits_read_from(SpeexBits *bits, char *bytes, int len);
85
86/** Append bytes to the bit-stream
87 *
88 * @param bits Bit-stream to operate on
89 * @param bytes pointer to the bytes what will be appended
90 * @param len Number of bytes of append
91 */
92void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len);
93
94/** Write the content of a bit-stream to an area of memory
95 *
96 * @param bits Bit-stream to operate on
97 * @param bytes Memory location where to write the bits
98 * @param max_len Maximum number of bytes to write (i.e. size of the "bytes" buffer)
99 * @return Number of bytes written to the "bytes" buffer
100*/
101int speex_bits_write(SpeexBits *bits, char *bytes, int max_len);
102
103/** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */
104int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len);
105
106/** Append bits to the bit-stream
107 * @param bits Bit-stream to operate on
108 * @param data Value to append as integer
109 * @param nbBits number of bits to consider in "data"
110 */
111void speex_bits_pack(SpeexBits *bits, int data, int nbBits);
112
113/** Interpret the next bits in the bit-stream as a signed integer
114 *
115 * @param bits Bit-stream to operate on
116 * @param nbBits Number of bits to interpret
117 * @return A signed integer represented by the bits read
118 */
119/* Rockbox: unused
120int speex_bits_unpack_signed(SpeexBits *bits, int nbBits);
121*/
122
123/** Interpret the next bits in the bit-stream as an unsigned integer
124 *
125 * @param bits Bit-stream to operate on
126 * @param nbBits Number of bits to interpret
127 * @return An unsigned integer represented by the bits read
128 */
129unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits);
130
131/** Returns the number of bytes in the bit-stream, including the last one even if it is not "full"
132 *
133 * @param bits Bit-stream to operate on
134 * @return Number of bytes in the stream
135 */
136/* Rockbox: unused
137int speex_bits_nbytes(SpeexBits *bits);
138*/
139
140/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position
141 *
142 * @param bits Bit-stream to operate on
143 * @param nbBits Number of bits to look for
144 * @return Value of the bits peeked, interpreted as unsigned
145 */
146/* Rockbox: unused
147unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits);
148*/
149
150/** Get the value of the next bit in the stream, without modifying the
151 * "cursor" position
152 *
153 * @param bits Bit-stream to operate on
154 * @return Value of the bit peeked (one bit only)
155 */
156int speex_bits_peek(SpeexBits *bits);
157
158/** Advances the position of the "bit cursor" in the stream
159 *
160 * @param bits Bit-stream to operate on
161 * @param n Number of bits to advance
162 */
163void speex_bits_advance(SpeexBits *bits, int n);
164
165/** Returns the number of bits remaining to be read in a stream
166 *
167 * @param bits Bit-stream to operate on
168 * @return Number of bits that can still be read from the stream
169 */
170int speex_bits_remaining(SpeexBits *bits);
171
172/** Insert a terminator so that the data can be sent as a packet while auto-detecting
173 * the number of frames in each packet
174 *
175 * @param bits Bit-stream to operate on
176 */
177void speex_bits_insert_terminator(SpeexBits *bits);
178
179#ifdef __cplusplus
180}
181#endif
182
183/* @} */
184#endif
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex_callbacks.h b/lib/rbcodec/codecs/libspeex/speex/speex_callbacks.h
new file mode 100644
index 0000000000..6f450b3a3a
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex_callbacks.h
@@ -0,0 +1,134 @@
1/* Copyright (C) 2002 Jean-Marc Valin*/
2/**
3 @file speex_callbacks.h
4 @brief Describes callback handling and in-band signalling
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#ifndef SPEEX_CALLBACKS_H
37#define SPEEX_CALLBACKS_H
38/** @defgroup SpeexCallbacks Various definitions for Speex callbacks supported by the decoder.
39 * @{
40 */
41
42#include "speex.h"
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48/** Total number of callbacks */
49#define SPEEX_MAX_CALLBACKS 16
50
51/* Describes all the in-band requests */
52
53/*These are 1-bit requests*/
54/** Request for perceptual enhancement (1 for on, 0 for off) */
55#define SPEEX_INBAND_ENH_REQUEST 0
56/** Reserved */
57#define SPEEX_INBAND_RESERVED1 1
58
59/*These are 4-bit requests*/
60/** Request for a mode change */
61#define SPEEX_INBAND_MODE_REQUEST 2
62/** Request for a low mode change */
63#define SPEEX_INBAND_LOW_MODE_REQUEST 3
64/** Request for a high mode change */
65#define SPEEX_INBAND_HIGH_MODE_REQUEST 4
66/** Request for VBR (1 on, 0 off) */
67#define SPEEX_INBAND_VBR_QUALITY_REQUEST 5
68/** Request to be sent acknowledge */
69#define SPEEX_INBAND_ACKNOWLEDGE_REQUEST 6
70/** Request for VBR (1 for on, 0 for off) */
71#define SPEEX_INBAND_VBR_REQUEST 7
72
73/*These are 8-bit requests*/
74/** Send a character in-band */
75#define SPEEX_INBAND_CHAR 8
76/** Intensity stereo information */
77#define SPEEX_INBAND_STEREO 9
78
79/*These are 16-bit requests*/
80/** Transmit max bit-rate allowed */
81#define SPEEX_INBAND_MAX_BITRATE 10
82
83/*These are 32-bit requests*/
84/** Acknowledge packet reception */
85#define SPEEX_INBAND_ACKNOWLEDGE 12
86
87/** Callback function type */
88typedef int (*speex_callback_func)(SpeexBits *bits, void *state, void *data);
89
90/** Callback information */
91typedef struct SpeexCallback {
92 int callback_id; /**< ID associated to the callback */
93 speex_callback_func func; /**< Callback handler function */
94 void *data; /**< Data that will be sent to the handler */
95 void *reserved1; /**< Reserved for future use */
96 int reserved2; /**< Reserved for future use */
97} SpeexCallback;
98
99/** Handle in-band request */
100int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state);
101
102/** Standard handler for mode request (change mode, no questions asked) */
103int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data);
104
105/** Standard handler for high mode request (change high mode, no questions asked) */
106int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data);
107
108/** Standard handler for in-band characters (write to stderr) */
109int speex_std_char_handler(SpeexBits *bits, void *state, void *data);
110
111/** Default handler for user-defined requests: in this case, just ignore */
112int speex_default_user_handler(SpeexBits *bits, void *state, void *data);
113
114
115
116/** Standard handler for low mode request (change low mode, no questions asked) */
117int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data);
118
119/** Standard handler for VBR request (Set VBR, no questions asked) */
120int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data);
121
122/** Standard handler for enhancer request (Turn enhancer on/off, no questions asked) */
123int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data);
124
125/** Standard handler for VBR quality request (Set VBR quality, no questions asked) */
126int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data);
127
128
129#ifdef __cplusplus
130}
131#endif
132
133/** @} */
134#endif
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex_config_types.h b/lib/rbcodec/codecs/libspeex/speex/speex_config_types.h
new file mode 100644
index 0000000000..ef328d48c1
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex_config_types.h
@@ -0,0 +1,13 @@
1#ifndef __SPEEX_TYPES_H__
2#define __SPEEX_TYPES_H__
3
4#include "inttypes.h"
5#define spx_int16_t int16_t
6#define spx_uint16_t uint16_t
7#define spx_int32_t int32_t
8#define spx_uint32_t uint32_t
9#define spx_int64_t int64_t
10#define spx_uint64_t uint64_t
11
12#endif
13
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex_echo.h b/lib/rbcodec/codecs/libspeex/speex/speex_echo.h
new file mode 100644
index 0000000000..6fcb0c00d7
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex_echo.h
@@ -0,0 +1,123 @@
1/* Copyright (C) Jean-Marc Valin */
2/**
3 @file speex_echo.h
4 @brief Echo cancellation
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10
11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 3. The name of the author may not be used to endorse or promote products
19 derived from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.
32*/
33
34#ifndef SPEEX_ECHO_H
35#define SPEEX_ECHO_H
36/** @defgroup SpeexEchoState SpeexEchoState: Acoustic echo canceller
37 * This is the acoustic echo canceller module.
38 * @{
39 */
40#include "speex_types.h"
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/** Obtain frame size used by the AEC */
47#define SPEEX_ECHO_GET_FRAME_SIZE 3
48
49/** Set sampling rate */
50#define SPEEX_ECHO_SET_SAMPLING_RATE 24
51/** Get sampling rate */
52#define SPEEX_ECHO_GET_SAMPLING_RATE 25
53
54/** Internal echo canceller state. Should never be accessed directly. */
55struct SpeexEchoState_;
56
57/** @class SpeexEchoState
58 * This holds the state of the echo canceller. You need one per channel.
59*/
60
61/** Internal echo canceller state. Should never be accessed directly. */
62typedef struct SpeexEchoState_ SpeexEchoState;
63
64/** Creates a new echo canceller state
65 * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms)
66 * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms)
67 * @return Newly-created echo canceller state
68 */
69SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length);
70
71/** Destroys an echo canceller state
72 * @param st Echo canceller state
73*/
74void speex_echo_state_destroy(SpeexEchoState *st);
75
76/** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added
77 * to playback in this form)
78 *
79 * @param st Echo canceller state
80 * @param rec Signal from the microphone (near end + far end echo)
81 * @param play Signal played to the speaker (received from far end)
82 * @param out Returns near-end signal with echo removed
83 */
84void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out);
85
86/** Performs echo cancellation a frame (deprecated) */
87void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout);
88
89/** Perform echo cancellation using internal playback buffer, which is delayed by two frames
90 * to account for the delay introduced by most soundcards (but it could be off!)
91 * @param st Echo canceller state
92 * @param rec Signal from the microphone (near end + far end echo)
93 * @param out Returns near-end signal with echo removed
94*/
95void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out);
96
97/** Let the echo canceller know that a frame was just queued to the soundcard
98 * @param st Echo canceller state
99 * @param play Signal played to the speaker (received from far end)
100*/
101void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play);
102
103/** Reset the echo canceller to its original state
104 * @param st Echo canceller state
105 */
106void speex_echo_state_reset(SpeexEchoState *st);
107
108/** Used like the ioctl function to control the echo canceller parameters
109 *
110 * @param st Echo canceller state
111 * @param request ioctl-type request (one of the SPEEX_ECHO_* macros)
112 * @param ptr Data exchanged to-from function
113 * @return 0 if no error, -1 if request in unknown
114 */
115int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr);
116
117#ifdef __cplusplus
118}
119#endif
120
121
122/** @}*/
123#endif
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex_header.h b/lib/rbcodec/codecs/libspeex/speex/speex_header.h
new file mode 100644
index 0000000000..2b60003fe9
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex_header.h
@@ -0,0 +1,91 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file speex_header.h
4 @brief Describes the Speex header
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36
37#ifndef SPEEX_HEADER_H
38#define SPEEX_HEADER_H
39/** @defgroup SpeexHeader SpeexHeader: Makes it easy to write/parse an Ogg/Speex header
40 * This is the Speex header for the Ogg encapsulation. You don't need that if you just use RTP.
41 * @{
42 */
43
44#include "speex_types.h"
45
46#ifdef __cplusplus
47extern "C" {
48#endif
49
50struct SpeexMode;
51
52/** Length of the Speex header identifier */
53#define SPEEX_HEADER_STRING_LENGTH 8
54
55/** Maximum number of characters for encoding the Speex version number in the header */
56#define SPEEX_HEADER_VERSION_LENGTH 20
57
58/** Speex header info for file-based formats */
59typedef struct SpeexHeader {
60 char speex_string[SPEEX_HEADER_STRING_LENGTH]; /**< Identifies a Speex bit-stream, always set to "Speex " */
61 char speex_version[SPEEX_HEADER_VERSION_LENGTH]; /**< Speex version */
62 spx_int32_t speex_version_id; /**< Version for Speex (for checking compatibility) */
63 spx_int32_t header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */
64 spx_int32_t rate; /**< Sampling rate used */
65 spx_int32_t mode; /**< Mode used (0 for narrowband, 1 for wideband) */
66 spx_int32_t mode_bitstream_version; /**< Version ID of the bit-stream */
67 spx_int32_t nb_channels; /**< Number of channels encoded */
68 spx_int32_t bitrate; /**< Bit-rate used */
69 spx_int32_t frame_size; /**< Size of frames */
70 spx_int32_t vbr; /**< 1 for a VBR encoding, 0 otherwise */
71 spx_int32_t frames_per_packet; /**< Number of frames stored per Ogg packet */
72 spx_int32_t extra_headers; /**< Number of additional headers after the comments */
73 spx_int32_t reserved1; /**< Reserved for future use, must be zero */
74 spx_int32_t reserved2; /**< Reserved for future use, must be zero */
75} SpeexHeader;
76
77/** Initializes a SpeexHeader using basic information */
78void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const struct SpeexMode *m);
79
80/** Creates the header packet from the header itself (mostly involves endianness conversion) */
81char *speex_header_to_packet(SpeexHeader *header, int *size);
82
83/** Creates a SpeexHeader from a packet */
84SpeexHeader *speex_packet_to_header(char *packet, int size);
85
86#ifdef __cplusplus
87}
88#endif
89
90/** @} */
91#endif
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex_jitter.h b/lib/rbcodec/codecs/libspeex/speex/speex_jitter.h
new file mode 100644
index 0000000000..03bac15636
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex_jitter.h
@@ -0,0 +1,197 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file speex_jitter.h
4 @brief Adaptive jitter buffer for Speex
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#ifndef SPEEX_JITTER_H
37#define SPEEX_JITTER_H
38/** @defgroup JitterBuffer JitterBuffer: Adaptive jitter buffer
39 * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size
40 * to maintain good quality and low latency.
41 * @{
42 */
43
44#include "speex_types.h"
45
46#ifdef __cplusplus
47extern "C" {
48#endif
49
50/** Generic adaptive jitter buffer state */
51struct JitterBuffer_;
52
53/** Generic adaptive jitter buffer state */
54typedef struct JitterBuffer_ JitterBuffer;
55
56/** Definition of an incoming packet */
57typedef struct _JitterBufferPacket JitterBufferPacket;
58
59/** Definition of an incoming packet */
60struct _JitterBufferPacket {
61 char *data; /**< Data bytes contained in the packet */
62 spx_uint32_t len; /**< Length of the packet in bytes */
63 spx_uint32_t timestamp; /**< Timestamp for the packet */
64 spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */
65 spx_uint16_t sequence; /**< RTP Sequence number if available (0 otherwise) */
66 spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */
67};
68
69/** Packet has been retrieved */
70#define JITTER_BUFFER_OK 0
71/** Packet is lost or is late */
72#define JITTER_BUFFER_MISSING 1
73/** A "fake" packet is meant to be inserted here to increase buffering */
74#define JITTER_BUFFER_INSERTION 2
75/** There was an error in the jitter buffer */
76#define JITTER_BUFFER_INTERNAL_ERROR -1
77/** Invalid argument */
78#define JITTER_BUFFER_BAD_ARGUMENT -2
79
80
81/** Set minimum amount of extra buffering required (margin) */
82#define JITTER_BUFFER_SET_MARGIN 0
83/** Get minimum amount of extra buffering required (margin) */
84#define JITTER_BUFFER_GET_MARGIN 1
85/* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */
86
87/** Get the amount of available packets currently buffered */
88#define JITTER_BUFFER_GET_AVAILABLE_COUNT 3
89/** Included because of an early misspelling (will remove in next release) */
90#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3
91
92/** Assign a function to destroy unused packet. When setting that, the jitter
93 buffer no longer copies packet data. */
94#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4
95/** */
96#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5
97
98/** Tell the jitter buffer to only adjust the delay in multiples of the step parameter provided */
99#define JITTER_BUFFER_SET_DELAY_STEP 6
100/** */
101#define JITTER_BUFFER_GET_DELAY_STEP 7
102
103/** Tell the jitter buffer to only do concealment in multiples of the size parameter provided */
104#define JITTER_BUFFER_SET_CONCEALMENT_SIZE 8
105#define JITTER_BUFFER_GET_CONCEALMENT_SIZE 9
106
107/** Absolute max amount of loss that can be tolerated regardless of the delay. Typical loss
108 should be half of that or less. */
109#define JITTER_BUFFER_SET_MAX_LATE_RATE 10
110#define JITTER_BUFFER_GET_MAX_LATE_RATE 11
111
112/** Equivalent cost of one percent late packet in timestamp units */
113#define JITTER_BUFFER_SET_LATE_COST 12
114#define JITTER_BUFFER_GET_LATE_COST 13
115
116
117/** Initialises jitter buffer
118 *
119 * @param step_size Starting value for the size of concleanment packets and delay
120 adjustment steps. Can be changed at any time using JITTER_BUFFER_SET_DELAY_STEP
121 and JITTER_BUFFER_GET_CONCEALMENT_SIZE.
122 * @return Newly created jitter buffer state
123 */
124JitterBuffer *jitter_buffer_init(int step_size);
125
126/** Restores jitter buffer to its original state
127 *
128 * @param jitter Jitter buffer state
129 */
130void jitter_buffer_reset(JitterBuffer *jitter);
131
132/** Destroys jitter buffer
133 *
134 * @param jitter Jitter buffer state
135 */
136void jitter_buffer_destroy(JitterBuffer *jitter);
137
138/** Put one packet into the jitter buffer
139 *
140 * @param jitter Jitter buffer state
141 * @param packet Incoming packet
142*/
143void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet);
144
145/** Get one packet from the jitter buffer
146 *
147 * @param jitter Jitter buffer state
148 * @param packet Returned packet
149 * @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee)
150 * @param current_timestamp Timestamp for the returned packet
151*/
152int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset);
153
154/** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp.
155 * This is mainly useful for media where a single "frame" can be split into several packets.
156 *
157 * @param jitter Jitter buffer state
158 * @param packet Returned packet
159 */
160int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet);
161
162/** Get pointer timestamp of jitter buffer
163 *
164 * @param jitter Jitter buffer state
165*/
166int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter);
167
168/** Advance by one tick
169 *
170 * @param jitter Jitter buffer state
171*/
172void jitter_buffer_tick(JitterBuffer *jitter);
173
174/** Telling the jitter buffer about the remaining data in the application buffer
175 * @param jitter Jitter buffer state
176 * @param rem Amount of data buffered by the application (timestamp units)
177 */
178void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem);
179
180/** Used like the ioctl function to control the jitter buffer parameters
181 *
182 * @param jitter Jitter buffer state
183 * @param request ioctl-type request (one of the JITTER_BUFFER_* macros)
184 * @param ptr Data exchanged to-from function
185 * @return 0 if no error, -1 if request in unknown
186*/
187int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr);
188
189int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset);
190
191/* @} */
192
193#ifdef __cplusplus
194}
195#endif
196
197#endif
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex_preprocess.h b/lib/rbcodec/codecs/libspeex/speex/speex_preprocess.h
new file mode 100644
index 0000000000..273efaff79
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex_preprocess.h
@@ -0,0 +1,190 @@
1/* Copyright (C) 2003 Epic Games
2 Written by Jean-Marc Valin */
3/**
4 * @file speex_preprocess.h
5 * @brief Speex preprocessor. The preprocess can do noise suppression,
6 * residual echo suppression (after using the echo canceller), automatic
7 * gain control (AGC) and voice activity detection (VAD).
8*/
9/*
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions are
12 met:
13
14 1. Redistributions of source code must retain the above copyright notice,
15 this list of conditions and the following disclaimer.
16
17 2. Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
20
21 3. The name of the author may not be used to endorse or promote products
22 derived from this software without specific prior written permission.
23
24 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
28 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 POSSIBILITY OF SUCH DAMAGE.
35*/
36
37#ifndef SPEEX_PREPROCESS_H
38#define SPEEX_PREPROCESS_H
39/** @defgroup SpeexPreprocessState SpeexPreprocessState: The Speex preprocessor
40 * This is the Speex preprocessor. The preprocess can do noise suppression,
41 * residual echo suppression (after using the echo canceller), automatic
42 * gain control (AGC) and voice activity detection (VAD).
43 * @{
44 */
45
46#include "speex_types.h"
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52/** State of the preprocessor (one per channel). Should never be accessed directly. */
53struct SpeexPreprocessState_;
54
55/** State of the preprocessor (one per channel). Should never be accessed directly. */
56typedef struct SpeexPreprocessState_ SpeexPreprocessState;
57
58
59/** Creates a new preprocessing state. You MUST create one state per channel processed.
60 * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms). Must be
61 * the same value as that used for the echo canceller for residual echo cancellation to work.
62 * @param sampling_rate Sampling rate used for the input.
63 * @return Newly created preprocessor state
64*/
65SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate);
66
67/** Destroys a preprocessor state
68 * @param st Preprocessor state to destroy
69*/
70void speex_preprocess_state_destroy(SpeexPreprocessState *st);
71
72/** Preprocess a frame
73 * @param st Preprocessor state
74 * @param x Audio sample vector (in and out). Must be same size as specified in speex_preprocess_state_init().
75 * @return Bool value for voice activity (1 for speech, 0 for noise/silence), ONLY if VAD turned on.
76*/
77int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x);
78
79/** Preprocess a frame (deprecated, use speex_preprocess_run() instead)*/
80int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo);
81
82/** Update preprocessor state, but do not compute the output
83 * @param st Preprocessor state
84 * @param x Audio sample vector (in only). Must be same size as specified in speex_preprocess_state_init().
85*/
86void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x);
87
88/** Used like the ioctl function to control the preprocessor parameters
89 * @param st Preprocessor state
90 * @param request ioctl-type request (one of the SPEEX_PREPROCESS_* macros)
91 * @param ptr Data exchanged to-from function
92 * @return 0 if no error, -1 if request in unknown
93*/
94int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr);
95
96
97
98/** Set preprocessor denoiser state */
99#define SPEEX_PREPROCESS_SET_DENOISE 0
100/** Get preprocessor denoiser state */
101#define SPEEX_PREPROCESS_GET_DENOISE 1
102
103/** Set preprocessor Automatic Gain Control state */
104#define SPEEX_PREPROCESS_SET_AGC 2
105/** Get preprocessor Automatic Gain Control state */
106#define SPEEX_PREPROCESS_GET_AGC 3
107
108/** Set preprocessor Voice Activity Detection state */
109#define SPEEX_PREPROCESS_SET_VAD 4
110/** Get preprocessor Voice Activity Detection state */
111#define SPEEX_PREPROCESS_GET_VAD 5
112
113/** Set preprocessor Automatic Gain Control level */
114#define SPEEX_PREPROCESS_SET_AGC_LEVEL 6
115/** Get preprocessor Automatic Gain Control level */
116#define SPEEX_PREPROCESS_GET_AGC_LEVEL 7
117
118/** Set preprocessor dereverb state */
119#define SPEEX_PREPROCESS_SET_DEREVERB 8
120/** Get preprocessor dereverb state */
121#define SPEEX_PREPROCESS_GET_DEREVERB 9
122
123/** Set preprocessor dereverb level */
124#define SPEEX_PREPROCESS_SET_DEREVERB_LEVEL 10
125/** Get preprocessor dereverb level */
126#define SPEEX_PREPROCESS_GET_DEREVERB_LEVEL 11
127
128/** Set preprocessor dereverb decay */
129#define SPEEX_PREPROCESS_SET_DEREVERB_DECAY 12
130/** Get preprocessor dereverb decay */
131#define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13
132
133/** Set probability required for the VAD to go from silence to voice */
134#define SPEEX_PREPROCESS_SET_PROB_START 14
135/** Get probability required for the VAD to go from silence to voice */
136#define SPEEX_PREPROCESS_GET_PROB_START 15
137
138/** Set probability required for the VAD to stay in the voice state (integer percent) */
139#define SPEEX_PREPROCESS_SET_PROB_CONTINUE 16
140/** Get probability required for the VAD to stay in the voice state (integer percent) */
141#define SPEEX_PREPROCESS_GET_PROB_CONTINUE 17
142
143/** Set maximum attenuation of the noise in dB (negative number) */
144#define SPEEX_PREPROCESS_SET_NOISE_SUPPRESS 18
145/** Get maximum attenuation of the noise in dB (negative number) */
146#define SPEEX_PREPROCESS_GET_NOISE_SUPPRESS 19
147
148/** Set maximum attenuation of the residual echo in dB (negative number) */
149#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS 20
150/** Get maximum attenuation of the residual echo in dB (negative number) */
151#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS 21
152
153/** Set maximum attenuation of the residual echo in dB when near end is active (negative number) */
154#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE 22
155/** Get maximum attenuation of the residual echo in dB when near end is active (negative number) */
156#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE 23
157
158/** Set the corresponding echo canceller state so that residual echo suppression can be performed (NULL for no residual echo suppression) */
159#define SPEEX_PREPROCESS_SET_ECHO_STATE 24
160/** Get the corresponding echo canceller state */
161#define SPEEX_PREPROCESS_GET_ECHO_STATE 25
162
163/** Set maximal gain increase in dB/second (int32) */
164#define SPEEX_PREPROCESS_SET_AGC_INCREMENT 26
165
166/** Get maximal gain increase in dB/second (int32) */
167#define SPEEX_PREPROCESS_GET_AGC_INCREMENT 27
168
169/** Set maximal gain decrease in dB/second (int32) */
170#define SPEEX_PREPROCESS_SET_AGC_DECREMENT 28
171
172/** Get maximal gain decrease in dB/second (int32) */
173#define SPEEX_PREPROCESS_GET_AGC_DECREMENT 29
174
175/** Set maximal gain in dB (int32) */
176#define SPEEX_PREPROCESS_SET_AGC_MAX_GAIN 30
177
178/** Get maximal gain in dB (int32) */
179#define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31
180
181/* Can't set loudness */
182/** Get loudness */
183#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33
184
185#ifdef __cplusplus
186}
187#endif
188
189/** @}*/
190#endif
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex_resampler.h b/lib/rbcodec/codecs/libspeex/speex/speex_resampler.h
new file mode 100644
index 0000000000..c44fbcd0d1
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex_resampler.h
@@ -0,0 +1,328 @@
1/* Copyright (C) 2007 Jean-Marc Valin
2
3 File: speex_resampler.h
4 Resampling code
5
6 The design goals of this code are:
7 - Very fast algorithm
8 - Low memory requirement
9 - Good *perceptual* quality (and not best SNR)
10
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions are
13 met:
14
15 1. Redistributions of source code must retain the above copyright notice,
16 this list of conditions and the following disclaimer.
17
18 2. Redistributions in binary form must reproduce the above copyright
19 notice, this list of conditions and the following disclaimer in the
20 documentation and/or other materials provided with the distribution.
21
22 3. The name of the author may not be used to endorse or promote products
23 derived from this software without specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
29 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 POSSIBILITY OF SUCH DAMAGE.
36*/
37
38
39#ifndef SPEEX_RESAMPLER_H
40#define SPEEX_RESAMPLER_H
41
42#ifdef OUTSIDE_SPEEX
43
44/********* WARNING: MENTAL SANITY ENDS HERE *************/
45
46/* If the resampler is defined outside of Speex, we change the symbol names so that
47 there won't be any clash if linking with Speex later on. */
48
49/* #define RANDOM_PREFIX your software name here */
50#ifndef RANDOM_PREFIX
51#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes"
52#endif
53
54#define CAT_PREFIX2(a,b) a ## b
55#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)
56
57#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)
58#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)
59#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)
60#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float)
61#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int)
62#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float)
63#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int)
64#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate)
65#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate)
66#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac)
67#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio)
68#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality)
69#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality)
70#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride)
71#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride)
72#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride)
73#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride)
74#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros)
75#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
76#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
77
78#define spx_int16_t short
79#define spx_int32_t int
80#define spx_uint16_t unsigned short
81#define spx_uint32_t unsigned int
82
83#else /* OUTSIDE_SPEEX */
84
85#include "speex/speex_types.h"
86
87#endif /* OUTSIDE_SPEEX */
88
89#ifdef __cplusplus
90extern "C" {
91#endif
92
93#define SPEEX_RESAMPLER_QUALITY_MAX 10
94#define SPEEX_RESAMPLER_QUALITY_MIN 0
95#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
96#define SPEEX_RESAMPLER_QUALITY_VOIP 3
97#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
98
99enum {
100 RESAMPLER_ERR_SUCCESS = 0,
101 RESAMPLER_ERR_ALLOC_FAILED = 1,
102 RESAMPLER_ERR_BAD_STATE = 2,
103 RESAMPLER_ERR_INVALID_ARG = 3,
104 RESAMPLER_ERR_PTR_OVERLAP = 4,
105
106 RESAMPLER_ERR_MAX_ERROR
107};
108
109struct SpeexResamplerState_;
110typedef struct SpeexResamplerState_ SpeexResamplerState;
111
112/** Create a new resampler with integer input and output rates.
113 * @param nb_channels Number of channels to be processed
114 * @param in_rate Input sampling rate (integer number of Hz).
115 * @param out_rate Output sampling rate (integer number of Hz).
116 * @param quality Resampling quality between 0 and 10, where 0 has poor quality
117 * and 10 has very high quality.
118 * @return Newly created resampler state
119 * @retval NULL Error: not enough memory
120 */
121SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,
122 spx_uint32_t in_rate,
123 spx_uint32_t out_rate,
124 int quality,
125 int *err);
126
127/** Create a new resampler with fractional input/output rates. The sampling
128 * rate ratio is an arbitrary rational number with both the numerator and
129 * denominator being 32-bit integers.
130 * @param nb_channels Number of channels to be processed
131 * @param ratio_num Numerator of the sampling rate ratio
132 * @param ratio_den Denominator of the sampling rate ratio
133 * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
134 * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
135 * @param quality Resampling quality between 0 and 10, where 0 has poor quality
136 * and 10 has very high quality.
137 * @return Newly created resampler state
138 * @retval NULL Error: not enough memory
139 */
140SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
141 spx_uint32_t ratio_num,
142 spx_uint32_t ratio_den,
143 spx_uint32_t in_rate,
144 spx_uint32_t out_rate,
145 int quality,
146 int *err);
147
148/** Destroy a resampler state.
149 * @param st Resampler state
150 */
151void speex_resampler_destroy(SpeexResamplerState *st);
152
153/** Resample a float array. The input and output buffers must *not* overlap.
154 * @param st Resampler state
155 * @param channel_index Index of the channel to process for the multi-channel
156 * base (0 otherwise)
157 * @param in Input buffer
158 * @param in_len Number of input samples in the input buffer. Returns the
159 * number of samples processed
160 * @param out Output buffer
161 * @param out_len Size of the output buffer. Returns the number of samples written
162 */
163int speex_resampler_process_float(SpeexResamplerState *st,
164 spx_uint32_t channel_index,
165 const float *in,
166 spx_uint32_t *in_len,
167 float *out,
168 spx_uint32_t *out_len);
169
170/** Resample an int array. The input and output buffers must *not* overlap.
171 * @param st Resampler state
172 * @param channel_index Index of the channel to process for the multi-channel
173 * base (0 otherwise)
174 * @param in Input buffer
175 * @param in_len Number of input samples in the input buffer. Returns the number
176 * of samples processed
177 * @param out Output buffer
178 * @param out_len Size of the output buffer. Returns the number of samples written
179 */
180int speex_resampler_process_int(SpeexResamplerState *st,
181 spx_uint32_t channel_index,
182 const spx_int16_t *in,
183 spx_uint32_t *in_len,
184 spx_int16_t *out,
185 spx_uint32_t *out_len);
186
187/** Resample an interleaved float array. The input and output buffers must *not* overlap.
188 * @param st Resampler state
189 * @param in Input buffer
190 * @param in_len Number of input samples in the input buffer. Returns the number
191 * of samples processed. This is all per-channel.
192 * @param out Output buffer
193 * @param out_len Size of the output buffer. Returns the number of samples written.
194 * This is all per-channel.
195 */
196int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
197 const float *in,
198 spx_uint32_t *in_len,
199 float *out,
200 spx_uint32_t *out_len);
201
202/** Resample an interleaved int array. The input and output buffers must *not* overlap.
203 * @param st Resampler state
204 * @param in Input buffer
205 * @param in_len Number of input samples in the input buffer. Returns the number
206 * of samples processed. This is all per-channel.
207 * @param out Output buffer
208 * @param out_len Size of the output buffer. Returns the number of samples written.
209 * This is all per-channel.
210 */
211int speex_resampler_process_interleaved_int(SpeexResamplerState *st,
212 const spx_int16_t *in,
213 spx_uint32_t *in_len,
214 spx_int16_t *out,
215 spx_uint32_t *out_len);
216
217/** Set (change) the input/output sampling rates (integer value).
218 * @param st Resampler state
219 * @param in_rate Input sampling rate (integer number of Hz).
220 * @param out_rate Output sampling rate (integer number of Hz).
221 */
222int speex_resampler_set_rate(SpeexResamplerState *st,
223 spx_uint32_t in_rate,
224 spx_uint32_t out_rate);
225
226/** Get the current input/output sampling rates (integer value).
227 * @param st Resampler state
228 * @param in_rate Input sampling rate (integer number of Hz) copied.
229 * @param out_rate Output sampling rate (integer number of Hz) copied.
230 */
231void speex_resampler_get_rate(SpeexResamplerState *st,
232 spx_uint32_t *in_rate,
233 spx_uint32_t *out_rate);
234
235/** Set (change) the input/output sampling rates and resampling ratio
236 * (fractional values in Hz supported).
237 * @param st Resampler state
238 * @param ratio_num Numerator of the sampling rate ratio
239 * @param ratio_den Denominator of the sampling rate ratio
240 * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
241 * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
242 */
243int speex_resampler_set_rate_frac(SpeexResamplerState *st,
244 spx_uint32_t ratio_num,
245 spx_uint32_t ratio_den,
246 spx_uint32_t in_rate,
247 spx_uint32_t out_rate);
248
249/** Get the current resampling ratio. This will be reduced to the least
250 * common denominator.
251 * @param st Resampler state
252 * @param ratio_num Numerator of the sampling rate ratio copied
253 * @param ratio_den Denominator of the sampling rate ratio copied
254 */
255void speex_resampler_get_ratio(SpeexResamplerState *st,
256 spx_uint32_t *ratio_num,
257 spx_uint32_t *ratio_den);
258
259/** Set (change) the conversion quality.
260 * @param st Resampler state
261 * @param quality Resampling quality between 0 and 10, where 0 has poor
262 * quality and 10 has very high quality.
263 */
264int speex_resampler_set_quality(SpeexResamplerState *st,
265 int quality);
266
267/** Get the conversion quality.
268 * @param st Resampler state
269 * @param quality Resampling quality between 0 and 10, where 0 has poor
270 * quality and 10 has very high quality.
271 */
272void speex_resampler_get_quality(SpeexResamplerState *st,
273 int *quality);
274
275/** Set (change) the input stride.
276 * @param st Resampler state
277 * @param stride Input stride
278 */
279void speex_resampler_set_input_stride(SpeexResamplerState *st,
280 spx_uint32_t stride);
281
282/** Get the input stride.
283 * @param st Resampler state
284 * @param stride Input stride copied
285 */
286void speex_resampler_get_input_stride(SpeexResamplerState *st,
287 spx_uint32_t *stride);
288
289/** Set (change) the output stride.
290 * @param st Resampler state
291 * @param stride Output stride
292 */
293void speex_resampler_set_output_stride(SpeexResamplerState *st,
294 spx_uint32_t stride);
295
296/** Get the output stride.
297 * @param st Resampler state copied
298 * @param stride Output stride
299 */
300void speex_resampler_get_output_stride(SpeexResamplerState *st,
301 spx_uint32_t *stride);
302
303/** Make sure that the first samples to go out of the resamplers don't have
304 * leading zeros. This is only useful before starting to use a newly created
305 * resampler. It is recommended to use that when resampling an audio file, as
306 * it will generate a file with the same length. For real-time processing,
307 * it is probably easier not to use this call (so that the output duration
308 * is the same for the first frame).
309 * @param st Resampler state
310 */
311int speex_resampler_skip_zeros(SpeexResamplerState *st);
312
313/** Reset a resampler so a new (unrelated) stream can be processed.
314 * @param st Resampler state
315 */
316int speex_resampler_reset_mem(SpeexResamplerState *st);
317
318/** Returns the English meaning for an error code
319 * @param err Error code
320 * @return English string
321 */
322const char *speex_resampler_strerror(int err);
323
324#ifdef __cplusplus
325}
326#endif
327
328#endif
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex_stereo.h b/lib/rbcodec/codecs/libspeex/speex/speex_stereo.h
new file mode 100644
index 0000000000..67e2a8d4e0
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex_stereo.h
@@ -0,0 +1,91 @@
1/* Copyright (C) 2002 Jean-Marc Valin*/
2/**
3 @file speex_stereo.h
4 @brief Describes the handling for intensity stereo
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef STEREO_H
36#define STEREO_H
37/** @defgroup SpeexStereoState SpeexStereoState: Handling Speex stereo files
38 * This describes the Speex intensity stereo encoding/decoding
39 * @{
40 */
41
42#include "speex_types.h"
43#include "speex_bits.h"
44
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49/** If you access any of these fields directly, I'll personally come and bite you */
50typedef struct SpeexStereoState {
51 float balance; /**< Left/right balance info */
52 float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */
53 float smooth_left; /**< Smoothed left channel gain */
54 float smooth_right; /**< Smoothed right channel gain */
55 float reserved1; /**< Reserved for future use */
56 float reserved2; /**< Reserved for future use */
57} SpeexStereoState;
58
59/** Deprecated. Use speex_stereo_state_init() instead. */
60#define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0}
61
62/** Initialise/create a stereo stereo state */
63SpeexStereoState *speex_stereo_state_init(void);
64
65/** Reset/re-initialise an already allocated stereo state */
66void speex_stereo_state_reset(SpeexStereoState *stereo);
67
68/** Destroy a stereo stereo state */
69void speex_stereo_state_destroy(SpeexStereoState *stereo);
70
71/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */
72void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits);
73
74/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */
75void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits);
76
77/** Transforms a mono frame into a stereo frame using intensity stereo info */
78void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo);
79
80/** Transforms a mono frame into a stereo frame using intensity stereo info */
81void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo);
82
83/** Callback handler for intensity stereo info */
84int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data);
85
86#ifdef __cplusplus
87}
88#endif
89
90/** @} */
91#endif
diff --git a/lib/rbcodec/codecs/libspeex/speex/speex_types.h b/lib/rbcodec/codecs/libspeex/speex/speex_types.h
new file mode 100644
index 0000000000..a2ff1d6b53
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex/speex_types.h
@@ -0,0 +1,126 @@
1/* speex_types.h taken from libogg */
2/********************************************************************
3 * *
4 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * *
9 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
10 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 * *
12 ********************************************************************
13
14 function: #ifdef jail to whip a few platforms into the UNIX ideal.
15 last mod: $Id$
16
17 ********************************************************************/
18/**
19 @file speex_types.h
20 @brief Speex types
21*/
22#ifndef _SPEEX_TYPES_H
23#define _SPEEX_TYPES_H
24
25#if defined(_WIN32)
26
27# if defined(__CYGWIN__)
28# include <_G_config.h>
29 typedef _G_int32_t spx_int32_t;
30 typedef _G_uint32_t spx_uint32_t;
31 typedef _G_int16_t spx_int16_t;
32 typedef _G_uint16_t spx_uint16_t;
33# elif defined(__MINGW32__)
34 typedef short spx_int16_t;
35 typedef unsigned short spx_uint16_t;
36 typedef int spx_int32_t;
37 typedef unsigned int spx_uint32_t;
38# elif defined(__MWERKS__)
39 typedef int spx_int32_t;
40 typedef unsigned int spx_uint32_t;
41 typedef short spx_int16_t;
42 typedef unsigned short spx_uint16_t;
43# else
44 /* MSVC/Borland */
45 typedef __int32 spx_int32_t;
46 typedef unsigned __int32 spx_uint32_t;
47 typedef __int16 spx_int16_t;
48 typedef unsigned __int16 spx_uint16_t;
49# endif
50
51#elif defined(__MACOS__)
52
53# include <sys/types.h>
54 typedef SInt16 spx_int16_t;
55 typedef UInt16 spx_uint16_t;
56 typedef SInt32 spx_int32_t;
57 typedef UInt32 spx_uint32_t;
58
59#elif defined(__MACOSX__) /* MacOS X Framework build */
60
61# include <sys/types.h>
62 typedef int16_t spx_int16_t;
63 typedef u_int16_t spx_uint16_t;
64 typedef int32_t spx_int32_t;
65 typedef u_int32_t spx_uint32_t;
66
67#elif defined(__BEOS__)
68
69 /* Be */
70# include <inttypes.h>
71 typedef int16_t spx_int16_t;
72 typedef u_int16_t spx_uint16_t;
73 typedef int32_t spx_int32_t;
74 typedef u_int32_t spx_uint32_t;
75
76#elif defined (__EMX__)
77
78 /* OS/2 GCC */
79 typedef short spx_int16_t;
80 typedef unsigned short spx_uint16_t;
81 typedef int spx_int32_t;
82 typedef unsigned int spx_uint32_t;
83
84#elif defined (DJGPP)
85
86 /* DJGPP */
87 typedef short spx_int16_t;
88 typedef int spx_int32_t;
89 typedef unsigned int spx_uint32_t;
90
91#elif defined(R5900)
92
93 /* PS2 EE */
94 typedef int spx_int32_t;
95 typedef unsigned spx_uint32_t;
96 typedef short spx_int16_t;
97
98#elif defined(__SYMBIAN32__)
99
100 /* Symbian GCC */
101 typedef signed short spx_int16_t;
102 typedef unsigned short spx_uint16_t;
103 typedef signed int spx_int32_t;
104 typedef unsigned int spx_uint32_t;
105
106#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
107
108 typedef short spx_int16_t;
109 typedef unsigned short spx_uint16_t;
110 typedef long spx_int32_t;
111 typedef unsigned long spx_uint32_t;
112
113#elif defined(CONFIG_TI_C6X)
114
115 typedef short spx_int16_t;
116 typedef unsigned short spx_uint16_t;
117 typedef int spx_int32_t;
118 typedef unsigned int spx_uint32_t;
119
120#else
121
122# include "speex_config_types.h"
123
124#endif
125
126#endif /* _SPEEX_TYPES_H */
diff --git a/lib/rbcodec/codecs/libspeex/speex_callbacks.c b/lib/rbcodec/codecs/libspeex/speex_callbacks.c
new file mode 100644
index 0000000000..f1de038488
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex_callbacks.c
@@ -0,0 +1,160 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File speex_callbacks.c
3 Callback handling and in-band signalling
4
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35#ifdef HAVE_CONFIG_H
36#include "config-speex.h"
37#endif
38
39#include "speex/speex_callbacks.h"
40#include "arch.h"
41#include "os_support.h"
42
43int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state)
44{
45 int id;
46 SpeexCallback *callback;
47 /*speex_bits_advance(bits, 5);*/
48 id=speex_bits_unpack_unsigned(bits, 4);
49 callback = callback_list+id;
50
51 if (callback->func)
52 {
53 return callback->func(bits, state, callback->data);
54 } else
55 /*If callback is not registered, skip the right number of bits*/
56 {
57 int adv;
58 if (id<2)
59 adv = 1;
60 else if (id<8)
61 adv = 4;
62 else if (id<10)
63 adv = 8;
64 else if (id<12)
65 adv = 16;
66 else if (id<14)
67 adv = 32;
68 else
69 adv = 64;
70 speex_bits_advance(bits, adv);
71 }
72 return 0;
73}
74
75#if 0
76/* Rockbox: unused */
77int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data)
78{
79 (void)state;
80 spx_int32_t m;
81 m = speex_bits_unpack_unsigned(bits, 4);
82 speex_encoder_ctl(data, SPEEX_SET_MODE, &m);
83 return 0;
84}
85
86int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data)
87{
88 (void)state;
89 spx_int32_t m;
90 m = speex_bits_unpack_unsigned(bits, 4);
91 speex_encoder_ctl(data, SPEEX_SET_LOW_MODE, &m);
92 return 0;
93}
94
95int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data)
96{
97 (void)state;
98 spx_int32_t m;
99 m = speex_bits_unpack_unsigned(bits, 4);
100 speex_encoder_ctl(data, SPEEX_SET_HIGH_MODE, &m);
101 return 0;
102}
103#endif
104
105#ifndef DISABLE_VBR
106int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
107{
108 (void)state;
109 spx_int32_t vbr;
110 vbr = speex_bits_unpack_unsigned(bits, 1);
111 speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr);
112 return 0;
113}
114#endif /* #ifndef DISABLE_VBR */
115
116#if 0
117/* Rockbox: unused */
118int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
119{
120 (void)state;
121 spx_int32_t enh;
122 enh = speex_bits_unpack_unsigned(bits, 1);
123 speex_decoder_ctl(data, SPEEX_SET_ENH, &enh);
124 return 0;
125}
126#endif
127
128#ifndef DISABLE_VBR
129int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data)
130{
131 (void)state;
132 float qual;
133 qual = speex_bits_unpack_unsigned(bits, 4);
134 speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual);
135 return 0;
136}
137#endif /* #ifndef DISABLE_VBR */
138
139#if 0
140/* Rockbox: unused */
141int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
142{
143 (void)state;
144 unsigned char ch;
145 ch = speex_bits_unpack_unsigned(bits, 8);
146 _speex_putc(ch, data);
147 /*printf("speex_std_char_handler ch=%x\n", ch);*/
148 return 0;
149}
150#endif
151
152/* Default handler for user callbacks: skip it */
153int speex_default_user_handler(SpeexBits *bits, void *state, void *data)
154{
155 (void)state;
156 (void)data;
157 int req_size = speex_bits_unpack_unsigned(bits, 4);
158 speex_bits_advance(bits, 5+8*req_size);
159 return 0;
160}
diff --git a/lib/rbcodec/codecs/libspeex/speex_header.c b/lib/rbcodec/codecs/libspeex/speex_header.c
new file mode 100644
index 0000000000..b0e98b7c9c
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/speex_header.c
@@ -0,0 +1,188 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: speex_header.c
3 Describes the Speex header
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32*/
33
34#ifdef HAVE_CONFIG_H
35#include "config-speex.h"
36#endif
37
38#include "arch.h"
39#include "speex/speex_header.h"
40#include "speex/speex.h"
41#include "os_support.h"
42
43#ifndef NULL
44#define NULL 0
45#endif
46
47/** Convert little endian */
48static inline spx_int32_t le_int(spx_int32_t i)
49{
50#ifdef ROCKBOX
51 return letoh32(i);
52#elif !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
53 spx_uint32_t ui, ret;
54 ui = i;
55 ret = ui>>24;
56 ret |= (ui>>8)&0x0000ff00;
57 ret |= (ui<<8)&0x00ff0000;
58 ret |= (ui<<24);
59 return ret;
60#else
61 return i;
62#endif
63}
64
65#define ENDIAN_SWITCH(x) {x=le_int(x);}
66
67
68/*
69typedef struct SpeexHeader {
70 char speex_string[8];
71 char speex_version[SPEEX_HEADER_VERSION_LENGTH];
72 int speex_version_id;
73 int header_size;
74 int rate;
75 int mode;
76 int mode_bitstream_version;
77 int nb_channels;
78 int bitrate;
79 int frame_size;
80 int vbr;
81 int frames_per_packet;
82 int extra_headers;
83 int reserved1;
84 int reserved2;
85} SpeexHeader;
86*/
87
88#ifndef SPEEX_DISABLE_ENCODER
89void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m)
90{
91 int i;
92 const char *h="Speex ";
93 /*
94 strncpy(header->speex_string, "Speex ", 8);
95 strncpy(header->speex_version, SPEEX_VERSION, SPEEX_HEADER_VERSION_LENGTH-1);
96 header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0;
97 */
98 for (i=0;i<8;i++)
99 header->speex_string[i]=h[i];
100 for (i=0;i<SPEEX_HEADER_VERSION_LENGTH-1 && SPEEX_VERSION[i];i++)
101 header->speex_version[i]=SPEEX_VERSION[i];
102 for (;i<SPEEX_HEADER_VERSION_LENGTH;i++)
103 header->speex_version[i]=0;
104
105 header->speex_version_id = 1;
106 header->header_size = sizeof(SpeexHeader);
107
108 header->rate = rate;
109 header->mode = m->modeID;
110 header->mode_bitstream_version = m->bitstream_version;
111 if (m->modeID<0)
112 speex_warning("This mode is meant to be used alone");
113 header->nb_channels = nb_channels;
114 header->bitrate = -1;
115 speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size);
116 header->vbr = 0;
117
118 header->frames_per_packet = 0;
119 header->extra_headers = 0;
120 header->reserved1 = 0;
121 header->reserved2 = 0;
122}
123
124char *speex_header_to_packet(SpeexHeader *header, int *size)
125{
126 SpeexHeader *le_header;
127 le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
128
129 SPEEX_COPY(le_header, header, 1);
130
131 /*Make sure everything is now little-endian*/
132 ENDIAN_SWITCH(le_header->speex_version_id);
133 ENDIAN_SWITCH(le_header->header_size);
134 ENDIAN_SWITCH(le_header->rate);
135 ENDIAN_SWITCH(le_header->mode);
136 ENDIAN_SWITCH(le_header->mode_bitstream_version);
137 ENDIAN_SWITCH(le_header->nb_channels);
138 ENDIAN_SWITCH(le_header->bitrate);
139 ENDIAN_SWITCH(le_header->frame_size);
140 ENDIAN_SWITCH(le_header->vbr);
141 ENDIAN_SWITCH(le_header->frames_per_packet);
142 ENDIAN_SWITCH(le_header->extra_headers);
143
144 *size = sizeof(SpeexHeader);
145 return (char *)le_header;
146}
147#endif /* SPEEX_DISABLE_ENCODER */
148
149static SpeexHeader global_le_header; /* Avoid malloc */
150SpeexHeader *speex_packet_to_header(char *packet, int size)
151{
152 int i;
153 SpeexHeader *le_header = &global_le_header;
154 const char *h = "Speex ";
155 for (i=0;i<8;i++)
156 if (packet[i]!=h[i])
157 {
158 speex_notify("This doesn't look like a Speex file");
159 return NULL;
160 }
161
162 /*FIXME: Do we allow larger headers?*/
163 if (size < (int)sizeof(SpeexHeader))
164 {
165 speex_notify("Speex header too small");
166 return NULL;
167 }
168
169 /* le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); */
170
171 SPEEX_COPY(le_header, (SpeexHeader*)packet, 1);
172
173 /*Make sure everything is converted correctly from little-endian*/
174 ENDIAN_SWITCH(le_header->speex_version_id);
175 ENDIAN_SWITCH(le_header->header_size);
176 ENDIAN_SWITCH(le_header->rate);
177 ENDIAN_SWITCH(le_header->mode);
178 ENDIAN_SWITCH(le_header->mode_bitstream_version);
179 ENDIAN_SWITCH(le_header->nb_channels);
180 ENDIAN_SWITCH(le_header->bitrate);
181 ENDIAN_SWITCH(le_header->frame_size);
182 ENDIAN_SWITCH(le_header->vbr);
183 ENDIAN_SWITCH(le_header->frames_per_packet);
184 ENDIAN_SWITCH(le_header->extra_headers);
185
186 return le_header;
187
188}
diff --git a/lib/rbcodec/codecs/libspeex/stack_alloc.h b/lib/rbcodec/codecs/libspeex/stack_alloc.h
new file mode 100644
index 0000000000..f06f2f6f7f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/stack_alloc.h
@@ -0,0 +1,130 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file stack_alloc.h
4 @brief Temporary memory allocation on stack
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef STACK_ALLOC_H
36#define STACK_ALLOC_H
37
38#include "config-speex.h"
39
40#ifdef USE_ALLOCA
41# ifdef WIN32
42# include <malloc.h>
43# else
44# ifdef HAVE_ALLOCA_H
45# include <alloca.h>
46# else
47# include <stdlib.h>
48# endif
49# endif
50#endif
51
52/**
53 * @def ALIGN(stack, size)
54 *
55 * Aligns the stack to a 'size' boundary
56 *
57 * @param stack Stack
58 * @param size New size boundary
59 */
60
61/**
62 * @def PUSH(stack, size, type)
63 *
64 * Allocates 'size' elements of type 'type' on the stack
65 *
66 * @param stack Stack
67 * @param size Number of elements
68 * @param type Type of element
69 */
70
71/**
72 * @def PUSHS(stack, type)
73 *
74 * Allocates a struct stack
75 *
76 * @param stack Stack
77 * @param type Struct type
78 */
79
80/**
81 * @def VARDECL(var)
82 *
83 * Declare variable on stack
84 *
85 * @param var Variable to declare
86 */
87
88/**
89 * @def ALLOC(var, size, type)
90 *
91 * Allocate 'size' elements of 'type' on stack
92 *
93 * @param var Name of variable to allocate
94 * @param size Number of elements
95 * @param type Type of element
96 */
97
98#ifdef ENABLE_VALGRIND
99
100#include <valgrind/memcheck.h>
101
102#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
103
104#define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
105
106#define PUSHS(stack, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(long)),VALGRIND_MAKE_WRITABLE(stack, (sizeof(type))),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type))))
107
108#else
109
110#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
111
112#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
113
114#define PUSHS(stack, type) (ALIGN((stack),sizeof(long)),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type))))
115
116#endif
117
118#if defined(VAR_ARRAYS)
119#define VARDECL(var)
120#define ALLOC(var, size, type) type var[size]
121#elif defined(USE_ALLOCA)
122#define VARDECL(var) var
123#define ALLOC(var, size, type) var = alloca(sizeof(type)*(size))
124#else
125#define VARDECL(var) var
126#define ALLOC(var, size, type) var = PUSH(stack, size, type)
127#endif
128
129
130#endif
diff --git a/lib/rbcodec/codecs/libspeex/stereo.c b/lib/rbcodec/codecs/libspeex/stereo.c
new file mode 100644
index 0000000000..652d2a6e90
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/stereo.c
@@ -0,0 +1,302 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: stereo.c
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#ifdef HAVE_CONFIG_H
33#include "config-speex.h"
34#endif
35
36#include "speex/speex_stereo.h"
37#include "speex/speex_callbacks.h"
38#include "math_approx.h"
39#include "vq.h"
40#include <math.h>
41#include "os_support.h"
42
43typedef struct RealSpeexStereoState {
44 spx_word32_t balance; /**< Left/right balance info */
45 spx_word32_t e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */
46 spx_word32_t smooth_left; /**< Smoothed left channel gain */
47 spx_word32_t smooth_right; /**< Smoothed right channel gain */
48 spx_uint32_t reserved1; /**< Reserved for future use */
49 spx_int32_t reserved2; /**< Reserved for future use */
50} RealSpeexStereoState;
51
52
53/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/
54#ifndef FIXED_POINT
55static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f};
56static const float e_ratio_quant_bounds[3] = {0.2825f, 0.356f, 0.4485f};
57#else
58static const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384};
59static const spx_word16_t e_ratio_quant_bounds[3] = {9257, 11665, 14696};
60static const spx_word16_t balance_bounds[31] = {18, 23, 30, 38, 49, 63, 81, 104,
61 134, 172, 221, 284, 364, 468, 600, 771,
62 990, 1271, 1632, 2096, 2691, 3455, 4436, 5696,
63 7314, 9392, 12059, 15484, 19882, 25529, 32766};
64#endif
65
66/* This is an ugly compatibility hack that properly resets the stereo state
67 In case it it compiled in fixed-point, but initialised with the deprecated
68 floating point static initialiser */
69#ifdef FIXED_POINT
70#define COMPATIBILITY_HACK(s) do {if ((s)->reserved1 != 0xdeadbeef) speex_stereo_state_reset((SpeexStereoState*)s); } while (0);
71#else
72#define COMPATIBILITY_HACK(s)
73#endif
74
75static SpeexStereoState global_stereo_state;
76SpeexStereoState *speex_stereo_state_init()
77{
78 /* SpeexStereoState *stereo = speex_alloc(sizeof(SpeexStereoState)); */
79 SpeexStereoState *stereo = &global_stereo_state;
80 speex_stereo_state_reset(stereo);
81 return stereo;
82}
83
84void speex_stereo_state_reset(SpeexStereoState *_stereo)
85{
86 RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
87#ifdef FIXED_POINT
88 stereo->balance = 65536;
89 stereo->e_ratio = 16384;
90 stereo->smooth_left = 16384;
91 stereo->smooth_right = 16384;
92 stereo->reserved1 = 0xdeadbeef;
93 stereo->reserved2 = 0;
94#else
95 stereo->balance = 1.0f;
96 stereo->e_ratio = .5f;
97 stereo->smooth_left = 1.f;
98 stereo->smooth_right = 1.f;
99 stereo->reserved1 = 0;
100 stereo->reserved2 = 0;
101#endif
102}
103
104void speex_stereo_state_destroy(SpeexStereoState *stereo)
105{
106 (void)stereo;
107 /* speex_free(stereo); */
108}
109
110#ifndef SPEEX_DISABLE_ENCODER
111#ifndef DISABLE_FLOAT_API
112void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
113{
114 int i, tmp;
115 float e_left=0, e_right=0, e_tot=0;
116 float balance, e_ratio;
117 for (i=0;i<frame_size;i++)
118 {
119 e_left += ((float)data[2*i])*data[2*i];
120 e_right += ((float)data[2*i+1])*data[2*i+1];
121 data[i] = .5*(((float)data[2*i])+data[2*i+1]);
122 e_tot += ((float)data[i])*data[i];
123 }
124 balance=(e_left+1)/(e_right+1);
125 e_ratio = e_tot/(1+e_left+e_right);
126
127 /*Quantization*/
128 speex_bits_pack(bits, 14, 5);
129 speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
130
131 balance=4*log(balance);
132
133 /*Pack sign*/
134 if (balance>0)
135 speex_bits_pack(bits, 0, 1);
136 else
137 speex_bits_pack(bits, 1, 1);
138 balance=floor(.5+fabs(balance));
139 if (balance>30)
140 balance=31;
141
142 speex_bits_pack(bits, (int)balance, 5);
143
144 /* FIXME: this is a hack */
145 tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 4);
146 speex_bits_pack(bits, tmp, 2);
147}
148#endif /* #ifndef DISABLE_FLOAT_API */
149
150void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits)
151{
152 int i, tmp;
153 spx_word32_t e_left=0, e_right=0, e_tot=0;
154 spx_word32_t balance, e_ratio;
155 spx_word32_t largest, smallest;
156 int balance_id;
157#ifdef FIXED_POINT
158 int shift;
159#endif
160
161 /* In band marker */
162 speex_bits_pack(bits, 14, 5);
163 /* Stereo marker */
164 speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
165
166 for (i=0;i<frame_size;i++)
167 {
168 e_left += SHR32(MULT16_16(data[2*i],data[2*i]),8);
169 e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),8);
170#ifdef FIXED_POINT
171 /* I think this is actually unbiased */
172 data[i] = SHR16(data[2*i],1)+PSHR16(data[2*i+1],1);
173#else
174 data[i] = .5*(((float)data[2*i])+data[2*i+1]);
175#endif
176 e_tot += SHR32(MULT16_16(data[i],data[i]),8);
177 }
178 if (e_left > e_right)
179 {
180 speex_bits_pack(bits, 0, 1);
181 largest = e_left;
182 smallest = e_right;
183 } else {
184 speex_bits_pack(bits, 1, 1);
185 largest = e_right;
186 smallest = e_left;
187 }
188
189 /* Balance quantization */
190#ifdef FIXED_POINT
191 shift = spx_ilog2(largest)-15;
192 largest = VSHR32(largest, shift-4);
193 smallest = VSHR32(smallest, shift);
194 balance = DIV32(largest, ADD32(smallest, 1));
195 if (balance > 32767)
196 balance = 32767;
197 balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32);
198#else
199 balance=(largest+1.)/(smallest+1.);
200 balance=4*log(balance);
201 balance_id=floor(.5+fabs(balance));
202 if (balance_id>30)
203 balance_id=31;
204#endif
205
206 speex_bits_pack(bits, balance_id, 5);
207
208 /* "coherence" quantisation */
209#ifdef FIXED_POINT
210 shift = spx_ilog2(e_tot);
211 e_tot = VSHR32(e_tot, shift-25);
212 e_left = VSHR32(e_left, shift-10);
213 e_right = VSHR32(e_right, shift-10);
214 e_ratio = DIV32(e_tot, e_left+e_right+1);
215#else
216 e_ratio = e_tot/(1.+e_left+e_right);
217#endif
218
219 tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4);
220 /*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio);*/
221 speex_bits_pack(bits, tmp, 2);
222}
223#endif /* SPEEX_DISABLE_ENCODER */
224
225#ifndef DISABLE_FLOAT_API
226void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo)
227{
228 int i;
229 spx_word32_t balance;
230 spx_word16_t e_left, e_right, e_ratio;
231 RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
232
233 COMPATIBILITY_HACK(stereo);
234
235 balance=stereo->balance;
236 e_ratio=stereo->e_ratio;
237
238 /* These two are Q14, with max value just below 2. */
239 e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));
240 e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);
241
242 for (i=frame_size-1;i>=0;i--)
243 {
244 spx_word16_t tmp=data[i];
245 stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));
246 stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));
247 data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp);
248 data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp);
249 }
250}
251#endif /* #ifndef DISABLE_FLOAT_API */
252
253void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo)
254{
255 int i;
256 spx_word32_t balance;
257 spx_word16_t e_left, e_right, e_ratio;
258 RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
259
260 /* COMPATIBILITY_HACK(stereo); */
261
262 balance=stereo->balance;
263 e_ratio=stereo->e_ratio;
264
265 /* These two are Q14, with max value just below 2. */
266 e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));
267 e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);
268
269 for (i=frame_size-1;i>=0;i--)
270 {
271 spx_int16_t tmp=data[i];
272 stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));
273 stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));
274 data[2*i] = (spx_int16_t)MULT16_16_P14(stereo->smooth_left, tmp);
275 data[2*i+1] = (spx_int16_t)MULT16_16_P14(stereo->smooth_right, tmp);
276 }
277}
278
279int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
280{
281 (void)state;
282 RealSpeexStereoState *stereo;
283 spx_word16_t sign=1, dexp;
284 int tmp;
285
286 stereo = (RealSpeexStereoState*)data;
287
288 /* COMPATIBILITY_HACK(stereo); */
289
290 if (speex_bits_unpack_unsigned(bits, 1))
291 sign=-1;
292 dexp = speex_bits_unpack_unsigned(bits, 5);
293#ifndef FIXED_POINT
294 stereo->balance = exp(sign*.25*dexp);
295#else
296 stereo->balance = spx_exp(MULT16_16(sign, SHL16(dexp, 9)));
297#endif
298 tmp = speex_bits_unpack_unsigned(bits, 2);
299 stereo->e_ratio = e_ratio_quant[tmp];
300
301 return 0;
302}
diff --git a/lib/rbcodec/codecs/libspeex/vbr.c b/lib/rbcodec/codecs/libspeex/vbr.c
new file mode 100644
index 0000000000..32b33bc10e
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/vbr.c
@@ -0,0 +1,275 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: vbr.c
3
4 VBR-related routines
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35#ifdef HAVE_CONFIG_H
36#include "config-speex.h"
37#endif
38
39#include "vbr.h"
40#include <math.h>
41
42
43#define sqr(x) ((x)*(x))
44
45#define MIN_ENERGY 6000
46#define NOISE_POW .3
47
48#ifndef DISABLE_VBR
49
50const float vbr_nb_thresh[9][11]={
51 {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* CNG */
52 { 4.0f, 2.5f, 2.0f, 1.2f, 0.5f, 0.0f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /* 2 kbps */
53 {10.0f, 6.5f, 5.2f, 4.5f, 3.9f, 3.5f, 3.0f, 2.5f, 2.3f, 1.8f, 1.0f}, /* 6 kbps */
54 {11.0f, 8.8f, 7.5f, 6.5f, 5.0f, 3.9f, 3.9f, 3.9f, 3.5f, 3.0f, 1.0f}, /* 8 kbps */
55 {11.0f, 11.0f, 9.9f, 8.5f, 7.0f, 6.0f, 4.5f, 4.0f, 4.0f, 4.0f, 2.0f}, /* 11 kbps */
56 {11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 8.0f, 7.0f, 6.0f, 5.0f, 3.0f}, /* 15 kbps */
57 {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 7.0f, 6.0f, 5.0f}, /* 18 kbps */
58 {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 9.5f, 7.5f}, /* 24 kbps */
59 { 7.0f, 4.5f, 3.7f, 3.0f, 2.5f, 2.0f, 1.8f, 1.5f, 1.0f, 0.0f, 0.0f} /* 4 kbps */
60};
61
62
63const float vbr_hb_thresh[5][11]={
64 {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */
65 {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* 2 kbps */
66 {11.0f, 11.0f, 9.5f, 8.5f, 7.5f, 6.0f, 5.0f, 3.9f, 3.0f, 2.0f, 1.0f}, /* 6 kbps */
67 {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.7f, 7.8f, 7.0f, 6.5f, 4.0f}, /* 10 kbps */
68 {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 7.5f, 5.5f} /* 18 kbps */
69};
70
71const float vbr_uhb_thresh[2][11]={
72 {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */
73 { 3.9f, 2.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f} /* 2 kbps */
74};
75
76void vbr_init(VBRState *vbr)
77{
78 int i;
79
80 vbr->average_energy=0;
81 vbr->last_energy=1;
82 vbr->accum_sum=0;
83 vbr->energy_alpha=.1;
84 vbr->soft_pitch=0;
85 vbr->last_pitch_coef=0;
86 vbr->last_quality=0;
87
88 vbr->noise_accum = .05*pow(MIN_ENERGY, NOISE_POW);
89 vbr->noise_accum_count=.05;
90 vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count;
91 vbr->consec_noise=0;
92
93
94 for (i=0;i<VBR_MEMORY_SIZE;i++)
95 vbr->last_log_energy[i] = log(MIN_ENERGY);
96}
97
98
99/*
100 This function should analyse the signal and decide how critical the
101 coding error will be perceptually. The following factors should be
102 taken into account:
103
104 -Attacks (positive energy derivative) should be coded with more bits
105
106 -Stationary voiced segments should receive more bits
107
108 -Segments with (very) low absolute energy should receive less bits (maybe
109 only shaped noise?)
110
111 -DTX for near-zero energy?
112
113 -Stationary fricative segments should have less bits
114
115 -Temporal masking: when energy slope is decreasing, decrease the bit-rate
116
117 -Decrease bit-rate for males (low pitch)?
118
119 -(wideband only) less bits in the high-band when signal is very
120 non-stationary (harder to notice high-frequency noise)???
121
122*/
123
124float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef)
125{
126 int i;
127 float ener=0, ener1=0, ener2=0;
128 float qual=7;
129 int va;
130 float log_energy;
131 float non_st=0;
132 float voicing;
133 float pow_ener;
134
135 for (i=0;i<len>>1;i++)
136 ener1 += ((float)sig[i])*sig[i];
137
138 for (i=len>>1;i<len;i++)
139 ener2 += ((float)sig[i])*sig[i];
140 ener=ener1+ener2;
141
142 log_energy = log(ener+MIN_ENERGY);
143 for (i=0;i<VBR_MEMORY_SIZE;i++)
144 non_st += sqr(log_energy-vbr->last_log_energy[i]);
145 non_st = non_st/(30*VBR_MEMORY_SIZE);
146 if (non_st>1)
147 non_st=1;
148
149 voicing = 3*(pitch_coef-.4)*fabs(pitch_coef-.4);
150 vbr->average_energy = (1-vbr->energy_alpha)*vbr->average_energy + vbr->energy_alpha*ener;
151 vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count;
152 pow_ener = pow(ener,NOISE_POW);
153 if (vbr->noise_accum_count<.06 && ener>MIN_ENERGY)
154 vbr->noise_accum = .05*pow_ener;
155
156 if ((voicing<.3 && non_st < .2 && pow_ener < 1.2*vbr->noise_level)
157 || (voicing<.3 && non_st < .05 && pow_ener < 1.5*vbr->noise_level)
158 || (voicing<.4 && non_st < .05 && pow_ener < 1.2*vbr->noise_level)
159 || (voicing<0 && non_st < .05))
160 {
161 float tmp;
162 va = 0;
163 vbr->consec_noise++;
164 if (pow_ener > 3*vbr->noise_level)
165 tmp = 3*vbr->noise_level;
166 else
167 tmp = pow_ener;
168 if (vbr->consec_noise>=4)
169 {
170 vbr->noise_accum = .95*vbr->noise_accum + .05*tmp;
171 vbr->noise_accum_count = .95*vbr->noise_accum_count + .05;
172 }
173 } else {
174 va = 1;
175 vbr->consec_noise=0;
176 }
177
178 if (pow_ener < vbr->noise_level && ener>MIN_ENERGY)
179 {
180 vbr->noise_accum = .95*vbr->noise_accum + .05*pow_ener;
181 vbr->noise_accum_count = .95*vbr->noise_accum_count + .05;
182 }
183
184 /* Checking for very low absolute energy */
185 if (ener < 30000)
186 {
187 qual -= .7;
188 if (ener < 10000)
189 qual-=.7;
190 if (ener < 3000)
191 qual-=.7;
192 } else {
193 float short_diff, long_diff;
194 short_diff = log((ener+1)/(1+vbr->last_energy));
195 long_diff = log((ener+1)/(1+vbr->average_energy));
196 /*fprintf (stderr, "%f %f\n", short_diff, long_diff);*/
197
198 if (long_diff<-5)
199 long_diff=-5;
200 if (long_diff>2)
201 long_diff=2;
202
203 if (long_diff>0)
204 qual += .6*long_diff;
205 if (long_diff<0)
206 qual += .5*long_diff;
207 if (short_diff>0)
208 {
209 if (short_diff>5)
210 short_diff=5;
211 qual += .5*short_diff;
212 }
213 /* Checking for energy increases */
214 if (ener2 > 1.6*ener1)
215 qual += .5;
216 }
217 vbr->last_energy = ener;
218 vbr->soft_pitch = .6*vbr->soft_pitch + .4*pitch_coef;
219 qual += 2.2*((pitch_coef-.4) + (vbr->soft_pitch-.4));
220
221 if (qual < vbr->last_quality)
222 qual = .5*qual + .5*vbr->last_quality;
223 if (qual<4)
224 qual=4;
225 if (qual>10)
226 qual=10;
227
228 /*
229 if (vbr->consec_noise>=2)
230 qual-=1.3;
231 if (vbr->consec_noise>=5)
232 qual-=1.3;
233 if (vbr->consec_noise>=12)
234 qual-=1.3;
235 */
236 if (vbr->consec_noise>=3)
237 qual=4;
238
239 if (vbr->consec_noise)
240 qual -= 1.0 * (log(3.0 + vbr->consec_noise)-log(3));
241 if (qual<0)
242 qual=0;
243
244 if (ener<60000)
245 {
246 if (vbr->consec_noise>2)
247 qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3));
248 if (ener<10000&&vbr->consec_noise>2)
249 qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3));
250 if (qual<0)
251 qual=0;
252 qual += .3*log(.0001+ener/60000.0);
253 }
254 if (qual<-1)
255 qual=-1;
256
257 /*printf ("%f %f %f %f %d\n", qual, voicing, non_st, pow_ener/(.01+vbr->noise_level), va);*/
258
259 vbr->last_pitch_coef = pitch_coef;
260 vbr->last_quality = qual;
261
262 for (i=VBR_MEMORY_SIZE-1;i>0;i--)
263 vbr->last_log_energy[i] = vbr->last_log_energy[i-1];
264 vbr->last_log_energy[0] = log_energy;
265
266 /*printf ("VBR: %f %f %f %d %f\n", (float)(log_energy-log(vbr->average_energy+MIN_ENERGY)), non_st, voicing, va, vbr->noise_level);*/
267
268 return qual;
269}
270
271void vbr_destroy(VBRState *vbr)
272{
273}
274
275#endif /* #ifndef DISABLE_VBR */
diff --git a/lib/rbcodec/codecs/libspeex/vbr.h b/lib/rbcodec/codecs/libspeex/vbr.h
new file mode 100644
index 0000000000..ff1e3e46f2
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/vbr.h
@@ -0,0 +1,70 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file vbr.h
4 @brief Variable Bit-Rate (VBR) related routines
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36
37#ifndef VBR_H
38#define VBR_H
39
40#include "arch.h"
41
42#define VBR_MEMORY_SIZE 5
43
44extern const float vbr_nb_thresh[9][11];
45extern const float vbr_hb_thresh[5][11];
46extern const float vbr_uhb_thresh[2][11];
47
48/** VBR state. */
49typedef struct VBRState {
50 float energy_alpha;
51 float average_energy;
52 float last_energy;
53 float last_log_energy[VBR_MEMORY_SIZE];
54 float accum_sum;
55 float last_pitch_coef;
56 float soft_pitch;
57 float last_quality;
58 float noise_level;
59 float noise_accum;
60 float noise_accum_count;
61 int consec_noise;
62} VBRState;
63
64void vbr_init(VBRState *vbr);
65
66float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef);
67
68void vbr_destroy(VBRState *vbr);
69
70#endif
diff --git a/lib/rbcodec/codecs/libspeex/vorbis_psy.c b/lib/rbcodec/codecs/libspeex/vorbis_psy.c
new file mode 100644
index 0000000000..2032bf63e2
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/vorbis_psy.c
@@ -0,0 +1,508 @@
1/* Copyright (C) 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery
2 File: vorbis_psy.c
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#ifdef HAVE_CONFIG_H
33#include "config-speex.h"
34#endif
35
36#ifdef VORBIS_PSYCHO
37
38#include "arch.h"
39#include "smallft.h"
40#include "lpc.h"
41#include "vorbis_psy.h"
42
43#include <stdlib.h>
44#include <math.h>
45#include <string.h>
46
47/* psychoacoustic setup ********************************************/
48
49static VorbisPsyInfo example_tuning = {
50
51 .5,.5,
52 3,3,25,
53
54 /*63 125 250 500 1k 2k 4k 8k 16k*/
55 // vorbis mode 4 style
56 //{-32,-32,-32,-32,-28,-24,-22,-20,-20, -20, -20, -8, -6, -6, -6, -6, -6},
57 { -4, -6, -6, -6, -6, -6, -6, -6, -8, -8,-10,-10, -8, -6, -4, -4, -2},
58
59 {
60 0, 1, 2, 3, 4, 5, 5, 5, /* 7dB */
61 6, 6, 6, 5, 4, 4, 4, 4, /* 15dB */
62 4, 4, 5, 5, 5, 6, 6, 6, /* 23dB */
63 7, 7, 7, 8, 8, 8, 9, 10, /* 31dB */
64 11,12,13,14,15,16,17, 18, /* 39dB */
65 }
66
67};
68
69
70
71/* there was no great place to put this.... */
72#include <stdio.h>
73static void _analysis_output(char *base,int i,float *v,int n,int bark,int dB){
74 int j;
75 FILE *of;
76 char buffer[80];
77
78 sprintf(buffer,"%s_%d.m",base,i);
79 of=fopen(buffer,"w");
80
81 if(!of)perror("failed to open data dump file");
82
83 for(j=0;j<n;j++){
84 if(bark){
85 float b=toBARK((4000.f*j/n)+.25);
86 fprintf(of,"%f ",b);
87 }else
88 fprintf(of,"%f ",(double)j);
89
90 if(dB){
91 float val;
92 if(v[j]==0.)
93 val=-140.;
94 else
95 val=todB(v[j]);
96 fprintf(of,"%f\n",val);
97 }else{
98 fprintf(of,"%f\n",v[j]);
99 }
100 }
101 fclose(of);
102}
103
104static void bark_noise_hybridmp(int n,const long *b,
105 const float *f,
106 float *noise,
107 const float offset,
108 const int fixed){
109
110 float *N=alloca(n*sizeof(*N));
111 float *X=alloca(n*sizeof(*N));
112 float *XX=alloca(n*sizeof(*N));
113 float *Y=alloca(n*sizeof(*N));
114 float *XY=alloca(n*sizeof(*N));
115
116 float tN, tX, tXX, tY, tXY;
117 int i;
118
119 int lo, hi;
120 float R, A, B, D;
121 float w, x, y;
122
123 tN = tX = tXX = tY = tXY = 0.f;
124
125 y = f[0] + offset;
126 if (y < 1.f) y = 1.f;
127
128 w = y * y * .5;
129
130 tN += w;
131 tX += w;
132 tY += w * y;
133
134 N[0] = tN;
135 X[0] = tX;
136 XX[0] = tXX;
137 Y[0] = tY;
138 XY[0] = tXY;
139
140 for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
141
142 y = f[i] + offset;
143 if (y < 1.f) y = 1.f;
144
145 w = y * y;
146
147 tN += w;
148 tX += w * x;
149 tXX += w * x * x;
150 tY += w * y;
151 tXY += w * x * y;
152
153 N[i] = tN;
154 X[i] = tX;
155 XX[i] = tXX;
156 Y[i] = tY;
157 XY[i] = tXY;
158 }
159
160 for (i = 0, x = 0.f;; i++, x += 1.f) {
161
162 lo = b[i] >> 16;
163 if( lo>=0 ) break;
164 hi = b[i] & 0xffff;
165
166 tN = N[hi] + N[-lo];
167 tX = X[hi] - X[-lo];
168 tXX = XX[hi] + XX[-lo];
169 tY = Y[hi] + Y[-lo];
170 tXY = XY[hi] - XY[-lo];
171
172 A = tY * tXX - tX * tXY;
173 B = tN * tXY - tX * tY;
174 D = tN * tXX - tX * tX;
175 R = (A + x * B) / D;
176 if (R < 0.f)
177 R = 0.f;
178
179 noise[i] = R - offset;
180 }
181
182 for ( ;; i++, x += 1.f) {
183
184 lo = b[i] >> 16;
185 hi = b[i] & 0xffff;
186 if(hi>=n)break;
187
188 tN = N[hi] - N[lo];
189 tX = X[hi] - X[lo];
190 tXX = XX[hi] - XX[lo];
191 tY = Y[hi] - Y[lo];
192 tXY = XY[hi] - XY[lo];
193
194 A = tY * tXX - tX * tXY;
195 B = tN * tXY - tX * tY;
196 D = tN * tXX - tX * tX;
197 R = (A + x * B) / D;
198 if (R < 0.f) R = 0.f;
199
200 noise[i] = R - offset;
201 }
202 for ( ; i < n; i++, x += 1.f) {
203
204 R = (A + x * B) / D;
205 if (R < 0.f) R = 0.f;
206
207 noise[i] = R - offset;
208 }
209
210 if (fixed <= 0) return;
211
212 for (i = 0, x = 0.f;; i++, x += 1.f) {
213 hi = i + fixed / 2;
214 lo = hi - fixed;
215 if(lo>=0)break;
216
217 tN = N[hi] + N[-lo];
218 tX = X[hi] - X[-lo];
219 tXX = XX[hi] + XX[-lo];
220 tY = Y[hi] + Y[-lo];
221 tXY = XY[hi] - XY[-lo];
222
223
224 A = tY * tXX - tX * tXY;
225 B = tN * tXY - tX * tY;
226 D = tN * tXX - tX * tX;
227 R = (A + x * B) / D;
228
229 if (R - offset < noise[i]) noise[i] = R - offset;
230 }
231 for ( ;; i++, x += 1.f) {
232
233 hi = i + fixed / 2;
234 lo = hi - fixed;
235 if(hi>=n)break;
236
237 tN = N[hi] - N[lo];
238 tX = X[hi] - X[lo];
239 tXX = XX[hi] - XX[lo];
240 tY = Y[hi] - Y[lo];
241 tXY = XY[hi] - XY[lo];
242
243 A = tY * tXX - tX * tXY;
244 B = tN * tXY - tX * tY;
245 D = tN * tXX - tX * tX;
246 R = (A + x * B) / D;
247
248 if (R - offset < noise[i]) noise[i] = R - offset;
249 }
250 for ( ; i < n; i++, x += 1.f) {
251 R = (A + x * B) / D;
252 if (R - offset < noise[i]) noise[i] = R - offset;
253 }
254}
255
256static void _vp_noisemask(VorbisPsy *p,
257 float *logfreq,
258 float *logmask){
259
260 int i,n=p->n/2;
261 float *work=alloca(n*sizeof(*work));
262
263 bark_noise_hybridmp(n,p->bark,logfreq,logmask,
264 140.,-1);
265
266 for(i=0;i<n;i++)work[i]=logfreq[i]-logmask[i];
267
268 bark_noise_hybridmp(n,p->bark,work,logmask,0.,
269 p->vi->noisewindowfixed);
270
271 for(i=0;i<n;i++)work[i]=logfreq[i]-work[i];
272
273 {
274 static int seq=0;
275
276 float work2[n];
277 for(i=0;i<n;i++){
278 work2[i]=logmask[i]+work[i];
279 }
280
281 //_analysis_output("logfreq",seq,logfreq,n,0,0);
282 //_analysis_output("median",seq,work,n,0,0);
283 //_analysis_output("envelope",seq,work2,n,0,0);
284 seq++;
285 }
286
287 for(i=0;i<n;i++){
288 int dB=logmask[i]+.5;
289 if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;
290 if(dB<0)dB=0;
291 logmask[i]= work[i]+p->vi->noisecompand[dB]+p->noiseoffset[i];
292 }
293
294}
295
296VorbisPsy *vorbis_psy_init(int rate, int n)
297{
298 long i,j,lo=-99,hi=1;
299 VorbisPsy *p = speex_alloc(sizeof(VorbisPsy));
300 memset(p,0,sizeof(*p));
301
302 p->n = n;
303 spx_drft_init(&p->lookup, n);
304 p->bark = speex_alloc(n*sizeof(*p->bark));
305 p->rate=rate;
306 p->vi = &example_tuning;
307
308 /* BH4 window */
309 p->window = speex_alloc(sizeof(*p->window)*n);
310 float a0 = .35875f;
311 float a1 = .48829f;
312 float a2 = .14128f;
313 float a3 = .01168f;
314 for(i=0;i<n;i++)
315 p->window[i] = //a0 - a1*cos(2.*M_PI/n*(i+.5)) + a2*cos(4.*M_PI/n*(i+.5)) - a3*cos(6.*M_PI/n*(i+.5));
316 sin((i+.5)/n * M_PI)*sin((i+.5)/n * M_PI);
317 /* bark scale lookups */
318 for(i=0;i<n;i++){
319 float bark=toBARK(rate/(2*n)*i);
320
321 for(;lo+p->vi->noisewindowlomin<i &&
322 toBARK(rate/(2*n)*lo)<(bark-p->vi->noisewindowlo);lo++);
323
324 for(;hi<=n && (hi<i+p->vi->noisewindowhimin ||
325 toBARK(rate/(2*n)*hi)<(bark+p->vi->noisewindowhi));hi++);
326
327 p->bark[i]=((lo-1)<<16)+(hi-1);
328
329 }
330
331 /* set up rolling noise median */
332 p->noiseoffset=speex_alloc(n*sizeof(*p->noiseoffset));
333
334 for(i=0;i<n;i++){
335 float halfoc=toOC((i+.5)*rate/(2.*n))*2.;
336 int inthalfoc;
337 float del;
338
339 if(halfoc<0)halfoc=0;
340 if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
341 inthalfoc=(int)halfoc;
342 del=halfoc-inthalfoc;
343
344 p->noiseoffset[i]=
345 p->vi->noiseoff[inthalfoc]*(1.-del) +
346 p->vi->noiseoff[inthalfoc+1]*del;
347
348 }
349#if 0
350 _analysis_output_always("noiseoff0",ls,p->noiseoffset,n,1,0,0);
351#endif
352
353 return p;
354}
355
356void vorbis_psy_destroy(VorbisPsy *p)
357{
358 if(p){
359 spx_drft_clear(&p->lookup);
360 if(p->bark)
361 speex_free(p->bark);
362 if(p->noiseoffset)
363 speex_free(p->noiseoffset);
364 if(p->window)
365 speex_free(p->window);
366 memset(p,0,sizeof(*p));
367 speex_free(p);
368 }
369}
370
371void compute_curve(VorbisPsy *psy, float *audio, float *curve)
372{
373 int i;
374 float work[psy->n];
375
376 float scale=4.f/psy->n;
377 float scale_dB;
378
379 scale_dB=todB(scale);
380
381 /* window the PCM data; use a BH4 window, not vorbis */
382 for(i=0;i<psy->n;i++)
383 work[i]=audio[i] * psy->window[i];
384
385 {
386 static int seq=0;
387
388 //_analysis_output("win",seq,work,psy->n,0,0);
389
390 seq++;
391 }
392
393 /* FFT yields more accurate tonal estimation (not phase sensitive) */
394 spx_drft_forward(&psy->lookup,work);
395
396 /* magnitudes */
397 work[0]=scale_dB+todB(work[0]);
398 for(i=1;i<psy->n-1;i+=2){
399 float temp = work[i]*work[i] + work[i+1]*work[i+1];
400 work[(i+1)>>1] = scale_dB+.5f * todB(temp);
401 }
402
403 /* derive a noise curve */
404 _vp_noisemask(psy,work,curve);
405#define SIDEL 12
406 for (i=0;i<SIDEL;i++)
407 {
408 curve[i]=curve[SIDEL];
409 }
410#define SIDEH 12
411 for (i=0;i<SIDEH;i++)
412 {
413 curve[(psy->n>>1)-i-1]=curve[(psy->n>>1)-SIDEH];
414 }
415 for(i=0;i<((psy->n)>>1);i++)
416 curve[i] = fromdB(1.2*curve[i]+.2*i);
417 //curve[i] = fromdB(0.8*curve[i]+.35*i);
418 //curve[i] = fromdB(0.9*curve[i])*pow(1.0*i+45,1.3);
419}
420
421/* Transform a masking curve (power spectrum) into a pole-zero filter */
422void curve_to_lpc(VorbisPsy *psy, float *curve, float *awk1, float *awk2, int ord)
423{
424 int i;
425 float ac[psy->n];
426 float tmp;
427 int len = psy->n >> 1;
428 for (i=0;i<2*len;i++)
429 ac[i] = 0;
430 for (i=1;i<len;i++)
431 ac[2*i-1] = curve[i];
432 ac[0] = curve[0];
433 ac[2*len-1] = curve[len-1];
434
435 spx_drft_backward(&psy->lookup, ac);
436 _spx_lpc(awk1, ac, ord);
437 tmp = 1.;
438 for (i=0;i<ord;i++)
439 {
440 tmp *= .99;
441 awk1[i] *= tmp;
442 }
443#if 0
444 for (i=0;i<ord;i++)
445 awk2[i] = 0;
446#else
447 /* Use the second (awk2) filter to correct the first one */
448 for (i=0;i<2*len;i++)
449 ac[i] = 0;
450 for (i=0;i<ord;i++)
451 ac[i+1] = awk1[i];
452 ac[0] = 1;
453 spx_drft_forward(&psy->lookup, ac);
454 /* Compute (power) response of awk1 (all zero) */
455 ac[0] *= ac[0];
456 for (i=1;i<len;i++)
457 ac[i] = ac[2*i-1]*ac[2*i-1] + ac[2*i]*ac[2*i];
458 ac[len] = ac[2*len-1]*ac[2*len-1];
459 /* Compute correction required */
460 for (i=0;i<len;i++)
461 curve[i] = 1. / (1e-6f+curve[i]*ac[i]);
462
463 for (i=0;i<2*len;i++)
464 ac[i] = 0;
465 for (i=1;i<len;i++)
466 ac[2*i-1] = curve[i];
467 ac[0] = curve[0];
468 ac[2*len-1] = curve[len-1];
469
470 spx_drft_backward(&psy->lookup, ac);
471 _spx_lpc(awk2, ac, ord);
472 tmp = 1;
473 for (i=0;i<ord;i++)
474 {
475 tmp *= .99;
476 awk2[i] *= tmp;
477 }
478#endif
479}
480
481#if 0
482#include <stdio.h>
483#include <math.h>
484
485#define ORDER 10
486#define CURVE_SIZE 24
487
488int main()
489{
490 int i;
491 float curve[CURVE_SIZE];
492 float awk1[ORDER], awk2[ORDER];
493 for (i=0;i<CURVE_SIZE;i++)
494 scanf("%f ", &curve[i]);
495 for (i=0;i<CURVE_SIZE;i++)
496 curve[i] = pow(10.f, .1*curve[i]);
497 curve_to_lpc(curve, CURVE_SIZE, awk1, awk2, ORDER);
498 for (i=0;i<ORDER;i++)
499 printf("%f ", awk1[i]);
500 printf ("\n");
501 for (i=0;i<ORDER;i++)
502 printf("%f ", awk2[i]);
503 printf ("\n");
504 return 0;
505}
506#endif
507
508#endif
diff --git a/lib/rbcodec/codecs/libspeex/vorbis_psy.h b/lib/rbcodec/codecs/libspeex/vorbis_psy.h
new file mode 100644
index 0000000000..6871057753
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/vorbis_psy.h
@@ -0,0 +1,97 @@
1/* Copyright (C) 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery
2 File: vorbis_psy.h
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#ifndef VORBIS_PSY_H
33#define VORBIS_PSY_H
34
35#ifdef VORBIS_PSYCHO
36
37#include "smallft.h"
38#define P_BANDS 17 /* 62Hz to 16kHz */
39#define NOISE_COMPAND_LEVELS 40
40
41
42#define todB(x) ((x)>1e-13?log((x)*(x))*4.34294480f:-30)
43#define fromdB(x) (exp((x)*.11512925f))
44
45/* The bark scale equations are approximations, since the original
46 table was somewhat hand rolled. The below are chosen to have the
47 best possible fit to the rolled tables, thus their somewhat odd
48 appearance (these are more accurate and over a longer range than
49 the oft-quoted bark equations found in the texts I have). The
50 approximations are valid from 0 - 30kHz (nyquist) or so.
51
52 all f in Hz, z in Bark */
53
54#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
55#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f)
56
57/* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave
58 0.0 */
59
60#define toOC(n) (log(n)*1.442695f-5.965784f)
61#define fromOC(o) (exp(((o)+5.965784f)*.693147f))
62
63
64typedef struct {
65
66 float noisewindowlo;
67 float noisewindowhi;
68 int noisewindowlomin;
69 int noisewindowhimin;
70 int noisewindowfixed;
71 float noiseoff[P_BANDS];
72 float noisecompand[NOISE_COMPAND_LEVELS];
73
74} VorbisPsyInfo;
75
76
77
78typedef struct {
79 int n;
80 int rate;
81 struct drft_lookup lookup;
82 VorbisPsyInfo *vi;
83
84 float *window;
85 float *noiseoffset;
86 long *bark;
87
88} VorbisPsy;
89
90
91VorbisPsy *vorbis_psy_init(int rate, int size);
92void vorbis_psy_destroy(VorbisPsy *psy);
93void compute_curve(VorbisPsy *psy, float *audio, float *curve);
94void curve_to_lpc(VorbisPsy *psy, float *curve, float *awk1, float *awk2, int ord);
95
96#endif
97#endif
diff --git a/lib/rbcodec/codecs/libspeex/vq.c b/lib/rbcodec/codecs/libspeex/vq.c
new file mode 100644
index 0000000000..fff470a588
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/vq.c
@@ -0,0 +1,147 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: vq.c
3 Vector quantization
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#ifdef HAVE_CONFIG_H
34#include "config-speex.h"
35#endif
36
37#include "vq.h"
38#include "stack_alloc.h"
39#include "arch.h"
40
41#ifdef _USE_SSE
42#include <xmmintrin.h>
43#include "vq_sse.h"
44#elif defined(SHORTCUTS) && (defined(ARM4_ASM) || defined(ARM5E_ASM))
45#include "vq_arm4.h"
46#elif defined(BFIN_ASM)
47#include "vq_bfin.h"
48#endif
49
50
51int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries)
52{
53 int i=0;
54 while (i<entries-1 && in>boundary[0])
55 {
56 boundary++;
57 i++;
58 }
59 return i;
60}
61
62int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries)
63{
64 int i=0;
65 while (i<entries-1 && in>boundary[0])
66 {
67 boundary++;
68 i++;
69 }
70 return i;
71}
72
73
74#ifndef OVERRIDE_VQ_NBEST
75/*Finds the indices of the n-best entries in a codebook*/
76void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
77{
78 int i,j,k,used;
79 used = 0;
80 for (i=0;i<entries;i++)
81 {
82 spx_word32_t dist=0;
83 for (j=0;j<len;j++)
84 dist = MAC16_16(dist,in[j],*codebook++);
85#ifdef FIXED_POINT
86 dist=SUB32(SHR32(E[i],1),dist);
87#else
88 dist=.5f*E[i]-dist;
89#endif
90 if (i<N || dist<best_dist[N-1])
91 {
92 for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)
93 {
94 best_dist[k]=best_dist[k-1];
95 nbest[k] = nbest[k-1];
96 }
97 best_dist[k]=dist;
98 nbest[k]=i;
99 used++;
100 }
101 }
102}
103#endif
104
105
106
107
108#ifndef OVERRIDE_VQ_NBEST_SIGN
109/*Finds the indices of the n-best entries in a codebook with sign*/
110void vq_nbest_sign(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
111{
112 int i,j,k, sign, used;
113 used=0;
114 for (i=0;i<entries;i++)
115 {
116 spx_word32_t dist=0;
117 for (j=0;j<len;j++)
118 dist = MAC16_16(dist,in[j],*codebook++);
119 if (dist>0)
120 {
121 sign=0;
122 dist=-dist;
123 } else
124 {
125 sign=1;
126 }
127#ifdef FIXED_POINT
128 dist = ADD32(dist,SHR32(E[i],1));
129#else
130 dist = ADD32(dist,.5f*E[i]);
131#endif
132 if (i<N || dist<best_dist[N-1])
133 {
134 for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)
135 {
136 best_dist[k]=best_dist[k-1];
137 nbest[k] = nbest[k-1];
138 }
139 best_dist[k]=dist;
140 nbest[k]=i;
141 used++;
142 if (sign)
143 nbest[k]+=entries;
144 }
145 }
146}
147#endif
diff --git a/lib/rbcodec/codecs/libspeex/vq.h b/lib/rbcodec/codecs/libspeex/vq.h
new file mode 100644
index 0000000000..5a4ced249c
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/vq.h
@@ -0,0 +1,54 @@
1/* Copyright (C) 2002 Jean-Marc Valin */
2/**
3 @file vq.h
4 @brief Vector quantization
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef VQ_H
36#define VQ_H
37
38#include "arch.h"
39
40int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries);
41int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries);
42
43#ifdef _USE_SSE
44#include <xmmintrin.h>
45void 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);
46
47void vq_nbest_sign(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
48#else
49void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
50
51void vq_nbest_sign(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
52#endif
53
54#endif
diff --git a/lib/rbcodec/codecs/libspeex/vq_arm4.h b/lib/rbcodec/codecs/libspeex/vq_arm4.h
new file mode 100644
index 0000000000..d2697e5784
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/vq_arm4.h
@@ -0,0 +1,115 @@
1/* Copyright (C) 2004 Jean-Marc Valin */
2/**
3 @file vq_arm4.h
4 @brief ARM4-optimized vq routine
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#define OVERRIDE_VQ_NBEST
36void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
37{
38 int i,j;
39 for (i=0;i<entries;i+=4)
40 {
41#if 1
42 spx_word32_t dist1, dist2, dist3, dist4;
43 int dead1, dead2, dead3, dead4, dead5, dead6, dead7, dead8;
44 __asm__ __volatile__ (
45 "mov %0, #0 \n\t"
46 "mov %1, #0 \n\t"
47 "mov %2, #0 \n\t"
48 "mov %3, #0 \n\t"
49 "mov %10, %4 \n\t"
50 "add %4, %4, %4\n\t"
51 ".vqloop%=:\n\t"
52 "ldrsh %7, [%5], #2 \n\t"
53 "ldrsh %8, [%6] \n\t"
54 "mov %9, %6 \n\t"
55 "mla %0, %7, %8, %0 \n\t"
56 "ldrsh %8, [%9, %4]! \n\t"
57 "mla %1, %7, %8, %1 \n\t"
58 "ldrsh %8, [%9, %4]!\n\t"
59 "mla %2, %7, %8, %2 \n\t"
60 "ldrsh %8, [%9, %4]! \n\t"
61 "mla %3, %7, %8, %3 \n\t"
62 "subs %10, %10, #1 \n\t"
63 "add %6, %6, #2 \n\t"
64 "bne .vqloop%="
65 : "=r" (dist1), "=r" (dist2), "=r" (dist3), "=r" (dist4),
66 "=r" (dead1), "=r" (dead2), "=r" (codebook), "=r" (dead4),
67 "=r" (dead5), "=r" (dead6), "=r" (dead7)
68 : "4" (len), "5" (in), "6" (codebook)
69 : "cc", "memory");
70#else
71dist1=dist2=dist3=dist4=0;
72 /* spx_word32_t dist1=0;
73 spx_word32_t dist2=0;
74 spx_word32_t dist3=0;
75 spx_word32_t dist4=0;*/
76 for (j=0;j<2;j++)
77 {
78 const spx_word16_t *code = codebook;
79 dist1 = MAC16_16(dist1,in[j],*code);
80 code += len;
81 dist2 = MAC16_16(dist2,in[j],*code);
82 code += len;
83 dist3 = MAC16_16(dist3,in[j],*code);
84 code += len;
85 dist4 = MAC16_16(dist4,in[j],*code);
86 codebook++;
87 }
88#endif
89 dist1=SUB32(SHR(*E++,1),dist1);
90 if (dist1<*best_dist || i==0)
91 {
92 *best_dist=dist1;
93 *nbest=i;
94 }
95 dist2=SUB32(SHR(*E++,1),dist2);
96 if (dist2<*best_dist)
97 {
98 *best_dist=dist2;
99 *nbest=i+1;
100 }
101 dist3=SUB32(SHR(*E++,1),dist3);
102 if (dist3<*best_dist)
103 {
104 *best_dist=dist3;
105 *nbest=i+2;
106 }
107 dist4=SUB32(SHR(*E++,1),dist4);
108 if (dist4<*best_dist)
109 {
110 *best_dist=dist4;
111 *nbest=i+3;
112 }
113 codebook += 3*len;
114 }
115}
diff --git a/lib/rbcodec/codecs/libspeex/vq_bfin.h b/lib/rbcodec/codecs/libspeex/vq_bfin.h
new file mode 100644
index 0000000000..2cc9ea5f17
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/vq_bfin.h
@@ -0,0 +1,107 @@
1/* Copyright (C) 2005 Analog Devices */
2/**
3 @file vq_bfin.h
4 @author Jean-Marc Valin
5 @brief Blackfin-optimized vq routine
6*/
7/*
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 - Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 - Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19 - Neither the name of the Xiph.org Foundation nor the names of its
20 contributors may be used to endorse or promote products derived from
21 this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#define OVERRIDE_VQ_NBEST
37void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
38{
39 if (N==1)
40 {
41 best_dist[0] = 2147483647;
42 {
43 spx_word32_t dist;
44 __asm__ __volatile__
45 (
46 "LC0 = %8;\n\t"
47 "R2 = 0;\n\t"
48 "I0 = %6;\n\t"
49 "B0 = %6;\n\t"
50 "L0 = %9;\n\t"
51 "LOOP entries_loop%= LC0;\n\t"
52 "LOOP_BEGIN entries_loop%=;\n\t"
53 "%0 = [%4++];\n\t"
54 "%0 >>= 1;\n\t"
55 "A0 = %0;\n\t"
56 "R0.L = W[%1++%7] || R1.L = W[I0++];\n\t"
57 "LOOP vq_loop%= LC1 = %5;\n\t"
58 "LOOP_BEGIN vq_loop%=;\n\t"
59 "%0 = (A0 -= R0.L*R1.L) (IS) || R0.L = W[%1++%7] || R1.L = W[I0++];\n\t"
60 "LOOP_END vq_loop%=;\n\t"
61 "%0 = (A0 -= R0.L*R1.L) (IS);\n\t"
62 "cc = %0 < %2;\n\t"
63 "if cc %2 = %0;\n\t"
64 "if cc %3 = R2;\n\t"
65 "R2 += 1;\n\t"
66 "LOOP_END entries_loop%=;\n\t"
67 : "=&D" (dist), "=&a" (codebook), "=&d" (best_dist[0]), "=&d" (nbest[0]), "=&a" (E)
68 : "a" (len-1), "a" (in), "a" (2), "d" (entries), "d" (len<<1), "1" (codebook), "4" (E), "2" (best_dist[0]), "3" (nbest[0])
69 : "R0", "R1", "R2", "I0", "L0", "B0", "A0", "cc", "memory"
70 );
71 }
72 } else {
73 int i,k,used;
74 used = 0;
75 for (i=0;i<entries;i++)
76 {
77 spx_word32_t dist;
78 __asm__
79 (
80 "%0 >>= 1;\n\t"
81 "A0 = %0;\n\t"
82 "I0 = %3;\n\t"
83 "L0 = 0;\n\t"
84 "R0.L = W[%1++%4] || R1.L = W[I0++];\n\t"
85 "LOOP vq_loop%= LC0 = %2;\n\t"
86 "LOOP_BEGIN vq_loop%=;\n\t"
87 "%0 = (A0 -= R0.L*R1.L) (IS) || R0.L = W[%1++%4] || R1.L = W[I0++];\n\t"
88 "LOOP_END vq_loop%=;\n\t"
89 "%0 = (A0 -= R0.L*R1.L) (IS);\n\t"
90 : "=D" (dist), "=a" (codebook)
91 : "a" (len-1), "a" (in), "a" (2), "1" (codebook), "0" (E[i])
92 : "R0", "R1", "I0", "L0", "A0"
93 );
94 if (i<N || dist<best_dist[N-1])
95 {
96 for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)
97 {
98 best_dist[k]=best_dist[k-1];
99 nbest[k] = nbest[k-1];
100 }
101 best_dist[k]=dist;
102 nbest[k]=i;
103 used++;
104 }
105 }
106 }
107}
diff --git a/lib/rbcodec/codecs/libspeex/vq_sse.h b/lib/rbcodec/codecs/libspeex/vq_sse.h
new file mode 100644
index 0000000000..00a42ce354
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/vq_sse.h
@@ -0,0 +1,120 @@
1/* Copyright (C) 2004 Jean-Marc Valin */
2/**
3 @file vq_sse.h
4 @brief SSE-optimized vq routine
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#define OVERRIDE_VQ_NBEST
36void 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)
37{
38 int i,j,k,used;
39 VARDECL(float *dist);
40 VARDECL(__m128 *in);
41 __m128 half;
42 used = 0;
43 ALLOC(dist, entries, float);
44 half = _mm_set_ps1(.5f);
45 ALLOC(in, len, __m128);
46 for (i=0;i<len;i++)
47 in[i] = _mm_set_ps1(_in[i]);
48 for (i=0;i<entries>>2;i++)
49 {
50 __m128 d = _mm_mul_ps(E[i], half);
51 for (j=0;j<len;j++)
52 d = _mm_sub_ps(d, _mm_mul_ps(in[j], *codebook++));
53 _mm_storeu_ps(dist+4*i, d);
54 }
55 for (i=0;i<entries;i++)
56 {
57 if (i<N || dist[i]<best_dist[N-1])
58 {
59 for (k=N-1; (k >= 1) && (k > used || dist[i] < best_dist[k-1]); k--)
60 {
61 best_dist[k]=best_dist[k-1];
62 nbest[k] = nbest[k-1];
63 }
64 best_dist[k]=dist[i];
65 nbest[k]=i;
66 used++;
67 }
68 }
69}
70
71
72
73
74#define OVERRIDE_VQ_NBEST_SIGN
75void vq_nbest_sign(spx_word16_t *_in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
76{
77 int i,j,k,used;
78 VARDECL(float *dist);
79 VARDECL(__m128 *in);
80 __m128 half;
81 used = 0;
82 ALLOC(dist, entries, float);
83 half = _mm_set_ps1(.5f);
84 ALLOC(in, len, __m128);
85 for (i=0;i<len;i++)
86 in[i] = _mm_set_ps1(_in[i]);
87 for (i=0;i<entries>>2;i++)
88 {
89 __m128 d = _mm_setzero_ps();
90 for (j=0;j<len;j++)
91 d = _mm_add_ps(d, _mm_mul_ps(in[j], *codebook++));
92 _mm_storeu_ps(dist+4*i, d);
93 }
94 for (i=0;i<entries;i++)
95 {
96 int sign;
97 if (dist[i]>0)
98 {
99 sign=0;
100 dist[i]=-dist[i];
101 } else
102 {
103 sign=1;
104 }
105 dist[i] += .5f*((float*)E)[i];
106 if (i<N || dist[i]<best_dist[N-1])
107 {
108 for (k=N-1; (k >= 1) && (k > used || dist[i] < best_dist[k-1]); k--)
109 {
110 best_dist[k]=best_dist[k-1];
111 nbest[k] = nbest[k-1];
112 }
113 best_dist[k]=dist[i];
114 nbest[k]=i;
115 used++;
116 if (sign)
117 nbest[k]+=entries;
118 }
119 }
120}
diff --git a/lib/rbcodec/codecs/libspeex/window.c b/lib/rbcodec/codecs/libspeex/window.c
new file mode 100644
index 0000000000..84ed4916cf
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/window.c
@@ -0,0 +1,102 @@
1/* Copyright (C) 2006 Jean-Marc Valin
2 File: window.c
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#ifdef HAVE_CONFIG_H
33#include "config-speex.h"
34#endif
35
36#include "arch.h"
37
38#ifdef FIXED_POINT
39const spx_word16_t lag_window[11] ICONST_ATTR = {
40 16384, 16337, 16199, 15970, 15656, 15260, 14790, 14254, 13659, 13015, 12330
41};
42
43const spx_word16_t lpc_window[200] ICONST_ATTR = {
441310, 1313, 1321, 1333, 1352, 1375, 1403, 1436,
451475, 1518, 1567, 1621, 1679, 1743, 1811, 1884,
461962, 2044, 2132, 2224, 2320, 2421, 2526, 2636,
472750, 2868, 2990, 3116, 3246, 3380, 3518, 3659,
483804, 3952, 4104, 4259, 4417, 4578, 4742, 4909,
495079, 5251, 5425, 5602, 5781, 5963, 6146, 6331,
506518, 6706, 6896, 7087, 7280, 7473, 7668, 7863,
518059, 8256, 8452, 8650, 8847, 9044, 9241, 9438,
529635, 9831, 10026, 10220, 10414, 10606, 10797, 10987,
5311176, 11363, 11548, 11731, 11912, 12091, 12268, 12443,
5412615, 12785, 12952, 13116, 13277, 13435, 13590, 13742,
5513890, 14035, 14176, 14314, 14448, 14578, 14704, 14826,
5614944, 15058, 15168, 15273, 15374, 15470, 15562, 15649,
5715732, 15810, 15883, 15951, 16015, 16073, 16127, 16175,
5816219, 16257, 16291, 16319, 16342, 16360, 16373, 16381,
5916384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,
6016384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,
6116384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,
6216384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,
6316384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,
6416384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,
6516384, 16384, 16384, 16361, 16294, 16183, 16028, 15830,
6615588, 15304, 14979, 14613, 14207, 13763, 13282, 12766,
6712215, 11631, 11016, 10373, 9702, 9007, 8289, 7551,
686797, 6028, 5251, 4470, 3695, 2943, 2248, 1696
69};
70#else
71const spx_word16_t lag_window[11] = {
72 1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998, 0.83367, 0.79434, 0.75258
73};
74
75const spx_word16_t lpc_window[200] = {
76 0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f,
77 0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f,
78 0.119769f, 0.124811f, 0.130137f, 0.135744f, 0.141628f, 0.147786f, 0.154212f, 0.160902f,
79 0.167852f, 0.175057f, 0.182513f, 0.190213f, 0.198153f, 0.206328f, 0.214731f, 0.223357f,
80 0.232200f, 0.241254f, 0.250513f, 0.259970f, 0.269619f, 0.279453f, 0.289466f, 0.299651f,
81 0.310000f, 0.320507f, 0.331164f, 0.341965f, 0.352901f, 0.363966f, 0.375151f, 0.386449f,
82 0.397852f, 0.409353f, 0.420943f, 0.432615f, 0.444361f, 0.456172f, 0.468040f, 0.479958f,
83 0.491917f, 0.503909f, 0.515925f, 0.527959f, 0.540000f, 0.552041f, 0.564075f, 0.576091f,
84 0.588083f, 0.600042f, 0.611960f, 0.623828f, 0.635639f, 0.647385f, 0.659057f, 0.670647f,
85 0.682148f, 0.693551f, 0.704849f, 0.716034f, 0.727099f, 0.738035f, 0.748836f, 0.759493f,
86 0.770000f, 0.780349f, 0.790534f, 0.800547f, 0.810381f, 0.820030f, 0.829487f, 0.838746f,
87 0.847800f, 0.856643f, 0.865269f, 0.873672f, 0.881847f, 0.889787f, 0.897487f, 0.904943f,
88 0.912148f, 0.919098f, 0.925788f, 0.932214f, 0.938372f, 0.944256f, 0.949863f, 0.955189f,
89 0.960231f, 0.964985f, 0.969447f, 0.973615f, 0.977486f, 0.981057f, 0.984326f, 0.987290f,
90 0.989948f, 0.992297f, 0.994337f, 0.996065f, 0.997480f, 0.998582f, 0.999370f, 0.999842f,
91 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
92 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
93 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
94 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
95 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
96 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
97 1.000000f, 1.000000f, 1.000000f, 0.998640f, 0.994566f, 0.987787f, 0.978324f, 0.966203f,
98 0.951458f, 0.934131f, 0.914270f, 0.891931f, 0.867179f, 0.840084f, 0.810723f, 0.779182f,
99 0.745551f, 0.709930f, 0.672424f, 0.633148f, 0.592223f, 0.549781f, 0.505964f, 0.460932f,
100 0.414863f, 0.367968f, 0.320511f, 0.272858f, 0.225569f, 0.179655f, 0.137254f, 0.103524f
101};
102#endif