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 | 441k | { |
64 | 441k | int ret; |
65 | 441k | switch (rate) |
66 | 441k | { |
67 | | #ifdef ENABLE_QEXT |
68 | | case 96000: |
69 | | #endif |
70 | 59.4k | case 48000: |
71 | 59.4k | ret = 1; |
72 | 59.4k | break; |
73 | 60.4k | case 24000: |
74 | 60.4k | ret = 2; |
75 | 60.4k | break; |
76 | 69.2k | case 16000: |
77 | 69.2k | ret = 3; |
78 | 69.2k | break; |
79 | 61.6k | case 12000: |
80 | 61.6k | ret = 4; |
81 | 61.6k | break; |
82 | 191k | case 8000: |
83 | 191k | ret = 6; |
84 | 191k | break; |
85 | 0 | default: |
86 | 0 | #ifndef CUSTOM_MODES |
87 | 0 | celt_assert(0); |
88 | 0 | #endif |
89 | 0 | ret = 0; |
90 | 0 | break; |
91 | 441k | } |
92 | 441k | return ret; |
93 | 441k | } |
94 | | |
95 | | |
96 | | #if !defined(OVERRIDE_COMB_FILTER_CONST) || defined(NON_STATIC_COMB_FILTER_CONST_C) |
97 | | /* This version should be faster on ARM */ |
98 | | #ifdef OPUS_ARM_ASM |
99 | | #ifndef NON_STATIC_COMB_FILTER_CONST_C |
100 | | static |
101 | | #endif |
102 | | void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N, |
103 | | celt_coef g10, celt_coef g11, celt_coef g12) |
104 | | { |
105 | | opus_val32 x0, x1, x2, x3, x4; |
106 | | int i; |
107 | | x4 = SHL32(x[-T-2], 1); |
108 | | x3 = SHL32(x[-T-1], 1); |
109 | | x2 = SHL32(x[-T], 1); |
110 | | x1 = SHL32(x[-T+1], 1); |
111 | | for (i=0;i<N-4;i+=5) |
112 | | { |
113 | | opus_val32 t; |
114 | | x0=SHL32(x[i-T+2],1); |
115 | | t = MAC_COEF_32_ARM(x[i], g10, x2); |
116 | | t = MAC_COEF_32_ARM(t, g11, ADD32(x1,x3)); |
117 | | t = MAC_COEF_32_ARM(t, g12, ADD32(x0,x4)); |
118 | | t = SATURATE(t, SIG_SAT); |
119 | | y[i] = t; |
120 | | x4=SHL32(x[i-T+3],1); |
121 | | t = MAC_COEF_32_ARM(x[i+1], g10, x1); |
122 | | t = MAC_COEF_32_ARM(t, g11, ADD32(x0,x2)); |
123 | | t = MAC_COEF_32_ARM(t, g12, ADD32(x4,x3)); |
124 | | t = SATURATE(t, SIG_SAT); |
125 | | y[i+1] = t; |
126 | | x3=SHL32(x[i-T+4],1); |
127 | | t = MAC_COEF_32_ARM(x[i+2], g10, x0); |
128 | | t = MAC_COEF_32_ARM(t, g11, ADD32(x4,x1)); |
129 | | t = MAC_COEF_32_ARM(t, g12, ADD32(x3,x2)); |
130 | | t = SATURATE(t, SIG_SAT); |
131 | | y[i+2] = t; |
132 | | x2=SHL32(x[i-T+5],1); |
133 | | t = MAC_COEF_32_ARM(x[i+3], g10, x4); |
134 | | t = MAC_COEF_32_ARM(t, g11, ADD32(x3,x0)); |
135 | | t = MAC_COEF_32_ARM(t, g12, ADD32(x2,x1)); |
136 | | t = SATURATE(t, SIG_SAT); |
137 | | y[i+3] = t; |
138 | | x1=SHL32(x[i-T+6],1); |
139 | | t = MAC_COEF_32_ARM(x[i+4], g10, x3); |
140 | | t = MAC_COEF_32_ARM(t, g11, ADD32(x2,x4)); |
141 | | t = MAC_COEF_32_ARM(t, g12, ADD32(x1,x0)); |
142 | | t = SATURATE(t, SIG_SAT); |
143 | | y[i+4] = t; |
144 | | } |
145 | | #ifdef CUSTOM_MODES |
146 | | for (;i<N;i++) |
147 | | { |
148 | | opus_val32 t; |
149 | | x0=SHL32(x[i-T+2],1); |
150 | | t = MAC_COEF_32_ARM(x[i], g10, x2); |
151 | | t = MAC_COEF_32_ARM(t, g11, ADD32(x1,x3)); |
152 | | t = MAC_COEF_32_ARM(t, g12, ADD32(x0,x4)); |
153 | | t = SATURATE(t, SIG_SAT); |
154 | | y[i] = t; |
155 | | x4=x3; |
156 | | x3=x2; |
157 | | x2=x1; |
158 | | x1=x0; |
159 | | } |
160 | | #endif |
161 | | } |
162 | | #else |
163 | | #ifndef NON_STATIC_COMB_FILTER_CONST_C |
164 | | static |
165 | | #endif |
166 | | void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N, |
167 | | celt_coef g10, celt_coef g11, celt_coef g12) |
168 | 91.9k | { |
169 | 91.9k | opus_val32 x0, x1, x2, x3, x4; |
170 | 91.9k | int i; |
171 | 91.9k | x4 = x[-T-2]; |
172 | 91.9k | x3 = x[-T-1]; |
173 | 91.9k | x2 = x[-T]; |
174 | 91.9k | x1 = x[-T+1]; |
175 | 21.7M | for (i=0;i<N;i++) |
176 | 21.6M | { |
177 | 21.6M | x0=x[i-T+2]; |
178 | 21.6M | y[i] = x[i] |
179 | 21.6M | + MULT_COEF_32(g10,x2) |
180 | 21.6M | + MULT_COEF_32(g11,ADD32(x1,x3)) |
181 | 21.6M | + MULT_COEF_32(g12,ADD32(x0,x4)); |
182 | 21.6M | #ifdef FIXED_POINT |
183 | | /* A bit of bias seems to help here. */ |
184 | 21.6M | y[i] = SUB32(y[i], 1); |
185 | 21.6M | #endif |
186 | 21.6M | y[i] = SATURATE(y[i], SIG_SAT); |
187 | 21.6M | x4=x3; |
188 | 21.6M | x3=x2; |
189 | 21.6M | x2=x1; |
190 | 21.6M | x1=x0; |
191 | 21.6M | } |
192 | | |
193 | 91.9k | } |
194 | | #endif |
195 | | #endif |
196 | | |
197 | | #ifndef OVERRIDE_comb_filter |
198 | | void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N, |
199 | | opus_val16 g0, opus_val16 g1, int tapset0, int tapset1, |
200 | | const celt_coef *window, int overlap, int arch) |
201 | 139M | { |
202 | 139M | int i; |
203 | | /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */ |
204 | 139M | celt_coef g00, g01, g02, g10, g11, g12; |
205 | 139M | opus_val32 x0, x1, x2, x3, x4; |
206 | 139M | static const opus_val16 gains[3][3] = { |
207 | 139M | {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)}, |
208 | 139M | {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)}, |
209 | 139M | {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}}; |
210 | | #ifdef ENABLE_QEXT |
211 | 920k | if (overlap==240) { |
212 | 107k | opus_val32 mem_buf[COMBFILTER_MAXPERIOD+960]; |
213 | 107k | opus_val32 buf[COMBFILTER_MAXPERIOD+960]; |
214 | 107k | celt_coef new_window[120]; |
215 | 107k | int s; |
216 | 107k | int N2; |
217 | 107k | int overlap2; |
218 | 107k | N2 = N/2; |
219 | 107k | overlap2=overlap/2; |
220 | | /* At 96 kHz, we double the period and the spacing between taps, which is equivalent |
221 | | to creating a mirror image of the filter around 24 kHz. It also means we can process |
222 | | the even and odd samples completely independently. */ |
223 | 322k | for (s=0;s<2;s++) { |
224 | 214k | opus_val32 *yptr; |
225 | 25.9M | for (i=0;i<overlap2;i++) new_window[i] = window[2*i+s]; |
226 | 259M | for (i=0;i<COMBFILTER_MAXPERIOD+N2;i++) mem_buf[i] = x[2*i+s-2*COMBFILTER_MAXPERIOD]; |
227 | 214k | if (x==y) { |
228 | 188k | yptr = mem_buf+COMBFILTER_MAXPERIOD; |
229 | 188k | } else { |
230 | 6.69M | for (i=0;i<N2;i++) buf[i] = y[2*i+s]; |
231 | 26.1k | yptr = buf; |
232 | 26.1k | } |
233 | 214k | comb_filter(yptr, mem_buf+COMBFILTER_MAXPERIOD, T0, T1, N2, g0, g1, tapset0, tapset1, new_window, overlap2, arch); |
234 | 39.7M | for (i=0;i<N2;i++) y[2*i+s] = yptr[i]; |
235 | 214k | } |
236 | 107k | return; |
237 | 107k | } |
238 | 813k | #endif |
239 | 139M | if (g0==0 && g1==0) |
240 | 138M | { |
241 | | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ |
242 | 138M | if (x!=y) |
243 | 138M | OPUS_MOVE(y, x, N); |
244 | 138M | return; |
245 | 138M | } |
246 | | /* When the gain is zero, T0 and/or T1 is set to zero. We need |
247 | | to have then be at least 2 to avoid processing garbage data. */ |
248 | 291k | T0 = IMAX(T0, COMBFILTER_MINPERIOD); |
249 | 291k | T1 = IMAX(T1, COMBFILTER_MINPERIOD); |
250 | 291k | g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]); |
251 | 291k | g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]); |
252 | 291k | g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]); |
253 | 291k | g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]); |
254 | 291k | g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]); |
255 | 291k | g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]); |
256 | 291k | x1 = x[-T1+1]; |
257 | 291k | x2 = x[-T1 ]; |
258 | 291k | x3 = x[-T1-1]; |
259 | 291k | x4 = x[-T1-2]; |
260 | | /* If the filter didn't change, we don't need the overlap */ |
261 | 291k | if (g0==g1 && T0==T1 && tapset0==tapset1) |
262 | 73.6k | overlap=0; |
263 | 24.0M | for (i=0;i<overlap;i++) |
264 | 23.7M | { |
265 | 23.7M | celt_coef f; |
266 | 23.7M | x0=x[i-T1+2]; |
267 | 23.7M | f = MULT_COEF(window[i],window[i]); |
268 | 23.7M | y[i] = x[i] |
269 | 23.7M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0]) |
270 | 23.7M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1])) |
271 | 23.7M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2])) |
272 | 23.7M | + MULT_COEF_32(MULT_COEF(f,g10),x2) |
273 | 23.7M | + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3)) |
274 | 23.7M | + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4)); |
275 | | #ifdef FIXED_POINT |
276 | | /* A bit of bias seems to help here. */ |
277 | 8.39M | y[i] = SUB32(y[i], 3); |
278 | | #endif |
279 | 23.7M | y[i] = SATURATE(y[i], SIG_SAT); |
280 | 23.7M | x4=x3; |
281 | 23.7M | x3=x2; |
282 | 23.7M | x2=x1; |
283 | 23.7M | x1=x0; |
284 | | |
285 | 23.7M | } |
286 | 291k | if (g1==0) |
287 | 35.7k | { |
288 | | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ |
289 | 35.7k | if (x!=y) |
290 | 16.0k | OPUS_MOVE(y+overlap, x+overlap, N-overlap); |
291 | 35.7k | return; |
292 | 35.7k | } |
293 | | |
294 | | /* Compute the part with the constant filter. */ |
295 | 255k | comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch); |
296 | 255k | } Line | Count | Source | 201 | 413k | { | 202 | 413k | int i; | 203 | | /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */ | 204 | 413k | celt_coef g00, g01, g02, g10, g11, g12; | 205 | 413k | opus_val32 x0, x1, x2, x3, x4; | 206 | 413k | static const opus_val16 gains[3][3] = { | 207 | 413k | {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)}, | 208 | 413k | {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)}, | 209 | 413k | {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}}; | 210 | | #ifdef ENABLE_QEXT | 211 | | if (overlap==240) { | 212 | | opus_val32 mem_buf[COMBFILTER_MAXPERIOD+960]; | 213 | | opus_val32 buf[COMBFILTER_MAXPERIOD+960]; | 214 | | celt_coef new_window[120]; | 215 | | int s; | 216 | | int N2; | 217 | | int overlap2; | 218 | | N2 = N/2; | 219 | | overlap2=overlap/2; | 220 | | /* At 96 kHz, we double the period and the spacing between taps, which is equivalent | 221 | | to creating a mirror image of the filter around 24 kHz. It also means we can process | 222 | | the even and odd samples completely independently. */ | 223 | | for (s=0;s<2;s++) { | 224 | | opus_val32 *yptr; | 225 | | for (i=0;i<overlap2;i++) new_window[i] = window[2*i+s]; | 226 | | for (i=0;i<COMBFILTER_MAXPERIOD+N2;i++) mem_buf[i] = x[2*i+s-2*COMBFILTER_MAXPERIOD]; | 227 | | if (x==y) { | 228 | | yptr = mem_buf+COMBFILTER_MAXPERIOD; | 229 | | } else { | 230 | | for (i=0;i<N2;i++) buf[i] = y[2*i+s]; | 231 | | yptr = buf; | 232 | | } | 233 | | comb_filter(yptr, mem_buf+COMBFILTER_MAXPERIOD, T0, T1, N2, g0, g1, tapset0, tapset1, new_window, overlap2, arch); | 234 | | for (i=0;i<N2;i++) y[2*i+s] = yptr[i]; | 235 | | } | 236 | | return; | 237 | | } | 238 | | #endif | 239 | 413k | if (g0==0 && g1==0) | 240 | 360k | { | 241 | | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ | 242 | 360k | if (x!=y) | 243 | 201k | OPUS_MOVE(y, x, N); | 244 | 360k | return; | 245 | 360k | } | 246 | | /* When the gain is zero, T0 and/or T1 is set to zero. We need | 247 | | to have then be at least 2 to avoid processing garbage data. */ | 248 | 52.2k | T0 = IMAX(T0, COMBFILTER_MINPERIOD); | 249 | 52.2k | T1 = IMAX(T1, COMBFILTER_MINPERIOD); | 250 | 52.2k | g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]); | 251 | 52.2k | g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]); | 252 | 52.2k | g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]); | 253 | 52.2k | g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]); | 254 | 52.2k | g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]); | 255 | 52.2k | g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]); | 256 | 52.2k | x1 = x[-T1+1]; | 257 | 52.2k | x2 = x[-T1 ]; | 258 | 52.2k | x3 = x[-T1-1]; | 259 | 52.2k | x4 = x[-T1-2]; | 260 | | /* If the filter didn't change, we don't need the overlap */ | 261 | 52.2k | if (g0==g1 && T0==T1 && tapset0==tapset1) | 262 | 7.53k | overlap=0; | 263 | 4.18M | for (i=0;i<overlap;i++) | 264 | 4.12M | { | 265 | 4.12M | celt_coef f; | 266 | 4.12M | x0=x[i-T1+2]; | 267 | 4.12M | f = MULT_COEF(window[i],window[i]); | 268 | 4.12M | y[i] = x[i] | 269 | 4.12M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0]) | 270 | 4.12M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1])) | 271 | 4.12M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2])) | 272 | 4.12M | + MULT_COEF_32(MULT_COEF(f,g10),x2) | 273 | 4.12M | + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3)) | 274 | 4.12M | + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4)); | 275 | 4.12M | #ifdef FIXED_POINT | 276 | | /* A bit of bias seems to help here. */ | 277 | 4.12M | y[i] = SUB32(y[i], 3); | 278 | 4.12M | #endif | 279 | 4.12M | y[i] = SATURATE(y[i], SIG_SAT); | 280 | 4.12M | x4=x3; | 281 | 4.12M | x3=x2; | 282 | 4.12M | x2=x1; | 283 | 4.12M | x1=x0; | 284 | | | 285 | 4.12M | } | 286 | 52.2k | if (g1==0) | 287 | 11.7k | { | 288 | | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ | 289 | 11.7k | if (x!=y) | 290 | 4.69k | OPUS_MOVE(y+overlap, x+overlap, N-overlap); | 291 | 11.7k | return; | 292 | 11.7k | } | 293 | | | 294 | | /* Compute the part with the constant filter. */ | 295 | 40.5k | comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch); | 296 | 40.5k | } |
Line | Count | Source | 201 | 506k | { | 202 | 506k | int i; | 203 | | /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */ | 204 | 506k | celt_coef g00, g01, g02, g10, g11, g12; | 205 | 506k | opus_val32 x0, x1, x2, x3, x4; | 206 | 506k | static const opus_val16 gains[3][3] = { | 207 | 506k | {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)}, | 208 | 506k | {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)}, | 209 | 506k | {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}}; | 210 | 506k | #ifdef ENABLE_QEXT | 211 | 506k | if (overlap==240) { | 212 | 63.9k | opus_val32 mem_buf[COMBFILTER_MAXPERIOD+960]; | 213 | 63.9k | opus_val32 buf[COMBFILTER_MAXPERIOD+960]; | 214 | 63.9k | celt_coef new_window[120]; | 215 | 63.9k | int s; | 216 | 63.9k | int N2; | 217 | 63.9k | int overlap2; | 218 | 63.9k | N2 = N/2; | 219 | 63.9k | overlap2=overlap/2; | 220 | | /* At 96 kHz, we double the period and the spacing between taps, which is equivalent | 221 | | to creating a mirror image of the filter around 24 kHz. It also means we can process | 222 | | the even and odd samples completely independently. */ | 223 | 191k | for (s=0;s<2;s++) { | 224 | 127k | opus_val32 *yptr; | 225 | 15.4M | for (i=0;i<overlap2;i++) new_window[i] = window[2*i+s]; | 226 | 154M | for (i=0;i<COMBFILTER_MAXPERIOD+N2;i++) mem_buf[i] = x[2*i+s-2*COMBFILTER_MAXPERIOD]; | 227 | 127k | if (x==y) { | 228 | 111k | yptr = mem_buf+COMBFILTER_MAXPERIOD; | 229 | 111k | } else { | 230 | 4.44M | for (i=0;i<N2;i++) buf[i] = y[2*i+s]; | 231 | 16.6k | yptr = buf; | 232 | 16.6k | } | 233 | 127k | comb_filter(yptr, mem_buf+COMBFILTER_MAXPERIOD, T0, T1, N2, g0, g1, tapset0, tapset1, new_window, overlap2, arch); | 234 | 23.9M | for (i=0;i<N2;i++) y[2*i+s] = yptr[i]; | 235 | 127k | } | 236 | 63.9k | return; | 237 | 63.9k | } | 238 | 442k | #endif | 239 | 442k | if (g0==0 && g1==0) | 240 | 383k | { | 241 | | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ | 242 | 383k | if (x!=y) | 243 | 206k | OPUS_MOVE(y, x, N); | 244 | 383k | return; | 245 | 383k | } | 246 | | /* When the gain is zero, T0 and/or T1 is set to zero. We need | 247 | | to have then be at least 2 to avoid processing garbage data. */ | 248 | 58.8k | T0 = IMAX(T0, COMBFILTER_MINPERIOD); | 249 | 58.8k | T1 = IMAX(T1, COMBFILTER_MINPERIOD); | 250 | 58.8k | g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]); | 251 | 58.8k | g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]); | 252 | 58.8k | g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]); | 253 | 58.8k | g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]); | 254 | 58.8k | g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]); | 255 | 58.8k | g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]); | 256 | 58.8k | x1 = x[-T1+1]; | 257 | 58.8k | x2 = x[-T1 ]; | 258 | 58.8k | x3 = x[-T1-1]; | 259 | 58.8k | x4 = x[-T1-2]; | 260 | | /* If the filter didn't change, we don't need the overlap */ | 261 | 58.8k | if (g0==g1 && T0==T1 && tapset0==tapset1) | 262 | 18.5k | overlap=0; | 263 | 4.32M | for (i=0;i<overlap;i++) | 264 | 4.26M | { | 265 | 4.26M | celt_coef f; | 266 | 4.26M | x0=x[i-T1+2]; | 267 | 4.26M | f = MULT_COEF(window[i],window[i]); | 268 | 4.26M | y[i] = x[i] | 269 | 4.26M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0]) | 270 | 4.26M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1])) | 271 | 4.26M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2])) | 272 | 4.26M | + MULT_COEF_32(MULT_COEF(f,g10),x2) | 273 | 4.26M | + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3)) | 274 | 4.26M | + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4)); | 275 | 4.26M | #ifdef FIXED_POINT | 276 | | /* A bit of bias seems to help here. */ | 277 | 4.26M | y[i] = SUB32(y[i], 3); | 278 | 4.26M | #endif | 279 | 4.26M | y[i] = SATURATE(y[i], SIG_SAT); | 280 | 4.26M | x4=x3; | 281 | 4.26M | x3=x2; | 282 | 4.26M | x2=x1; | 283 | 4.26M | x1=x0; | 284 | | | 285 | 4.26M | } | 286 | 58.8k | if (g1==0) | 287 | 7.42k | { | 288 | | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ | 289 | 7.42k | if (x!=y) | 290 | 1.91k | OPUS_MOVE(y+overlap, x+overlap, N-overlap); | 291 | 7.42k | return; | 292 | 7.42k | } | 293 | | | 294 | | /* Compute the part with the constant filter. */ | 295 | 51.4k | comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch); | 296 | 51.4k | } |
Line | Count | Source | 201 | 414k | { | 202 | 414k | int i; | 203 | | /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */ | 204 | 414k | celt_coef g00, g01, g02, g10, g11, g12; | 205 | 414k | opus_val32 x0, x1, x2, x3, x4; | 206 | 414k | static const opus_val16 gains[3][3] = { | 207 | 414k | {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)}, | 208 | 414k | {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)}, | 209 | 414k | {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}}; | 210 | 414k | #ifdef ENABLE_QEXT | 211 | 414k | if (overlap==240) { | 212 | 43.4k | opus_val32 mem_buf[COMBFILTER_MAXPERIOD+960]; | 213 | 43.4k | opus_val32 buf[COMBFILTER_MAXPERIOD+960]; | 214 | 43.4k | celt_coef new_window[120]; | 215 | 43.4k | int s; | 216 | 43.4k | int N2; | 217 | 43.4k | int overlap2; | 218 | 43.4k | N2 = N/2; | 219 | 43.4k | overlap2=overlap/2; | 220 | | /* At 96 kHz, we double the period and the spacing between taps, which is equivalent | 221 | | to creating a mirror image of the filter around 24 kHz. It also means we can process | 222 | | the even and odd samples completely independently. */ | 223 | 130k | for (s=0;s<2;s++) { | 224 | 86.8k | opus_val32 *yptr; | 225 | 10.5M | for (i=0;i<overlap2;i++) new_window[i] = window[2*i+s]; | 226 | 104M | for (i=0;i<COMBFILTER_MAXPERIOD+N2;i++) mem_buf[i] = x[2*i+s-2*COMBFILTER_MAXPERIOD]; | 227 | 86.8k | if (x==y) { | 228 | 77.3k | yptr = mem_buf+COMBFILTER_MAXPERIOD; | 229 | 77.3k | } else { | 230 | 2.24M | for (i=0;i<N2;i++) buf[i] = y[2*i+s]; | 231 | 9.55k | yptr = buf; | 232 | 9.55k | } | 233 | 86.8k | comb_filter(yptr, mem_buf+COMBFILTER_MAXPERIOD, T0, T1, N2, g0, g1, tapset0, tapset1, new_window, overlap2, arch); | 234 | 15.8M | for (i=0;i<N2;i++) y[2*i+s] = yptr[i]; | 235 | 86.8k | } | 236 | 43.4k | return; | 237 | 43.4k | } | 238 | 371k | #endif | 239 | 371k | if (g0==0 && g1==0) | 240 | 338k | { | 241 | | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ | 242 | 338k | if (x!=y) | 243 | 185k | OPUS_MOVE(y, x, N); | 244 | 338k | return; | 245 | 338k | } | 246 | | /* When the gain is zero, T0 and/or T1 is set to zero. We need | 247 | | to have then be at least 2 to avoid processing garbage data. */ | 248 | 32.4k | T0 = IMAX(T0, COMBFILTER_MINPERIOD); | 249 | 32.4k | T1 = IMAX(T1, COMBFILTER_MINPERIOD); | 250 | 32.4k | g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]); | 251 | 32.4k | g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]); | 252 | 32.4k | g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]); | 253 | 32.4k | g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]); | 254 | 32.4k | g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]); | 255 | 32.4k | g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]); | 256 | 32.4k | x1 = x[-T1+1]; | 257 | 32.4k | x2 = x[-T1 ]; | 258 | 32.4k | x3 = x[-T1-1]; | 259 | 32.4k | x4 = x[-T1-2]; | 260 | | /* If the filter didn't change, we don't need the overlap */ | 261 | 32.4k | if (g0==g1 && T0==T1 && tapset0==tapset1) | 262 | 10.2k | overlap=0; | 263 | 2.59M | for (i=0;i<overlap;i++) | 264 | 2.55M | { | 265 | 2.55M | celt_coef f; | 266 | 2.55M | x0=x[i-T1+2]; | 267 | 2.55M | f = MULT_COEF(window[i],window[i]); | 268 | 2.55M | y[i] = x[i] | 269 | 2.55M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0]) | 270 | 2.55M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1])) | 271 | 2.55M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2])) | 272 | 2.55M | + MULT_COEF_32(MULT_COEF(f,g10),x2) | 273 | 2.55M | + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3)) | 274 | 2.55M | + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4)); | 275 | | #ifdef FIXED_POINT | 276 | | /* A bit of bias seems to help here. */ | 277 | | y[i] = SUB32(y[i], 3); | 278 | | #endif | 279 | 2.55M | y[i] = SATURATE(y[i], SIG_SAT); | 280 | 2.55M | x4=x3; | 281 | 2.55M | x3=x2; | 282 | 2.55M | x2=x1; | 283 | 2.55M | x1=x0; | 284 | | | 285 | 2.55M | } | 286 | 32.4k | if (g1==0) | 287 | 2.68k | { | 288 | | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ | 289 | 2.68k | if (x!=y) | 290 | 740 | OPUS_MOVE(y+overlap, x+overlap, N-overlap); | 291 | 2.68k | return; | 292 | 2.68k | } | 293 | | | 294 | | /* Compute the part with the constant filter. */ | 295 | 29.7k | comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch); | 296 | 29.7k | } |
Line | Count | Source | 201 | 137M | { | 202 | 137M | int i; | 203 | | /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */ | 204 | 137M | celt_coef g00, g01, g02, g10, g11, g12; | 205 | 137M | opus_val32 x0, x1, x2, x3, x4; | 206 | 137M | static const opus_val16 gains[3][3] = { | 207 | 137M | {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)}, | 208 | 137M | {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)}, | 209 | 137M | {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}}; | 210 | | #ifdef ENABLE_QEXT | 211 | | if (overlap==240) { | 212 | | opus_val32 mem_buf[COMBFILTER_MAXPERIOD+960]; | 213 | | opus_val32 buf[COMBFILTER_MAXPERIOD+960]; | 214 | | celt_coef new_window[120]; | 215 | | int s; | 216 | | int N2; | 217 | | int overlap2; | 218 | | N2 = N/2; | 219 | | overlap2=overlap/2; | 220 | | /* At 96 kHz, we double the period and the spacing between taps, which is equivalent | 221 | | to creating a mirror image of the filter around 24 kHz. It also means we can process | 222 | | the even and odd samples completely independently. */ | 223 | | for (s=0;s<2;s++) { | 224 | | opus_val32 *yptr; | 225 | | for (i=0;i<overlap2;i++) new_window[i] = window[2*i+s]; | 226 | | for (i=0;i<COMBFILTER_MAXPERIOD+N2;i++) mem_buf[i] = x[2*i+s-2*COMBFILTER_MAXPERIOD]; | 227 | | if (x==y) { | 228 | | yptr = mem_buf+COMBFILTER_MAXPERIOD; | 229 | | } else { | 230 | | for (i=0;i<N2;i++) buf[i] = y[2*i+s]; | 231 | | yptr = buf; | 232 | | } | 233 | | comb_filter(yptr, mem_buf+COMBFILTER_MAXPERIOD, T0, T1, N2, g0, g1, tapset0, tapset1, new_window, overlap2, arch); | 234 | | for (i=0;i<N2;i++) y[2*i+s] = yptr[i]; | 235 | | } | 236 | | return; | 237 | | } | 238 | | #endif | 239 | 137M | if (g0==0 && g1==0) | 240 | 137M | { | 241 | | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ | 242 | 137M | if (x!=y) | 243 | 137M | OPUS_MOVE(y, x, N); | 244 | 137M | return; | 245 | 137M | } | 246 | | /* When the gain is zero, T0 and/or T1 is set to zero. We need | 247 | | to have then be at least 2 to avoid processing garbage data. */ | 248 | 147k | T0 = IMAX(T0, COMBFILTER_MINPERIOD); | 249 | 147k | T1 = IMAX(T1, COMBFILTER_MINPERIOD); | 250 | 147k | g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]); | 251 | 147k | g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]); | 252 | 147k | g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]); | 253 | 147k | g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]); | 254 | 147k | g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]); | 255 | 147k | g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]); | 256 | 147k | x1 = x[-T1+1]; | 257 | 147k | x2 = x[-T1 ]; | 258 | 147k | x3 = x[-T1-1]; | 259 | 147k | x4 = x[-T1-2]; | 260 | | /* If the filter didn't change, we don't need the overlap */ | 261 | 147k | if (g0==g1 && T0==T1 && tapset0==tapset1) | 262 | 37.3k | overlap=0; | 263 | 12.9M | for (i=0;i<overlap;i++) | 264 | 12.7M | { | 265 | 12.7M | celt_coef f; | 266 | 12.7M | x0=x[i-T1+2]; | 267 | 12.7M | f = MULT_COEF(window[i],window[i]); | 268 | 12.7M | y[i] = x[i] | 269 | 12.7M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0]) | 270 | 12.7M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1])) | 271 | 12.7M | + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2])) | 272 | 12.7M | + MULT_COEF_32(MULT_COEF(f,g10),x2) | 273 | 12.7M | + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3)) | 274 | 12.7M | + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4)); | 275 | | #ifdef FIXED_POINT | 276 | | /* A bit of bias seems to help here. */ | 277 | | y[i] = SUB32(y[i], 3); | 278 | | #endif | 279 | 12.7M | y[i] = SATURATE(y[i], SIG_SAT); | 280 | 12.7M | x4=x3; | 281 | 12.7M | x3=x2; | 282 | 12.7M | x2=x1; | 283 | 12.7M | x1=x0; | 284 | | | 285 | 12.7M | } | 286 | 147k | if (g1==0) | 287 | 13.8k | { | 288 | | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ | 289 | 13.8k | if (x!=y) | 290 | 8.68k | OPUS_MOVE(y+overlap, x+overlap, N-overlap); | 291 | 13.8k | return; | 292 | 13.8k | } | 293 | | | 294 | | /* Compute the part with the constant filter. */ | 295 | 133k | comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch); | 296 | 133k | } |
|
297 | | #endif /* OVERRIDE_comb_filter */ |
298 | | |
299 | | /* TF change table. Positive values mean better frequency resolution (longer |
300 | | effective window), whereas negative values mean better time resolution |
301 | | (shorter effective window). The second index is computed as: |
302 | | 4*isTransient + 2*tf_select + per_band_flag */ |
303 | | const signed char tf_select_table[4][8] = { |
304 | | /*isTransient=0 isTransient=1 */ |
305 | | {0, -1, 0, -1, 0,-1, 0,-1}, /* 2.5 ms */ |
306 | | {0, -1, 0, -2, 1, 0, 1,-1}, /* 5 ms */ |
307 | | {0, -2, 0, -3, 2, 0, 1,-1}, /* 10 ms */ |
308 | | {0, -2, 0, -3, 3, 0, 1,-1}, /* 20 ms */ |
309 | | }; |
310 | | |
311 | | |
312 | | void init_caps(const CELTMode *m,int *cap,int LM,int C) |
313 | 62.0M | { |
314 | 62.0M | int i; |
315 | 1.36G | for (i=0;i<m->nbEBands;i++) |
316 | 1.30G | { |
317 | 1.30G | int N; |
318 | 1.30G | N=(m->eBands[i+1]-m->eBands[i])<<LM; |
319 | 1.30G | cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2; |
320 | 1.30G | } |
321 | 62.0M | } |
322 | | |
323 | | |
324 | | |
325 | | const char *opus_strerror(int error) |
326 | 0 | { |
327 | 0 | static const char * const error_strings[8] = { |
328 | 0 | "success", |
329 | 0 | "invalid argument", |
330 | 0 | "buffer too small", |
331 | 0 | "internal error", |
332 | 0 | "corrupted stream", |
333 | 0 | "request not implemented", |
334 | 0 | "invalid state", |
335 | 0 | "memory allocation failed" |
336 | 0 | }; |
337 | 0 | if (error > 0 || error < -7) |
338 | 0 | return "unknown error"; |
339 | 0 | else |
340 | 0 | return error_strings[-error]; |
341 | 0 | } |
342 | | |
343 | | const char *opus_get_version_string(void) |
344 | 0 | { |
345 | 0 | return "libopus " PACKAGE_VERSION |
346 | | /* Applications may rely on the presence of this substring in the version |
347 | | string to determine if they have a fixed-point or floating-point build |
348 | | at runtime. */ |
349 | | #ifdef FIXED_POINT |
350 | | "-fixed" |
351 | | #endif |
352 | | #ifdef FUZZING |
353 | | "-fuzzing" |
354 | | #endif |
355 | 0 | ; |
356 | 0 | } Unexecuted instantiation: opus_get_version_string Unexecuted instantiation: opus_get_version_string |