Coverage Report

Created: 2025-08-28 07:12

/src/opus/celt/celt.c
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(FIXED_POINT) && defined(__mips_dsp) && __mips == 32
58
#include "mips/celt_mipsr1.h"
59
#endif
60
61
62
int resampling_factor(opus_int32 rate)
63
59.7k
{
64
59.7k
   int ret;
65
59.7k
   switch (rate)
66
59.7k
   {
67
59.7k
   case 48000:
68
59.7k
      ret = 1;
69
59.7k
      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
59.7k
   }
89
59.7k
   return ret;
90
59.7k
}
91
92
93
#if !defined(OVERRIDE_COMB_FILTER_CONST) || defined(NON_STATIC_COMB_FILTER_CONST_C)
94
/* This version should be faster on ARM */
95
#ifdef OPUS_ARM_ASM
96
#ifndef NON_STATIC_COMB_FILTER_CONST_C
97
static
98
#endif
99
void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
100
      celt_coef g10, celt_coef g11, celt_coef g12)
101
{
102
   opus_val32 x0, x1, x2, x3, x4;
103
   int i;
104
   x4 = SHL32(x[-T-2], 1);
105
   x3 = SHL32(x[-T-1], 1);
106
   x2 = SHL32(x[-T], 1);
107
   x1 = SHL32(x[-T+1], 1);
108
   for (i=0;i<N-4;i+=5)
109
   {
110
      opus_val32 t;
111
      x0=SHL32(x[i-T+2],1);
112
      t = MAC_COEF_32_ARM(x[i], g10, x2);
113
      t = MAC_COEF_32_ARM(t, g11, ADD32(x1,x3));
114
      t = MAC_COEF_32_ARM(t, g12, ADD32(x0,x4));
115
      t = SATURATE(t, SIG_SAT);
116
      y[i] = t;
117
      x4=SHL32(x[i-T+3],1);
118
      t = MAC_COEF_32_ARM(x[i+1], g10, x1);
119
      t = MAC_COEF_32_ARM(t, g11, ADD32(x0,x2));
120
      t = MAC_COEF_32_ARM(t, g12, ADD32(x4,x3));
121
      t = SATURATE(t, SIG_SAT);
122
      y[i+1] = t;
123
      x3=SHL32(x[i-T+4],1);
124
      t = MAC_COEF_32_ARM(x[i+2], g10, x0);
125
      t = MAC_COEF_32_ARM(t, g11, ADD32(x4,x1));
126
      t = MAC_COEF_32_ARM(t, g12, ADD32(x3,x2));
127
      t = SATURATE(t, SIG_SAT);
128
      y[i+2] = t;
129
      x2=SHL32(x[i-T+5],1);
130
      t = MAC_COEF_32_ARM(x[i+3], g10, x4);
131
      t = MAC_COEF_32_ARM(t, g11, ADD32(x3,x0));
132
      t = MAC_COEF_32_ARM(t, g12, ADD32(x2,x1));
133
      t = SATURATE(t, SIG_SAT);
134
      y[i+3] = t;
135
      x1=SHL32(x[i-T+6],1);
136
      t = MAC_COEF_32_ARM(x[i+4], g10, x3);
137
      t = MAC_COEF_32_ARM(t, g11, ADD32(x2,x4));
138
      t = MAC_COEF_32_ARM(t, g12, ADD32(x1,x0));
139
      t = SATURATE(t, SIG_SAT);
140
      y[i+4] = t;
141
   }
142
#ifdef CUSTOM_MODES
143
   for (;i<N;i++)
144
   {
145
      opus_val32 t;
146
      x0=SHL32(x[i-T+2],1);
147
      t = MAC_COEF_32_ARM(x[i], g10, x2);
148
      t = MAC_COEF_32_ARM(t, g11, ADD32(x1,x3));
149
      t = MAC_COEF_32_ARM(t, g12, ADD32(x0,x4));
150
      t = SATURATE(t, SIG_SAT);
151
      y[i] = t;
152
      x4=x3;
153
      x3=x2;
154
      x2=x1;
155
      x1=x0;
156
   }
157
#endif
158
}
159
#else
160
#ifndef NON_STATIC_COMB_FILTER_CONST_C
161
static
162
#endif
163
void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
164
      celt_coef g10, celt_coef g11, celt_coef g12)
165
{
166
   opus_val32 x0, x1, x2, x3, x4;
167
   int i;
168
   x4 = x[-T-2];
169
   x3 = x[-T-1];
170
   x2 = x[-T];
171
   x1 = x[-T+1];
172
   for (i=0;i<N;i++)
173
   {
174
      x0=x[i-T+2];
175
      y[i] = x[i]
176
               + MULT_COEF_32(g10,x2)
177
               + MULT_COEF_32(g11,ADD32(x1,x3))
178
               + MULT_COEF_32(g12,ADD32(x0,x4));
179
#ifdef FIXED_POINT
180
      /* A bit of bias seems to help here. */
181
      y[i] = SUB32(y[i], 1);
182
#endif
183
      y[i] = SATURATE(y[i], SIG_SAT);
184
      x4=x3;
185
      x3=x2;
186
      x2=x1;
187
      x1=x0;
188
   }
189
190
}
191
#endif
192
#endif
193
194
#ifndef OVERRIDE_comb_filter
195
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
196
      opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
197
      const celt_coef *window, int overlap, int arch)
198
406k
{
199
406k
   int i;
200
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
201
406k
   celt_coef g00, g01, g02, g10, g11, g12;
202
406k
   opus_val32 x0, x1, x2, x3, x4;
203
406k
   static const opus_val16 gains[3][3] = {
204
406k
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
205
406k
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
206
406k
         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
207
208
406k
   if (g0==0 && g1==0)
209
353k
   {
210
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
211
353k
      if (x!=y)
212
12.3k
         OPUS_MOVE(y, x, N);
213
353k
      return;
214
353k
   }
215
   /* When the gain is zero, T0 and/or T1 is set to zero. We need
216
      to have then be at least 2 to avoid processing garbage data. */
217
52.8k
   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
218
52.8k
   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
219
52.8k
   g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
220
52.8k
   g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
221
52.8k
   g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
222
52.8k
   g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
223
52.8k
   g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
224
52.8k
   g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
225
52.8k
   x1 = x[-T1+1];
226
52.8k
   x2 = x[-T1  ];
227
52.8k
   x3 = x[-T1-1];
228
52.8k
   x4 = x[-T1-2];
229
   /* If the filter didn't change, we don't need the overlap */
230
52.8k
   if (g0==g1 && T0==T1 && tapset0==tapset1)
231
26.8k
      overlap=0;
232
3.09M
   for (i=0;i<overlap;i++)
233
3.04M
   {
234
3.04M
      celt_coef f;
235
3.04M
      x0=x[i-T1+2];
236
3.04M
      f = MULT_COEF(window[i],window[i]);
237
3.04M
      y[i] = x[i]
238
3.04M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
239
3.04M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
240
3.04M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
241
3.04M
               + MULT_COEF_32(MULT_COEF(f,g10),x2)
242
3.04M
               + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
243
3.04M
               + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4));
244
#ifdef FIXED_POINT
245
      /* A bit of bias seems to help here. */
246
      y[i] = SUB32(y[i], 3);
247
#endif
248
3.04M
      y[i] = SATURATE(y[i], SIG_SAT);
249
3.04M
      x4=x3;
250
3.04M
      x3=x2;
251
3.04M
      x2=x1;
252
3.04M
      x1=x0;
253
254
3.04M
   }
255
52.8k
   if (g1==0)
256
5.09k
   {
257
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
258
5.09k
      if (x!=y)
259
303
         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
260
5.09k
      return;
261
5.09k
   }
262
263
   /* Compute the part with the constant filter. */
264
47.7k
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
265
47.7k
}
266
#endif /* OVERRIDE_comb_filter */
267
268
/* TF change table. Positive values mean better frequency resolution (longer
269
   effective window), whereas negative values mean better time resolution
270
   (shorter effective window). The second index is computed as:
271
   4*isTransient + 2*tf_select + per_band_flag */
272
const signed char tf_select_table[4][8] = {
273
    /*isTransient=0     isTransient=1 */
274
      {0, -1, 0, -1,    0,-1, 0,-1}, /* 2.5 ms */
275
      {0, -1, 0, -2,    1, 0, 1,-1}, /* 5 ms */
276
      {0, -2, 0, -3,    2, 0, 1,-1}, /* 10 ms */
277
      {0, -2, 0, -3,    3, 0, 1,-1}, /* 20 ms */
278
};
279
280
281
void init_caps(const CELTMode *m,int *cap,int LM,int C)
282
116k
{
283
116k
   int i;
284
2.57M
   for (i=0;i<m->nbEBands;i++)
285
2.45M
   {
286
2.45M
      int N;
287
2.45M
      N=(m->eBands[i+1]-m->eBands[i])<<LM;
288
2.45M
      cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
289
2.45M
   }
290
116k
}
291
292
293
294
const char *opus_strerror(int error)
295
66.2k
{
296
66.2k
   static const char * const error_strings[8] = {
297
66.2k
      "success",
298
66.2k
      "invalid argument",
299
66.2k
      "buffer too small",
300
66.2k
      "internal error",
301
66.2k
      "corrupted stream",
302
66.2k
      "request not implemented",
303
66.2k
      "invalid state",
304
66.2k
      "memory allocation failed"
305
66.2k
   };
306
66.2k
   if (error > 0 || error < -7)
307
0
      return "unknown error";
308
66.2k
   else
309
66.2k
      return error_strings[-error];
310
66.2k
}
311
312
const char *opus_get_version_string(void)
313
0
{
314
0
    return "libopus " PACKAGE_VERSION
315
    /* Applications may rely on the presence of this substring in the version
316
       string to determine if they have a fixed-point or floating-point build
317
       at runtime. */
318
#ifdef FIXED_POINT
319
          "-fixed"
320
#endif
321
#ifdef FUZZING
322
          "-fuzzing"
323
#endif
324
0
          ;
325
0
}