Coverage Report

Created: 2025-12-31 07:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opus/silk/x86/NSQ_del_dec_avx2.c
Line
Count
Source
1
/***********************************************************************
2
Copyright (c) 2021 Google Inc.
3
Redistribution and use in source and binary forms, with or without
4
modification, are permitted provided that the following conditions
5
are met:
6
- Redistributions of source code must retain the above copyright notice,
7
this list of conditions and the following disclaimer.
8
- Redistributions in binary form must reproduce the above copyright
9
notice, this list of conditions and the following disclaimer in the
10
documentation and/or other materials provided with the distribution.
11
- Neither the name of Internet Society, IETF or IETF Trust, nor the
12
names of specific contributors, may be used to endorse or promote
13
products derived from this software without specific prior written
14
permission.
15
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
POSSIBILITY OF SUCH DAMAGE.
26
***********************************************************************/
27
28
#ifdef HAVE_CONFIG_H
29
#include "config.h"
30
#endif
31
32
#ifdef OPUS_CHECK_ASM
33
#include <string.h>
34
#endif
35
36
#include "opus_defines.h"
37
#include <immintrin.h>
38
39
#include "main.h"
40
#include "stack_alloc.h"
41
#include "NSQ.h"
42
#include "celt/x86/x86cpu.h"
43
44
/* Returns TRUE if all assumptions met */
45
static OPUS_INLINE int verify_assumptions(const silk_encoder_state *psEncC)
46
0
{
47
    /* This optimization is based on these assumptions        */
48
    /* These assumptions are fundamental and hence assert are */
49
    /* used. Should any assert triggers, we have to re-visit  */
50
    /* all related code to make sure it still functions the   */
51
    /* same as the C implementation.                          */
52
0
    silk_assert(MAX_DEL_DEC_STATES  <= 4      &&
53
0
                MAX_FRAME_LENGTH     % 4 == 0 &&
54
0
                MAX_SUB_FRAME_LENGTH % 4 == 0 &&
55
0
                LTP_MEM_LENGTH_MS    % 4 == 0 );
56
0
    silk_assert(psEncC->fs_kHz ==  8 ||
57
0
                psEncC->fs_kHz == 12 ||
58
0
                psEncC->fs_kHz == 16 );
59
0
    silk_assert(psEncC->nb_subfr <= MAX_NB_SUBFR &&
60
0
                psEncC->nb_subfr > 0             );
61
0
    silk_assert(psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES &&
62
0
                psEncC->nStatesDelayedDecision > 0                   );
63
0
    silk_assert(psEncC->ltp_mem_length == psEncC->fs_kHz * LTP_MEM_LENGTH_MS);
64
65
    /* Regressions were observed on certain AMD Zen CPUs when      */
66
    /* nStatesDelayedDecision is 1 or 2. Ideally we should detect  */
67
    /* these CPUs and enable this optimization on others; however, */
68
    /* there is no good way to do so under current OPUS framework. */
69
0
    return psEncC->nStatesDelayedDecision == 3 ||
70
0
           psEncC->nStatesDelayedDecision == 4;
71
0
}
72
73
/* Intrinsics not defined on MSVC */
74
#ifdef _MSC_VER
75
#include <intsafe.h>
76
static inline int __builtin_sadd_overflow(opus_int32 a, opus_int32 b, opus_int32* res)
77
{
78
    *res = a+b;
79
    return (*res ^ a) & (*res ^ b) & 0x80000000;
80
}
81
static inline int __builtin_ctz(unsigned int x)
82
{
83
    DWORD res = 0;
84
    return _BitScanForward(&res, x) ? res : 32;
85
}
86
#endif
87
88
static OPUS_INLINE __m128i silk_cvtepi64_epi32_high(__m256i num)
89
0
{
90
0
    return _mm256_castsi256_si128(_mm256_permutevar8x32_epi32(num, _mm256_set_epi32(0, 0, 0, 0, 7, 5, 3, 1)));
91
0
}
92
93
static OPUS_INLINE opus_int16 silk_sat16(opus_int32 num)
94
0
{
95
0
    num = num > silk_int16_MAX ? silk_int16_MAX : num;
96
0
    num = num < silk_int16_MIN ? silk_int16_MIN : num;
97
0
    return num;
98
0
}
99
100
static OPUS_INLINE opus_int32 silk_sar_round_32(opus_int32 a, int bits)
101
0
{
102
0
    silk_assert(bits > 0 && bits < 31);
103
0
    a += 1 << (bits-1);
104
0
    return a >> bits;
105
0
}
106
107
static OPUS_INLINE opus_int64 silk_sar_round_smulww(opus_int32 a, opus_int32 b, int bits)
108
0
{
109
0
#ifndef OPUS_CHECK_ASM
110
0
    opus_int64 t;
111
0
#endif
112
0
    silk_assert(bits > 0 && bits < 63);
113
#ifdef OPUS_CHECK_ASM
114
    return silk_RSHIFT_ROUND(silk_SMULWW(a, b), bits);
115
#else
116
    /* This code is more correct, but it won't overflow like the C code in some rare cases. */
117
0
    silk_assert(bits > 0 && bits < 63);
118
0
    t = ((opus_int64)a) * ((opus_int64)b);
119
0
    bits += 16;
120
0
    t += 1ull << (bits-1);
121
0
    return t >> bits;
122
0
#endif
123
0
}
124
125
static OPUS_INLINE opus_int32 silk_add_sat32(opus_int32 a, opus_int32 b)
126
0
{
127
0
    opus_int32 sum;
128
0
    if (__builtin_sadd_overflow(a, b, &sum))
129
0
    {
130
0
        return a >= 0 ? silk_int32_MAX : silk_int32_MIN;
131
0
    }
132
0
    return sum;
133
0
}
134
135
static OPUS_INLINE __m128i silk_mm_srai_round_epi32(__m128i a, int bits)
136
0
{
137
0
    silk_assert(bits > 0 && bits < 31);
138
0
    return _mm_srai_epi32(_mm_add_epi32(a, _mm_set1_epi32(1 << (bits - 1))), bits);
139
0
}
140
141
/* add/subtract with output saturated */
142
static OPUS_INLINE __m128i silk_mm_add_sat_epi32(__m128i a, __m128i b)
143
0
{
144
0
    __m128i r = _mm_add_epi32(a, b);
145
0
    __m128i OF = _mm_and_si128(_mm_xor_si128(a, r), _mm_xor_si128(b, r));           /* OF = (sum ^ a) & (sum ^ b)   */
146
0
    __m128i SAT = _mm_add_epi32(_mm_srli_epi32(a, 31), _mm_set1_epi32(0x7FFFFFFF)); /* SAT = (a >> 31) + 0x7FFFFFFF */
147
0
    return _mm_blendv_epi8(r, SAT, _mm_srai_epi32(OF, 31));
148
0
}
149
static OPUS_INLINE __m128i silk_mm_sub_sat_epi32(__m128i a, __m128i b)
150
0
{
151
0
    __m128i r = _mm_sub_epi32(a, b);
152
0
    __m128i OF = _mm_andnot_si128(_mm_xor_si128(b, r), _mm_xor_si128(a, r));        /* OF = (sum ^ a) & (sum ^ ~b) = (sum ^ a) & ~(sum ^ b) */
153
0
    __m128i SAT = _mm_add_epi32(_mm_srli_epi32(a, 31), _mm_set1_epi32(0x7FFFFFFF)); /* SAT = (a >> 31) + 0x7FFFFFFF                         */
154
0
    return _mm_blendv_epi8(r, SAT, _mm_srai_epi32(OF, 31));
155
0
}
156
static OPUS_INLINE __m256i silk_mm256_sub_sat_epi32(__m256i a, __m256i b)
157
0
{
158
0
    __m256i r = _mm256_sub_epi32(a, b);
159
0
    __m256i OF = _mm256_andnot_si256(_mm256_xor_si256(b, r), _mm256_xor_si256(a, r));        /* OF = (sum ^ a) & (sum ^ ~b) = (sum ^ a) & ~(sum ^ b) */
160
0
    __m256i SAT = _mm256_add_epi32(_mm256_srli_epi32(a, 31), _mm256_set1_epi32(0x7FFFFFFF)); /* SAT = (a >> 31) + 0x7FFFFFFF                         */
161
0
    return _mm256_blendv_epi8(r, SAT, _mm256_srai_epi32(OF, 31));
162
0
}
163
164
static OPUS_INLINE __m128i silk_mm_limit_epi32(__m128i num, opus_int32 limit1, opus_int32 limit2)
165
0
{
166
0
    opus_int32 lo = limit1 < limit2 ? limit1 : limit2;
167
0
    opus_int32 hi = limit1 > limit2 ? limit1 : limit2;
168
169
0
    num = _mm_min_epi32(num, _mm_set1_epi32(hi));
170
0
    num = _mm_max_epi32(num, _mm_set1_epi32(lo));
171
0
    return num;
172
0
}
173
174
/* cond < 0 ? -num : num */
175
static OPUS_INLINE __m128i silk_mm_sign_epi32(__m128i num, __m128i cond)
176
0
{
177
0
    return _mm_sign_epi32(num, _mm_or_si128(cond, _mm_set1_epi32(1)));
178
0
}
179
static OPUS_INLINE __m256i silk_mm256_sign_epi32(__m256i num, __m256i cond)
180
0
{
181
0
    return _mm256_sign_epi32(num, _mm256_or_si256(cond, _mm256_set1_epi32(1)));
182
0
}
183
184
/* (a32 * b32) >> 16 */
185
static OPUS_INLINE __m128i silk_mm_smulww_epi32(__m128i a, opus_int32 b)
186
0
{
187
0
    return silk_cvtepi64_epi32_high(_mm256_slli_epi64(_mm256_mul_epi32(_mm256_cvtepi32_epi64(a), _mm256_set1_epi32(b)), 16));
188
0
}
189
190
/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
191
static OPUS_INLINE __m128i silk_mm_smulwb_epi32(__m128i a, opus_int32 b)
192
0
{
193
0
    return silk_cvtepi64_epi32_high(_mm256_mul_epi32(_mm256_cvtepi32_epi64(a), _mm256_set1_epi32((opus_uint32)b<<16)));
194
0
}
195
196
/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */
197
static OPUS_INLINE __m256i silk_mm256_smulbb_epi32(__m256i a, __m256i b)
198
0
{
199
0
    const char FF = (char)0xFF;
200
0
    __m256i msk = _mm256_set_epi8(
201
0
        FF, FF, FF, FF, FF, FF, FF, FF, 13, 12, 9, 8, 5, 4, 1, 0,
202
0
        FF, FF, FF, FF, FF, FF, FF, FF, 13, 12, 9, 8, 5, 4, 1, 0);
203
0
    __m256i lo = _mm256_mullo_epi16(a, b);
204
0
    __m256i hi = _mm256_mulhi_epi16(a, b);
205
0
    lo = _mm256_shuffle_epi8(lo, msk);
206
0
    hi = _mm256_shuffle_epi8(hi, msk);
207
0
    return _mm256_unpacklo_epi16(lo, hi);
208
0
}
209
210
static OPUS_INLINE __m256i silk_mm256_reverse_epi32(__m256i v)
211
0
{
212
0
    v = _mm256_shuffle_epi32(v, 0x1B);
213
0
    v = _mm256_permute4x64_epi64(v, 0x4E);
214
0
    return v;
215
0
}
216
217
static OPUS_INLINE opus_int32 silk_mm256_hsum_epi32(__m256i v)
218
0
{
219
0
    __m128i sum = _mm_add_epi32(_mm256_extracti128_si256(v, 1), _mm256_extracti128_si256(v, 0));
220
0
    sum = _mm_add_epi32(sum, _mm_shuffle_epi32(sum, 0x4E));
221
0
    sum = _mm_add_epi32(sum, _mm_shuffle_epi32(sum, 0xB1));
222
0
    return _mm_cvtsi128_si32(sum);
223
0
}
224
225
static OPUS_INLINE __m128i silk_mm_hmin_epi32(__m128i num)
226
0
{
227
0
    num = _mm_min_epi32(num, _mm_shuffle_epi32(num, 0x4E)); /* 0123 -> 2301 */
228
0
    num = _mm_min_epi32(num, _mm_shuffle_epi32(num, 0xB1)); /* 0123 -> 1032 */
229
0
    return num;
230
0
}
231
232
static OPUS_INLINE __m128i silk_mm_hmax_epi32(__m128i num)
233
0
{
234
0
    num = _mm_max_epi32(num, _mm_shuffle_epi32(num, 0x4E)); /* 0123 -> 2310 */
235
0
    num = _mm_max_epi32(num, _mm_shuffle_epi32(num, 0xB1)); /* 0123 -> 1032 */
236
0
    return num;
237
0
}
238
239
static OPUS_INLINE __m128i silk_mm_mask_hmin_epi32(__m128i num, __m128i mask)
240
0
{
241
0
    num = _mm_blendv_epi8(num, _mm_set1_epi32(silk_int32_MAX), mask);
242
0
    return silk_mm_hmin_epi32(num);
243
0
}
244
245
static OPUS_INLINE __m128i silk_mm_mask_hmax_epi32(__m128i num, __m128i mask)
246
0
{
247
0
    num = _mm_blendv_epi8(num, _mm_set1_epi32(silk_int32_MIN), mask);
248
0
    return silk_mm_hmax_epi32(num);
249
0
}
250
251
static OPUS_INLINE __m128i silk_mm256_rand_epi32(__m128i seed)
252
0
{
253
0
    seed = _mm_mullo_epi32(seed, _mm_set1_epi32(RAND_MULTIPLIER));
254
0
    seed = _mm_add_epi32(seed, _mm_set1_epi32(RAND_INCREMENT));
255
0
    return seed;
256
0
}
257
258
static OPUS_INLINE opus_int32 silk_index_of_first_equal_epi32(__m128i a, __m128i b)
259
0
{
260
0
    unsigned int mask = _mm_movemask_epi8(_mm_cmpeq_epi32(a, b)) & 0x1111;
261
0
    silk_assert(mask != 0);
262
0
    return __builtin_ctz(mask) >> 2;
263
0
}
264
265
static __m128i silk_index_to_selector(opus_int32 index)
266
0
{
267
0
    silk_assert(index < 4);
268
0
    index <<= 2;
269
0
    return _mm_set_epi8(
270
0
        index + 3, index + 2, index + 1, index + 0,
271
0
        index + 3, index + 2, index + 1, index + 0,
272
0
        index + 3, index + 2, index + 1, index + 0,
273
0
        index + 3, index + 2, index + 1, index + 0);
274
0
}
275
276
static opus_int32 silk_select_winner(__m128i num, __m128i selector)
277
0
{
278
0
    return _mm_cvtsi128_si32(_mm_shuffle_epi8(num, selector));
279
0
}
280
281
typedef struct
282
{
283
    __m128i RandState;
284
    __m128i Q_Q10;
285
    __m128i Xq_Q14;
286
    __m128i Pred_Q15;
287
    __m128i Shape_Q14;
288
} NSQ_del_dec_sample_struct;
289
290
typedef struct
291
{
292
    __m128i sLPC_Q14[MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH];
293
    __m128i LF_AR_Q14;
294
    __m128i Seed;
295
    __m128i SeedInit;
296
    __m128i RD_Q10;
297
    __m128i Diff_Q14;
298
    __m128i sAR2_Q14[MAX_SHAPE_LPC_ORDER];
299
    NSQ_del_dec_sample_struct Samples[DECISION_DELAY];
300
} NSQ_del_dec_struct;
301
302
static OPUS_INLINE void silk_nsq_del_dec_scale_states_avx2(
303
    const silk_encoder_state *psEncC,          /* I    Encoder State                   */
304
    silk_nsq_state *NSQ,                       /* I/O  NSQ state                       */
305
    NSQ_del_dec_struct *psDelDec,              /* I/O  Delayed decision states         */
306
    const opus_int16 x16[],                    /* I    Input                           */
307
    opus_int32 x_sc_Q10[MAX_SUB_FRAME_LENGTH], /* O    Input scaled with 1/Gain in Q10 */
308
    const opus_int16 sLTP[],                   /* I    Re-whitened LTP state in Q0     */
309
    opus_int32 sLTP_Q15[],                     /* O    LTP state matching scaled input */
310
    opus_int subfr,                            /* I    Subframe number                 */
311
    const opus_int LTP_scale_Q14,              /* I    LTP state scaling               */
312
    const opus_int32 Gains_Q16[MAX_NB_SUBFR],  /* I                                    */
313
    const opus_int pitchL[MAX_NB_SUBFR],       /* I    Pitch lag                       */
314
    const opus_int signal_type,                /* I    Signal type                     */
315
    const opus_int decisionDelay               /* I    Decision delay                  */
316
);
317
318
/*******************************************/
319
/* LPC analysis filter                     */
320
/* NB! State is kept internally and the    */
321
/* filter always starts with zero state    */
322
/* first d output samples are set to zero  */
323
/*******************************************/
324
static OPUS_INLINE void silk_LPC_analysis_filter_avx2(
325
    opus_int16                  *out,               /* O    Output signal                           */
326
    const opus_int16            *in,                /* I    Input signal                            */
327
    const opus_int16            *B,                 /* I    MA prediction coefficients, Q12 [order] */
328
    const opus_int32            len,                /* I    Signal length                           */
329
    const opus_int32            order               /* I    Filter order                            */
330
);
331
332
/******************************************/
333
/* Noise shape quantizer for one subframe */
334
/******************************************/
335
static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_avx2(
336
    silk_nsq_state *NSQ,                        /* I/O  NSQ state                          */
337
    NSQ_del_dec_struct psDelDec[],              /* I/O  Delayed decision states            */
338
    opus_int signalType,                        /* I    Signal type                        */
339
    const opus_int32 x_Q10[],                   /* I                                       */
340
    opus_int8 pulses[],                         /* O                                       */
341
    opus_int16 xq[],                            /* O                                       */
342
    opus_int32 sLTP_Q15[],                      /* I/O  LTP filter state                   */
343
    opus_int32 delayedGain_Q10[DECISION_DELAY], /* I/O  Gain delay buffer                  */
344
    const opus_int16 a_Q12[],                   /* I    Short term prediction coefs        */
345
    const opus_int16 b_Q14[],                   /* I    Long term prediction coefs         */
346
    const opus_int16 AR_shp_Q13[],              /* I    Noise shaping coefs                */
347
    opus_int lag,                               /* I    Pitch lag                          */
348
    opus_int32 HarmShapeFIRPacked_Q14,          /* I                                       */
349
    opus_int Tilt_Q14,                          /* I    Spectral tilt                      */
350
    opus_int32 LF_shp_Q14,                      /* I                                       */
351
    opus_int32 Gain_Q16,                        /* I                                       */
352
    opus_int Lambda_Q10,                        /* I                                       */
353
    opus_int offset_Q10,                        /* I                                       */
354
    opus_int length,                            /* I    Input length                       */
355
    opus_int subfr,                             /* I    Subframe number                    */
356
    opus_int shapingLPCOrder,                   /* I    Shaping LPC filter order           */
357
    opus_int predictLPCOrder,                   /* I    Prediction filter order            */
358
    opus_int warping_Q16,                       /* I                                       */
359
    __m128i MaskDelDec,                         /* I    Mask of states in decision tree    */
360
    opus_int *smpl_buf_idx,                     /* I/O  Index to newest samples in buffers */
361
    opus_int decisionDelay                      /* I                                       */
362
);
363
364
void silk_NSQ_del_dec_avx2(
365
    const silk_encoder_state *psEncC,                            /* I    Encoder State               */
366
    silk_nsq_state *NSQ,                                         /* I/O  NSQ state                   */
367
    SideInfoIndices *psIndices,                                  /* I/O  Quantization Indices        */
368
    const opus_int16 x16[],                                      /* I    Input                       */
369
    opus_int8 pulses[],                                          /* O    Quantized pulse signal      */
370
    const opus_int16 *PredCoef_Q12,                              /* I    Short term prediction coefs */
371
    const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR],      /* I    Long term prediction coefs  */
372
    const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER], /* I    Noise shaping coefs         */
373
    const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR],              /* I    Long term shaping coefs     */
374
    const opus_int Tilt_Q14[MAX_NB_SUBFR],                       /* I    Spectral tilt               */
375
    const opus_int32 LF_shp_Q14[MAX_NB_SUBFR],                   /* I    Low frequency shaping coefs */
376
    const opus_int32 Gains_Q16[MAX_NB_SUBFR],                    /* I    Quantization step sizes     */
377
    const opus_int32 pitchL[MAX_NB_SUBFR],                       /* I    Pitch lags                  */
378
    const opus_int Lambda_Q10,                                   /* I    Rate/distortion tradeoff    */
379
    const opus_int LTP_scale_Q14                                 /* I    LTP state scaling           */
380
)
381
0
{
382
#ifdef OPUS_CHECK_ASM
383
    silk_nsq_state NSQ_c;
384
    SideInfoIndices psIndices_c;
385
    opus_int8 pulses_c[MAX_FRAME_LENGTH];
386
    const opus_int8 *const pulses_a = pulses;
387
388
    silk_memcpy(&NSQ_c, NSQ, sizeof(NSQ_c));
389
    silk_memcpy(&psIndices_c, psIndices, sizeof(psIndices_c));
390
    silk_memcpy(pulses_c, pulses, sizeof(pulses_c));
391
    silk_NSQ_del_dec_c(psEncC, &NSQ_c, &psIndices_c, x16, pulses_c, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16,
392
                       pitchL, Lambda_Q10, LTP_scale_Q14);
393
#endif
394
395
0
    if (!verify_assumptions(psEncC))
396
0
    {
397
0
        silk_NSQ_del_dec_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14);
398
0
        return;
399
0
    }
400
401
0
    opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
402
0
    opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
403
0
    const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
404
0
    opus_int16 *pxq;
405
0
    VARDECL(opus_int32, sLTP_Q15);
406
0
    VARDECL(opus_int16, sLTP);
407
0
    opus_int32 HarmShapeFIRPacked_Q14;
408
0
    opus_int offset_Q10;
409
0
    opus_int32 Gain_Q10;
410
0
    opus_int32 x_sc_Q10[MAX_SUB_FRAME_LENGTH];
411
0
    opus_int32 delayedGain_Q10[DECISION_DELAY];
412
0
    NSQ_del_dec_struct psDelDec = {0};
413
0
    NSQ_del_dec_sample_struct *psSample;
414
0
    __m128i RDmin_Q10, MaskDelDec, Winner_selector;
415
0
    SAVE_STACK;
416
417
0
    MaskDelDec = _mm_cvtepi8_epi32(_mm_cvtsi32_si128(0xFFFFFF00ul << ((psEncC->nStatesDelayedDecision - 1) << 3)));
418
419
    /* Set unvoiced lag to the previous one, overwrite later for voiced */
420
0
    lag = NSQ->lagPrev;
421
422
0
    silk_assert(NSQ->prev_gain_Q16 != 0);
423
0
    psDelDec.Seed = _mm_and_si128(
424
0
        _mm_add_epi32(_mm_set_epi32(3, 2, 1, 0), _mm_set1_epi32(psIndices->Seed)),
425
0
        _mm_set1_epi32(3));
426
0
    psDelDec.SeedInit = psDelDec.Seed;
427
0
    psDelDec.RD_Q10 = _mm_setzero_si128();
428
0
    psDelDec.LF_AR_Q14 = _mm_set1_epi32(NSQ->sLF_AR_shp_Q14);
429
0
    psDelDec.Diff_Q14 = _mm_set1_epi32(NSQ->sDiff_shp_Q14);
430
0
    psDelDec.Samples[0].Shape_Q14 = _mm_set1_epi32(NSQ->sLTP_shp_Q14[psEncC->ltp_mem_length - 1]);
431
0
    for (i = 0; i < NSQ_LPC_BUF_LENGTH; i++)
432
0
    {
433
0
        psDelDec.sLPC_Q14[i] = _mm_set1_epi32(NSQ->sLPC_Q14[i]);
434
0
    }
435
0
    for (i = 0; i < MAX_SHAPE_LPC_ORDER; i++)
436
0
    {
437
0
        psDelDec.sAR2_Q14[i] = _mm_set1_epi32(NSQ->sAR2_Q14[i]);
438
0
    }
439
440
0
    offset_Q10 = silk_Quantization_Offsets_Q10[psIndices->signalType >> 1][psIndices->quantOffsetType];
441
0
    smpl_buf_idx = 0; /* index of oldest samples */
442
443
0
    decisionDelay = silk_min_int(DECISION_DELAY, psEncC->subfr_length);
444
445
    /* For voiced frames limit the decision delay to lower than the pitch lag */
446
0
    if (psIndices->signalType == TYPE_VOICED)
447
0
    {
448
0
        for (k = 0; k < psEncC->nb_subfr; k++)
449
0
        {
450
0
            decisionDelay = silk_min_int(decisionDelay, pitchL[k] - LTP_ORDER / 2 - 1);
451
0
        }
452
0
    }
453
0
    else
454
0
    {
455
0
        if (lag > 0)
456
0
        {
457
0
            decisionDelay = silk_min_int(decisionDelay, lag - LTP_ORDER / 2 - 1);
458
0
        }
459
0
    }
460
461
0
    if (psIndices->NLSFInterpCoef_Q2 == 4)
462
0
    {
463
0
        LSF_interpolation_flag = 0;
464
0
    }
465
0
    else
466
0
    {
467
0
        LSF_interpolation_flag = 1;
468
0
    }
469
470
0
    ALLOC(sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32);
471
0
    ALLOC(sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16);
472
    /* Set up pointers to start of sub frame */
473
0
    pxq = &NSQ->xq[psEncC->ltp_mem_length];
474
0
    NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
475
0
    NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
476
0
    subfr = 0;
477
0
    for (k = 0; k < psEncC->nb_subfr; k++)
478
0
    {
479
0
        A_Q12 = &PredCoef_Q12[((k >> 1) | (1 ^ LSF_interpolation_flag)) * MAX_LPC_ORDER];
480
0
        B_Q14 = &LTPCoef_Q14[k * LTP_ORDER];
481
0
        AR_shp_Q13 = &AR_Q13[k * MAX_SHAPE_LPC_ORDER];
482
483
        /* Noise shape parameters */
484
0
        silk_assert(HarmShapeGain_Q14[k] >= 0);
485
0
        HarmShapeFIRPacked_Q14  =                          silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
486
0
        HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
487
488
0
        NSQ->rewhite_flag = 0;
489
0
        if (psIndices->signalType == TYPE_VOICED)
490
0
        {
491
            /* Voiced */
492
0
            lag = pitchL[k];
493
494
            /* Re-whitening */
495
0
            if ((k & (3 ^ (LSF_interpolation_flag << 1))) == 0)
496
0
            {
497
0
                if (k == 2)
498
0
                {
499
                    /* RESET DELAYED DECISIONS */
500
                    /* Find winner */
501
0
                    RDmin_Q10 = silk_mm_mask_hmin_epi32(psDelDec.RD_Q10, MaskDelDec);
502
0
                    Winner_ind = silk_index_of_first_equal_epi32(RDmin_Q10, psDelDec.RD_Q10);
503
0
                    Winner_selector = silk_index_to_selector(Winner_ind);
504
0
                    psDelDec.RD_Q10 = _mm_add_epi32(
505
0
                        psDelDec.RD_Q10,
506
0
                        _mm_blendv_epi8(
507
0
                            _mm_set1_epi32(silk_int32_MAX >> 4),
508
0
                            _mm_setzero_si128(),
509
0
                            _mm_cvtepi8_epi32(_mm_cvtsi32_si128(0xFFU << (unsigned)(Winner_ind << 3)))));
510
511
                    /* Copy final part of signals from winner state to output and long-term filter states */
512
0
                    last_smple_idx = smpl_buf_idx + decisionDelay;
513
0
                    for (i = 0; i < decisionDelay; i++)
514
0
                    {
515
0
                        last_smple_idx = (last_smple_idx + DECISION_DELAY - 1) % DECISION_DELAY;
516
0
                        psSample = &psDelDec.Samples[last_smple_idx];
517
0
                        pulses[i - decisionDelay] =
518
0
                            (opus_int8)silk_sar_round_32(silk_select_winner(psSample->Q_Q10, Winner_selector), 10);
519
0
                        pxq[i - decisionDelay] =
520
0
                            silk_sat16((opus_int32)silk_sar_round_smulww(silk_select_winner(psSample->Xq_Q14, Winner_selector), Gains_Q16[1], 14));
521
0
                        NSQ->sLTP_shp_Q14[NSQ->sLTP_shp_buf_idx - decisionDelay + i] =
522
0
                            silk_select_winner(psSample->Shape_Q14, Winner_selector);
523
0
                    }
524
525
0
                    subfr = 0;
526
0
                }
527
528
                /* Rewhiten with new A coefs */
529
0
                start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
530
0
                silk_assert(start_idx > 0);
531
532
0
                silk_LPC_analysis_filter_avx2(&sLTP[start_idx], &NSQ->xq[start_idx + k * psEncC->subfr_length],
533
0
                                              A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder);
534
535
0
                NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
536
0
                NSQ->rewhite_flag = 1;
537
0
            }
538
0
        }
539
540
0
        silk_nsq_del_dec_scale_states_avx2(psEncC, NSQ, &psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k,
541
0
                                           LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay);
542
543
0
        silk_noise_shape_quantizer_del_dec_avx2(NSQ, &psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
544
0
                                                delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[k], LF_shp_Q14[k],
545
0
                                                Gains_Q16[k], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
546
0
                                                psEncC->predictLPCOrder, psEncC->warping_Q16, MaskDelDec, &smpl_buf_idx, decisionDelay);
547
548
0
        x16 += psEncC->subfr_length;
549
0
        pulses += psEncC->subfr_length;
550
0
        pxq += psEncC->subfr_length;
551
0
    }
552
553
    /* Find winner */
554
0
    RDmin_Q10 = silk_mm_mask_hmin_epi32(psDelDec.RD_Q10, MaskDelDec);
555
0
    Winner_selector = silk_index_to_selector(silk_index_of_first_equal_epi32(RDmin_Q10, psDelDec.RD_Q10));
556
557
    /* Copy final part of signals from winner state to output and long-term filter states */
558
0
    psIndices->Seed = silk_select_winner(psDelDec.SeedInit, Winner_selector);
559
0
    last_smple_idx = smpl_buf_idx + decisionDelay;
560
0
    Gain_Q10 = Gains_Q16[psEncC->nb_subfr - 1] >> 6;
561
0
    for (i = 0; i < decisionDelay; i++)
562
0
    {
563
0
        last_smple_idx = (last_smple_idx + DECISION_DELAY - 1) % DECISION_DELAY;
564
0
        psSample = &psDelDec.Samples[last_smple_idx];
565
566
0
        pulses[i - decisionDelay] =
567
0
            (opus_int8)silk_sar_round_32(silk_select_winner(psSample->Q_Q10, Winner_selector), 10);
568
0
        pxq[i - decisionDelay] =
569
0
            silk_sat16((opus_int32)silk_sar_round_smulww(silk_select_winner(psSample->Xq_Q14, Winner_selector), Gain_Q10, 8));
570
0
        NSQ->sLTP_shp_Q14[NSQ->sLTP_shp_buf_idx - decisionDelay + i] =
571
0
            silk_select_winner(psSample->Shape_Q14, Winner_selector);
572
0
    }
573
0
    for (i = 0; i < NSQ_LPC_BUF_LENGTH; i++)
574
0
    {
575
0
        NSQ->sLPC_Q14[i] = silk_select_winner(psDelDec.sLPC_Q14[i], Winner_selector);
576
0
    }
577
0
    for (i = 0; i < MAX_SHAPE_LPC_ORDER; i++)
578
0
    {
579
0
        NSQ->sAR2_Q14[i] = silk_select_winner(psDelDec.sAR2_Q14[i], Winner_selector);
580
0
    }
581
582
    /* Update states */
583
0
    NSQ->sLF_AR_shp_Q14 = silk_select_winner(psDelDec.LF_AR_Q14, Winner_selector);
584
0
    NSQ->sDiff_shp_Q14 = silk_select_winner(psDelDec.Diff_Q14, Winner_selector);
585
0
    NSQ->lagPrev = pitchL[psEncC->nb_subfr - 1];
586
587
    /* Save quantized speech signal */
588
0
    silk_memmove(NSQ->xq, &NSQ->xq[psEncC->frame_length], psEncC->ltp_mem_length * sizeof(opus_int16));
589
0
    silk_memmove(NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[psEncC->frame_length], psEncC->ltp_mem_length * sizeof(opus_int32));
590
591
#ifdef OPUS_CHECK_ASM
592
    silk_assert(!memcmp(&NSQ_c, NSQ, sizeof(NSQ_c)));
593
    silk_assert(!memcmp(&psIndices_c, psIndices, sizeof(psIndices_c)));
594
    silk_assert(!memcmp(pulses_c, pulses_a, sizeof(pulses_c)));
595
#endif
596
597
0
    RESTORE_STACK;
598
0
}
599
600
static OPUS_INLINE __m128i silk_noise_shape_quantizer_short_prediction_x4(const __m128i *buf32, const opus_int16 *coef16, opus_int order)
601
0
{
602
0
    __m256i out;
603
0
    silk_assert(order == 10 || order == 16);
604
605
    /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
606
0
    out = _mm256_set1_epi32(order >> 1);
607
0
    out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-0]), _mm256_set1_epi32(silk_LSHIFT(coef16[0], 16)))); /* High DWORD */
608
0
    out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-1]), _mm256_set1_epi32(silk_LSHIFT(coef16[1], 16)))); /* High DWORD */
609
0
    out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-2]), _mm256_set1_epi32(silk_LSHIFT(coef16[2], 16)))); /* High DWORD */
610
0
    out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-3]), _mm256_set1_epi32(silk_LSHIFT(coef16[3], 16)))); /* High DWORD */
611
0
    out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-4]), _mm256_set1_epi32(silk_LSHIFT(coef16[4], 16)))); /* High DWORD */
612
0
    out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-5]), _mm256_set1_epi32(silk_LSHIFT(coef16[5], 16)))); /* High DWORD */
613
0
    out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-6]), _mm256_set1_epi32(silk_LSHIFT(coef16[6], 16)))); /* High DWORD */
614
0
    out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-7]), _mm256_set1_epi32(silk_LSHIFT(coef16[7], 16)))); /* High DWORD */
615
0
    out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-8]), _mm256_set1_epi32(silk_LSHIFT(coef16[8], 16)))); /* High DWORD */
616
0
    out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-9]), _mm256_set1_epi32(silk_LSHIFT(coef16[9], 16)))); /* High DWORD */
617
618
0
    if (order == 16)
619
0
    {
620
0
        out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-10]), _mm256_set1_epi32(silk_LSHIFT(coef16[10], 16)))); /* High DWORD */
621
0
        out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-11]), _mm256_set1_epi32(silk_LSHIFT(coef16[11], 16)))); /* High DWORD */
622
0
        out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-12]), _mm256_set1_epi32(silk_LSHIFT(coef16[12], 16)))); /* High DWORD */
623
0
        out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-13]), _mm256_set1_epi32(silk_LSHIFT(coef16[13], 16)))); /* High DWORD */
624
0
        out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-14]), _mm256_set1_epi32(silk_LSHIFT(coef16[14], 16)))); /* High DWORD */
625
0
        out = _mm256_add_epi32(out, _mm256_mul_epi32(_mm256_cvtepi32_epi64(buf32[-15]), _mm256_set1_epi32(silk_LSHIFT(coef16[15], 16)))); /* High DWORD */
626
0
    }
627
0
    return silk_cvtepi64_epi32_high(out);
628
0
}
629
630
/******************************************/
631
/* Noise shape quantizer for one subframe */
632
/******************************************/
633
static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_avx2(
634
    silk_nsq_state *NSQ,                        /* I/O  NSQ state                          */
635
    NSQ_del_dec_struct *psDelDec,               /* I/O  Delayed decision states            */
636
    opus_int signalType,                        /* I    Signal type                        */
637
    const opus_int32 x_Q10[],                   /* I                                       */
638
    opus_int8 pulses[],                         /* O                                       */
639
    opus_int16 xq[],                            /* O                                       */
640
    opus_int32 sLTP_Q15[],                      /* I/O  LTP filter state                   */
641
    opus_int32 delayedGain_Q10[DECISION_DELAY], /* I/O  Gain delay buffer                  */
642
    const opus_int16 a_Q12[],                   /* I    Short term prediction coefs        */
643
    const opus_int16 b_Q14[],                   /* I    Long term prediction coefs         */
644
    const opus_int16 AR_shp_Q13[],              /* I    Noise shaping coefs                */
645
    opus_int lag,                               /* I    Pitch lag                          */
646
    opus_int32 HarmShapeFIRPacked_Q14,          /* I                                       */
647
    opus_int Tilt_Q14,                          /* I    Spectral tilt                      */
648
    opus_int32 LF_shp_Q14,                      /* I                                       */
649
    opus_int32 Gain_Q16,                        /* I                                       */
650
    opus_int Lambda_Q10,                        /* I                                       */
651
    opus_int offset_Q10,                        /* I                                       */
652
    opus_int length,                            /* I    Input length                       */
653
    opus_int subfr,                             /* I    Subframe number                    */
654
    opus_int shapingLPCOrder,                   /* I    Shaping LPC filter order           */
655
    opus_int predictLPCOrder,                   /* I    Prediction filter order            */
656
    opus_int warping_Q16,                       /* I                                       */
657
    __m128i MaskDelDec,                         /* I    Mask of states in decision tree    */
658
    opus_int *smpl_buf_idx,                     /* I/O  Index to newest samples in buffers */
659
    opus_int decisionDelay                      /* I                                       */
660
)
661
0
{
662
0
    int i;
663
0
    opus_int32 *shp_lag_ptr = &NSQ->sLTP_shp_Q14[NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2];
664
0
    opus_int32 *pred_lag_ptr = &sLTP_Q15[NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2];
665
0
    opus_int32 Gain_Q10 = Gain_Q16 >> 6;
666
667
0
    for (i = 0; i < length; i++)
668
0
    {
669
        /* Perform common calculations used in all states */
670
        /* NSQ_sample_struct */
671
        /* Low  128 bits => 1st set */
672
        /* High 128 bits => 2nd set */
673
0
        int j;
674
0
        __m256i SS_Q_Q10;
675
0
        __m256i SS_RD_Q10;
676
0
        __m256i SS_xq_Q14;
677
0
        __m256i SS_LF_AR_Q14;
678
0
        __m256i SS_Diff_Q14;
679
0
        __m256i SS_sLTP_shp_Q14;
680
0
        __m256i SS_LPC_exc_Q14;
681
0
        __m256i exc_Q14;
682
0
        __m256i q_Q10, rr_Q10, rd_Q10;
683
0
        __m256i mask;
684
0
        __m128i LPC_pred_Q14, n_AR_Q14;
685
0
        __m128i RDmin_Q10, RDmax_Q10;
686
0
        __m128i n_LF_Q14;
687
0
        __m128i r_Q10, q1_Q0, q1_Q10, q2_Q10;
688
0
        __m128i Winner_rand_state, Winner_selector;
689
0
        __m128i tmp0, tmp1;
690
0
        NSQ_del_dec_sample_struct *psLastSample, *psSample;
691
0
        opus_int32 RDmin_ind, RDmax_ind, last_smple_idx;
692
0
        opus_int32 LTP_pred_Q14, n_LTP_Q14;
693
694
        /* Long-term prediction */
695
0
        if (signalType == TYPE_VOICED)
696
0
        {
697
            /* Unrolled loop */
698
            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
699
0
            LTP_pred_Q14 = 2;
700
0
            LTP_pred_Q14 += silk_SMULWB(pred_lag_ptr[-0], b_Q14[0]);
701
0
            LTP_pred_Q14 += silk_SMULWB(pred_lag_ptr[-1], b_Q14[1]);
702
0
            LTP_pred_Q14 += silk_SMULWB(pred_lag_ptr[-2], b_Q14[2]);
703
0
            LTP_pred_Q14 += silk_SMULWB(pred_lag_ptr[-3], b_Q14[3]);
704
0
            LTP_pred_Q14 += silk_SMULWB(pred_lag_ptr[-4], b_Q14[4]);
705
0
            LTP_pred_Q14 = silk_LSHIFT(LTP_pred_Q14, 1); /* Q13 -> Q14 */
706
0
            pred_lag_ptr++;
707
0
        }
708
0
        else
709
0
        {
710
0
            LTP_pred_Q14 = 0;
711
0
        }
712
713
        /* Long-term shaping */
714
0
        if (lag > 0)
715
0
        {
716
            /* Symmetric, packed FIR coefficients */
717
0
            n_LTP_Q14 = silk_add_sat32(shp_lag_ptr[0], shp_lag_ptr[-2]);
718
0
            n_LTP_Q14 = silk_SMULWB(n_LTP_Q14, HarmShapeFIRPacked_Q14);
719
0
            n_LTP_Q14 = n_LTP_Q14 + silk_SMULWT(shp_lag_ptr[-1], HarmShapeFIRPacked_Q14);
720
0
            n_LTP_Q14 = LTP_pred_Q14 - (silk_LSHIFT(n_LTP_Q14, 2)); /* Q12 -> Q14 */
721
0
            shp_lag_ptr++;
722
0
        }
723
0
        else
724
0
        {
725
0
            n_LTP_Q14 = 0;
726
0
        }
727
728
        /* BEGIN Updating Delayed Decision States */
729
730
        /* Generate dither */
731
0
        psDelDec->Seed = silk_mm256_rand_epi32(psDelDec->Seed);
732
733
        /* Short-term prediction */
734
0
        LPC_pred_Q14 = silk_noise_shape_quantizer_short_prediction_x4(&psDelDec->sLPC_Q14[NSQ_LPC_BUF_LENGTH - 1 + i], a_Q12, predictLPCOrder);
735
0
        LPC_pred_Q14 = _mm_slli_epi32(LPC_pred_Q14, 4); /* Q10 -> Q14 */
736
737
        /* Noise shape feedback */
738
0
        silk_assert(shapingLPCOrder > 0);
739
0
        silk_assert((shapingLPCOrder & 1) == 0); /* check that order is even */
740
        /* Output of lowpass section */
741
0
        tmp0 = _mm_add_epi32(psDelDec->Diff_Q14, silk_mm_smulwb_epi32(psDelDec->sAR2_Q14[0], warping_Q16));
742
0
        n_AR_Q14 = _mm_set1_epi32(shapingLPCOrder >> 1);
743
0
        for (j = 0; j < shapingLPCOrder - 1; j++)
744
0
        {
745
            /* Output of allpass section */
746
0
            tmp1 = psDelDec->sAR2_Q14[j];
747
0
            psDelDec->sAR2_Q14[j] = tmp0;
748
0
            n_AR_Q14 = _mm_add_epi32(n_AR_Q14, silk_mm_smulwb_epi32(tmp0, AR_shp_Q13[j]));
749
0
            tmp0 = _mm_add_epi32(tmp1, silk_mm_smulwb_epi32(_mm_sub_epi32(psDelDec->sAR2_Q14[j + 1], tmp0), warping_Q16));
750
0
        }
751
0
        psDelDec->sAR2_Q14[shapingLPCOrder - 1] = tmp0;
752
0
        n_AR_Q14 = _mm_add_epi32(n_AR_Q14, silk_mm_smulwb_epi32(tmp0, AR_shp_Q13[shapingLPCOrder - 1]));
753
754
0
        n_AR_Q14 = _mm_slli_epi32(n_AR_Q14, 1);                                                  /* Q11 -> Q12 */
755
0
        n_AR_Q14 = _mm_add_epi32(n_AR_Q14, silk_mm_smulwb_epi32(psDelDec->LF_AR_Q14, Tilt_Q14)); /* Q12 */
756
0
        n_AR_Q14 = _mm_slli_epi32(n_AR_Q14, 2);                                                  /* Q12 -> Q14 */
757
758
0
        tmp0 = silk_mm_smulwb_epi32(psDelDec->Samples[*smpl_buf_idx].Shape_Q14, LF_shp_Q14); /* Q12 */
759
0
        tmp1 = silk_mm_smulwb_epi32(psDelDec->LF_AR_Q14, LF_shp_Q14 >> 16);                  /* Q12 */
760
0
        n_LF_Q14 = _mm_add_epi32(tmp0, tmp1);                                                /* Q12 */
761
0
        n_LF_Q14 = _mm_slli_epi32(n_LF_Q14, 2);                                              /* Q12 -> Q14 */
762
763
        /* Input minus prediction plus noise feedback                       */
764
        /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP  */
765
0
        tmp0 = silk_mm_add_sat_epi32(n_AR_Q14, n_LF_Q14);              /* Q14 */
766
0
        tmp1 = _mm_add_epi32(_mm_set1_epi32(n_LTP_Q14), LPC_pred_Q14); /* Q13 */
767
0
        tmp0 = silk_mm_sub_sat_epi32(tmp1, tmp0);                      /* Q13 */
768
0
        tmp0 = silk_mm_srai_round_epi32(tmp0, 4);                      /* Q10 */
769
770
0
        r_Q10 = _mm_sub_epi32(_mm_set1_epi32(x_Q10[i]), tmp0); /* residual error Q10 */
771
772
        /* Flip sign depending on dither */
773
0
        r_Q10 = silk_mm_sign_epi32(r_Q10, psDelDec->Seed);
774
0
        r_Q10 = silk_mm_limit_epi32(r_Q10, -(31 << 10), 30 << 10);
775
776
        /* Find two quantization level candidates and measure their rate-distortion */
777
0
        q1_Q10 = _mm_sub_epi32(r_Q10, _mm_set1_epi32(offset_Q10));
778
0
        q1_Q0 = _mm_srai_epi32(q1_Q10, 10);
779
0
        if (Lambda_Q10 > 2048)
780
0
        {
781
            /* For aggressive RDO, the bias becomes more than one pulse. */
782
0
            tmp0 = _mm_sub_epi32(_mm_abs_epi32(q1_Q10), _mm_set1_epi32(Lambda_Q10 / 2 - 512)); /* rdo_offset */
783
0
            q1_Q0 = _mm_srai_epi32(q1_Q10, 31);
784
0
            tmp1 = _mm_cmpgt_epi32(tmp0, _mm_setzero_si128());
785
0
            tmp0 = _mm_srai_epi32(silk_mm_sign_epi32(tmp0, q1_Q10), 10);
786
0
            q1_Q0 = _mm_blendv_epi8(q1_Q0, tmp0, tmp1);
787
0
        }
788
789
0
        tmp0 = _mm_sign_epi32(_mm_set1_epi32(QUANT_LEVEL_ADJUST_Q10), q1_Q0);
790
0
        q1_Q10 = _mm_sub_epi32(_mm_slli_epi32(q1_Q0, 10), tmp0);
791
0
        q1_Q10 = _mm_add_epi32(q1_Q10, _mm_set1_epi32(offset_Q10));
792
793
        /* check if q1_Q0 is 0 or -1 */
794
0
        tmp0 = _mm_add_epi32(_mm_srli_epi32(q1_Q0, 31), q1_Q0);
795
0
        tmp1 = _mm_cmpeq_epi32(tmp0, _mm_setzero_si128());
796
0
        tmp0 = _mm_blendv_epi8(_mm_set1_epi32(1024), _mm_set1_epi32(1024 - QUANT_LEVEL_ADJUST_Q10), tmp1);
797
0
        q2_Q10 = _mm_add_epi32(q1_Q10, tmp0);
798
0
        q_Q10 = _mm256_set_m128i(q2_Q10, q1_Q10);
799
800
0
        rr_Q10 = _mm256_sub_epi32(_mm256_broadcastsi128_si256(r_Q10), q_Q10);
801
0
        rd_Q10 = _mm256_abs_epi32(q_Q10);
802
0
        rr_Q10 = silk_mm256_smulbb_epi32(rr_Q10, rr_Q10);
803
0
        rd_Q10 = silk_mm256_smulbb_epi32(rd_Q10, _mm256_set1_epi32(Lambda_Q10));
804
0
        rd_Q10 = _mm256_add_epi32(rd_Q10, rr_Q10);
805
0
        rd_Q10 = _mm256_srai_epi32(rd_Q10, 10);
806
807
0
        mask = _mm256_broadcastsi128_si256(_mm_cmplt_epi32(_mm256_extracti128_si256(rd_Q10, 0), _mm256_extracti128_si256(rd_Q10, 1)));
808
0
        SS_RD_Q10 = _mm256_add_epi32(
809
0
            _mm256_broadcastsi128_si256(psDelDec->RD_Q10),
810
0
            _mm256_blendv_epi8(
811
0
                _mm256_permute2x128_si256(rd_Q10, rd_Q10, 0x1),
812
0
                rd_Q10,
813
0
                mask));
814
0
        SS_Q_Q10 = _mm256_blendv_epi8(
815
0
            _mm256_permute2x128_si256(q_Q10, q_Q10, 0x1),
816
0
            q_Q10,
817
0
            mask);
818
819
        /* Update states for best and second best quantization */
820
821
        /* Quantized excitation */
822
0
        exc_Q14 = silk_mm256_sign_epi32(_mm256_slli_epi32(SS_Q_Q10, 4), _mm256_broadcastsi128_si256(psDelDec->Seed));
823
824
        /* Add predictions */
825
0
        exc_Q14 = _mm256_add_epi32(exc_Q14, _mm256_set1_epi32(LTP_pred_Q14));
826
0
        SS_LPC_exc_Q14 = _mm256_slli_epi32(exc_Q14, 1);
827
0
        SS_xq_Q14 = _mm256_add_epi32(exc_Q14, _mm256_broadcastsi128_si256(LPC_pred_Q14));
828
829
        /* Update states */
830
0
        SS_Diff_Q14 = _mm256_sub_epi32(SS_xq_Q14, _mm256_set1_epi32(silk_LSHIFT(x_Q10[i], 4)));
831
0
        SS_LF_AR_Q14 = _mm256_sub_epi32(SS_Diff_Q14, _mm256_broadcastsi128_si256(n_AR_Q14));
832
0
        SS_sLTP_shp_Q14 = silk_mm256_sub_sat_epi32(SS_LF_AR_Q14, _mm256_broadcastsi128_si256(n_LF_Q14));
833
834
        /* END Updating Delayed Decision States */
835
836
0
        *smpl_buf_idx = (*smpl_buf_idx + DECISION_DELAY - 1) % DECISION_DELAY;
837
0
        last_smple_idx = (*smpl_buf_idx + decisionDelay) % DECISION_DELAY;
838
0
        psLastSample = &psDelDec->Samples[last_smple_idx];
839
840
        /* Find winner */
841
0
        RDmin_Q10 = silk_mm_mask_hmin_epi32(_mm256_castsi256_si128(SS_RD_Q10), MaskDelDec);
842
0
        Winner_selector = silk_index_to_selector(silk_index_of_first_equal_epi32(RDmin_Q10, _mm256_castsi256_si128(SS_RD_Q10)));
843
844
        /* Increase RD values of expired states */
845
0
        Winner_rand_state = _mm_shuffle_epi8(psLastSample->RandState, Winner_selector);
846
847
0
        SS_RD_Q10 = _mm256_blendv_epi8(
848
0
            _mm256_add_epi32(SS_RD_Q10, _mm256_set1_epi32(silk_int32_MAX >> 4)),
849
0
            SS_RD_Q10,
850
0
            _mm256_broadcastsi128_si256(_mm_cmpeq_epi32(psLastSample->RandState, Winner_rand_state)));
851
852
        /* find worst in first set */
853
0
        RDmax_Q10 = silk_mm_mask_hmax_epi32(_mm256_extracti128_si256(SS_RD_Q10, 0), MaskDelDec);
854
        /* find best in second set */
855
0
        RDmin_Q10 = silk_mm_mask_hmin_epi32(_mm256_extracti128_si256(SS_RD_Q10, 1), MaskDelDec);
856
857
        /* Replace a state if best from second set outperforms worst in first set */
858
0
        tmp0 = _mm_cmplt_epi32(RDmin_Q10, RDmax_Q10);
859
0
        if (!_mm_test_all_zeros(tmp0, tmp0))
860
0
        {
861
0
            int t;
862
0
            RDmax_ind = silk_index_of_first_equal_epi32(RDmax_Q10, _mm256_extracti128_si256(SS_RD_Q10, 0));
863
0
            RDmin_ind = silk_index_of_first_equal_epi32(RDmin_Q10, _mm256_extracti128_si256(SS_RD_Q10, 1));
864
0
            tmp1 = _mm_cvtepi8_epi32(_mm_cvtsi32_si128(0xFFU << (unsigned)(RDmax_ind << 3)));
865
0
            tmp0 = _mm_blendv_epi8(
866
0
                _mm_set_epi8(0xF, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0),
867
0
                silk_index_to_selector(RDmin_ind),
868
0
                tmp1);
869
0
            for (t = i; t < MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH; t++)
870
0
            {
871
0
                psDelDec->sLPC_Q14[t] = _mm_shuffle_epi8(psDelDec->sLPC_Q14[t], tmp0);
872
0
            }
873
0
            psDelDec->Seed = _mm_shuffle_epi8(psDelDec->Seed, tmp0);
874
0
            psDelDec->SeedInit = _mm_shuffle_epi8(psDelDec->SeedInit, tmp0);
875
0
            for (t = 0; t < MAX_SHAPE_LPC_ORDER; t++)
876
0
            {
877
0
                psDelDec->sAR2_Q14[t] = _mm_shuffle_epi8(psDelDec->sAR2_Q14[t], tmp0);
878
0
            }
879
0
            for (t = 0; t < DECISION_DELAY; t++)
880
0
            {
881
0
                psDelDec->Samples[t].RandState = _mm_shuffle_epi8(psDelDec->Samples[t].RandState, tmp0);
882
0
                psDelDec->Samples[t].Q_Q10 = _mm_shuffle_epi8(psDelDec->Samples[t].Q_Q10, tmp0);
883
0
                psDelDec->Samples[t].Xq_Q14 = _mm_shuffle_epi8(psDelDec->Samples[t].Xq_Q14, tmp0);
884
0
                psDelDec->Samples[t].Pred_Q15 = _mm_shuffle_epi8(psDelDec->Samples[t].Pred_Q15, tmp0);
885
0
                psDelDec->Samples[t].Shape_Q14 = _mm_shuffle_epi8(psDelDec->Samples[t].Shape_Q14, tmp0);
886
0
            }
887
0
            mask = _mm256_castsi128_si256(_mm_blendv_epi8(_mm_set_epi32(0x3, 0x2, 0x1, 0x0), _mm_set1_epi32(RDmin_ind + 4), tmp1));
888
0
            SS_Q_Q10 = _mm256_permutevar8x32_epi32(SS_Q_Q10, mask);
889
0
            SS_RD_Q10 = _mm256_permutevar8x32_epi32(SS_RD_Q10, mask);
890
0
            SS_xq_Q14 = _mm256_permutevar8x32_epi32(SS_xq_Q14, mask);
891
0
            SS_LF_AR_Q14 = _mm256_permutevar8x32_epi32(SS_LF_AR_Q14, mask);
892
0
            SS_Diff_Q14 = _mm256_permutevar8x32_epi32(SS_Diff_Q14, mask);
893
0
            SS_sLTP_shp_Q14 = _mm256_permutevar8x32_epi32(SS_sLTP_shp_Q14, mask);
894
0
            SS_LPC_exc_Q14 = _mm256_permutevar8x32_epi32(SS_LPC_exc_Q14, mask);
895
0
        }
896
897
        /* Write samples from winner to output and long-term filter states */
898
0
        if (subfr > 0 || i >= decisionDelay)
899
0
        {
900
0
            pulses[i - decisionDelay] =
901
0
                (opus_int8)silk_sar_round_32(silk_select_winner(psLastSample->Q_Q10, Winner_selector), 10);
902
0
            xq[i - decisionDelay] =
903
0
                silk_sat16((opus_int32)silk_sar_round_smulww(silk_select_winner(psLastSample->Xq_Q14, Winner_selector), delayedGain_Q10[last_smple_idx], 8));
904
0
            NSQ->sLTP_shp_Q14[NSQ->sLTP_shp_buf_idx - decisionDelay] =
905
0
                silk_select_winner(psLastSample->Shape_Q14, Winner_selector);
906
0
            sLTP_Q15[NSQ->sLTP_buf_idx - decisionDelay] =
907
0
                silk_select_winner(psLastSample->Pred_Q15, Winner_selector);
908
0
        }
909
0
        NSQ->sLTP_shp_buf_idx++;
910
0
        NSQ->sLTP_buf_idx++;
911
912
        /* Update states */
913
0
        psSample = &psDelDec->Samples[*smpl_buf_idx];
914
0
        psDelDec->Seed = _mm_add_epi32(psDelDec->Seed, silk_mm_srai_round_epi32(_mm256_castsi256_si128(SS_Q_Q10), 10));
915
0
        psDelDec->LF_AR_Q14 = _mm256_castsi256_si128(SS_LF_AR_Q14);
916
0
        psDelDec->Diff_Q14 = _mm256_castsi256_si128(SS_Diff_Q14);
917
0
        psDelDec->sLPC_Q14[i + NSQ_LPC_BUF_LENGTH] = _mm256_castsi256_si128(SS_xq_Q14);
918
0
        psDelDec->RD_Q10 = _mm256_castsi256_si128(SS_RD_Q10);
919
0
        psSample->Xq_Q14 = _mm256_castsi256_si128(SS_xq_Q14);
920
0
        psSample->Q_Q10 = _mm256_castsi256_si128(SS_Q_Q10);
921
0
        psSample->Pred_Q15 = _mm256_castsi256_si128(SS_LPC_exc_Q14);
922
0
        psSample->Shape_Q14 = _mm256_castsi256_si128(SS_sLTP_shp_Q14);
923
0
        psSample->RandState = psDelDec->Seed;
924
0
        delayedGain_Q10[*smpl_buf_idx] = Gain_Q10;
925
0
    }
926
    /* Update LPC states */
927
0
    for (i = 0; i < NSQ_LPC_BUF_LENGTH; i++)
928
0
    {
929
0
        psDelDec->sLPC_Q14[i] = (&psDelDec->sLPC_Q14[length])[i];
930
0
    }
931
0
}
932
933
static OPUS_INLINE void silk_nsq_del_dec_scale_states_avx2(
934
    const silk_encoder_state *psEncC,          /* I    Encoder State                   */
935
    silk_nsq_state *NSQ,                       /* I/O  NSQ state                       */
936
    NSQ_del_dec_struct *psDelDec,              /* I/O  Delayed decision states         */
937
    const opus_int16 x16[],                    /* I    Input                           */
938
    opus_int32 x_sc_Q10[MAX_SUB_FRAME_LENGTH], /* O    Input scaled with 1/Gain in Q10 */
939
    const opus_int16 sLTP[],                   /* I    Re-whitened LTP state in Q0     */
940
    opus_int32 sLTP_Q15[],                     /* O    LTP state matching scaled input */
941
    opus_int subfr,                            /* I    Subframe number                 */
942
    const opus_int LTP_scale_Q14,              /* I    LTP state scaling               */
943
    const opus_int32 Gains_Q16[MAX_NB_SUBFR],  /* I                                    */
944
    const opus_int pitchL[MAX_NB_SUBFR],       /* I    Pitch lag                       */
945
    const opus_int signal_type,                /* I    Signal type                     */
946
    const opus_int decisionDelay               /* I    Decision delay                  */
947
)
948
0
{
949
0
    int i;
950
0
    opus_int lag;
951
0
    opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
952
0
    NSQ_del_dec_sample_struct *psSample;
953
954
0
    lag = pitchL[subfr];
955
0
    inv_gain_Q31 = silk_INVERSE32_varQ(silk_max(Gains_Q16[subfr], 1), 47);
956
0
    silk_assert(inv_gain_Q31 != 0);
957
958
    /* Scale input */
959
0
    inv_gain_Q26 = silk_sar_round_32(inv_gain_Q31, 5);
960
0
    for (i = 0; i < psEncC->subfr_length; i+=4)
961
0
    {
962
0
        __m256i x = _mm256_cvtepi16_epi64(_mm_loadu_si64(&x16[i]));
963
0
        x = _mm256_slli_epi64(_mm256_mul_epi32(x, _mm256_set1_epi32(inv_gain_Q26)), 16);
964
0
        _mm_storeu_si128((__m128i*)(void*)&x_sc_Q10[i], silk_cvtepi64_epi32_high(x));
965
0
    }
966
967
    /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
968
0
    if (NSQ->rewhite_flag)
969
0
    {
970
0
        if (subfr == 0)
971
0
        {
972
            /* Do LTP downscaling */
973
0
            inv_gain_Q31 = silk_LSHIFT(silk_SMULWB(inv_gain_Q31, LTP_scale_Q14), 2);
974
0
        }
975
0
        for (i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++)
976
0
        {
977
0
            silk_assert(i < MAX_FRAME_LENGTH);
978
0
            sLTP_Q15[i] = silk_SMULWB(inv_gain_Q31, sLTP[i]);
979
0
        }
980
0
    }
981
982
    /* Adjust for changing gain */
983
0
    if (Gains_Q16[subfr] != NSQ->prev_gain_Q16)
984
0
    {
985
0
        gain_adj_Q16 = silk_DIV32_varQ(NSQ->prev_gain_Q16, Gains_Q16[subfr], 16);
986
987
        /* Scale long-term shaping state */
988
0
        for (i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i+=4)
989
0
        {
990
0
      opus_int32 *p = &NSQ->sLTP_shp_Q14[i];
991
0
            _mm_storeu_si128((__m128i*)(void*)p, silk_mm_smulww_epi32(_mm_loadu_si128((__m128i*)(void*)p), gain_adj_Q16));
992
0
        }
993
994
        /* Scale long-term prediction state */
995
0
        if (signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0)
996
0
        {
997
0
            for (i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++)
998
0
            {
999
0
                sLTP_Q15[i] = ((opus_int64)sLTP_Q15[i]) * ((opus_int64)gain_adj_Q16) >> 16;
1000
0
            }
1001
0
        }
1002
1003
        /* Scale scalar states */
1004
0
        psDelDec->LF_AR_Q14 = silk_mm_smulww_epi32(psDelDec->LF_AR_Q14, gain_adj_Q16);
1005
0
        psDelDec->Diff_Q14 = silk_mm_smulww_epi32(psDelDec->Diff_Q14, gain_adj_Q16);
1006
1007
        /* Scale short-term prediction and shaping states */
1008
0
        for (i = 0; i < NSQ_LPC_BUF_LENGTH; i++)
1009
0
        {
1010
0
            psDelDec->sLPC_Q14[i] = silk_mm_smulww_epi32(psDelDec->sLPC_Q14[i], gain_adj_Q16);
1011
0
        }
1012
0
        for (i = 0; i < DECISION_DELAY; i++)
1013
0
        {
1014
0
            psSample = &psDelDec->Samples[i];
1015
0
            psSample->Pred_Q15 = silk_mm_smulww_epi32(psSample->Pred_Q15, gain_adj_Q16);
1016
0
            psSample->Shape_Q14 = silk_mm_smulww_epi32(psSample->Shape_Q14, gain_adj_Q16);
1017
0
        }
1018
0
        for (i = 0; i < MAX_SHAPE_LPC_ORDER; i++)
1019
0
        {
1020
0
            psDelDec->sAR2_Q14[i] = silk_mm_smulww_epi32(psDelDec->sAR2_Q14[i], gain_adj_Q16);
1021
0
        }
1022
1023
        /* Save inverse gain */
1024
0
        NSQ->prev_gain_Q16 = Gains_Q16[subfr];
1025
0
    }
1026
0
}
1027
1028
static OPUS_INLINE void silk_LPC_analysis_filter_avx2(
1029
    opus_int16                  *out,               /* O    Output signal                           */
1030
    const opus_int16            *in,                /* I    Input signal                            */
1031
    const opus_int16            *B,                 /* I    MA prediction coefficients, Q12 [order] */
1032
    const opus_int32            len,                /* I    Signal length                           */
1033
    const opus_int32            order               /* I    Filter order                            */
1034
)
1035
0
{
1036
0
    int i;
1037
0
    opus_int32       out32_Q12, out32;
1038
0
    silk_assert(order == 10 || order == 16);
1039
1040
0
    for(i = order; i < len; i++ )
1041
0
    {
1042
0
        const opus_int16 *in_ptr = &in[ i ];
1043
        /* Allowing wrap around so that two wraps can cancel each other. The rare
1044
           cases where the result wraps around can only be triggered by invalid streams*/
1045
1046
0
        __m256i in_v = _mm256_cvtepi16_epi32(_mm_loadu_si128((__m128i*)(void*)&in_ptr[-8]));
1047
0
        __m256i B_v  = _mm256_cvtepi16_epi32(_mm_loadu_si128((__m128i*)(void*)&      B[0]));
1048
0
        __m256i sum = _mm256_mullo_epi32(in_v, silk_mm256_reverse_epi32(B_v));
1049
0
        if (order > 10)
1050
0
        {
1051
0
            in_v = _mm256_cvtepi16_epi32(_mm_loadu_si128((__m128i*)(void*)&in_ptr[-16]));
1052
0
            B_v  = _mm256_cvtepi16_epi32(_mm_loadu_si128((__m128i*)(void*)&B       [8]));
1053
0
            B_v  = silk_mm256_reverse_epi32(B_v);
1054
0
        }
1055
0
        else
1056
0
        {
1057
0
            in_v = _mm256_cvtepi16_epi32(_mm_loadu_si32(&in_ptr[-10]));
1058
0
            B_v  = _mm256_cvtepi16_epi32(_mm_loadu_si32(&B       [8]));
1059
0
            B_v  = _mm256_shuffle_epi32(B_v, 0x01);
1060
0
        }
1061
0
        sum = _mm256_add_epi32(sum, _mm256_mullo_epi32(in_v, B_v));
1062
1063
0
        out32_Q12 = silk_mm256_hsum_epi32(sum);
1064
1065
        /* Subtract prediction */
1066
0
        out32_Q12 = silk_SUB32_ovflw( silk_LSHIFT( (opus_int32)*in_ptr, 12 ), out32_Q12 );
1067
1068
        /* Scale to Q0 */
1069
0
        out32 = silk_sar_round_32(out32_Q12, 12);
1070
1071
        /* Saturate output */
1072
0
        out[ i ] = silk_sat16(out32);
1073
0
    }
1074
1075
    /* Set first d output samples to zero */
1076
0
    silk_memset( out, 0, order * sizeof( opus_int16 ) );
1077
0
}