Coverage Report

Created: 2025-07-18 07:17

/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(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
}
comb_filter
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
}
comb_filter
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
}
comb_filter
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
}
comb_filter
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