Coverage Report

Created: 2026-10-17 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opus/celt/celt.c
Line
Count
Source
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(FIXED_POINT) && defined(__mips)
58
#include "mips/celt_mipsr1.h"
59
#endif
60
61
62
int resampling_factor(opus_int32 rate)
63
457k
{
64
457k
   int ret;
65
457k
   switch (rate)
66
457k
   {
67
#ifdef ENABLE_QEXT
68
   case 96000:
69
#endif
70
60.3k
   case 48000:
71
60.3k
      ret = 1;
72
60.3k
      break;
73
61.2k
   case 24000:
74
61.2k
      ret = 2;
75
61.2k
      break;
76
67.9k
   case 16000:
77
67.9k
      ret = 3;
78
67.9k
      break;
79
67.3k
   case 12000:
80
67.3k
      ret = 4;
81
67.3k
      break;
82
200k
   case 8000:
83
200k
      ret = 6;
84
200k
      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
457k
   }
92
457k
   return ret;
93
457k
}
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
1.12M
{
169
1.12M
   opus_val32 x0, x1, x2, x3, x4;
170
1.12M
   int i;
171
1.12M
   x4 = x[-T-2];
172
1.12M
   x3 = x[-T-1];
173
1.12M
   x2 = x[-T];
174
1.12M
   x1 = x[-T+1];
175
714M
   for (i=0;i<N;i++)
176
713M
   {
177
713M
      x0=x[i-T+2];
178
713M
      y[i] = x[i]
179
713M
               + MULT_COEF_32(g10,x2)
180
713M
               + MULT_COEF_32(g11,ADD32(x1,x3))
181
713M
               + MULT_COEF_32(g12,ADD32(x0,x4));
182
713M
#ifdef FIXED_POINT
183
      /* A bit of bias seems to help here. */
184
713M
      y[i] = SUB32(y[i], 1);
185
713M
#endif
186
713M
      y[i] = SATURATE(y[i], SIG_SAT);
187
713M
      x4=x3;
188
713M
      x3=x2;
189
713M
      x2=x1;
190
713M
      x1=x0;
191
713M
   }
192
193
1.12M
}
194
#endif
195
#endif
196
197
#ifdef ENABLE_QEXT
198
void comb_filter_qext(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
16.6M
{
202
16.6M
   VARDECL(opus_val32, mem_buf);
203
16.6M
   VARDECL(opus_val32, buf);
204
16.6M
   celt_coef new_window[120];
205
16.6M
   int s;
206
16.6M
   int i;
207
16.6M
   int N2;
208
16.6M
   int overlap2;
209
16.6M
   SAVE_STACK;
210
   /* Using ALLOC() instead of a regular stack allocation to minimize real stack use when using the pseudostack.
211
      This is useful on some embedded systems. */
212
16.6M
   ALLOC(mem_buf, COMBFILTER_MAXPERIOD+960, opus_val32);
213
16.6M
   ALLOC(buf, COMBFILTER_MAXPERIOD+960, opus_val32);
214
16.6M
   N2 = N/2;
215
16.6M
   overlap2=overlap/2;
216
   /* At 96 kHz, we double the period and the spacing between taps, which is equivalent
217
      to creating a mirror image of the filter around 24 kHz. It also means we can process
218
      the even and odd samples completely independently. */
219
49.9M
   for (s=0;s<2;s++) {
220
33.2M
      opus_val32 *yptr;
221
4.02G
      for (i=0;i<overlap2;i++) new_window[i] = window[2*i+s];
222
53.8G
      for (i=0;i<COMBFILTER_MAXPERIOD+N2;i++) mem_buf[i] = x[2*i+s-2*COMBFILTER_MAXPERIOD];
223
33.2M
      if (x==y) {
224
204k
         yptr = mem_buf+COMBFILTER_MAXPERIOD;
225
33.0M
      } else {
226
19.6G
         for (i=0;i<N2;i++) buf[i] = y[2*i+s];
227
33.0M
         yptr = buf;
228
33.0M
      }
229
33.2M
      comb_filter(yptr, mem_buf+COMBFILTER_MAXPERIOD, T0, T1, N2, g0, g1, tapset0, tapset1, new_window, overlap2, arch);
230
19.7G
      for (i=0;i<N2;i++) y[2*i+s] = yptr[i];
231
33.2M
   }
232
16.6M
   RESTORE_STACK;
233
16.6M
   return;
234
16.6M
}
235
#endif
236
237
#ifndef OVERRIDE_comb_filter
238
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
239
      opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
240
      const celt_coef *window, int overlap, int arch)
241
335M
{
242
335M
   int i;
243
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
244
335M
   celt_coef g00, g01, g02, g10, g11, g12;
245
335M
   opus_val32 x0, x1, x2, x3, x4;
246
335M
   static const opus_val16 gains[3][3] = {
247
335M
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
248
335M
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
249
335M
         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
250
#ifdef ENABLE_QEXT
251
255M
   if (overlap==240) {
252
16.6M
      comb_filter_qext(y, x, T0, T1, N, g0, g1, tapset0, tapset1, window, overlap, arch);
253
16.6M
      return;
254
16.6M
   }
255
238M
#endif
256
318M
   if (g0==0 && g1==0)
257
317M
   {
258
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
259
317M
      if (x!=y)
260
317M
         OPUS_MOVE(y, x, N);
261
317M
      return;
262
317M
   }
263
   /* When the gain is zero, T0 and/or T1 is set to zero. We need
264
      to have then be at least 2 to avoid processing garbage data. */
265
1.22M
   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
266
1.22M
   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
267
1.22M
   g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
268
1.22M
   g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
269
1.22M
   g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
270
1.22M
   g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
271
1.22M
   g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
272
1.22M
   g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
273
1.22M
   x1 = x[-T1+1];
274
1.22M
   x2 = x[-T1  ];
275
1.22M
   x3 = x[-T1-1];
276
1.22M
   x4 = x[-T1-2];
277
   /* If the filter didn't change, we don't need the overlap */
278
1.22M
   if (g0==g1 && T0==T1 && tapset0==tapset1)
279
374k
      overlap=0;
280
100M
   for (i=0;i<overlap;i++)
281
99.2M
   {
282
99.2M
      celt_coef f;
283
99.2M
      x0=x[i-T1+2];
284
99.2M
      f = MULT_COEF(window[i],window[i]);
285
99.2M
      y[i] = x[i]
286
99.2M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
287
99.2M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
288
99.2M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
289
99.2M
               + MULT_COEF_32(MULT_COEF(f,g10),x2)
290
99.2M
               + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
291
99.2M
               + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4));
292
#ifdef FIXED_POINT
293
      /* A bit of bias seems to help here. */
294
93.1M
      y[i] = SUB32(y[i], 3);
295
#endif
296
99.2M
      y[i] = SATURATE(y[i], SIG_SAT);
297
99.2M
      x4=x3;
298
99.2M
      x3=x2;
299
99.2M
      x2=x1;
300
99.2M
      x1=x0;
301
302
99.2M
   }
303
1.22M
   if (g1==0)
304
38.3k
   {
305
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
306
38.3k
      if (x!=y)
307
18.7k
         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
308
38.3k
      return;
309
38.3k
   }
310
311
   /* Compute the part with the constant filter. */
312
1.19M
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
313
1.19M
}
comb_filter
Line
Count
Source
241
80.2M
{
242
80.2M
   int i;
243
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
244
80.2M
   celt_coef g00, g01, g02, g10, g11, g12;
245
80.2M
   opus_val32 x0, x1, x2, x3, x4;
246
80.2M
   static const opus_val16 gains[3][3] = {
247
80.2M
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
248
80.2M
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
249
80.2M
         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
250
#ifdef ENABLE_QEXT
251
   if (overlap==240) {
252
      comb_filter_qext(y, x, T0, T1, N, g0, g1, tapset0, tapset1, window, overlap, arch);
253
      return;
254
   }
255
#endif
256
80.2M
   if (g0==0 && g1==0)
257
79.3M
   {
258
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
259
79.3M
      if (x!=y)
260
79.1M
         OPUS_MOVE(y, x, N);
261
79.3M
      return;
262
79.3M
   }
263
   /* When the gain is zero, T0 and/or T1 is set to zero. We need
264
      to have then be at least 2 to avoid processing garbage data. */
265
957k
   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
266
957k
   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
267
957k
   g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
268
957k
   g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
269
957k
   g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
270
957k
   g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
271
957k
   g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
272
957k
   g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
273
957k
   x1 = x[-T1+1];
274
957k
   x2 = x[-T1  ];
275
957k
   x3 = x[-T1-1];
276
957k
   x4 = x[-T1-2];
277
   /* If the filter didn't change, we don't need the overlap */
278
957k
   if (g0==g1 && T0==T1 && tapset0==tapset1)
279
302k
      overlap=0;
280
78.4M
   for (i=0;i<overlap;i++)
281
77.4M
   {
282
77.4M
      celt_coef f;
283
77.4M
      x0=x[i-T1+2];
284
77.4M
      f = MULT_COEF(window[i],window[i]);
285
77.4M
      y[i] = x[i]
286
77.4M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
287
77.4M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
288
77.4M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
289
77.4M
               + MULT_COEF_32(MULT_COEF(f,g10),x2)
290
77.4M
               + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
291
77.4M
               + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4));
292
77.4M
#ifdef FIXED_POINT
293
      /* A bit of bias seems to help here. */
294
77.4M
      y[i] = SUB32(y[i], 3);
295
77.4M
#endif
296
77.4M
      y[i] = SATURATE(y[i], SIG_SAT);
297
77.4M
      x4=x3;
298
77.4M
      x3=x2;
299
77.4M
      x2=x1;
300
77.4M
      x1=x0;
301
302
77.4M
   }
303
957k
   if (g1==0)
304
13.2k
   {
305
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
306
13.2k
      if (x!=y)
307
7.21k
         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
308
13.2k
      return;
309
13.2k
   }
310
311
   /* Compute the part with the constant filter. */
312
943k
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
313
943k
}
comb_filter
Line
Count
Source
241
103M
{
242
103M
   int i;
243
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
244
103M
   celt_coef g00, g01, g02, g10, g11, g12;
245
103M
   opus_val32 x0, x1, x2, x3, x4;
246
103M
   static const opus_val16 gains[3][3] = {
247
103M
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
248
103M
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
249
103M
         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
250
103M
#ifdef ENABLE_QEXT
251
103M
   if (overlap==240) {
252
2.30M
      comb_filter_qext(y, x, T0, T1, N, g0, g1, tapset0, tapset1, window, overlap, arch);
253
2.30M
      return;
254
2.30M
   }
255
101M
#endif
256
101M
   if (g0==0 && g1==0)
257
101M
   {
258
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
259
101M
      if (x!=y)
260
101M
         OPUS_MOVE(y, x, N);
261
101M
      return;
262
101M
   }
263
   /* When the gain is zero, T0 and/or T1 is set to zero. We need
264
      to have then be at least 2 to avoid processing garbage data. */
265
191k
   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
266
191k
   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
267
191k
   g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
268
191k
   g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
269
191k
   g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
270
191k
   g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
271
191k
   g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
272
191k
   g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
273
191k
   x1 = x[-T1+1];
274
191k
   x2 = x[-T1  ];
275
191k
   x3 = x[-T1-1];
276
191k
   x4 = x[-T1-2];
277
   /* If the filter didn't change, we don't need the overlap */
278
191k
   if (g0==g1 && T0==T1 && tapset0==tapset1)
279
48.8k
      overlap=0;
280
15.8M
   for (i=0;i<overlap;i++)
281
15.6M
   {
282
15.6M
      celt_coef f;
283
15.6M
      x0=x[i-T1+2];
284
15.6M
      f = MULT_COEF(window[i],window[i]);
285
15.6M
      y[i] = x[i]
286
15.6M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
287
15.6M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
288
15.6M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
289
15.6M
               + MULT_COEF_32(MULT_COEF(f,g10),x2)
290
15.6M
               + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
291
15.6M
               + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4));
292
15.6M
#ifdef FIXED_POINT
293
      /* A bit of bias seems to help here. */
294
15.6M
      y[i] = SUB32(y[i], 3);
295
15.6M
#endif
296
15.6M
      y[i] = SATURATE(y[i], SIG_SAT);
297
15.6M
      x4=x3;
298
15.6M
      x3=x2;
299
15.6M
      x2=x1;
300
15.6M
      x1=x0;
301
302
15.6M
   }
303
191k
   if (g1==0)
304
15.4k
   {
305
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
306
15.4k
      if (x!=y)
307
6.31k
         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
308
15.4k
      return;
309
15.4k
   }
310
311
   /* Compute the part with the constant filter. */
312
176k
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
313
176k
}
comb_filter
Line
Count
Source
241
151M
{
242
151M
   int i;
243
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
244
151M
   celt_coef g00, g01, g02, g10, g11, g12;
245
151M
   opus_val32 x0, x1, x2, x3, x4;
246
151M
   static const opus_val16 gains[3][3] = {
247
151M
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
248
151M
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
249
151M
         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
250
151M
#ifdef ENABLE_QEXT
251
151M
   if (overlap==240) {
252
14.3M
      comb_filter_qext(y, x, T0, T1, N, g0, g1, tapset0, tapset1, window, overlap, arch);
253
14.3M
      return;
254
14.3M
   }
255
137M
#endif
256
137M
   if (g0==0 && g1==0)
257
137M
   {
258
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
259
137M
      if (x!=y)
260
136M
         OPUS_MOVE(y, x, N);
261
137M
      return;
262
137M
   }
263
   /* When the gain is zero, T0 and/or T1 is set to zero. We need
264
      to have then be at least 2 to avoid processing garbage data. */
265
79.3k
   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
266
79.3k
   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
267
79.3k
   g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
268
79.3k
   g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
269
79.3k
   g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
270
79.3k
   g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
271
79.3k
   g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
272
79.3k
   g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
273
79.3k
   x1 = x[-T1+1];
274
79.3k
   x2 = x[-T1  ];
275
79.3k
   x3 = x[-T1-1];
276
79.3k
   x4 = x[-T1-2];
277
   /* If the filter didn't change, we don't need the overlap */
278
79.3k
   if (g0==g1 && T0==T1 && tapset0==tapset1)
279
23.0k
      overlap=0;
280
6.21M
   for (i=0;i<overlap;i++)
281
6.13M
   {
282
6.13M
      celt_coef f;
283
6.13M
      x0=x[i-T1+2];
284
6.13M
      f = MULT_COEF(window[i],window[i]);
285
6.13M
      y[i] = x[i]
286
6.13M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
287
6.13M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
288
6.13M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
289
6.13M
               + MULT_COEF_32(MULT_COEF(f,g10),x2)
290
6.13M
               + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
291
6.13M
               + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4));
292
#ifdef FIXED_POINT
293
      /* A bit of bias seems to help here. */
294
      y[i] = SUB32(y[i], 3);
295
#endif
296
6.13M
      y[i] = SATURATE(y[i], SIG_SAT);
297
6.13M
      x4=x3;
298
6.13M
      x3=x2;
299
6.13M
      x2=x1;
300
6.13M
      x1=x0;
301
302
6.13M
   }
303
79.3k
   if (g1==0)
304
9.52k
   {
305
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
306
9.52k
      if (x!=y)
307
5.18k
         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
308
9.52k
      return;
309
9.52k
   }
310
311
   /* Compute the part with the constant filter. */
312
69.8k
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
313
69.8k
}
314
#endif /* OVERRIDE_comb_filter */
315
316
/* TF change table. Positive values mean better frequency resolution (longer
317
   effective window), whereas negative values mean better time resolution
318
   (shorter effective window). The second index is computed as:
319
   4*isTransient + 2*tf_select + per_band_flag */
320
const signed char tf_select_table[4][8] = {
321
    /*isTransient=0     isTransient=1 */
322
      {0, -1, 0, -1,    0,-1, 0,-1}, /* 2.5 ms */
323
      {0, -1, 0, -2,    1, 0, 1,-1}, /* 5 ms */
324
      {0, -2, 0, -3,    2, 0, 1,-1}, /* 10 ms */
325
      {0, -2, 0, -3,    3, 0, 1,-1}, /* 20 ms */
326
};
327
328
329
void init_caps(const CELTMode *m,int *cap,int LM,int C)
330
243M
{
331
243M
   int i;
332
5.36G
   for (i=0;i<m->nbEBands;i++)
333
5.11G
   {
334
5.11G
      int N;
335
5.11G
      N=(m->eBands[i+1]-m->eBands[i])<<LM;
336
5.11G
      cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
337
5.11G
   }
338
243M
}
339
340
341
342
const char *opus_strerror(int error)
343
0
{
344
0
   static const char * const error_strings[8] = {
345
0
      "success",
346
0
      "invalid argument",
347
0
      "buffer too small",
348
0
      "internal error",
349
0
      "corrupted stream",
350
0
      "request not implemented",
351
0
      "invalid state",
352
0
      "memory allocation failed"
353
0
   };
354
0
   if (error > 0 || error < -7)
355
0
      return "unknown error";
356
0
   else
357
0
      return error_strings[-error];
358
0
}
359
360
const char *opus_get_version_string(void)
361
0
{
362
0
    return "libopus " PACKAGE_VERSION
363
    /* Applications may rely on the presence of this substring in the version
364
       string to determine if they have a fixed-point or floating-point build
365
       at runtime. */
366
#ifdef FIXED_POINT
367
          "-fixed"
368
#endif
369
#ifdef FUZZING
370
          "-fuzzing"
371
#endif
372
0
          ;
373
0
}
Unexecuted instantiation: opus_get_version_string
Unexecuted instantiation: opus_get_version_string