Coverage Report

Created: 2026-01-17 07:45

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
442k
{
64
442k
   int ret;
65
442k
   switch (rate)
66
442k
   {
67
#ifdef ENABLE_QEXT
68
   case 96000:
69
#endif
70
61.0k
   case 48000:
71
61.0k
      ret = 1;
72
61.0k
      break;
73
60.1k
   case 24000:
74
60.1k
      ret = 2;
75
60.1k
      break;
76
70.0k
   case 16000:
77
70.0k
      ret = 3;
78
70.0k
      break;
79
61.9k
   case 12000:
80
61.9k
      ret = 4;
81
61.9k
      break;
82
189k
   case 8000:
83
189k
      ret = 6;
84
189k
      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
442k
   }
92
442k
   return ret;
93
442k
}
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.84M
{
169
1.84M
   opus_val32 x0, x1, x2, x3, x4;
170
1.84M
   int i;
171
1.84M
   x4 = x[-T-2];
172
1.84M
   x3 = x[-T-1];
173
1.84M
   x2 = x[-T];
174
1.84M
   x1 = x[-T+1];
175
1.14G
   for (i=0;i<N;i++)
176
1.13G
   {
177
1.13G
      x0=x[i-T+2];
178
1.13G
      y[i] = x[i]
179
1.13G
               + MULT_COEF_32(g10,x2)
180
1.13G
               + MULT_COEF_32(g11,ADD32(x1,x3))
181
1.13G
               + MULT_COEF_32(g12,ADD32(x0,x4));
182
1.13G
#ifdef FIXED_POINT
183
      /* A bit of bias seems to help here. */
184
1.13G
      y[i] = SUB32(y[i], 1);
185
1.13G
#endif
186
1.13G
      y[i] = SATURATE(y[i], SIG_SAT);
187
1.13G
      x4=x3;
188
1.13G
      x3=x2;
189
1.13G
      x2=x1;
190
1.13G
      x1=x0;
191
1.13G
   }
192
193
1.84M
}
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
217M
{
202
217M
   int i;
203
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
204
217M
   celt_coef g00, g01, g02, g10, g11, g12;
205
217M
   opus_val32 x0, x1, x2, x3, x4;
206
217M
   static const opus_val16 gains[3][3] = {
207
217M
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
208
217M
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
209
217M
         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
210
#ifdef ENABLE_QEXT
211
1.03M
   if (overlap==240) {
212
116k
      opus_val32 mem_buf[COMBFILTER_MAXPERIOD+960];
213
116k
      opus_val32 buf[COMBFILTER_MAXPERIOD+960];
214
116k
      celt_coef new_window[120];
215
116k
      int s;
216
116k
      int N2;
217
116k
      int overlap2;
218
116k
      N2 = N/2;
219
116k
      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
348k
      for (s=0;s<2;s++) {
224
232k
         opus_val32 *yptr;
225
28.1M
         for (i=0;i<overlap2;i++) new_window[i] = window[2*i+s];
226
281M
         for (i=0;i<COMBFILTER_MAXPERIOD+N2;i++) mem_buf[i] = x[2*i+s-2*COMBFILTER_MAXPERIOD];
227
232k
         if (x==y) {
228
208k
            yptr = mem_buf+COMBFILTER_MAXPERIOD;
229
208k
         } else {
230
6.94M
            for (i=0;i<N2;i++) buf[i] = y[2*i+s];
231
24.2k
            yptr = buf;
232
24.2k
         }
233
232k
         comb_filter(yptr, mem_buf+COMBFILTER_MAXPERIOD, T0, T1, N2, g0, g1, tapset0, tapset1, new_window, overlap2, arch);
234
43.4M
         for (i=0;i<N2;i++) y[2*i+s] = yptr[i];
235
232k
      }
236
116k
      return;
237
116k
   }
238
914k
#endif
239
216M
   if (g0==0 && g1==0)
240
214M
   {
241
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
242
214M
      if (x!=y)
243
214M
         OPUS_MOVE(y, x, N);
244
214M
      return;
245
214M
   }
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
2.16M
   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
249
2.16M
   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
250
2.16M
   g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
251
2.16M
   g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
252
2.16M
   g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
253
2.16M
   g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
254
2.16M
   g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
255
2.16M
   g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
256
2.16M
   x1 = x[-T1+1];
257
2.16M
   x2 = x[-T1  ];
258
2.16M
   x3 = x[-T1-1];
259
2.16M
   x4 = x[-T1-2];
260
   /* If the filter didn't change, we don't need the overlap */
261
2.16M
   if (g0==g1 && T0==T1 && tapset0==tapset1)
262
627k
      overlap=0;
263
182M
   for (i=0;i<overlap;i++)
264
180M
   {
265
180M
      celt_coef f;
266
180M
      x0=x[i-T1+2];
267
180M
      f = MULT_COEF(window[i],window[i]);
268
180M
      y[i] = x[i]
269
180M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
270
180M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
271
180M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
272
180M
               + MULT_COEF_32(MULT_COEF(f,g10),x2)
273
180M
               + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
274
180M
               + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4));
275
#ifdef FIXED_POINT
276
      /* A bit of bias seems to help here. */
277
152M
      y[i] = SUB32(y[i], 3);
278
#endif
279
180M
      y[i] = SATURATE(y[i], SIG_SAT);
280
180M
      x4=x3;
281
180M
      x3=x2;
282
180M
      x2=x1;
283
180M
      x1=x0;
284
285
180M
   }
286
2.16M
   if (g1==0)
287
48.2k
   {
288
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
289
48.2k
      if (x!=y)
290
23.9k
         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
291
48.2k
      return;
292
48.2k
   }
293
294
   /* Compute the part with the constant filter. */
295
2.11M
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
296
2.11M
}
comb_filter
Line
Count
Source
201
94.1M
{
202
94.1M
   int i;
203
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
204
94.1M
   celt_coef g00, g01, g02, g10, g11, g12;
205
94.1M
   opus_val32 x0, x1, x2, x3, x4;
206
94.1M
   static const opus_val16 gains[3][3] = {
207
94.1M
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
208
94.1M
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
209
94.1M
         {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
94.1M
   if (g0==0 && g1==0)
240
92.3M
   {
241
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
242
92.3M
      if (x!=y)
243
92.1M
         OPUS_MOVE(y, x, N);
244
92.3M
      return;
245
92.3M
   }
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
1.80M
   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
249
1.80M
   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
250
1.80M
   g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
251
1.80M
   g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
252
1.80M
   g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
253
1.80M
   g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
254
1.80M
   g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
255
1.80M
   g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
256
1.80M
   x1 = x[-T1+1];
257
1.80M
   x2 = x[-T1  ];
258
1.80M
   x3 = x[-T1-1];
259
1.80M
   x4 = x[-T1-2];
260
   /* If the filter didn't change, we don't need the overlap */
261
1.80M
   if (g0==g1 && T0==T1 && tapset0==tapset1)
262
565k
      overlap=0;
263
149M
   for (i=0;i<overlap;i++)
264
147M
   {
265
147M
      celt_coef f;
266
147M
      x0=x[i-T1+2];
267
147M
      f = MULT_COEF(window[i],window[i]);
268
147M
      y[i] = x[i]
269
147M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
270
147M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
271
147M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
272
147M
               + MULT_COEF_32(MULT_COEF(f,g10),x2)
273
147M
               + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
274
147M
               + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4));
275
147M
#ifdef FIXED_POINT
276
      /* A bit of bias seems to help here. */
277
147M
      y[i] = SUB32(y[i], 3);
278
147M
#endif
279
147M
      y[i] = SATURATE(y[i], SIG_SAT);
280
147M
      x4=x3;
281
147M
      x3=x2;
282
147M
      x2=x1;
283
147M
      x1=x0;
284
285
147M
   }
286
1.80M
   if (g1==0)
287
16.1k
   {
288
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
289
16.1k
      if (x!=y)
290
9.24k
         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
291
16.1k
      return;
292
16.1k
   }
293
294
   /* Compute the part with the constant filter. */
295
1.79M
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
296
1.79M
}
comb_filter
Line
Count
Source
201
547k
{
202
547k
   int i;
203
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
204
547k
   celt_coef g00, g01, g02, g10, g11, g12;
205
547k
   opus_val32 x0, x1, x2, x3, x4;
206
547k
   static const opus_val16 gains[3][3] = {
207
547k
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
208
547k
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
209
547k
         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
210
547k
#ifdef ENABLE_QEXT
211
547k
   if (overlap==240) {
212
66.6k
      opus_val32 mem_buf[COMBFILTER_MAXPERIOD+960];
213
66.6k
      opus_val32 buf[COMBFILTER_MAXPERIOD+960];
214
66.6k
      celt_coef new_window[120];
215
66.6k
      int s;
216
66.6k
      int N2;
217
66.6k
      int overlap2;
218
66.6k
      N2 = N/2;
219
66.6k
      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
199k
      for (s=0;s<2;s++) {
224
133k
         opus_val32 *yptr;
225
16.1M
         for (i=0;i<overlap2;i++) new_window[i] = window[2*i+s];
226
162M
         for (i=0;i<COMBFILTER_MAXPERIOD+N2;i++) mem_buf[i] = x[2*i+s-2*COMBFILTER_MAXPERIOD];
227
133k
         if (x==y) {
228
120k
            yptr = mem_buf+COMBFILTER_MAXPERIOD;
229
120k
         } else {
230
4.36M
            for (i=0;i<N2;i++) buf[i] = y[2*i+s];
231
13.2k
            yptr = buf;
232
13.2k
         }
233
133k
         comb_filter(yptr, mem_buf+COMBFILTER_MAXPERIOD, T0, T1, N2, g0, g1, tapset0, tapset1, new_window, overlap2, arch);
234
25.7M
         for (i=0;i<N2;i++) y[2*i+s] = yptr[i];
235
133k
      }
236
66.6k
      return;
237
66.6k
   }
238
480k
#endif
239
480k
   if (g0==0 && g1==0)
240
417k
   {
241
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
242
417k
      if (x!=y)
243
202k
         OPUS_MOVE(y, x, N);
244
417k
      return;
245
417k
   }
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
63.8k
   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
249
63.8k
   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
250
63.8k
   g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
251
63.8k
   g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
252
63.8k
   g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
253
63.8k
   g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
254
63.8k
   g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
255
63.8k
   g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
256
63.8k
   x1 = x[-T1+1];
257
63.8k
   x2 = x[-T1  ];
258
63.8k
   x3 = x[-T1-1];
259
63.8k
   x4 = x[-T1-2];
260
   /* If the filter didn't change, we don't need the overlap */
261
63.8k
   if (g0==g1 && T0==T1 && tapset0==tapset1)
262
17.9k
      overlap=0;
263
4.68M
   for (i=0;i<overlap;i++)
264
4.61M
   {
265
4.61M
      celt_coef f;
266
4.61M
      x0=x[i-T1+2];
267
4.61M
      f = MULT_COEF(window[i],window[i]);
268
4.61M
      y[i] = x[i]
269
4.61M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
270
4.61M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
271
4.61M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
272
4.61M
               + MULT_COEF_32(MULT_COEF(f,g10),x2)
273
4.61M
               + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
274
4.61M
               + MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4));
275
4.61M
#ifdef FIXED_POINT
276
      /* A bit of bias seems to help here. */
277
4.61M
      y[i] = SUB32(y[i], 3);
278
4.61M
#endif
279
4.61M
      y[i] = SATURATE(y[i], SIG_SAT);
280
4.61M
      x4=x3;
281
4.61M
      x3=x2;
282
4.61M
      x2=x1;
283
4.61M
      x1=x0;
284
285
4.61M
   }
286
63.8k
   if (g1==0)
287
9.32k
   {
288
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
289
9.32k
      if (x!=y)
290
2.99k
         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
291
9.32k
      return;
292
9.32k
   }
293
294
   /* Compute the part with the constant filter. */
295
54.5k
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
296
54.5k
}
comb_filter
Line
Count
Source
201
483k
{
202
483k
   int i;
203
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
204
483k
   celt_coef g00, g01, g02, g10, g11, g12;
205
483k
   opus_val32 x0, x1, x2, x3, x4;
206
483k
   static const opus_val16 gains[3][3] = {
207
483k
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
208
483k
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
209
483k
         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
210
483k
#ifdef ENABLE_QEXT
211
483k
   if (overlap==240) {
212
49.6k
      opus_val32 mem_buf[COMBFILTER_MAXPERIOD+960];
213
49.6k
      opus_val32 buf[COMBFILTER_MAXPERIOD+960];
214
49.6k
      celt_coef new_window[120];
215
49.6k
      int s;
216
49.6k
      int N2;
217
49.6k
      int overlap2;
218
49.6k
      N2 = N/2;
219
49.6k
      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
148k
      for (s=0;s<2;s++) {
224
99.3k
         opus_val32 *yptr;
225
12.0M
         for (i=0;i<overlap2;i++) new_window[i] = window[2*i+s];
226
119M
         for (i=0;i<COMBFILTER_MAXPERIOD+N2;i++) mem_buf[i] = x[2*i+s-2*COMBFILTER_MAXPERIOD];
227
99.3k
         if (x==y) {
228
88.2k
            yptr = mem_buf+COMBFILTER_MAXPERIOD;
229
88.2k
         } else {
230
2.58M
            for (i=0;i<N2;i++) buf[i] = y[2*i+s];
231
11.0k
            yptr = buf;
232
11.0k
         }
233
99.3k
         comb_filter(yptr, mem_buf+COMBFILTER_MAXPERIOD, T0, T1, N2, g0, g1, tapset0, tapset1, new_window, overlap2, arch);
234
17.7M
         for (i=0;i<N2;i++) y[2*i+s] = yptr[i];
235
99.3k
      }
236
49.6k
      return;
237
49.6k
   }
238
433k
#endif
239
433k
   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
195k
         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
49.8k
   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
249
49.8k
   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
250
49.8k
   g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
251
49.8k
   g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
252
49.8k
   g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
253
49.8k
   g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
254
49.8k
   g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
255
49.8k
   g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
256
49.8k
   x1 = x[-T1+1];
257
49.8k
   x2 = x[-T1  ];
258
49.8k
   x3 = x[-T1-1];
259
49.8k
   x4 = x[-T1-2];
260
   /* If the filter didn't change, we don't need the overlap */
261
49.8k
   if (g0==g1 && T0==T1 && tapset0==tapset1)
262
11.2k
      overlap=0;
263
3.84M
   for (i=0;i<overlap;i++)
264
3.79M
   {
265
3.79M
      celt_coef f;
266
3.79M
      x0=x[i-T1+2];
267
3.79M
      f = MULT_COEF(window[i],window[i]);
268
3.79M
      y[i] = x[i]
269
3.79M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
270
3.79M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
271
3.79M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
272
3.79M
               + MULT_COEF_32(MULT_COEF(f,g10),x2)
273
3.79M
               + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
274
3.79M
               + 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
3.79M
      y[i] = SATURATE(y[i], SIG_SAT);
280
3.79M
      x4=x3;
281
3.79M
      x3=x2;
282
3.79M
      x2=x1;
283
3.79M
      x1=x0;
284
285
3.79M
   }
286
49.8k
   if (g1==0)
287
8.95k
   {
288
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
289
8.95k
      if (x!=y)
290
3.15k
         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
291
8.95k
      return;
292
8.95k
   }
293
294
   /* Compute the part with the constant filter. */
295
40.8k
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
296
40.8k
}
comb_filter
Line
Count
Source
201
121M
{
202
121M
   int i;
203
   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
204
121M
   celt_coef g00, g01, g02, g10, g11, g12;
205
121M
   opus_val32 x0, x1, x2, x3, x4;
206
121M
   static const opus_val16 gains[3][3] = {
207
121M
         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
208
121M
         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
209
121M
         {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
121M
   if (g0==0 && g1==0)
240
121M
   {
241
      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
242
121M
      if (x!=y)
243
121M
         OPUS_MOVE(y, x, N);
244
121M
      return;
245
121M
   }
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
239k
   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
249
239k
   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
250
239k
   g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
251
239k
   g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
252
239k
   g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
253
239k
   g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
254
239k
   g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
255
239k
   g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
256
239k
   x1 = x[-T1+1];
257
239k
   x2 = x[-T1  ];
258
239k
   x3 = x[-T1-1];
259
239k
   x4 = x[-T1-2];
260
   /* If the filter didn't change, we don't need the overlap */
261
239k
   if (g0==g1 && T0==T1 && tapset0==tapset1)
262
33.1k
      overlap=0;
263
24.4M
   for (i=0;i<overlap;i++)
264
24.2M
   {
265
24.2M
      celt_coef f;
266
24.2M
      x0=x[i-T1+2];
267
24.2M
      f = MULT_COEF(window[i],window[i]);
268
24.2M
      y[i] = x[i]
269
24.2M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
270
24.2M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
271
24.2M
               + MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
272
24.2M
               + MULT_COEF_32(MULT_COEF(f,g10),x2)
273
24.2M
               + MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
274
24.2M
               + 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
24.2M
      y[i] = SATURATE(y[i], SIG_SAT);
280
24.2M
      x4=x3;
281
24.2M
      x3=x2;
282
24.2M
      x2=x1;
283
24.2M
      x1=x0;
284
285
24.2M
   }
286
239k
   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.56k
         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
225k
   comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
296
225k
}
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
106M
{
314
106M
   int i;
315
2.34G
   for (i=0;i<m->nbEBands;i++)
316
2.24G
   {
317
2.24G
      int N;
318
2.24G
      N=(m->eBands[i+1]-m->eBands[i])<<LM;
319
2.24G
      cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
320
2.24G
   }
321
106M
}
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