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