1*a58d3d2aSXin Li /* Copyright (c) 2007-2008 CSIRO
2*a58d3d2aSXin Li Copyright (c) 2007-2010 Xiph.Org Foundation
3*a58d3d2aSXin Li Copyright (c) 2008 Gregory Maxwell
4*a58d3d2aSXin Li Written by Jean-Marc Valin and Gregory Maxwell */
5*a58d3d2aSXin Li /*
6*a58d3d2aSXin Li Redistribution and use in source and binary forms, with or without
7*a58d3d2aSXin Li modification, are permitted provided that the following conditions
8*a58d3d2aSXin Li are met:
9*a58d3d2aSXin Li
10*a58d3d2aSXin Li - Redistributions of source code must retain the above copyright
11*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer.
12*a58d3d2aSXin Li
13*a58d3d2aSXin Li - Redistributions in binary form must reproduce the above copyright
14*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer in the
15*a58d3d2aSXin Li documentation and/or other materials provided with the distribution.
16*a58d3d2aSXin Li
17*a58d3d2aSXin Li THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*a58d3d2aSXin Li ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*a58d3d2aSXin Li LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*a58d3d2aSXin Li A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21*a58d3d2aSXin Li OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22*a58d3d2aSXin Li EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23*a58d3d2aSXin Li PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24*a58d3d2aSXin Li PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25*a58d3d2aSXin Li LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26*a58d3d2aSXin Li NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27*a58d3d2aSXin Li SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*a58d3d2aSXin Li */
29*a58d3d2aSXin Li
30*a58d3d2aSXin Li #ifdef HAVE_CONFIG_H
31*a58d3d2aSXin Li #include "config.h"
32*a58d3d2aSXin Li #endif
33*a58d3d2aSXin Li
34*a58d3d2aSXin Li #define CELT_C
35*a58d3d2aSXin Li
36*a58d3d2aSXin Li #include "os_support.h"
37*a58d3d2aSXin Li #include "mdct.h"
38*a58d3d2aSXin Li #include <math.h>
39*a58d3d2aSXin Li #include "celt.h"
40*a58d3d2aSXin Li #include "pitch.h"
41*a58d3d2aSXin Li #include "bands.h"
42*a58d3d2aSXin Li #include "modes.h"
43*a58d3d2aSXin Li #include "entcode.h"
44*a58d3d2aSXin Li #include "quant_bands.h"
45*a58d3d2aSXin Li #include "rate.h"
46*a58d3d2aSXin Li #include "stack_alloc.h"
47*a58d3d2aSXin Li #include "mathops.h"
48*a58d3d2aSXin Li #include "float_cast.h"
49*a58d3d2aSXin Li #include <stdarg.h>
50*a58d3d2aSXin Li #include "celt_lpc.h"
51*a58d3d2aSXin Li #include "vq.h"
52*a58d3d2aSXin Li
53*a58d3d2aSXin Li #ifndef PACKAGE_VERSION
54*a58d3d2aSXin Li #define PACKAGE_VERSION "unknown"
55*a58d3d2aSXin Li #endif
56*a58d3d2aSXin Li
57*a58d3d2aSXin Li #if defined(MIPSr1_ASM)
58*a58d3d2aSXin Li #include "mips/celt_mipsr1.h"
59*a58d3d2aSXin Li #endif
60*a58d3d2aSXin Li
61*a58d3d2aSXin Li
resampling_factor(opus_int32 rate)62*a58d3d2aSXin Li int resampling_factor(opus_int32 rate)
63*a58d3d2aSXin Li {
64*a58d3d2aSXin Li int ret;
65*a58d3d2aSXin Li switch (rate)
66*a58d3d2aSXin Li {
67*a58d3d2aSXin Li case 48000:
68*a58d3d2aSXin Li ret = 1;
69*a58d3d2aSXin Li break;
70*a58d3d2aSXin Li case 24000:
71*a58d3d2aSXin Li ret = 2;
72*a58d3d2aSXin Li break;
73*a58d3d2aSXin Li case 16000:
74*a58d3d2aSXin Li ret = 3;
75*a58d3d2aSXin Li break;
76*a58d3d2aSXin Li case 12000:
77*a58d3d2aSXin Li ret = 4;
78*a58d3d2aSXin Li break;
79*a58d3d2aSXin Li case 8000:
80*a58d3d2aSXin Li ret = 6;
81*a58d3d2aSXin Li break;
82*a58d3d2aSXin Li default:
83*a58d3d2aSXin Li #ifndef CUSTOM_MODES
84*a58d3d2aSXin Li celt_assert(0);
85*a58d3d2aSXin Li #endif
86*a58d3d2aSXin Li ret = 0;
87*a58d3d2aSXin Li break;
88*a58d3d2aSXin Li }
89*a58d3d2aSXin Li return ret;
90*a58d3d2aSXin Li }
91*a58d3d2aSXin Li
92*a58d3d2aSXin Li #if !defined(OVERRIDE_COMB_FILTER_CONST) || defined(NON_STATIC_COMB_FILTER_CONST_C)
93*a58d3d2aSXin Li /* This version should be faster on ARM */
94*a58d3d2aSXin Li #ifdef OPUS_ARM_ASM
95*a58d3d2aSXin Li #ifndef NON_STATIC_COMB_FILTER_CONST_C
96*a58d3d2aSXin Li static
97*a58d3d2aSXin Li #endif
comb_filter_const_c(opus_val32 * y,opus_val32 * x,int T,int N,opus_val16 g10,opus_val16 g11,opus_val16 g12)98*a58d3d2aSXin Li void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
99*a58d3d2aSXin Li opus_val16 g10, opus_val16 g11, opus_val16 g12)
100*a58d3d2aSXin Li {
101*a58d3d2aSXin Li opus_val32 x0, x1, x2, x3, x4;
102*a58d3d2aSXin Li int i;
103*a58d3d2aSXin Li x4 = SHL32(x[-T-2], 1);
104*a58d3d2aSXin Li x3 = SHL32(x[-T-1], 1);
105*a58d3d2aSXin Li x2 = SHL32(x[-T], 1);
106*a58d3d2aSXin Li x1 = SHL32(x[-T+1], 1);
107*a58d3d2aSXin Li for (i=0;i<N-4;i+=5)
108*a58d3d2aSXin Li {
109*a58d3d2aSXin Li opus_val32 t;
110*a58d3d2aSXin Li x0=SHL32(x[i-T+2],1);
111*a58d3d2aSXin Li t = MAC16_32_Q16(x[i], g10, x2);
112*a58d3d2aSXin Li t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
113*a58d3d2aSXin Li t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
114*a58d3d2aSXin Li t = SATURATE(t, SIG_SAT);
115*a58d3d2aSXin Li y[i] = t;
116*a58d3d2aSXin Li x4=SHL32(x[i-T+3],1);
117*a58d3d2aSXin Li t = MAC16_32_Q16(x[i+1], g10, x1);
118*a58d3d2aSXin Li t = MAC16_32_Q16(t, g11, ADD32(x0,x2));
119*a58d3d2aSXin Li t = MAC16_32_Q16(t, g12, ADD32(x4,x3));
120*a58d3d2aSXin Li t = SATURATE(t, SIG_SAT);
121*a58d3d2aSXin Li y[i+1] = t;
122*a58d3d2aSXin Li x3=SHL32(x[i-T+4],1);
123*a58d3d2aSXin Li t = MAC16_32_Q16(x[i+2], g10, x0);
124*a58d3d2aSXin Li t = MAC16_32_Q16(t, g11, ADD32(x4,x1));
125*a58d3d2aSXin Li t = MAC16_32_Q16(t, g12, ADD32(x3,x2));
126*a58d3d2aSXin Li t = SATURATE(t, SIG_SAT);
127*a58d3d2aSXin Li y[i+2] = t;
128*a58d3d2aSXin Li x2=SHL32(x[i-T+5],1);
129*a58d3d2aSXin Li t = MAC16_32_Q16(x[i+3], g10, x4);
130*a58d3d2aSXin Li t = MAC16_32_Q16(t, g11, ADD32(x3,x0));
131*a58d3d2aSXin Li t = MAC16_32_Q16(t, g12, ADD32(x2,x1));
132*a58d3d2aSXin Li t = SATURATE(t, SIG_SAT);
133*a58d3d2aSXin Li y[i+3] = t;
134*a58d3d2aSXin Li x1=SHL32(x[i-T+6],1);
135*a58d3d2aSXin Li t = MAC16_32_Q16(x[i+4], g10, x3);
136*a58d3d2aSXin Li t = MAC16_32_Q16(t, g11, ADD32(x2,x4));
137*a58d3d2aSXin Li t = MAC16_32_Q16(t, g12, ADD32(x1,x0));
138*a58d3d2aSXin Li t = SATURATE(t, SIG_SAT);
139*a58d3d2aSXin Li y[i+4] = t;
140*a58d3d2aSXin Li }
141*a58d3d2aSXin Li #ifdef CUSTOM_MODES
142*a58d3d2aSXin Li for (;i<N;i++)
143*a58d3d2aSXin Li {
144*a58d3d2aSXin Li opus_val32 t;
145*a58d3d2aSXin Li x0=SHL32(x[i-T+2],1);
146*a58d3d2aSXin Li t = MAC16_32_Q16(x[i], g10, x2);
147*a58d3d2aSXin Li t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
148*a58d3d2aSXin Li t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
149*a58d3d2aSXin Li t = SATURATE(t, SIG_SAT);
150*a58d3d2aSXin Li y[i] = t;
151*a58d3d2aSXin Li x4=x3;
152*a58d3d2aSXin Li x3=x2;
153*a58d3d2aSXin Li x2=x1;
154*a58d3d2aSXin Li x1=x0;
155*a58d3d2aSXin Li }
156*a58d3d2aSXin Li #endif
157*a58d3d2aSXin Li }
158*a58d3d2aSXin Li #else
159*a58d3d2aSXin Li #ifndef NON_STATIC_COMB_FILTER_CONST_C
160*a58d3d2aSXin Li static
161*a58d3d2aSXin Li #endif
comb_filter_const_c(opus_val32 * y,opus_val32 * x,int T,int N,opus_val16 g10,opus_val16 g11,opus_val16 g12)162*a58d3d2aSXin Li void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
163*a58d3d2aSXin Li opus_val16 g10, opus_val16 g11, opus_val16 g12)
164*a58d3d2aSXin Li {
165*a58d3d2aSXin Li opus_val32 x0, x1, x2, x3, x4;
166*a58d3d2aSXin Li int i;
167*a58d3d2aSXin Li x4 = x[-T-2];
168*a58d3d2aSXin Li x3 = x[-T-1];
169*a58d3d2aSXin Li x2 = x[-T];
170*a58d3d2aSXin Li x1 = x[-T+1];
171*a58d3d2aSXin Li for (i=0;i<N;i++)
172*a58d3d2aSXin Li {
173*a58d3d2aSXin Li x0=x[i-T+2];
174*a58d3d2aSXin Li y[i] = x[i]
175*a58d3d2aSXin Li + MULT16_32_Q15(g10,x2)
176*a58d3d2aSXin Li + MULT16_32_Q15(g11,ADD32(x1,x3))
177*a58d3d2aSXin Li + MULT16_32_Q15(g12,ADD32(x0,x4));
178*a58d3d2aSXin Li y[i] = SATURATE(y[i], SIG_SAT);
179*a58d3d2aSXin Li x4=x3;
180*a58d3d2aSXin Li x3=x2;
181*a58d3d2aSXin Li x2=x1;
182*a58d3d2aSXin Li x1=x0;
183*a58d3d2aSXin Li }
184*a58d3d2aSXin Li
185*a58d3d2aSXin Li }
186*a58d3d2aSXin Li #endif
187*a58d3d2aSXin Li #endif
188*a58d3d2aSXin Li
189*a58d3d2aSXin Li #ifndef OVERRIDE_comb_filter
comb_filter(opus_val32 * y,opus_val32 * x,int T0,int T1,int N,opus_val16 g0,opus_val16 g1,int tapset0,int tapset1,const opus_val16 * window,int overlap,int arch)190*a58d3d2aSXin Li void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
191*a58d3d2aSXin Li opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
192*a58d3d2aSXin Li const opus_val16 *window, int overlap, int arch)
193*a58d3d2aSXin Li {
194*a58d3d2aSXin Li int i;
195*a58d3d2aSXin Li /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
196*a58d3d2aSXin Li opus_val16 g00, g01, g02, g10, g11, g12;
197*a58d3d2aSXin Li opus_val32 x0, x1, x2, x3, x4;
198*a58d3d2aSXin Li static const opus_val16 gains[3][3] = {
199*a58d3d2aSXin Li {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
200*a58d3d2aSXin Li {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
201*a58d3d2aSXin Li {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
202*a58d3d2aSXin Li
203*a58d3d2aSXin Li if (g0==0 && g1==0)
204*a58d3d2aSXin Li {
205*a58d3d2aSXin Li /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
206*a58d3d2aSXin Li if (x!=y)
207*a58d3d2aSXin Li OPUS_MOVE(y, x, N);
208*a58d3d2aSXin Li return;
209*a58d3d2aSXin Li }
210*a58d3d2aSXin Li /* When the gain is zero, T0 and/or T1 is set to zero. We need
211*a58d3d2aSXin Li to have then be at least 2 to avoid processing garbage data. */
212*a58d3d2aSXin Li T0 = IMAX(T0, COMBFILTER_MINPERIOD);
213*a58d3d2aSXin Li T1 = IMAX(T1, COMBFILTER_MINPERIOD);
214*a58d3d2aSXin Li g00 = MULT16_16_P15(g0, gains[tapset0][0]);
215*a58d3d2aSXin Li g01 = MULT16_16_P15(g0, gains[tapset0][1]);
216*a58d3d2aSXin Li g02 = MULT16_16_P15(g0, gains[tapset0][2]);
217*a58d3d2aSXin Li g10 = MULT16_16_P15(g1, gains[tapset1][0]);
218*a58d3d2aSXin Li g11 = MULT16_16_P15(g1, gains[tapset1][1]);
219*a58d3d2aSXin Li g12 = MULT16_16_P15(g1, gains[tapset1][2]);
220*a58d3d2aSXin Li x1 = x[-T1+1];
221*a58d3d2aSXin Li x2 = x[-T1 ];
222*a58d3d2aSXin Li x3 = x[-T1-1];
223*a58d3d2aSXin Li x4 = x[-T1-2];
224*a58d3d2aSXin Li /* If the filter didn't change, we don't need the overlap */
225*a58d3d2aSXin Li if (g0==g1 && T0==T1 && tapset0==tapset1)
226*a58d3d2aSXin Li overlap=0;
227*a58d3d2aSXin Li for (i=0;i<overlap;i++)
228*a58d3d2aSXin Li {
229*a58d3d2aSXin Li opus_val16 f;
230*a58d3d2aSXin Li x0=x[i-T1+2];
231*a58d3d2aSXin Li f = MULT16_16_Q15(window[i],window[i]);
232*a58d3d2aSXin Li y[i] = x[i]
233*a58d3d2aSXin Li + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
234*a58d3d2aSXin Li + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
235*a58d3d2aSXin Li + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
236*a58d3d2aSXin Li + MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)
237*a58d3d2aSXin Li + MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))
238*a58d3d2aSXin Li + MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));
239*a58d3d2aSXin Li y[i] = SATURATE(y[i], SIG_SAT);
240*a58d3d2aSXin Li x4=x3;
241*a58d3d2aSXin Li x3=x2;
242*a58d3d2aSXin Li x2=x1;
243*a58d3d2aSXin Li x1=x0;
244*a58d3d2aSXin Li
245*a58d3d2aSXin Li }
246*a58d3d2aSXin Li if (g1==0)
247*a58d3d2aSXin Li {
248*a58d3d2aSXin Li /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
249*a58d3d2aSXin Li if (x!=y)
250*a58d3d2aSXin Li OPUS_MOVE(y+overlap, x+overlap, N-overlap);
251*a58d3d2aSXin Li return;
252*a58d3d2aSXin Li }
253*a58d3d2aSXin Li
254*a58d3d2aSXin Li /* Compute the part with the constant filter. */
255*a58d3d2aSXin Li comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
256*a58d3d2aSXin Li }
257*a58d3d2aSXin Li #endif /* OVERRIDE_comb_filter */
258*a58d3d2aSXin Li
259*a58d3d2aSXin Li /* TF change table. Positive values mean better frequency resolution (longer
260*a58d3d2aSXin Li effective window), whereas negative values mean better time resolution
261*a58d3d2aSXin Li (shorter effective window). The second index is computed as:
262*a58d3d2aSXin Li 4*isTransient + 2*tf_select + per_band_flag */
263*a58d3d2aSXin Li const signed char tf_select_table[4][8] = {
264*a58d3d2aSXin Li /*isTransient=0 isTransient=1 */
265*a58d3d2aSXin Li {0, -1, 0, -1, 0,-1, 0,-1}, /* 2.5 ms */
266*a58d3d2aSXin Li {0, -1, 0, -2, 1, 0, 1,-1}, /* 5 ms */
267*a58d3d2aSXin Li {0, -2, 0, -3, 2, 0, 1,-1}, /* 10 ms */
268*a58d3d2aSXin Li {0, -2, 0, -3, 3, 0, 1,-1}, /* 20 ms */
269*a58d3d2aSXin Li };
270*a58d3d2aSXin Li
271*a58d3d2aSXin Li
init_caps(const CELTMode * m,int * cap,int LM,int C)272*a58d3d2aSXin Li void init_caps(const CELTMode *m,int *cap,int LM,int C)
273*a58d3d2aSXin Li {
274*a58d3d2aSXin Li int i;
275*a58d3d2aSXin Li for (i=0;i<m->nbEBands;i++)
276*a58d3d2aSXin Li {
277*a58d3d2aSXin Li int N;
278*a58d3d2aSXin Li N=(m->eBands[i+1]-m->eBands[i])<<LM;
279*a58d3d2aSXin Li cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
280*a58d3d2aSXin Li }
281*a58d3d2aSXin Li }
282*a58d3d2aSXin Li
283*a58d3d2aSXin Li
284*a58d3d2aSXin Li
opus_strerror(int error)285*a58d3d2aSXin Li const char *opus_strerror(int error)
286*a58d3d2aSXin Li {
287*a58d3d2aSXin Li static const char * const error_strings[8] = {
288*a58d3d2aSXin Li "success",
289*a58d3d2aSXin Li "invalid argument",
290*a58d3d2aSXin Li "buffer too small",
291*a58d3d2aSXin Li "internal error",
292*a58d3d2aSXin Li "corrupted stream",
293*a58d3d2aSXin Li "request not implemented",
294*a58d3d2aSXin Li "invalid state",
295*a58d3d2aSXin Li "memory allocation failed"
296*a58d3d2aSXin Li };
297*a58d3d2aSXin Li if (error > 0 || error < -7)
298*a58d3d2aSXin Li return "unknown error";
299*a58d3d2aSXin Li else
300*a58d3d2aSXin Li return error_strings[-error];
301*a58d3d2aSXin Li }
302*a58d3d2aSXin Li
opus_get_version_string(void)303*a58d3d2aSXin Li const char *opus_get_version_string(void)
304*a58d3d2aSXin Li {
305*a58d3d2aSXin Li return "libopus " PACKAGE_VERSION
306*a58d3d2aSXin Li /* Applications may rely on the presence of this substring in the version
307*a58d3d2aSXin Li string to determine if they have a fixed-point or floating-point build
308*a58d3d2aSXin Li at runtime. */
309*a58d3d2aSXin Li #ifdef FIXED_POINT
310*a58d3d2aSXin Li "-fixed"
311*a58d3d2aSXin Li #endif
312*a58d3d2aSXin Li #ifdef FUZZING
313*a58d3d2aSXin Li "-fuzzing"
314*a58d3d2aSXin Li #endif
315*a58d3d2aSXin Li ;
316*a58d3d2aSXin Li }
317