Coverage Report

Created: 2026-08-13 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opus/celt/mdct.c
Line
Count
Source
1
/* Copyright (c) 2007-2008 CSIRO
2
   Copyright (c) 2007-2008 Xiph.Org Foundation
3
   Written by Jean-Marc Valin */
4
/*
5
   Redistribution and use in source and binary forms, with or without
6
   modification, are permitted provided that the following conditions
7
   are met:
8
9
   - Redistributions of source code must retain the above copyright
10
   notice, this list of conditions and the following disclaimer.
11
12
   - Redistributions in binary form must reproduce the above copyright
13
   notice, this list of conditions and the following disclaimer in the
14
   documentation and/or other materials provided with the distribution.
15
16
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20
   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
*/
28
29
/* This is a simple MDCT implementation that uses a N/4 complex FFT
30
   to do most of the work. It should be relatively straightforward to
31
   plug in pretty much and FFT here.
32
33
   This replaces the Vorbis FFT (and uses the exact same API), which
34
   was a bit too messy and that was ending up duplicating code
35
   (might as well use the same FFT everywhere).
36
37
   The algorithm is similar to (and inspired from) Fabrice Bellard's
38
   MDCT implementation in FFMPEG, but has differences in signs, ordering
39
   and scaling in many places.
40
*/
41
42
#ifndef SKIP_CONFIG_H
43
#ifdef HAVE_CONFIG_H
44
#include "config.h"
45
#endif
46
#endif
47
48
#include "mdct.h"
49
#include "kiss_fft.h"
50
#include "_kiss_fft_guts.h"
51
#include <math.h>
52
#include "os_support.h"
53
#include "mathops.h"
54
#include "stack_alloc.h"
55
56
#if defined(FIXED_POINT) && defined(__mips) && __mips == 32
57
#include "mips/mdct_mipsr1.h"
58
#endif
59
60
#ifndef M_PI
61
#define M_PI 3.141592653
62
#endif
63
64
#ifdef CUSTOM_MODES
65
66
int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch)
67
{
68
   int i;
69
   kiss_twiddle_scalar *trig;
70
   int shift;
71
   int N2=N>>1;
72
   l->n = N;
73
   l->maxshift = maxshift;
74
   for (i=0;i<=maxshift;i++)
75
   {
76
      if (i==0)
77
         l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0, arch);
78
      else
79
         l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0], arch);
80
#ifndef ENABLE_TI_DSPLIB55
81
      if (l->kfft[i]==NULL)
82
         return 0;
83
#endif
84
   }
85
   l->trig = trig = (kiss_twiddle_scalar*)opus_alloc((N-(N2>>maxshift))*sizeof(kiss_twiddle_scalar));
86
   if (l->trig==NULL)
87
     return 0;
88
   for (shift=0;shift<=maxshift;shift++)
89
   {
90
      /* We have enough points that sine isn't necessary */
91
#if defined(FIXED_POINT)
92
#ifndef ENABLE_QEXT
93
      for (i=0;i<N2;i++)
94
         trig[i] = TRIG_UPSCALE*celt_cos_norm(DIV32(ADD32(SHL32(EXTEND32(i),17),N2+16384),N));
95
#else
96
      for (i=0;i<N2;i++)
97
         trig[i] = (kiss_twiddle_scalar)MAX32(-2147483647,MIN32(2147483647,floor(.5+2147483648*cos(2*M_PI*(i+.125)/N))));
98
#endif
99
#else
100
      for (i=0;i<N2;i++)
101
         trig[i] = (kiss_twiddle_scalar)cos(2*PI*(i+.125)/N);
102
#endif
103
      trig += N2;
104
      N2 >>= 1;
105
      N >>= 1;
106
   }
107
   return 1;
108
}
109
110
void clt_mdct_clear(mdct_lookup *l, int arch)
111
{
112
   int i;
113
   for (i=0;i<=l->maxshift;i++)
114
      opus_fft_free(l->kfft[i], arch);
115
   opus_free((kiss_twiddle_scalar*)l->trig);
116
}
117
118
#endif /* CUSTOM_MODES */
119
120
/* Forward MDCT trashes the input array */
121
#ifndef OVERRIDE_clt_mdct_forward
122
void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
123
      const celt_coef *window, int overlap, int shift, int stride, int arch)
124
692M
{
125
692M
   int i;
126
692M
   int N, N2, N4;
127
692M
   VARDECL(kiss_fft_scalar, f);
128
692M
   VARDECL(kiss_fft_cpx, f2);
129
692M
   const kiss_fft_state *st = l->kfft[shift];
130
692M
   const kiss_twiddle_scalar *trig;
131
692M
   celt_coef scale;
132
#ifdef FIXED_POINT
133
   /* Allows us to scale with MULT16_32_Q16(), which is faster than
134
      MULT16_32_Q15() on ARM. */
135
   int scale_shift = st->scale_shift-1;
136
   int headroom;
137
#endif
138
692M
   SAVE_STACK;
139
692M
   (void)arch;
140
692M
   scale = st->scale;
141
142
692M
   N = l->n;
143
692M
   trig = l->trig;
144
2.14G
   for (i=0;i<shift;i++)
145
1.44G
   {
146
1.44G
      N >>= 1;
147
1.44G
      trig += N;
148
1.44G
   }
149
692M
   N2 = N>>1;
150
692M
   N4 = N>>2;
151
152
692M
   ALLOC(f, N2, kiss_fft_scalar);
153
692M
   ALLOC(f2, N4, kiss_fft_cpx);
154
155
   /* Consider the input to be composed of four blocks: [a, b, c, d] */
156
   /* Window, shuffle, fold */
157
692M
   {
158
      /* Temp pointers to make it really clear to the compiler what we're doing */
159
692M
      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
160
692M
      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
161
692M
      kiss_fft_scalar * OPUS_RESTRICT yp = f;
162
692M
      const celt_coef * OPUS_RESTRICT wp1 = window+(overlap>>1);
163
692M
      const celt_coef * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
164
22.4G
      for(i=0;i<((overlap+3)>>2);i++)
165
21.7G
      {
166
         /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
167
21.7G
         *yp++ = S_MUL(xp1[N2], *wp2) + S_MUL(*xp2, *wp1);
168
21.7G
         *yp++ = S_MUL(*xp1, *wp1)    - S_MUL(xp2[-N2], *wp2);
169
21.7G
         xp1+=2;
170
21.7G
         xp2-=2;
171
21.7G
         wp1+=2;
172
21.7G
         wp2-=2;
173
21.7G
      }
174
692M
      wp1 = window;
175
692M
      wp2 = window+overlap-1;
176
80.0G
      for(;i<N4-((overlap+3)>>2);i++)
177
79.3G
      {
178
         /* Real part arranged as a-bR, Imag part arranged as -c-dR */
179
79.3G
         *yp++ = *xp2;
180
79.3G
         *yp++ = *xp1;
181
79.3G
         xp1+=2;
182
79.3G
         xp2-=2;
183
79.3G
      }
184
22.4G
      for(;i<N4;i++)
185
21.7G
      {
186
         /* Real part arranged as a-bR, Imag part arranged as -c-dR */
187
21.7G
         *yp++ =  -S_MUL(xp1[-N2], *wp1) + S_MUL(*xp2, *wp2);
188
21.7G
         *yp++ = S_MUL(*xp1, *wp2)     + S_MUL(xp2[N2], *wp1);
189
21.7G
         xp1+=2;
190
21.7G
         xp2-=2;
191
21.7G
         wp1+=2;
192
21.7G
         wp2-=2;
193
21.7G
      }
194
692M
   }
195
   /* Pre-rotation */
196
692M
   {
197
692M
      kiss_fft_scalar * OPUS_RESTRICT yp = f;
198
692M
      const kiss_twiddle_scalar *t = &trig[0];
199
#ifdef FIXED_POINT
200
      opus_val32 maxval=1;
201
#endif
202
123G
      for(i=0;i<N4;i++)
203
122G
      {
204
122G
         kiss_fft_cpx yc;
205
122G
         kiss_twiddle_scalar t0, t1;
206
122G
         kiss_fft_scalar re, im, yr, yi;
207
122G
         t0 = t[i];
208
122G
         t1 = t[N4+i];
209
122G
         re = *yp++;
210
122G
         im = *yp++;
211
122G
         yr = S_MUL(re,t0)  -  S_MUL(im,t1);
212
122G
         yi = S_MUL(im,t0)  +  S_MUL(re,t1);
213
         /* For QEXT, it's best to scale before the FFT, but otherwise it's best to scale after.
214
            For floating-point it doesn't matter. */
215
#ifdef ENABLE_QEXT
216
         yc.r = yr;
217
         yc.i = yi;
218
#else
219
61.4G
         yc.r = S_MUL2(yr, scale);
220
61.4G
         yc.i = S_MUL2(yi, scale);
221
#endif
222
#ifdef FIXED_POINT
223
53.5G
         maxval = MAX32(maxval, MAX32(ABS32(yc.r), ABS32(yc.i)));
224
#endif
225
122G
         f2[st->bitrev[i]] = yc;
226
122G
      }
227
#ifdef FIXED_POINT
228
333M
      headroom = IMAX(0, IMIN(scale_shift, 28-celt_ilog2(maxval)));
229
#endif
230
692M
   }
231
232
   /* N/4 complex FFT, does not downscale anymore */
233
692M
   opus_fft_impl(st, f2 ARG_FIXED(scale_shift-headroom));
234
235
   /* Post-rotate */
236
692M
   {
237
      /* Temp pointers to make it really clear to the compiler what we're doing */
238
692M
      const kiss_fft_cpx * OPUS_RESTRICT fp = f2;
239
692M
      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
240
692M
      kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
241
692M
      const kiss_twiddle_scalar *t = &trig[0];
242
      /* Temp pointers to make it really clear to the compiler what we're doing */
243
123G
      for(i=0;i<N4;i++)
244
122G
      {
245
122G
         kiss_fft_scalar yr, yi;
246
122G
         kiss_fft_scalar t0, t1;
247
#ifdef ENABLE_QEXT
248
61.4G
         t0 = S_MUL2(t[i], scale);
249
61.4G
         t1 = S_MUL2(t[N4+i], scale);
250
#else
251
         t0 = t[i];
252
         t1 = t[N4+i];
253
#endif
254
122G
         yr = PSHR32(S_MUL(fp->i,t1) - S_MUL(fp->r,t0), headroom);
255
122G
         yi = PSHR32(S_MUL(fp->r,t1) + S_MUL(fp->i,t0), headroom);
256
122G
         *yp1 = yr;
257
122G
         *yp2 = yi;
258
122G
         fp++;
259
122G
         yp1 += 2*stride;
260
122G
         yp2 -= 2*stride;
261
122G
      }
262
692M
   }
263
692M
   RESTORE_STACK;
264
692M
}
clt_mdct_forward_c
Line
Count
Source
124
166M
{
125
166M
   int i;
126
166M
   int N, N2, N4;
127
166M
   VARDECL(kiss_fft_scalar, f);
128
166M
   VARDECL(kiss_fft_cpx, f2);
129
166M
   const kiss_fft_state *st = l->kfft[shift];
130
166M
   const kiss_twiddle_scalar *trig;
131
166M
   celt_coef scale;
132
166M
#ifdef FIXED_POINT
133
   /* Allows us to scale with MULT16_32_Q16(), which is faster than
134
      MULT16_32_Q15() on ARM. */
135
166M
   int scale_shift = st->scale_shift-1;
136
166M
   int headroom;
137
166M
#endif
138
166M
   SAVE_STACK;
139
166M
   (void)arch;
140
166M
   scale = st->scale;
141
142
166M
   N = l->n;
143
166M
   trig = l->trig;
144
527M
   for (i=0;i<shift;i++)
145
360M
   {
146
360M
      N >>= 1;
147
360M
      trig += N;
148
360M
   }
149
166M
   N2 = N>>1;
150
166M
   N4 = N>>2;
151
152
166M
   ALLOC(f, N2, kiss_fft_scalar);
153
166M
   ALLOC(f2, N4, kiss_fft_cpx);
154
155
   /* Consider the input to be composed of four blocks: [a, b, c, d] */
156
   /* Window, shuffle, fold */
157
166M
   {
158
      /* Temp pointers to make it really clear to the compiler what we're doing */
159
166M
      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
160
166M
      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
161
166M
      kiss_fft_scalar * OPUS_RESTRICT yp = f;
162
166M
      const celt_coef * OPUS_RESTRICT wp1 = window+(overlap>>1);
163
166M
      const celt_coef * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
164
5.23G
      for(i=0;i<((overlap+3)>>2);i++)
165
5.06G
      {
166
         /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
167
5.06G
         *yp++ = S_MUL(xp1[N2], *wp2) + S_MUL(*xp2, *wp1);
168
5.06G
         *yp++ = S_MUL(*xp1, *wp1)    - S_MUL(xp2[-N2], *wp2);
169
5.06G
         xp1+=2;
170
5.06G
         xp2-=2;
171
5.06G
         wp1+=2;
172
5.06G
         wp2-=2;
173
5.06G
      }
174
166M
      wp1 = window;
175
166M
      wp2 = window+overlap-1;
176
16.8G
      for(;i<N4-((overlap+3)>>2);i++)
177
16.6G
      {
178
         /* Real part arranged as a-bR, Imag part arranged as -c-dR */
179
16.6G
         *yp++ = *xp2;
180
16.6G
         *yp++ = *xp1;
181
16.6G
         xp1+=2;
182
16.6G
         xp2-=2;
183
16.6G
      }
184
5.23G
      for(;i<N4;i++)
185
5.06G
      {
186
         /* Real part arranged as a-bR, Imag part arranged as -c-dR */
187
5.06G
         *yp++ =  -S_MUL(xp1[-N2], *wp1) + S_MUL(*xp2, *wp2);
188
5.06G
         *yp++ = S_MUL(*xp1, *wp2)     + S_MUL(xp2[N2], *wp1);
189
5.06G
         xp1+=2;
190
5.06G
         xp2-=2;
191
5.06G
         wp1+=2;
192
5.06G
         wp2-=2;
193
5.06G
      }
194
166M
   }
195
   /* Pre-rotation */
196
166M
   {
197
166M
      kiss_fft_scalar * OPUS_RESTRICT yp = f;
198
166M
      const kiss_twiddle_scalar *t = &trig[0];
199
166M
#ifdef FIXED_POINT
200
166M
      opus_val32 maxval=1;
201
166M
#endif
202
26.9G
      for(i=0;i<N4;i++)
203
26.7G
      {
204
26.7G
         kiss_fft_cpx yc;
205
26.7G
         kiss_twiddle_scalar t0, t1;
206
26.7G
         kiss_fft_scalar re, im, yr, yi;
207
26.7G
         t0 = t[i];
208
26.7G
         t1 = t[N4+i];
209
26.7G
         re = *yp++;
210
26.7G
         im = *yp++;
211
26.7G
         yr = S_MUL(re,t0)  -  S_MUL(im,t1);
212
26.7G
         yi = S_MUL(im,t0)  +  S_MUL(re,t1);
213
         /* For QEXT, it's best to scale before the FFT, but otherwise it's best to scale after.
214
            For floating-point it doesn't matter. */
215
#ifdef ENABLE_QEXT
216
         yc.r = yr;
217
         yc.i = yi;
218
#else
219
26.7G
         yc.r = S_MUL2(yr, scale);
220
26.7G
         yc.i = S_MUL2(yi, scale);
221
26.7G
#endif
222
26.7G
#ifdef FIXED_POINT
223
26.7G
         maxval = MAX32(maxval, MAX32(ABS32(yc.r), ABS32(yc.i)));
224
26.7G
#endif
225
26.7G
         f2[st->bitrev[i]] = yc;
226
26.7G
      }
227
166M
#ifdef FIXED_POINT
228
166M
      headroom = IMAX(0, IMIN(scale_shift, 28-celt_ilog2(maxval)));
229
166M
#endif
230
166M
   }
231
232
   /* N/4 complex FFT, does not downscale anymore */
233
166M
   opus_fft_impl(st, f2 ARG_FIXED(scale_shift-headroom));
234
235
   /* Post-rotate */
236
166M
   {
237
      /* Temp pointers to make it really clear to the compiler what we're doing */
238
166M
      const kiss_fft_cpx * OPUS_RESTRICT fp = f2;
239
166M
      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
240
166M
      kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
241
166M
      const kiss_twiddle_scalar *t = &trig[0];
242
      /* Temp pointers to make it really clear to the compiler what we're doing */
243
26.9G
      for(i=0;i<N4;i++)
244
26.7G
      {
245
26.7G
         kiss_fft_scalar yr, yi;
246
26.7G
         kiss_fft_scalar t0, t1;
247
#ifdef ENABLE_QEXT
248
         t0 = S_MUL2(t[i], scale);
249
         t1 = S_MUL2(t[N4+i], scale);
250
#else
251
26.7G
         t0 = t[i];
252
26.7G
         t1 = t[N4+i];
253
26.7G
#endif
254
26.7G
         yr = PSHR32(S_MUL(fp->i,t1) - S_MUL(fp->r,t0), headroom);
255
26.7G
         yi = PSHR32(S_MUL(fp->r,t1) + S_MUL(fp->i,t0), headroom);
256
26.7G
         *yp1 = yr;
257
26.7G
         *yp2 = yi;
258
26.7G
         fp++;
259
26.7G
         yp1 += 2*stride;
260
26.7G
         yp2 -= 2*stride;
261
26.7G
      }
262
166M
   }
263
166M
   RESTORE_STACK;
264
166M
}
clt_mdct_forward_c
Line
Count
Source
124
166M
{
125
166M
   int i;
126
166M
   int N, N2, N4;
127
166M
   VARDECL(kiss_fft_scalar, f);
128
166M
   VARDECL(kiss_fft_cpx, f2);
129
166M
   const kiss_fft_state *st = l->kfft[shift];
130
166M
   const kiss_twiddle_scalar *trig;
131
166M
   celt_coef scale;
132
166M
#ifdef FIXED_POINT
133
   /* Allows us to scale with MULT16_32_Q16(), which is faster than
134
      MULT16_32_Q15() on ARM. */
135
166M
   int scale_shift = st->scale_shift-1;
136
166M
   int headroom;
137
166M
#endif
138
166M
   SAVE_STACK;
139
166M
   (void)arch;
140
166M
   scale = st->scale;
141
142
166M
   N = l->n;
143
166M
   trig = l->trig;
144
527M
   for (i=0;i<shift;i++)
145
360M
   {
146
360M
      N >>= 1;
147
360M
      trig += N;
148
360M
   }
149
166M
   N2 = N>>1;
150
166M
   N4 = N>>2;
151
152
166M
   ALLOC(f, N2, kiss_fft_scalar);
153
166M
   ALLOC(f2, N4, kiss_fft_cpx);
154
155
   /* Consider the input to be composed of four blocks: [a, b, c, d] */
156
   /* Window, shuffle, fold */
157
166M
   {
158
      /* Temp pointers to make it really clear to the compiler what we're doing */
159
166M
      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
160
166M
      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
161
166M
      kiss_fft_scalar * OPUS_RESTRICT yp = f;
162
166M
      const celt_coef * OPUS_RESTRICT wp1 = window+(overlap>>1);
163
166M
      const celt_coef * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
164
5.23G
      for(i=0;i<((overlap+3)>>2);i++)
165
5.06G
      {
166
         /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
167
5.06G
         *yp++ = S_MUL(xp1[N2], *wp2) + S_MUL(*xp2, *wp1);
168
5.06G
         *yp++ = S_MUL(*xp1, *wp1)    - S_MUL(xp2[-N2], *wp2);
169
5.06G
         xp1+=2;
170
5.06G
         xp2-=2;
171
5.06G
         wp1+=2;
172
5.06G
         wp2-=2;
173
5.06G
      }
174
166M
      wp1 = window;
175
166M
      wp2 = window+overlap-1;
176
16.8G
      for(;i<N4-((overlap+3)>>2);i++)
177
16.6G
      {
178
         /* Real part arranged as a-bR, Imag part arranged as -c-dR */
179
16.6G
         *yp++ = *xp2;
180
16.6G
         *yp++ = *xp1;
181
16.6G
         xp1+=2;
182
16.6G
         xp2-=2;
183
16.6G
      }
184
5.23G
      for(;i<N4;i++)
185
5.06G
      {
186
         /* Real part arranged as a-bR, Imag part arranged as -c-dR */
187
5.06G
         *yp++ =  -S_MUL(xp1[-N2], *wp1) + S_MUL(*xp2, *wp2);
188
5.06G
         *yp++ = S_MUL(*xp1, *wp2)     + S_MUL(xp2[N2], *wp1);
189
5.06G
         xp1+=2;
190
5.06G
         xp2-=2;
191
5.06G
         wp1+=2;
192
5.06G
         wp2-=2;
193
5.06G
      }
194
166M
   }
195
   /* Pre-rotation */
196
166M
   {
197
166M
      kiss_fft_scalar * OPUS_RESTRICT yp = f;
198
166M
      const kiss_twiddle_scalar *t = &trig[0];
199
166M
#ifdef FIXED_POINT
200
166M
      opus_val32 maxval=1;
201
166M
#endif
202
26.9G
      for(i=0;i<N4;i++)
203
26.7G
      {
204
26.7G
         kiss_fft_cpx yc;
205
26.7G
         kiss_twiddle_scalar t0, t1;
206
26.7G
         kiss_fft_scalar re, im, yr, yi;
207
26.7G
         t0 = t[i];
208
26.7G
         t1 = t[N4+i];
209
26.7G
         re = *yp++;
210
26.7G
         im = *yp++;
211
26.7G
         yr = S_MUL(re,t0)  -  S_MUL(im,t1);
212
26.7G
         yi = S_MUL(im,t0)  +  S_MUL(re,t1);
213
         /* For QEXT, it's best to scale before the FFT, but otherwise it's best to scale after.
214
            For floating-point it doesn't matter. */
215
26.7G
#ifdef ENABLE_QEXT
216
26.7G
         yc.r = yr;
217
26.7G
         yc.i = yi;
218
#else
219
         yc.r = S_MUL2(yr, scale);
220
         yc.i = S_MUL2(yi, scale);
221
#endif
222
26.7G
#ifdef FIXED_POINT
223
26.7G
         maxval = MAX32(maxval, MAX32(ABS32(yc.r), ABS32(yc.i)));
224
26.7G
#endif
225
26.7G
         f2[st->bitrev[i]] = yc;
226
26.7G
      }
227
166M
#ifdef FIXED_POINT
228
166M
      headroom = IMAX(0, IMIN(scale_shift, 28-celt_ilog2(maxval)));
229
166M
#endif
230
166M
   }
231
232
   /* N/4 complex FFT, does not downscale anymore */
233
166M
   opus_fft_impl(st, f2 ARG_FIXED(scale_shift-headroom));
234
235
   /* Post-rotate */
236
166M
   {
237
      /* Temp pointers to make it really clear to the compiler what we're doing */
238
166M
      const kiss_fft_cpx * OPUS_RESTRICT fp = f2;
239
166M
      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
240
166M
      kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
241
166M
      const kiss_twiddle_scalar *t = &trig[0];
242
      /* Temp pointers to make it really clear to the compiler what we're doing */
243
26.9G
      for(i=0;i<N4;i++)
244
26.7G
      {
245
26.7G
         kiss_fft_scalar yr, yi;
246
26.7G
         kiss_fft_scalar t0, t1;
247
26.7G
#ifdef ENABLE_QEXT
248
26.7G
         t0 = S_MUL2(t[i], scale);
249
26.7G
         t1 = S_MUL2(t[N4+i], scale);
250
#else
251
         t0 = t[i];
252
         t1 = t[N4+i];
253
#endif
254
26.7G
         yr = PSHR32(S_MUL(fp->i,t1) - S_MUL(fp->r,t0), headroom);
255
26.7G
         yi = PSHR32(S_MUL(fp->r,t1) + S_MUL(fp->i,t0), headroom);
256
26.7G
         *yp1 = yr;
257
26.7G
         *yp2 = yi;
258
26.7G
         fp++;
259
26.7G
         yp1 += 2*stride;
260
26.7G
         yp2 -= 2*stride;
261
26.7G
      }
262
166M
   }
263
166M
   RESTORE_STACK;
264
166M
}
clt_mdct_forward_c
Line
Count
Source
124
179M
{
125
179M
   int i;
126
179M
   int N, N2, N4;
127
179M
   VARDECL(kiss_fft_scalar, f);
128
179M
   VARDECL(kiss_fft_cpx, f2);
129
179M
   const kiss_fft_state *st = l->kfft[shift];
130
179M
   const kiss_twiddle_scalar *trig;
131
179M
   celt_coef scale;
132
#ifdef FIXED_POINT
133
   /* Allows us to scale with MULT16_32_Q16(), which is faster than
134
      MULT16_32_Q15() on ARM. */
135
   int scale_shift = st->scale_shift-1;
136
   int headroom;
137
#endif
138
179M
   SAVE_STACK;
139
179M
   (void)arch;
140
179M
   scale = st->scale;
141
142
179M
   N = l->n;
143
179M
   trig = l->trig;
144
543M
   for (i=0;i<shift;i++)
145
363M
   {
146
363M
      N >>= 1;
147
363M
      trig += N;
148
363M
   }
149
179M
   N2 = N>>1;
150
179M
   N4 = N>>2;
151
152
179M
   ALLOC(f, N2, kiss_fft_scalar);
153
179M
   ALLOC(f2, N4, kiss_fft_cpx);
154
155
   /* Consider the input to be composed of four blocks: [a, b, c, d] */
156
   /* Window, shuffle, fold */
157
179M
   {
158
      /* Temp pointers to make it really clear to the compiler what we're doing */
159
179M
      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
160
179M
      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
161
179M
      kiss_fft_scalar * OPUS_RESTRICT yp = f;
162
179M
      const celt_coef * OPUS_RESTRICT wp1 = window+(overlap>>1);
163
179M
      const celt_coef * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
164
5.99G
      for(i=0;i<((overlap+3)>>2);i++)
165
5.81G
      {
166
         /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
167
5.81G
         *yp++ = S_MUL(xp1[N2], *wp2) + S_MUL(*xp2, *wp1);
168
5.81G
         *yp++ = S_MUL(*xp1, *wp1)    - S_MUL(xp2[-N2], *wp2);
169
5.81G
         xp1+=2;
170
5.81G
         xp2-=2;
171
5.81G
         wp1+=2;
172
5.81G
         wp2-=2;
173
5.81G
      }
174
179M
      wp1 = window;
175
179M
      wp2 = window+overlap-1;
176
23.2G
      for(;i<N4-((overlap+3)>>2);i++)
177
23.0G
      {
178
         /* Real part arranged as a-bR, Imag part arranged as -c-dR */
179
23.0G
         *yp++ = *xp2;
180
23.0G
         *yp++ = *xp1;
181
23.0G
         xp1+=2;
182
23.0G
         xp2-=2;
183
23.0G
      }
184
5.99G
      for(;i<N4;i++)
185
5.81G
      {
186
         /* Real part arranged as a-bR, Imag part arranged as -c-dR */
187
5.81G
         *yp++ =  -S_MUL(xp1[-N2], *wp1) + S_MUL(*xp2, *wp2);
188
5.81G
         *yp++ = S_MUL(*xp1, *wp2)     + S_MUL(xp2[N2], *wp1);
189
5.81G
         xp1+=2;
190
5.81G
         xp2-=2;
191
5.81G
         wp1+=2;
192
5.81G
         wp2-=2;
193
5.81G
      }
194
179M
   }
195
   /* Pre-rotation */
196
179M
   {
197
179M
      kiss_fft_scalar * OPUS_RESTRICT yp = f;
198
179M
      const kiss_twiddle_scalar *t = &trig[0];
199
#ifdef FIXED_POINT
200
      opus_val32 maxval=1;
201
#endif
202
34.8G
      for(i=0;i<N4;i++)
203
34.6G
      {
204
34.6G
         kiss_fft_cpx yc;
205
34.6G
         kiss_twiddle_scalar t0, t1;
206
34.6G
         kiss_fft_scalar re, im, yr, yi;
207
34.6G
         t0 = t[i];
208
34.6G
         t1 = t[N4+i];
209
34.6G
         re = *yp++;
210
34.6G
         im = *yp++;
211
34.6G
         yr = S_MUL(re,t0)  -  S_MUL(im,t1);
212
34.6G
         yi = S_MUL(im,t0)  +  S_MUL(re,t1);
213
         /* For QEXT, it's best to scale before the FFT, but otherwise it's best to scale after.
214
            For floating-point it doesn't matter. */
215
34.6G
#ifdef ENABLE_QEXT
216
34.6G
         yc.r = yr;
217
34.6G
         yc.i = yi;
218
#else
219
         yc.r = S_MUL2(yr, scale);
220
         yc.i = S_MUL2(yi, scale);
221
#endif
222
#ifdef FIXED_POINT
223
         maxval = MAX32(maxval, MAX32(ABS32(yc.r), ABS32(yc.i)));
224
#endif
225
34.6G
         f2[st->bitrev[i]] = yc;
226
34.6G
      }
227
#ifdef FIXED_POINT
228
      headroom = IMAX(0, IMIN(scale_shift, 28-celt_ilog2(maxval)));
229
#endif
230
179M
   }
231
232
   /* N/4 complex FFT, does not downscale anymore */
233
179M
   opus_fft_impl(st, f2 ARG_FIXED(scale_shift-headroom));
234
235
   /* Post-rotate */
236
179M
   {
237
      /* Temp pointers to make it really clear to the compiler what we're doing */
238
179M
      const kiss_fft_cpx * OPUS_RESTRICT fp = f2;
239
179M
      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
240
179M
      kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
241
179M
      const kiss_twiddle_scalar *t = &trig[0];
242
      /* Temp pointers to make it really clear to the compiler what we're doing */
243
34.8G
      for(i=0;i<N4;i++)
244
34.6G
      {
245
34.6G
         kiss_fft_scalar yr, yi;
246
34.6G
         kiss_fft_scalar t0, t1;
247
34.6G
#ifdef ENABLE_QEXT
248
34.6G
         t0 = S_MUL2(t[i], scale);
249
34.6G
         t1 = S_MUL2(t[N4+i], scale);
250
#else
251
         t0 = t[i];
252
         t1 = t[N4+i];
253
#endif
254
34.6G
         yr = PSHR32(S_MUL(fp->i,t1) - S_MUL(fp->r,t0), headroom);
255
34.6G
         yi = PSHR32(S_MUL(fp->r,t1) + S_MUL(fp->i,t0), headroom);
256
34.6G
         *yp1 = yr;
257
34.6G
         *yp2 = yi;
258
34.6G
         fp++;
259
34.6G
         yp1 += 2*stride;
260
34.6G
         yp2 -= 2*stride;
261
34.6G
      }
262
179M
   }
263
179M
   RESTORE_STACK;
264
179M
}
clt_mdct_forward_c
Line
Count
Source
124
179M
{
125
179M
   int i;
126
179M
   int N, N2, N4;
127
179M
   VARDECL(kiss_fft_scalar, f);
128
179M
   VARDECL(kiss_fft_cpx, f2);
129
179M
   const kiss_fft_state *st = l->kfft[shift];
130
179M
   const kiss_twiddle_scalar *trig;
131
179M
   celt_coef scale;
132
#ifdef FIXED_POINT
133
   /* Allows us to scale with MULT16_32_Q16(), which is faster than
134
      MULT16_32_Q15() on ARM. */
135
   int scale_shift = st->scale_shift-1;
136
   int headroom;
137
#endif
138
179M
   SAVE_STACK;
139
179M
   (void)arch;
140
179M
   scale = st->scale;
141
142
179M
   N = l->n;
143
179M
   trig = l->trig;
144
543M
   for (i=0;i<shift;i++)
145
363M
   {
146
363M
      N >>= 1;
147
363M
      trig += N;
148
363M
   }
149
179M
   N2 = N>>1;
150
179M
   N4 = N>>2;
151
152
179M
   ALLOC(f, N2, kiss_fft_scalar);
153
179M
   ALLOC(f2, N4, kiss_fft_cpx);
154
155
   /* Consider the input to be composed of four blocks: [a, b, c, d] */
156
   /* Window, shuffle, fold */
157
179M
   {
158
      /* Temp pointers to make it really clear to the compiler what we're doing */
159
179M
      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
160
179M
      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
161
179M
      kiss_fft_scalar * OPUS_RESTRICT yp = f;
162
179M
      const celt_coef * OPUS_RESTRICT wp1 = window+(overlap>>1);
163
179M
      const celt_coef * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
164
5.99G
      for(i=0;i<((overlap+3)>>2);i++)
165
5.81G
      {
166
         /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
167
5.81G
         *yp++ = S_MUL(xp1[N2], *wp2) + S_MUL(*xp2, *wp1);
168
5.81G
         *yp++ = S_MUL(*xp1, *wp1)    - S_MUL(xp2[-N2], *wp2);
169
5.81G
         xp1+=2;
170
5.81G
         xp2-=2;
171
5.81G
         wp1+=2;
172
5.81G
         wp2-=2;
173
5.81G
      }
174
179M
      wp1 = window;
175
179M
      wp2 = window+overlap-1;
176
23.2G
      for(;i<N4-((overlap+3)>>2);i++)
177
23.0G
      {
178
         /* Real part arranged as a-bR, Imag part arranged as -c-dR */
179
23.0G
         *yp++ = *xp2;
180
23.0G
         *yp++ = *xp1;
181
23.0G
         xp1+=2;
182
23.0G
         xp2-=2;
183
23.0G
      }
184
5.99G
      for(;i<N4;i++)
185
5.81G
      {
186
         /* Real part arranged as a-bR, Imag part arranged as -c-dR */
187
5.81G
         *yp++ =  -S_MUL(xp1[-N2], *wp1) + S_MUL(*xp2, *wp2);
188
5.81G
         *yp++ = S_MUL(*xp1, *wp2)     + S_MUL(xp2[N2], *wp1);
189
5.81G
         xp1+=2;
190
5.81G
         xp2-=2;
191
5.81G
         wp1+=2;
192
5.81G
         wp2-=2;
193
5.81G
      }
194
179M
   }
195
   /* Pre-rotation */
196
179M
   {
197
179M
      kiss_fft_scalar * OPUS_RESTRICT yp = f;
198
179M
      const kiss_twiddle_scalar *t = &trig[0];
199
#ifdef FIXED_POINT
200
      opus_val32 maxval=1;
201
#endif
202
34.8G
      for(i=0;i<N4;i++)
203
34.6G
      {
204
34.6G
         kiss_fft_cpx yc;
205
34.6G
         kiss_twiddle_scalar t0, t1;
206
34.6G
         kiss_fft_scalar re, im, yr, yi;
207
34.6G
         t0 = t[i];
208
34.6G
         t1 = t[N4+i];
209
34.6G
         re = *yp++;
210
34.6G
         im = *yp++;
211
34.6G
         yr = S_MUL(re,t0)  -  S_MUL(im,t1);
212
34.6G
         yi = S_MUL(im,t0)  +  S_MUL(re,t1);
213
         /* For QEXT, it's best to scale before the FFT, but otherwise it's best to scale after.
214
            For floating-point it doesn't matter. */
215
#ifdef ENABLE_QEXT
216
         yc.r = yr;
217
         yc.i = yi;
218
#else
219
34.6G
         yc.r = S_MUL2(yr, scale);
220
34.6G
         yc.i = S_MUL2(yi, scale);
221
34.6G
#endif
222
#ifdef FIXED_POINT
223
         maxval = MAX32(maxval, MAX32(ABS32(yc.r), ABS32(yc.i)));
224
#endif
225
34.6G
         f2[st->bitrev[i]] = yc;
226
34.6G
      }
227
#ifdef FIXED_POINT
228
      headroom = IMAX(0, IMIN(scale_shift, 28-celt_ilog2(maxval)));
229
#endif
230
179M
   }
231
232
   /* N/4 complex FFT, does not downscale anymore */
233
179M
   opus_fft_impl(st, f2 ARG_FIXED(scale_shift-headroom));
234
235
   /* Post-rotate */
236
179M
   {
237
      /* Temp pointers to make it really clear to the compiler what we're doing */
238
179M
      const kiss_fft_cpx * OPUS_RESTRICT fp = f2;
239
179M
      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
240
179M
      kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
241
179M
      const kiss_twiddle_scalar *t = &trig[0];
242
      /* Temp pointers to make it really clear to the compiler what we're doing */
243
34.8G
      for(i=0;i<N4;i++)
244
34.6G
      {
245
34.6G
         kiss_fft_scalar yr, yi;
246
34.6G
         kiss_fft_scalar t0, t1;
247
#ifdef ENABLE_QEXT
248
         t0 = S_MUL2(t[i], scale);
249
         t1 = S_MUL2(t[N4+i], scale);
250
#else
251
34.6G
         t0 = t[i];
252
34.6G
         t1 = t[N4+i];
253
34.6G
#endif
254
34.6G
         yr = PSHR32(S_MUL(fp->i,t1) - S_MUL(fp->r,t0), headroom);
255
34.6G
         yi = PSHR32(S_MUL(fp->r,t1) + S_MUL(fp->i,t0), headroom);
256
34.6G
         *yp1 = yr;
257
34.6G
         *yp2 = yi;
258
34.6G
         fp++;
259
34.6G
         yp1 += 2*stride;
260
34.6G
         yp2 -= 2*stride;
261
34.6G
      }
262
179M
   }
263
179M
   RESTORE_STACK;
264
179M
}
265
#endif /* OVERRIDE_clt_mdct_forward */
266
267
#ifndef OVERRIDE_clt_mdct_backward
268
void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
269
      const celt_coef * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch)
270
662k
{
271
662k
   int i;
272
662k
   int N, N2, N4;
273
662k
   const kiss_twiddle_scalar *trig;
274
#ifdef FIXED_POINT
275
   int pre_shift, post_shift, fft_shift;
276
#endif
277
662k
   (void) arch;
278
279
662k
   N = l->n;
280
662k
   trig = l->trig;
281
2.17M
   for (i=0;i<shift;i++)
282
1.51M
   {
283
1.51M
      N >>= 1;
284
1.51M
      trig += N;
285
1.51M
   }
286
662k
   N2 = N>>1;
287
662k
   N4 = N>>2;
288
289
#ifdef FIXED_POINT
290
   {
291
      opus_val32 sumval=N2;
292
      opus_val32 maxval=0;
293
94.5M
      for (i=0;i<N2;i++) {
294
94.1M
         maxval = MAX32(maxval, ABS32(in[i*stride]));
295
94.1M
         sumval = ADD32_ovflw(sumval, ABS32(SHR32(in[i*stride],11)));
296
94.1M
      }
297
348k
      pre_shift = IMAX(0, 29-celt_zlog2(1+maxval));
298
      /* Worst-case where all the energy goes to a single sample. */
299
348k
      post_shift = IMAX(0, 19-celt_ilog2(ABS32(sumval)));
300
348k
      post_shift = IMIN(post_shift, pre_shift);
301
      fft_shift = pre_shift - post_shift;
302
   }
303
#endif
304
   /* Pre-rotate */
305
662k
   {
306
      /* Temp pointers to make it really clear to the compiler what we're doing */
307
662k
      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
308
662k
      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
309
662k
      kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1);
310
662k
      const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];
311
662k
      const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev;
312
95.6M
      for(i=0;i<N4;i++)
313
94.9M
      {
314
94.9M
         int rev;
315
94.9M
         kiss_fft_scalar yr, yi;
316
94.9M
         opus_val32 x1, x2;
317
94.9M
         rev = *bitrev++;
318
94.9M
         x1 = SHL32_ovflw(*xp1, pre_shift);
319
94.9M
         x2 = SHL32_ovflw(*xp2, pre_shift);
320
94.9M
         yr = ADD32_ovflw(S_MUL(x2, t[i]), S_MUL(x1, t[N4+i]));
321
94.9M
         yi = SUB32_ovflw(S_MUL(x1, t[i]), S_MUL(x2, t[N4+i]));
322
         /* We swap real and imag because we use an FFT instead of an IFFT. */
323
94.9M
         yp[2*rev+1] = yr;
324
94.9M
         yp[2*rev] = yi;
325
         /* Storing the pre-rotation directly in the bitrev order. */
326
94.9M
         xp1+=2*stride;
327
94.9M
         xp2-=2*stride;
328
94.9M
      }
329
662k
   }
330
331
662k
   opus_fft_impl(l->kfft[shift], (kiss_fft_cpx*)(out+(overlap>>1)) ARG_FIXED(fft_shift));
332
333
   /* Post-rotate and de-shuffle from both ends of the buffer at once to make
334
      it in-place. */
335
662k
   {
336
662k
      kiss_fft_scalar * yp0 = out+(overlap>>1);
337
662k
      kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2;
338
662k
      const kiss_twiddle_scalar *t = &trig[0];
339
      /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
340
         middle pair will be computed twice. */
341
48.1M
      for(i=0;i<(N4+1)>>1;i++)
342
47.4M
      {
343
47.4M
         kiss_fft_scalar re, im, yr, yi;
344
47.4M
         kiss_twiddle_scalar t0, t1;
345
         /* We swap real and imag because we're using an FFT instead of an IFFT. */
346
47.4M
         re = yp0[1];
347
47.4M
         im = yp0[0];
348
47.4M
         t0 = t[i];
349
47.4M
         t1 = t[N4+i];
350
         /* We'd scale up by 2 here, but instead it's done when mixing the windows */
351
47.4M
         yr = PSHR32_ovflw(ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)), post_shift);
352
47.4M
         yi = PSHR32_ovflw(SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)), post_shift);
353
         /* We swap real and imag because we're using an FFT instead of an IFFT. */
354
47.4M
         re = yp1[1];
355
47.4M
         im = yp1[0];
356
47.4M
         yp0[0] = yr;
357
47.4M
         yp1[1] = yi;
358
359
47.4M
         t0 = t[(N4-i-1)];
360
47.4M
         t1 = t[(N2-i-1)];
361
         /* We'd scale up by 2 here, but instead it's done when mixing the windows */
362
47.4M
         yr = PSHR32_ovflw(ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)), post_shift);
363
47.4M
         yi = PSHR32_ovflw(SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)), post_shift);
364
47.4M
         yp1[0] = yr;
365
47.4M
         yp0[1] = yi;
366
47.4M
         yp0 += 2;
367
47.4M
         yp1 -= 2;
368
47.4M
      }
369
662k
   }
370
371
   /* Mirror on both sides for TDAC */
372
662k
   {
373
662k
      kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
374
662k
      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
375
662k
      const celt_coef * OPUS_RESTRICT wp1 = window;
376
662k
      const celt_coef * OPUS_RESTRICT wp2 = window+overlap-1;
377
378
45.3M
      for(i = 0; i < overlap/2; i++)
379
44.6M
      {
380
44.6M
         kiss_fft_scalar x1, x2;
381
44.6M
         x1 = *xp1;
382
44.6M
         x2 = *yp1;
383
44.6M
         *yp1++ = SUB32_ovflw(S_MUL(x2, *wp2), S_MUL(x1, *wp1));
384
44.6M
         *xp1-- = ADD32_ovflw(S_MUL(x2, *wp1), S_MUL(x1, *wp2));
385
44.6M
         wp1++;
386
44.6M
         wp2--;
387
44.6M
      }
388
662k
   }
389
662k
}
clt_mdct_backward_c
Line
Count
Source
270
348k
{
271
348k
   int i;
272
348k
   int N, N2, N4;
273
348k
   const kiss_twiddle_scalar *trig;
274
348k
#ifdef FIXED_POINT
275
348k
   int pre_shift, post_shift, fft_shift;
276
348k
#endif
277
348k
   (void) arch;
278
279
348k
   N = l->n;
280
348k
   trig = l->trig;
281
1.17M
   for (i=0;i<shift;i++)
282
822k
   {
283
822k
      N >>= 1;
284
822k
      trig += N;
285
822k
   }
286
348k
   N2 = N>>1;
287
348k
   N4 = N>>2;
288
289
348k
#ifdef FIXED_POINT
290
348k
   {
291
348k
      opus_val32 sumval=N2;
292
348k
      opus_val32 maxval=0;
293
94.5M
      for (i=0;i<N2;i++) {
294
94.1M
         maxval = MAX32(maxval, ABS32(in[i*stride]));
295
94.1M
         sumval = ADD32_ovflw(sumval, ABS32(SHR32(in[i*stride],11)));
296
94.1M
      }
297
348k
      pre_shift = IMAX(0, 29-celt_zlog2(1+maxval));
298
      /* Worst-case where all the energy goes to a single sample. */
299
348k
      post_shift = IMAX(0, 19-celt_ilog2(ABS32(sumval)));
300
348k
      post_shift = IMIN(post_shift, pre_shift);
301
348k
      fft_shift = pre_shift - post_shift;
302
348k
   }
303
348k
#endif
304
   /* Pre-rotate */
305
348k
   {
306
      /* Temp pointers to make it really clear to the compiler what we're doing */
307
348k
      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
308
348k
      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
309
348k
      kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1);
310
348k
      const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];
311
348k
      const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev;
312
47.4M
      for(i=0;i<N4;i++)
313
47.0M
      {
314
47.0M
         int rev;
315
47.0M
         kiss_fft_scalar yr, yi;
316
47.0M
         opus_val32 x1, x2;
317
47.0M
         rev = *bitrev++;
318
47.0M
         x1 = SHL32_ovflw(*xp1, pre_shift);
319
47.0M
         x2 = SHL32_ovflw(*xp2, pre_shift);
320
47.0M
         yr = ADD32_ovflw(S_MUL(x2, t[i]), S_MUL(x1, t[N4+i]));
321
47.0M
         yi = SUB32_ovflw(S_MUL(x1, t[i]), S_MUL(x2, t[N4+i]));
322
         /* We swap real and imag because we use an FFT instead of an IFFT. */
323
47.0M
         yp[2*rev+1] = yr;
324
47.0M
         yp[2*rev] = yi;
325
         /* Storing the pre-rotation directly in the bitrev order. */
326
47.0M
         xp1+=2*stride;
327
47.0M
         xp2-=2*stride;
328
47.0M
      }
329
348k
   }
330
331
348k
   opus_fft_impl(l->kfft[shift], (kiss_fft_cpx*)(out+(overlap>>1)) ARG_FIXED(fft_shift));
332
333
   /* Post-rotate and de-shuffle from both ends of the buffer at once to make
334
      it in-place. */
335
348k
   {
336
348k
      kiss_fft_scalar * yp0 = out+(overlap>>1);
337
348k
      kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2;
338
348k
      const kiss_twiddle_scalar *t = &trig[0];
339
      /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
340
         middle pair will be computed twice. */
341
23.8M
      for(i=0;i<(N4+1)>>1;i++)
342
23.5M
      {
343
23.5M
         kiss_fft_scalar re, im, yr, yi;
344
23.5M
         kiss_twiddle_scalar t0, t1;
345
         /* We swap real and imag because we're using an FFT instead of an IFFT. */
346
23.5M
         re = yp0[1];
347
23.5M
         im = yp0[0];
348
23.5M
         t0 = t[i];
349
23.5M
         t1 = t[N4+i];
350
         /* We'd scale up by 2 here, but instead it's done when mixing the windows */
351
23.5M
         yr = PSHR32_ovflw(ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)), post_shift);
352
23.5M
         yi = PSHR32_ovflw(SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)), post_shift);
353
         /* We swap real and imag because we're using an FFT instead of an IFFT. */
354
23.5M
         re = yp1[1];
355
23.5M
         im = yp1[0];
356
23.5M
         yp0[0] = yr;
357
23.5M
         yp1[1] = yi;
358
359
23.5M
         t0 = t[(N4-i-1)];
360
23.5M
         t1 = t[(N2-i-1)];
361
         /* We'd scale up by 2 here, but instead it's done when mixing the windows */
362
23.5M
         yr = PSHR32_ovflw(ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)), post_shift);
363
23.5M
         yi = PSHR32_ovflw(SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)), post_shift);
364
23.5M
         yp1[0] = yr;
365
23.5M
         yp0[1] = yi;
366
23.5M
         yp0 += 2;
367
23.5M
         yp1 -= 2;
368
23.5M
      }
369
348k
   }
370
371
   /* Mirror on both sides for TDAC */
372
348k
   {
373
348k
      kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
374
348k
      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
375
348k
      const celt_coef * OPUS_RESTRICT wp1 = window;
376
348k
      const celt_coef * OPUS_RESTRICT wp2 = window+overlap-1;
377
378
24.1M
      for(i = 0; i < overlap/2; i++)
379
23.8M
      {
380
23.8M
         kiss_fft_scalar x1, x2;
381
23.8M
         x1 = *xp1;
382
23.8M
         x2 = *yp1;
383
23.8M
         *yp1++ = SUB32_ovflw(S_MUL(x2, *wp2), S_MUL(x1, *wp1));
384
23.8M
         *xp1-- = ADD32_ovflw(S_MUL(x2, *wp1), S_MUL(x1, *wp2));
385
23.8M
         wp1++;
386
23.8M
         wp2--;
387
23.8M
      }
388
348k
   }
389
348k
}
clt_mdct_backward_c
Line
Count
Source
270
313k
{
271
313k
   int i;
272
313k
   int N, N2, N4;
273
313k
   const kiss_twiddle_scalar *trig;
274
#ifdef FIXED_POINT
275
   int pre_shift, post_shift, fft_shift;
276
#endif
277
313k
   (void) arch;
278
279
313k
   N = l->n;
280
313k
   trig = l->trig;
281
1.00M
   for (i=0;i<shift;i++)
282
694k
   {
283
694k
      N >>= 1;
284
694k
      trig += N;
285
694k
   }
286
313k
   N2 = N>>1;
287
313k
   N4 = N>>2;
288
289
#ifdef FIXED_POINT
290
   {
291
      opus_val32 sumval=N2;
292
      opus_val32 maxval=0;
293
      for (i=0;i<N2;i++) {
294
         maxval = MAX32(maxval, ABS32(in[i*stride]));
295
         sumval = ADD32_ovflw(sumval, ABS32(SHR32(in[i*stride],11)));
296
      }
297
      pre_shift = IMAX(0, 29-celt_zlog2(1+maxval));
298
      /* Worst-case where all the energy goes to a single sample. */
299
      post_shift = IMAX(0, 19-celt_ilog2(ABS32(sumval)));
300
      post_shift = IMIN(post_shift, pre_shift);
301
      fft_shift = pre_shift - post_shift;
302
   }
303
#endif
304
   /* Pre-rotate */
305
313k
   {
306
      /* Temp pointers to make it really clear to the compiler what we're doing */
307
313k
      const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
308
313k
      const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
309
313k
      kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1);
310
313k
      const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];
311
313k
      const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev;
312
48.1M
      for(i=0;i<N4;i++)
313
47.8M
      {
314
47.8M
         int rev;
315
47.8M
         kiss_fft_scalar yr, yi;
316
47.8M
         opus_val32 x1, x2;
317
47.8M
         rev = *bitrev++;
318
47.8M
         x1 = SHL32_ovflw(*xp1, pre_shift);
319
47.8M
         x2 = SHL32_ovflw(*xp2, pre_shift);
320
47.8M
         yr = ADD32_ovflw(S_MUL(x2, t[i]), S_MUL(x1, t[N4+i]));
321
47.8M
         yi = SUB32_ovflw(S_MUL(x1, t[i]), S_MUL(x2, t[N4+i]));
322
         /* We swap real and imag because we use an FFT instead of an IFFT. */
323
47.8M
         yp[2*rev+1] = yr;
324
47.8M
         yp[2*rev] = yi;
325
         /* Storing the pre-rotation directly in the bitrev order. */
326
47.8M
         xp1+=2*stride;
327
47.8M
         xp2-=2*stride;
328
47.8M
      }
329
313k
   }
330
331
313k
   opus_fft_impl(l->kfft[shift], (kiss_fft_cpx*)(out+(overlap>>1)) ARG_FIXED(fft_shift));
332
333
   /* Post-rotate and de-shuffle from both ends of the buffer at once to make
334
      it in-place. */
335
313k
   {
336
313k
      kiss_fft_scalar * yp0 = out+(overlap>>1);
337
313k
      kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2;
338
313k
      const kiss_twiddle_scalar *t = &trig[0];
339
      /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
340
         middle pair will be computed twice. */
341
24.2M
      for(i=0;i<(N4+1)>>1;i++)
342
23.9M
      {
343
23.9M
         kiss_fft_scalar re, im, yr, yi;
344
23.9M
         kiss_twiddle_scalar t0, t1;
345
         /* We swap real and imag because we're using an FFT instead of an IFFT. */
346
23.9M
         re = yp0[1];
347
23.9M
         im = yp0[0];
348
23.9M
         t0 = t[i];
349
23.9M
         t1 = t[N4+i];
350
         /* We'd scale up by 2 here, but instead it's done when mixing the windows */
351
23.9M
         yr = PSHR32_ovflw(ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)), post_shift);
352
23.9M
         yi = PSHR32_ovflw(SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)), post_shift);
353
         /* We swap real and imag because we're using an FFT instead of an IFFT. */
354
23.9M
         re = yp1[1];
355
23.9M
         im = yp1[0];
356
23.9M
         yp0[0] = yr;
357
23.9M
         yp1[1] = yi;
358
359
23.9M
         t0 = t[(N4-i-1)];
360
23.9M
         t1 = t[(N2-i-1)];
361
         /* We'd scale up by 2 here, but instead it's done when mixing the windows */
362
23.9M
         yr = PSHR32_ovflw(ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)), post_shift);
363
23.9M
         yi = PSHR32_ovflw(SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)), post_shift);
364
23.9M
         yp1[0] = yr;
365
23.9M
         yp0[1] = yi;
366
23.9M
         yp0 += 2;
367
23.9M
         yp1 -= 2;
368
23.9M
      }
369
313k
   }
370
371
   /* Mirror on both sides for TDAC */
372
313k
   {
373
313k
      kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
374
313k
      kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
375
313k
      const celt_coef * OPUS_RESTRICT wp1 = window;
376
313k
      const celt_coef * OPUS_RESTRICT wp2 = window+overlap-1;
377
378
21.1M
      for(i = 0; i < overlap/2; i++)
379
20.8M
      {
380
20.8M
         kiss_fft_scalar x1, x2;
381
20.8M
         x1 = *xp1;
382
20.8M
         x2 = *yp1;
383
20.8M
         *yp1++ = SUB32_ovflw(S_MUL(x2, *wp2), S_MUL(x1, *wp1));
384
20.8M
         *xp1-- = ADD32_ovflw(S_MUL(x2, *wp1), S_MUL(x1, *wp2));
385
20.8M
         wp1++;
386
20.8M
         wp2--;
387
20.8M
      }
388
313k
   }
389
313k
}
390
#endif /* OVERRIDE_clt_mdct_backward */