Coverage Report

Created: 2026-06-10 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opus/celt/celt_lpc.c
Line
Count
Source
1
/* Copyright (c) 2009-2010 Xiph.Org Foundation
2
   Written by Jean-Marc Valin */
3
/*
4
   Redistribution and use in source and binary forms, with or without
5
   modification, are permitted provided that the following conditions
6
   are met:
7
8
   - Redistributions of source code must retain the above copyright
9
   notice, this list of conditions and the following disclaimer.
10
11
   - Redistributions in binary form must reproduce the above copyright
12
   notice, this list of conditions and the following disclaimer in the
13
   documentation and/or other materials provided with the distribution.
14
15
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19
   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
*/
27
28
#ifdef HAVE_CONFIG_H
29
#include "config.h"
30
#endif
31
32
#include "celt_lpc.h"
33
#include "stack_alloc.h"
34
#include "mathops.h"
35
#include "pitch.h"
36
37
void _celt_lpc(
38
      opus_val16       *_lpc, /* out: [0...p-1] LPC coefficients      */
39
const opus_val32 *ac,  /* in:  [0...p] autocorrelation values  */
40
int          p
41
)
42
653k
{
43
653k
   int i, j;
44
653k
   opus_val32 r;
45
653k
   opus_val32 error = ac[0];
46
#ifdef FIXED_POINT
47
   opus_val32 lpc[CELT_LPC_ORDER];
48
#else
49
   float *lpc = _lpc;
50
#endif
51
52
653k
   OPUS_CLEAR(lpc, p);
53
#ifdef FIXED_POINT
54
477k
   if (ac[0] != 0)
55
#else
56
175k
   if (ac[0] > 1e-10f)
57
168k
#endif
58
646k
   {
59
4.99M
      for (i = 0; i < p; i++) {
60
         /* Sum up this iteration's reflection coefficient */
61
4.41M
         opus_val32 rr = 0;
62
#if defined (FIXED_POINT) && OPUS_FAST_INT64
63
         opus_int64 acc = 0;
64
24.5M
         for (j = 0; j < i; j++)
65
21.2M
            acc += (opus_int64)(lpc[j]) * (opus_int64)(ac[i - j]);
66
3.25M
         rr = (opus_val32)SHR64(acc, 31);
67
#else
68
9.21M
         for (j = 0; j < i; j++)
69
8.05M
            rr += MULT32_32_Q31(lpc[j],ac[i - j]);
70
#endif
71
4.41M
         rr += SHR32(ac[i + 1],6);
72
4.41M
         r = -frac_div32(SHL32(rr,6), error);
73
         /*  Update LPC coefficients and total error */
74
4.41M
         lpc[i] = SHR32(r,6);
75
20.1M
         for (j = 0; j < (i+1)>>1; j++)
76
15.7M
         {
77
15.7M
            opus_val32 tmp1, tmp2;
78
15.7M
            tmp1 = lpc[j];
79
15.7M
            tmp2 = lpc[i-1-j];
80
15.7M
            lpc[j]     = tmp1 + MULT32_32_Q31(r,tmp2);
81
15.7M
            lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
82
15.7M
         }
83
84
4.41M
         error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
85
         /* Bail out once we get 30 dB gain */
86
#ifdef FIXED_POINT
87
3.25M
         if (error<=SHR32(ac[0],10))
88
26.0k
            break;
89
#else
90
1.16M
         if (error<=.001f*ac[0])
91
45.3k
            break;
92
#endif
93
4.41M
      }
94
646k
   }
95
#ifdef FIXED_POINT
96
   {
97
      /* Convert the int32 lpcs to int16 and ensure there are no wrap-arounds.
98
         This reuses the logic in silk_LPC_fit() and silk_bwexpander_32(). Any bug
99
         fixes should also be applied there. */
100
      int iter, idx = 0;
101
      opus_val32 maxabs, absval, chirp_Q16, chirp_minus_one_Q16;
102
103
477k
      for (iter = 0; iter < 10; iter++) {
104
477k
         maxabs = 0;
105
4.20M
         for (i = 0; i < p; i++) {
106
3.72M
            absval = ABS32(lpc[i]);
107
3.72M
            if (absval > maxabs) {
108
656k
               maxabs = absval;
109
656k
               idx = i;
110
656k
            }
111
3.72M
         }
112
477k
         maxabs = PSHR32(maxabs, 13);  /* Q25->Q12 */
113
114
477k
         if (maxabs > 32767) {
115
0
            maxabs = MIN32(maxabs, 163838);
116
0
            chirp_Q16 = QCONST32(0.999, 16) - DIV32(SHL32(maxabs - 32767, 14),
117
0
                                                    SHR32(MULT32_32_32(maxabs, idx + 1), 2));
118
0
            chirp_minus_one_Q16 = chirp_Q16 - 65536;
119
120
            /* Apply bandwidth expansion. */
121
0
            for (i = 0; i < p - 1; i++) {
122
0
               lpc[i] = MULT32_32_Q16(chirp_Q16, lpc[i]);
123
0
               chirp_Q16 += PSHR32(MULT32_32_32(chirp_Q16, chirp_minus_one_Q16), 16);
124
0
            }
125
0
            lpc[p - 1] = MULT32_32_Q16(chirp_Q16, lpc[p - 1]);
126
477k
         } else {
127
477k
            break;
128
477k
         }
129
477k
      }
130
131
477k
      if (iter == 10) {
132
         /* If the coeffs still do not fit into the 16 bit range after 10 iterations,
133
            fall back to the A(z)=1 filter. */
134
0
         OPUS_CLEAR(lpc, p);
135
0
         _lpc[0] = 4096;  /* Q12 */
136
477k
      } else {
137
4.20M
         for (i = 0; i < p; i++) {
138
3.72M
            _lpc[i] = EXTRACT16(PSHR32(lpc[i], 13));  /* Q25->Q12 */
139
3.72M
         }
140
477k
      }
141
   }
142
#endif
143
653k
}
_celt_lpc
Line
Count
Source
42
477k
{
43
477k
   int i, j;
44
477k
   opus_val32 r;
45
477k
   opus_val32 error = ac[0];
46
477k
#ifdef FIXED_POINT
47
477k
   opus_val32 lpc[CELT_LPC_ORDER];
48
#else
49
   float *lpc = _lpc;
50
#endif
51
52
477k
   OPUS_CLEAR(lpc, p);
53
477k
#ifdef FIXED_POINT
54
477k
   if (ac[0] != 0)
55
#else
56
   if (ac[0] > 1e-10f)
57
#endif
58
477k
   {
59
3.70M
      for (i = 0; i < p; i++) {
60
         /* Sum up this iteration's reflection coefficient */
61
3.25M
         opus_val32 rr = 0;
62
3.25M
#if defined (FIXED_POINT) && OPUS_FAST_INT64
63
3.25M
         opus_int64 acc = 0;
64
24.5M
         for (j = 0; j < i; j++)
65
21.2M
            acc += (opus_int64)(lpc[j]) * (opus_int64)(ac[i - j]);
66
3.25M
         rr = (opus_val32)SHR64(acc, 31);
67
#else
68
         for (j = 0; j < i; j++)
69
            rr += MULT32_32_Q31(lpc[j],ac[i - j]);
70
#endif
71
3.25M
         rr += SHR32(ac[i + 1],6);
72
3.25M
         r = -frac_div32(SHL32(rr,6), error);
73
         /*  Update LPC coefficients and total error */
74
3.25M
         lpc[i] = SHR32(r,6);
75
14.6M
         for (j = 0; j < (i+1)>>1; j++)
76
11.4M
         {
77
11.4M
            opus_val32 tmp1, tmp2;
78
11.4M
            tmp1 = lpc[j];
79
11.4M
            tmp2 = lpc[i-1-j];
80
11.4M
            lpc[j]     = tmp1 + MULT32_32_Q31(r,tmp2);
81
11.4M
            lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
82
11.4M
         }
83
84
3.25M
         error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
85
         /* Bail out once we get 30 dB gain */
86
3.25M
#ifdef FIXED_POINT
87
3.25M
         if (error<=SHR32(ac[0],10))
88
26.0k
            break;
89
#else
90
         if (error<=.001f*ac[0])
91
            break;
92
#endif
93
3.25M
      }
94
477k
   }
95
477k
#ifdef FIXED_POINT
96
477k
   {
97
      /* Convert the int32 lpcs to int16 and ensure there are no wrap-arounds.
98
         This reuses the logic in silk_LPC_fit() and silk_bwexpander_32(). Any bug
99
         fixes should also be applied there. */
100
477k
      int iter, idx = 0;
101
477k
      opus_val32 maxabs, absval, chirp_Q16, chirp_minus_one_Q16;
102
103
477k
      for (iter = 0; iter < 10; iter++) {
104
477k
         maxabs = 0;
105
4.20M
         for (i = 0; i < p; i++) {
106
3.72M
            absval = ABS32(lpc[i]);
107
3.72M
            if (absval > maxabs) {
108
656k
               maxabs = absval;
109
656k
               idx = i;
110
656k
            }
111
3.72M
         }
112
477k
         maxabs = PSHR32(maxabs, 13);  /* Q25->Q12 */
113
114
477k
         if (maxabs > 32767) {
115
0
            maxabs = MIN32(maxabs, 163838);
116
0
            chirp_Q16 = QCONST32(0.999, 16) - DIV32(SHL32(maxabs - 32767, 14),
117
0
                                                    SHR32(MULT32_32_32(maxabs, idx + 1), 2));
118
0
            chirp_minus_one_Q16 = chirp_Q16 - 65536;
119
120
            /* Apply bandwidth expansion. */
121
0
            for (i = 0; i < p - 1; i++) {
122
0
               lpc[i] = MULT32_32_Q16(chirp_Q16, lpc[i]);
123
0
               chirp_Q16 += PSHR32(MULT32_32_32(chirp_Q16, chirp_minus_one_Q16), 16);
124
0
            }
125
0
            lpc[p - 1] = MULT32_32_Q16(chirp_Q16, lpc[p - 1]);
126
477k
         } else {
127
477k
            break;
128
477k
         }
129
477k
      }
130
131
477k
      if (iter == 10) {
132
         /* If the coeffs still do not fit into the 16 bit range after 10 iterations,
133
            fall back to the A(z)=1 filter. */
134
0
         OPUS_CLEAR(lpc, p);
135
0
         _lpc[0] = 4096;  /* Q12 */
136
477k
      } else {
137
4.20M
         for (i = 0; i < p; i++) {
138
3.72M
            _lpc[i] = EXTRACT16(PSHR32(lpc[i], 13));  /* Q25->Q12 */
139
3.72M
         }
140
477k
      }
141
477k
   }
142
477k
#endif
143
477k
}
_celt_lpc
Line
Count
Source
42
175k
{
43
175k
   int i, j;
44
175k
   opus_val32 r;
45
175k
   opus_val32 error = ac[0];
46
#ifdef FIXED_POINT
47
   opus_val32 lpc[CELT_LPC_ORDER];
48
#else
49
175k
   float *lpc = _lpc;
50
175k
#endif
51
52
175k
   OPUS_CLEAR(lpc, p);
53
#ifdef FIXED_POINT
54
   if (ac[0] != 0)
55
#else
56
175k
   if (ac[0] > 1e-10f)
57
168k
#endif
58
168k
   {
59
1.28M
      for (i = 0; i < p; i++) {
60
         /* Sum up this iteration's reflection coefficient */
61
1.16M
         opus_val32 rr = 0;
62
#if defined (FIXED_POINT) && OPUS_FAST_INT64
63
         opus_int64 acc = 0;
64
         for (j = 0; j < i; j++)
65
            acc += (opus_int64)(lpc[j]) * (opus_int64)(ac[i - j]);
66
         rr = (opus_val32)SHR64(acc, 31);
67
#else
68
9.21M
         for (j = 0; j < i; j++)
69
8.05M
            rr += MULT32_32_Q31(lpc[j],ac[i - j]);
70
1.16M
#endif
71
1.16M
         rr += SHR32(ac[i + 1],6);
72
1.16M
         r = -frac_div32(SHL32(rr,6), error);
73
         /*  Update LPC coefficients and total error */
74
1.16M
         lpc[i] = SHR32(r,6);
75
5.47M
         for (j = 0; j < (i+1)>>1; j++)
76
4.31M
         {
77
4.31M
            opus_val32 tmp1, tmp2;
78
4.31M
            tmp1 = lpc[j];
79
4.31M
            tmp2 = lpc[i-1-j];
80
4.31M
            lpc[j]     = tmp1 + MULT32_32_Q31(r,tmp2);
81
4.31M
            lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
82
4.31M
         }
83
84
1.16M
         error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
85
         /* Bail out once we get 30 dB gain */
86
#ifdef FIXED_POINT
87
         if (error<=SHR32(ac[0],10))
88
            break;
89
#else
90
1.16M
         if (error<=.001f*ac[0])
91
45.3k
            break;
92
1.16M
#endif
93
1.16M
      }
94
168k
   }
95
#ifdef FIXED_POINT
96
   {
97
      /* Convert the int32 lpcs to int16 and ensure there are no wrap-arounds.
98
         This reuses the logic in silk_LPC_fit() and silk_bwexpander_32(). Any bug
99
         fixes should also be applied there. */
100
      int iter, idx = 0;
101
      opus_val32 maxabs, absval, chirp_Q16, chirp_minus_one_Q16;
102
103
      for (iter = 0; iter < 10; iter++) {
104
         maxabs = 0;
105
         for (i = 0; i < p; i++) {
106
            absval = ABS32(lpc[i]);
107
            if (absval > maxabs) {
108
               maxabs = absval;
109
               idx = i;
110
            }
111
         }
112
         maxabs = PSHR32(maxabs, 13);  /* Q25->Q12 */
113
114
         if (maxabs > 32767) {
115
            maxabs = MIN32(maxabs, 163838);
116
            chirp_Q16 = QCONST32(0.999, 16) - DIV32(SHL32(maxabs - 32767, 14),
117
                                                    SHR32(MULT32_32_32(maxabs, idx + 1), 2));
118
            chirp_minus_one_Q16 = chirp_Q16 - 65536;
119
120
            /* Apply bandwidth expansion. */
121
            for (i = 0; i < p - 1; i++) {
122
               lpc[i] = MULT32_32_Q16(chirp_Q16, lpc[i]);
123
               chirp_Q16 += PSHR32(MULT32_32_32(chirp_Q16, chirp_minus_one_Q16), 16);
124
            }
125
            lpc[p - 1] = MULT32_32_Q16(chirp_Q16, lpc[p - 1]);
126
         } else {
127
            break;
128
         }
129
      }
130
131
      if (iter == 10) {
132
         /* If the coeffs still do not fit into the 16 bit range after 10 iterations,
133
            fall back to the A(z)=1 filter. */
134
         OPUS_CLEAR(lpc, p);
135
         _lpc[0] = 4096;  /* Q12 */
136
      } else {
137
         for (i = 0; i < p; i++) {
138
            _lpc[i] = EXTRACT16(PSHR32(lpc[i], 13));  /* Q25->Q12 */
139
         }
140
      }
141
   }
142
#endif
143
175k
}
144
145
146
void celt_fir_c(
147
         const opus_val16 *x,
148
         const opus_val16 *num,
149
         opus_val16 *y,
150
         int N,
151
         int ord,
152
         int arch)
153
128k
{
154
128k
   int i,j;
155
128k
   VARDECL(opus_val16, rnum);
156
128k
   SAVE_STACK;
157
128k
   celt_assert(x != y);
158
128k
   ALLOC(rnum, ord, opus_val16);
159
3.22M
   for(i=0;i<ord;i++)
160
3.09M
      rnum[i] = num[ord-i-1];
161
17.9M
   for (i=0;i<N-3;i+=4)
162
17.8M
   {
163
17.8M
      opus_val32 sum[4];
164
17.8M
      sum[0] = SHL32(EXTEND32(x[i  ]), SIG_SHIFT);
165
17.8M
      sum[1] = SHL32(EXTEND32(x[i+1]), SIG_SHIFT);
166
17.8M
      sum[2] = SHL32(EXTEND32(x[i+2]), SIG_SHIFT);
167
17.8M
      sum[3] = SHL32(EXTEND32(x[i+3]), SIG_SHIFT);
168
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
169
      {
170
         opus_val32 sum_c[4];
171
         memcpy(sum_c, sum, sizeof(sum_c));
172
         xcorr_kernel_c(rnum, x+i-ord, sum_c, ord);
173
#endif
174
17.8M
         xcorr_kernel(rnum, x+i-ord, sum, ord, arch);
175
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
176
0
         celt_assert(memcmp(sum, sum_c, sizeof(sum)) == 0);
177
0
      }
178
0
#endif
179
17.8M
      y[i  ] = SROUND16(sum[0], SIG_SHIFT);
180
17.8M
      y[i+1] = SROUND16(sum[1], SIG_SHIFT);
181
17.8M
      y[i+2] = SROUND16(sum[2], SIG_SHIFT);
182
17.8M
      y[i+3] = SROUND16(sum[3], SIG_SHIFT);
183
0
   }
184
183k
   for (;i<N;i++)
185
54.4k
   {
186
54.4k
      opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
187
1.36M
      for (j=0;j<ord;j++)
188
1.30M
         sum = MAC16_16(sum,rnum[j],x[i+j-ord]);
189
54.4k
      y[i] = SROUND16(sum, SIG_SHIFT);
190
54.4k
   }
191
0
   RESTORE_STACK;
192
0
}
Unexecuted instantiation: celt_fir_c
celt_fir_c
Line
Count
Source
153
128k
{
154
128k
   int i,j;
155
128k
   VARDECL(opus_val16, rnum);
156
128k
   SAVE_STACK;
157
128k
   celt_assert(x != y);
158
128k
   ALLOC(rnum, ord, opus_val16);
159
3.22M
   for(i=0;i<ord;i++)
160
3.09M
      rnum[i] = num[ord-i-1];
161
17.9M
   for (i=0;i<N-3;i+=4)
162
17.8M
   {
163
17.8M
      opus_val32 sum[4];
164
17.8M
      sum[0] = SHL32(EXTEND32(x[i  ]), SIG_SHIFT);
165
17.8M
      sum[1] = SHL32(EXTEND32(x[i+1]), SIG_SHIFT);
166
17.8M
      sum[2] = SHL32(EXTEND32(x[i+2]), SIG_SHIFT);
167
17.8M
      sum[3] = SHL32(EXTEND32(x[i+3]), SIG_SHIFT);
168
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
169
      {
170
         opus_val32 sum_c[4];
171
         memcpy(sum_c, sum, sizeof(sum_c));
172
         xcorr_kernel_c(rnum, x+i-ord, sum_c, ord);
173
#endif
174
17.8M
         xcorr_kernel(rnum, x+i-ord, sum, ord, arch);
175
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
176
         celt_assert(memcmp(sum, sum_c, sizeof(sum)) == 0);
177
      }
178
#endif
179
17.8M
      y[i  ] = SROUND16(sum[0], SIG_SHIFT);
180
17.8M
      y[i+1] = SROUND16(sum[1], SIG_SHIFT);
181
17.8M
      y[i+2] = SROUND16(sum[2], SIG_SHIFT);
182
17.8M
      y[i+3] = SROUND16(sum[3], SIG_SHIFT);
183
17.8M
   }
184
183k
   for (;i<N;i++)
185
54.4k
   {
186
54.4k
      opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
187
1.36M
      for (j=0;j<ord;j++)
188
1.30M
         sum = MAC16_16(sum,rnum[j],x[i+j-ord]);
189
54.4k
      y[i] = SROUND16(sum, SIG_SHIFT);
190
54.4k
   }
191
128k
   RESTORE_STACK;
192
128k
}
193
194
void celt_iir(const opus_val32 *_x,
195
         const opus_val16 *den,
196
         opus_val32 *_y,
197
         int N,
198
         int ord,
199
         opus_val16 *mem,
200
         int arch)
201
286k
{
202
#ifdef SMALL_FOOTPRINT
203
   int i,j;
204
   (void)arch;
205
   for (i=0;i<N;i++)
206
   {
207
      opus_val32 sum = _x[i];
208
      for (j=0;j<ord;j++)
209
      {
210
         sum -= MULT16_16(den[j],mem[j]);
211
      }
212
      for (j=ord-1;j>=1;j--)
213
      {
214
         mem[j]=mem[j-1];
215
      }
216
      mem[0] = SROUND16(sum, SIG_SHIFT);
217
      _y[i] = sum;
218
   }
219
#else
220
286k
   int i,j;
221
286k
   VARDECL(opus_val16, rden);
222
286k
   VARDECL(opus_val16, y);
223
286k
   SAVE_STACK;
224
225
286k
   celt_assert((ord&3)==0);
226
286k
   ALLOC(rden, ord, opus_val16);
227
286k
   ALLOC(y, N+ord, opus_val16);
228
7.15M
   for(i=0;i<ord;i++)
229
6.86M
      rden[i] = den[ord-i-1];
230
7.15M
   for(i=0;i<ord;i++)
231
6.86M
      y[i] = -mem[ord-i-1];
232
104M
   for(;i<N+ord;i++)
233
104M
      y[i]=0;
234
26.4M
   for (i=0;i<N-3;i+=4)
235
26.1M
   {
236
      /* Unroll by 4 as if it were an FIR filter */
237
26.1M
      opus_val32 sum[4];
238
26.1M
      sum[0]=_x[i];
239
26.1M
      sum[1]=_x[i+1];
240
26.1M
      sum[2]=_x[i+2];
241
26.1M
      sum[3]=_x[i+3];
242
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
243
      {
244
         opus_val32 sum_c[4];
245
         memcpy(sum_c, sum, sizeof(sum_c));
246
         xcorr_kernel_c(rden, y+i, sum_c, ord);
247
#endif
248
26.1M
         xcorr_kernel(rden, y+i, sum, ord, arch);
249
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
250
13.2M
         celt_assert(memcmp(sum, sum_c, sizeof(sum)) == 0);
251
13.2M
      }
252
0
#endif
253
      /* Patch up the result to compensate for the fact that this is an IIR */
254
26.1M
      y[i+ord  ] = -SROUND16(sum[0],SIG_SHIFT);
255
13.2M
      _y[i  ] = sum[0];
256
26.1M
      sum[1] = MAC16_16(sum[1], y[i+ord  ], den[0]);
257
26.1M
      y[i+ord+1] = -SROUND16(sum[1],SIG_SHIFT);
258
13.2M
      _y[i+1] = sum[1];
259
26.1M
      sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
260
26.1M
      sum[2] = MAC16_16(sum[2], y[i+ord  ], den[1]);
261
26.1M
      y[i+ord+2] = -SROUND16(sum[2],SIG_SHIFT);
262
13.2M
      _y[i+2] = sum[2];
263
264
26.1M
      sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
265
26.1M
      sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
266
26.1M
      sum[3] = MAC16_16(sum[3], y[i+ord  ], den[2]);
267
26.1M
      y[i+ord+3] = -SROUND16(sum[3],SIG_SHIFT);
268
13.2M
      _y[i+3] = sum[3];
269
13.2M
   }
270
286k
   for (;i<N;i++)
271
0
   {
272
0
      opus_val32 sum = _x[i];
273
0
      for (j=0;j<ord;j++)
274
0
         sum -= MULT16_16(rden[j],y[i+j]);
275
0
      y[i+ord] = SROUND16(sum,SIG_SHIFT);
276
0
      _y[i] = sum;
277
0
   }
278
7.15M
   for(i=0;i<ord;i++)
279
6.86M
      mem[i] = _y[N-i-1];
280
157k
   RESTORE_STACK;
281
157k
#endif
282
157k
}
celt_iir
Line
Count
Source
201
157k
{
202
#ifdef SMALL_FOOTPRINT
203
   int i,j;
204
   (void)arch;
205
   for (i=0;i<N;i++)
206
   {
207
      opus_val32 sum = _x[i];
208
      for (j=0;j<ord;j++)
209
      {
210
         sum -= MULT16_16(den[j],mem[j]);
211
      }
212
      for (j=ord-1;j>=1;j--)
213
      {
214
         mem[j]=mem[j-1];
215
      }
216
      mem[0] = SROUND16(sum, SIG_SHIFT);
217
      _y[i] = sum;
218
   }
219
#else
220
157k
   int i,j;
221
157k
   VARDECL(opus_val16, rden);
222
157k
   VARDECL(opus_val16, y);
223
157k
   SAVE_STACK;
224
225
157k
   celt_assert((ord&3)==0);
226
157k
   ALLOC(rden, ord, opus_val16);
227
157k
   ALLOC(y, N+ord, opus_val16);
228
3.93M
   for(i=0;i<ord;i++)
229
3.77M
      rden[i] = den[ord-i-1];
230
3.93M
   for(i=0;i<ord;i++)
231
3.77M
      y[i] = -mem[ord-i-1];
232
53.2M
   for(;i<N+ord;i++)
233
53.1M
      y[i]=0;
234
13.4M
   for (i=0;i<N-3;i+=4)
235
13.2M
   {
236
      /* Unroll by 4 as if it were an FIR filter */
237
13.2M
      opus_val32 sum[4];
238
13.2M
      sum[0]=_x[i];
239
13.2M
      sum[1]=_x[i+1];
240
13.2M
      sum[2]=_x[i+2];
241
13.2M
      sum[3]=_x[i+3];
242
13.2M
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
243
13.2M
      {
244
13.2M
         opus_val32 sum_c[4];
245
13.2M
         memcpy(sum_c, sum, sizeof(sum_c));
246
13.2M
         xcorr_kernel_c(rden, y+i, sum_c, ord);
247
13.2M
#endif
248
13.2M
         xcorr_kernel(rden, y+i, sum, ord, arch);
249
13.2M
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
250
13.2M
         celt_assert(memcmp(sum, sum_c, sizeof(sum)) == 0);
251
13.2M
      }
252
0
#endif
253
      /* Patch up the result to compensate for the fact that this is an IIR */
254
13.2M
      y[i+ord  ] = -SROUND16(sum[0],SIG_SHIFT);
255
13.2M
      _y[i  ] = sum[0];
256
13.2M
      sum[1] = MAC16_16(sum[1], y[i+ord  ], den[0]);
257
13.2M
      y[i+ord+1] = -SROUND16(sum[1],SIG_SHIFT);
258
13.2M
      _y[i+1] = sum[1];
259
13.2M
      sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
260
13.2M
      sum[2] = MAC16_16(sum[2], y[i+ord  ], den[1]);
261
13.2M
      y[i+ord+2] = -SROUND16(sum[2],SIG_SHIFT);
262
13.2M
      _y[i+2] = sum[2];
263
264
13.2M
      sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
265
13.2M
      sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
266
13.2M
      sum[3] = MAC16_16(sum[3], y[i+ord  ], den[2]);
267
13.2M
      y[i+ord+3] = -SROUND16(sum[3],SIG_SHIFT);
268
13.2M
      _y[i+3] = sum[3];
269
13.2M
   }
270
157k
   for (;i<N;i++)
271
0
   {
272
0
      opus_val32 sum = _x[i];
273
0
      for (j=0;j<ord;j++)
274
0
         sum -= MULT16_16(rden[j],y[i+j]);
275
0
      y[i+ord] = SROUND16(sum,SIG_SHIFT);
276
0
      _y[i] = sum;
277
0
   }
278
3.93M
   for(i=0;i<ord;i++)
279
3.77M
      mem[i] = _y[N-i-1];
280
157k
   RESTORE_STACK;
281
157k
#endif
282
157k
}
celt_iir
Line
Count
Source
201
128k
{
202
#ifdef SMALL_FOOTPRINT
203
   int i,j;
204
   (void)arch;
205
   for (i=0;i<N;i++)
206
   {
207
      opus_val32 sum = _x[i];
208
      for (j=0;j<ord;j++)
209
      {
210
         sum -= MULT16_16(den[j],mem[j]);
211
      }
212
      for (j=ord-1;j>=1;j--)
213
      {
214
         mem[j]=mem[j-1];
215
      }
216
      mem[0] = SROUND16(sum, SIG_SHIFT);
217
      _y[i] = sum;
218
   }
219
#else
220
128k
   int i,j;
221
128k
   VARDECL(opus_val16, rden);
222
128k
   VARDECL(opus_val16, y);
223
128k
   SAVE_STACK;
224
225
128k
   celt_assert((ord&3)==0);
226
128k
   ALLOC(rden, ord, opus_val16);
227
128k
   ALLOC(y, N+ord, opus_val16);
228
3.22M
   for(i=0;i<ord;i++)
229
3.09M
      rden[i] = den[ord-i-1];
230
3.22M
   for(i=0;i<ord;i++)
231
3.09M
      y[i] = -mem[ord-i-1];
232
51.5M
   for(;i<N+ord;i++)
233
51.3M
      y[i]=0;
234
12.9M
   for (i=0;i<N-3;i+=4)
235
12.8M
   {
236
      /* Unroll by 4 as if it were an FIR filter */
237
12.8M
      opus_val32 sum[4];
238
12.8M
      sum[0]=_x[i];
239
12.8M
      sum[1]=_x[i+1];
240
12.8M
      sum[2]=_x[i+2];
241
12.8M
      sum[3]=_x[i+3];
242
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
243
      {
244
         opus_val32 sum_c[4];
245
         memcpy(sum_c, sum, sizeof(sum_c));
246
         xcorr_kernel_c(rden, y+i, sum_c, ord);
247
#endif
248
12.8M
         xcorr_kernel(rden, y+i, sum, ord, arch);
249
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
250
         celt_assert(memcmp(sum, sum_c, sizeof(sum)) == 0);
251
      }
252
#endif
253
      /* Patch up the result to compensate for the fact that this is an IIR */
254
12.8M
      y[i+ord  ] = -SROUND16(sum[0],SIG_SHIFT);
255
12.8M
      _y[i  ] = sum[0];
256
12.8M
      sum[1] = MAC16_16(sum[1], y[i+ord  ], den[0]);
257
12.8M
      y[i+ord+1] = -SROUND16(sum[1],SIG_SHIFT);
258
12.8M
      _y[i+1] = sum[1];
259
12.8M
      sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
260
12.8M
      sum[2] = MAC16_16(sum[2], y[i+ord  ], den[1]);
261
12.8M
      y[i+ord+2] = -SROUND16(sum[2],SIG_SHIFT);
262
12.8M
      _y[i+2] = sum[2];
263
264
12.8M
      sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
265
12.8M
      sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
266
12.8M
      sum[3] = MAC16_16(sum[3], y[i+ord  ], den[2]);
267
12.8M
      y[i+ord+3] = -SROUND16(sum[3],SIG_SHIFT);
268
12.8M
      _y[i+3] = sum[3];
269
12.8M
   }
270
128k
   for (;i<N;i++)
271
0
   {
272
0
      opus_val32 sum = _x[i];
273
0
      for (j=0;j<ord;j++)
274
0
         sum -= MULT16_16(rden[j],y[i+j]);
275
0
      y[i+ord] = SROUND16(sum,SIG_SHIFT);
276
0
      _y[i] = sum;
277
0
   }
278
3.22M
   for(i=0;i<ord;i++)
279
3.09M
      mem[i] = _y[N-i-1];
280
128k
   RESTORE_STACK;
281
128k
#endif
282
128k
}
283
284
int _celt_autocorr(
285
                   const opus_val16 *x,   /*  in: [0...n-1] samples x   */
286
                   opus_val32       *ac,  /* out: [0...lag-1] ac values */
287
                   const celt_coef  *window,
288
                   int          overlap,
289
                   int          lag,
290
                   int          n,
291
                   int          arch
292
                  )
293
181M
{
294
181M
   opus_val32 d;
295
181M
   int i, k;
296
181M
   int fastN=n-lag;
297
181M
   int shift;
298
181M
   const opus_val16 *xptr;
299
181M
   VARDECL(opus_val16, xx);
300
181M
   SAVE_STACK;
301
181M
   ALLOC(xx, n, opus_val16);
302
181M
   celt_assert(n>0);
303
181M
   celt_assert(overlap>=0);
304
181M
   if (overlap == 0)
305
181M
   {
306
181M
      xptr = x;
307
181M
   } else {
308
286M
      for (i=0;i<n;i++)
309
286M
         xx[i] = x[i];
310
33.7M
      for (i=0;i<overlap;i++)
311
33.5M
      {
312
33.5M
         opus_val16 w = COEF2VAL16(window[i]);
313
33.5M
         xx[i] = MULT16_16_Q15(x[i],w);
314
33.5M
         xx[n-i-1] = MULT16_16_Q15(x[n-i-1],w);
315
33.5M
      }
316
254k
      xptr = xx;
317
254k
   }
318
181M
   shift=0;
319
#ifdef FIXED_POINT
320
   {
321
      opus_val32 ac0;
322
      int ac0_shift = celt_ilog2(n + (n>>4));
323
      ac0 = 1+(n<<7);
324
181M
      if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),ac0_shift);
325
12.3G
      for(i=(n&1);i<n;i+=2)
326
12.1G
      {
327
12.1G
         ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),ac0_shift);
328
12.1G
         ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),ac0_shift);
329
12.1G
      }
330
      /* Consider the effect of rounding-to-nearest when scaling the signal. */
331
181M
      ac0 += SHR32(ac0,7);
332
333
      shift = celt_ilog2(ac0)-30+ac0_shift+1;
334
      shift = (shift)/2;
335
181M
      if (shift>0)
336
1.95M
      {
337
284M
         for(i=0;i<n;i++)
338
282M
            xx[i] = PSHR32(xptr[i], shift);
339
1.95M
         xptr = xx;
340
1.95M
      } else
341
179M
         shift = 0;
342
   }
343
#endif
344
181M
   celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1, arch);
345
2.37G
   for (k=0;k<=lag;k++)
346
2.19G
   {
347
14.9G
      for (i = k+fastN, d = 0; i < n; i++)
348
12.7G
         d = MAC16_16(d, xptr[i], xptr[i-k]);
349
2.19G
      ac[k] += d;
350
2.19G
   }
351
#ifdef FIXED_POINT
352
   shift = 2*shift;
353
181M
   if (shift<=0)
354
179M
      ac[0] += SHL32((opus_int32)1, -shift);
355
181M
   if (ac[0] < 268435456)
356
178M
   {
357
178M
      int shift2 = 29 - EC_ILOG(ac[0]);
358
2.33G
      for (i=0;i<=lag;i++)
359
2.15G
         ac[i] = SHL32(ac[i], shift2);
360
178M
      shift -= shift2;
361
178M
   } else if (ac[0] >= 536870912)
362
2.45M
   {
363
2.45M
      int shift2=1;
364
2.45M
      if (ac[0] >= 1073741824)
365
1.22M
         shift2++;
366
31.8M
      for (i=0;i<=lag;i++)
367
29.3M
         ac[i] = SHR32(ac[i], shift2);
368
2.45M
      shift += shift2;
369
2.45M
   }
370
#endif
371
372
181M
   RESTORE_STACK;
373
181M
   return shift;
374
181M
}
_celt_autocorr
Line
Count
Source
293
90.7M
{
294
90.7M
   opus_val32 d;
295
90.7M
   int i, k;
296
90.7M
   int fastN=n-lag;
297
90.7M
   int shift;
298
90.7M
   const opus_val16 *xptr;
299
90.7M
   VARDECL(opus_val16, xx);
300
90.7M
   SAVE_STACK;
301
90.7M
   ALLOC(xx, n, opus_val16);
302
90.7M
   celt_assert(n>0);
303
90.7M
   celt_assert(overlap>=0);
304
90.7M
   if (overlap == 0)
305
90.6M
   {
306
90.6M
      xptr = x;
307
90.6M
   } else {
308
101M
      for (i=0;i<n;i++)
309
101M
         xx[i] = x[i];
310
11.9M
      for (i=0;i<overlap;i++)
311
11.8M
      {
312
11.8M
         opus_val16 w = COEF2VAL16(window[i]);
313
11.8M
         xx[i] = MULT16_16_Q15(x[i],w);
314
11.8M
         xx[n-i-1] = MULT16_16_Q15(x[n-i-1],w);
315
11.8M
      }
316
90.9k
      xptr = xx;
317
90.9k
   }
318
90.7M
   shift=0;
319
90.7M
#ifdef FIXED_POINT
320
90.7M
   {
321
90.7M
      opus_val32 ac0;
322
90.7M
      int ac0_shift = celt_ilog2(n + (n>>4));
323
90.7M
      ac0 = 1+(n<<7);
324
90.7M
      if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),ac0_shift);
325
6.15G
      for(i=(n&1);i<n;i+=2)
326
6.06G
      {
327
6.06G
         ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),ac0_shift);
328
6.06G
         ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),ac0_shift);
329
6.06G
      }
330
      /* Consider the effect of rounding-to-nearest when scaling the signal. */
331
90.7M
      ac0 += SHR32(ac0,7);
332
333
90.7M
      shift = celt_ilog2(ac0)-30+ac0_shift+1;
334
90.7M
      shift = (shift)/2;
335
90.7M
      if (shift>0)
336
979k
      {
337
142M
         for(i=0;i<n;i++)
338
141M
            xx[i] = PSHR32(xptr[i], shift);
339
979k
         xptr = xx;
340
979k
      } else
341
89.7M
         shift = 0;
342
90.7M
   }
343
90.7M
#endif
344
90.7M
   celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1, arch);
345
1.18G
   for (k=0;k<=lag;k++)
346
1.09G
   {
347
7.47G
      for (i = k+fastN, d = 0; i < n; i++)
348
6.37G
         d = MAC16_16(d, xptr[i], xptr[i-k]);
349
1.09G
      ac[k] += d;
350
1.09G
   }
351
90.7M
#ifdef FIXED_POINT
352
90.7M
   shift = 2*shift;
353
90.7M
   if (shift<=0)
354
89.7M
      ac[0] += SHL32((opus_int32)1, -shift);
355
90.7M
   if (ac[0] < 268435456)
356
89.4M
   {
357
89.4M
      int shift2 = 29 - EC_ILOG(ac[0]);
358
1.16G
      for (i=0;i<=lag;i++)
359
1.07G
         ac[i] = SHL32(ac[i], shift2);
360
89.4M
      shift -= shift2;
361
89.4M
   } else if (ac[0] >= 536870912)
362
1.22M
   {
363
1.22M
      int shift2=1;
364
1.22M
      if (ac[0] >= 1073741824)
365
614k
         shift2++;
366
15.9M
      for (i=0;i<=lag;i++)
367
14.6M
         ac[i] = SHR32(ac[i], shift2);
368
1.22M
      shift += shift2;
369
1.22M
   }
370
90.7M
#endif
371
372
90.7M
   RESTORE_STACK;
373
90.7M
   return shift;
374
90.7M
}
_celt_autocorr
Line
Count
Source
293
90.7M
{
294
90.7M
   opus_val32 d;
295
90.7M
   int i, k;
296
90.7M
   int fastN=n-lag;
297
90.7M
   int shift;
298
90.7M
   const opus_val16 *xptr;
299
90.7M
   VARDECL(opus_val16, xx);
300
90.7M
   SAVE_STACK;
301
90.7M
   ALLOC(xx, n, opus_val16);
302
90.7M
   celt_assert(n>0);
303
90.7M
   celt_assert(overlap>=0);
304
90.7M
   if (overlap == 0)
305
90.6M
   {
306
90.6M
      xptr = x;
307
90.6M
   } else {
308
101M
      for (i=0;i<n;i++)
309
101M
         xx[i] = x[i];
310
11.9M
      for (i=0;i<overlap;i++)
311
11.8M
      {
312
11.8M
         opus_val16 w = COEF2VAL16(window[i]);
313
11.8M
         xx[i] = MULT16_16_Q15(x[i],w);
314
11.8M
         xx[n-i-1] = MULT16_16_Q15(x[n-i-1],w);
315
11.8M
      }
316
90.9k
      xptr = xx;
317
90.9k
   }
318
90.7M
   shift=0;
319
90.7M
#ifdef FIXED_POINT
320
90.7M
   {
321
90.7M
      opus_val32 ac0;
322
90.7M
      int ac0_shift = celt_ilog2(n + (n>>4));
323
90.7M
      ac0 = 1+(n<<7);
324
90.7M
      if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),ac0_shift);
325
6.15G
      for(i=(n&1);i<n;i+=2)
326
6.06G
      {
327
6.06G
         ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),ac0_shift);
328
6.06G
         ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),ac0_shift);
329
6.06G
      }
330
      /* Consider the effect of rounding-to-nearest when scaling the signal. */
331
90.7M
      ac0 += SHR32(ac0,7);
332
333
90.7M
      shift = celt_ilog2(ac0)-30+ac0_shift+1;
334
90.7M
      shift = (shift)/2;
335
90.7M
      if (shift>0)
336
979k
      {
337
142M
         for(i=0;i<n;i++)
338
141M
            xx[i] = PSHR32(xptr[i], shift);
339
979k
         xptr = xx;
340
979k
      } else
341
89.7M
         shift = 0;
342
90.7M
   }
343
90.7M
#endif
344
90.7M
   celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1, arch);
345
1.18G
   for (k=0;k<=lag;k++)
346
1.09G
   {
347
7.47G
      for (i = k+fastN, d = 0; i < n; i++)
348
6.37G
         d = MAC16_16(d, xptr[i], xptr[i-k]);
349
1.09G
      ac[k] += d;
350
1.09G
   }
351
90.7M
#ifdef FIXED_POINT
352
90.7M
   shift = 2*shift;
353
90.7M
   if (shift<=0)
354
89.7M
      ac[0] += SHL32((opus_int32)1, -shift);
355
90.7M
   if (ac[0] < 268435456)
356
89.4M
   {
357
89.4M
      int shift2 = 29 - EC_ILOG(ac[0]);
358
1.16G
      for (i=0;i<=lag;i++)
359
1.07G
         ac[i] = SHL32(ac[i], shift2);
360
89.4M
      shift -= shift2;
361
89.4M
   } else if (ac[0] >= 536870912)
362
1.22M
   {
363
1.22M
      int shift2=1;
364
1.22M
      if (ac[0] >= 1073741824)
365
614k
         shift2++;
366
15.9M
      for (i=0;i<=lag;i++)
367
14.6M
         ac[i] = SHR32(ac[i], shift2);
368
1.22M
      shift += shift2;
369
1.22M
   }
370
90.7M
#endif
371
372
90.7M
   RESTORE_STACK;
373
90.7M
   return shift;
374
90.7M
}
_celt_autocorr
Line
Count
Source
293
175k
{
294
175k
   opus_val32 d;
295
175k
   int i, k;
296
175k
   int fastN=n-lag;
297
175k
   int shift;
298
175k
   const opus_val16 *xptr;
299
175k
   VARDECL(opus_val16, xx);
300
175k
   SAVE_STACK;
301
175k
   ALLOC(xx, n, opus_val16);
302
175k
   celt_assert(n>0);
303
175k
   celt_assert(overlap>=0);
304
175k
   if (overlap == 0)
305
103k
   {
306
103k
      xptr = x;
307
103k
   } else {
308
83.2M
      for (i=0;i<n;i++)
309
83.1M
         xx[i] = x[i];
310
9.82M
      for (i=0;i<overlap;i++)
311
9.74M
      {
312
9.74M
         opus_val16 w = COEF2VAL16(window[i]);
313
9.74M
         xx[i] = MULT16_16_Q15(x[i],w);
314
9.74M
         xx[n-i-1] = MULT16_16_Q15(x[n-i-1],w);
315
9.74M
      }
316
72.4k
      xptr = xx;
317
72.4k
   }
318
175k
   shift=0;
319
#ifdef FIXED_POINT
320
   {
321
      opus_val32 ac0;
322
      int ac0_shift = celt_ilog2(n + (n>>4));
323
      ac0 = 1+(n<<7);
324
      if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),ac0_shift);
325
      for(i=(n&1);i<n;i+=2)
326
      {
327
         ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),ac0_shift);
328
         ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),ac0_shift);
329
      }
330
      /* Consider the effect of rounding-to-nearest when scaling the signal. */
331
      ac0 += SHR32(ac0,7);
332
333
      shift = celt_ilog2(ac0)-30+ac0_shift+1;
334
      shift = (shift)/2;
335
      if (shift>0)
336
      {
337
         for(i=0;i<n;i++)
338
            xx[i] = PSHR32(xptr[i], shift);
339
         xptr = xx;
340
      } else
341
         shift = 0;
342
   }
343
#endif
344
175k
   celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1, arch);
345
2.50M
   for (k=0;k<=lag;k++)
346
2.32M
   {
347
25.0M
      for (i = k+fastN, d = 0; i < n; i++)
348
22.7M
         d = MAC16_16(d, xptr[i], xptr[i-k]);
349
2.32M
      ac[k] += d;
350
2.32M
   }
351
#ifdef FIXED_POINT
352
   shift = 2*shift;
353
   if (shift<=0)
354
      ac[0] += SHL32((opus_int32)1, -shift);
355
   if (ac[0] < 268435456)
356
   {
357
      int shift2 = 29 - EC_ILOG(ac[0]);
358
      for (i=0;i<=lag;i++)
359
         ac[i] = SHL32(ac[i], shift2);
360
      shift -= shift2;
361
   } else if (ac[0] >= 536870912)
362
   {
363
      int shift2=1;
364
      if (ac[0] >= 1073741824)
365
         shift2++;
366
      for (i=0;i<=lag;i++)
367
         ac[i] = SHR32(ac[i], shift2);
368
      shift += shift2;
369
   }
370
#endif
371
372
175k
   RESTORE_STACK;
373
175k
   return shift;
374
175k
}