Coverage Report

Created: 2026-03-31 07:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opus/silk/fixed/encode_frame_FIX.c
Line
Count
Source
1
/***********************************************************************
2
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
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
#include <stdlib.h>
33
#include "main_FIX.h"
34
#include "stack_alloc.h"
35
#include "tuning_parameters.h"
36
37
/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate           */
38
static OPUS_INLINE void silk_LBRR_encode_FIX(
39
    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
40
    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Pointer to Silk FIX encoder control struct                                  */
41
    const opus_int16                x16[],                                  /* I    Input signal                                                                */
42
    opus_int                        condCoding                              /* I    The type of conditional coding used so far for this frame                   */
43
);
44
45
void silk_encode_do_VAD_FIX(
46
    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
47
    opus_int                        activity                                /* I    Decision of Opus voice activity detector                                    */
48
)
49
43.5M
{
50
43.5M
    const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
51
52
    /****************************/
53
    /* Voice Activity Detection */
54
    /****************************/
55
43.5M
    silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
56
    /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */
57
43.5M
    if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
58
5.31k
        psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
59
5.31k
    }
60
61
    /**************************************************/
62
    /* Convert speech activity into VAD and DTX flags */
63
    /**************************************************/
64
43.5M
    if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
65
42.5M
        psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
66
42.5M
        psEnc->sCmn.noSpeechCounter++;
67
42.5M
        if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
68
241k
            psEnc->sCmn.inDTX = 0;
69
42.2M
        } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
70
2.00M
            psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
71
2.00M
            psEnc->sCmn.inDTX           = 0;
72
2.00M
        }
73
42.5M
        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
74
42.5M
    } else {
75
1.00M
        psEnc->sCmn.noSpeechCounter    = 0;
76
1.00M
        psEnc->sCmn.inDTX              = 0;
77
1.00M
        psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
78
1.00M
        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
79
1.00M
    }
80
43.5M
}
81
82
/****************/
83
/* Encode frame */
84
/****************/
85
opus_int silk_encode_frame_FIX(
86
    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
87
    opus_int32                      *pnBytesOut,                            /* O    Pointer to number of payload bytes;                                         */
88
    ec_enc                          *psRangeEnc,                            /* I/O  compressor data structure                                                   */
89
    opus_int                        condCoding,                             /* I    The type of conditional coding to use                                       */
90
    opus_int                        maxBits,                                /* I    If > 0: maximum number of output bits                                       */
91
    opus_int                        useCBR                                  /* I    Flag to force constant-bitrate operation                                    */
92
)
93
43.5M
{
94
43.5M
    silk_encoder_control_FIX sEncCtrl;
95
43.5M
    opus_int     i, iter, maxIter, found_upper, found_lower, ret = 0;
96
43.5M
    opus_int16   *x_frame;
97
43.5M
    ec_enc       sRangeEnc_copy, sRangeEnc_copy2;
98
43.5M
    VARDECL(silk_nsq_state, sNSQ_copy);
99
43.5M
    opus_int32   seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
100
43.5M
    opus_int32   gainsID, gainsID_lower, gainsID_upper;
101
43.5M
    opus_int16   gainMult_Q8;
102
43.5M
    opus_int16   ec_prevLagIndex_copy;
103
43.5M
    opus_int     ec_prevSignalType_copy;
104
43.5M
    opus_int8    LastGainIndex_copy2;
105
43.5M
    opus_int     gain_lock[ MAX_NB_SUBFR ] = {0};
106
43.5M
    opus_int16   best_gain_mult[ MAX_NB_SUBFR ];
107
43.5M
    opus_int     best_sum[ MAX_NB_SUBFR ];
108
43.5M
    opus_int     bits_margin;
109
43.5M
    SAVE_STACK;
110
111
    /* Using ALLOC() instead of a regular stack allocation to minimize real stack use when using the pseudostack.
112
       This is useful on some embedded systems. */
113
43.5M
    ALLOC(sNSQ_copy, 2, silk_nsq_state);
114
115
    /* For CBR, 5 bits below budget is close enough. For VBR, allow up to 25% below the cap if we initially busted the budget. */
116
43.5M
    bits_margin = useCBR ? 5 : maxBits/4;
117
    /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
118
43.5M
    LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
119
120
43.5M
    psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
121
122
    /**************************************************************/
123
    /* Set up Input Pointers, and insert frame in input buffer   */
124
    /*************************************************************/
125
    /* start of frame to encode */
126
43.5M
    x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;
127
128
    /***************************************/
129
    /* Ensure smooth bandwidth transitions */
130
    /***************************************/
131
43.5M
    silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
132
133
    /*******************************************/
134
    /* Copy new frame to front of input buffer */
135
    /*******************************************/
136
43.5M
    silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
137
138
43.5M
    if( !psEnc->sCmn.prefillFlag ) {
139
43.5M
        VARDECL( opus_int16, res_pitch );
140
43.5M
        VARDECL( opus_uint8, ec_buf_copy );
141
43.5M
        opus_int16 *res_pitch_frame;
142
143
43.5M
        ALLOC( res_pitch,
144
43.5M
               psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length
145
43.5M
                   + psEnc->sCmn.ltp_mem_length, opus_int16 );
146
        /* start of pitch LPC residual frame */
147
43.5M
        res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;
148
149
        /*****************************************/
150
        /* Find pitch lags, initial LPC analysis */
151
        /*****************************************/
152
43.5M
        silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch );
153
154
        /************************/
155
        /* Noise shape analysis */
156
        /************************/
157
43.5M
        silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch );
158
159
        /***************************************************/
160
        /* Find linear prediction coefficients (LPC + LTP) */
161
        /***************************************************/
162
43.5M
        silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
163
164
        /****************************************/
165
        /* Process gains                        */
166
        /****************************************/
167
43.5M
        silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
168
169
        /****************************************/
170
        /* Low Bitrate Redundant Encoding       */
171
        /****************************************/
172
43.5M
        silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding );
173
174
        /* Loop over quantizer and entropy coding to control bitrate */
175
43.5M
        maxIter = 6;
176
43.5M
        gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
177
43.5M
        found_lower = 0;
178
43.5M
        found_upper = 0;
179
43.5M
        gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
180
43.5M
        gainsID_lower = -1;
181
43.5M
        gainsID_upper = -1;
182
        /* Copy part of the input state */
183
43.5M
        silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
184
43.5M
        silk_memcpy( &sNSQ_copy[0], &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
185
43.5M
        seed_copy = psEnc->sCmn.indices.Seed;
186
43.5M
        ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
187
43.5M
        ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
188
43.5M
        ALLOC( ec_buf_copy, 1275, opus_uint8 );
189
169M
        for( iter = 0; ; iter++ ) {
190
169M
            if( gainsID == gainsID_lower ) {
191
123M
                nBits = nBits_lower;
192
123M
            } else if( gainsID == gainsID_upper ) {
193
207k
                nBits = nBits_upper;
194
45.1M
            } else {
195
                /* Restore part of the input state */
196
45.1M
                if( iter > 0 ) {
197
1.67M
                    silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
198
1.67M
                    silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy[0], sizeof( silk_nsq_state ) );
199
1.67M
                    psEnc->sCmn.indices.Seed = seed_copy;
200
1.67M
                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
201
1.67M
                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
202
1.67M
                }
203
204
                /*****************************************/
205
                /* Noise shaping quantization            */
206
                /*****************************************/
207
45.1M
                if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
208
18.2M
                    silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
209
18.2M
                           sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
210
18.2M
                           sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
211
18.2M
                           psEnc->sCmn.arch );
212
26.8M
                } else {
213
26.8M
                    silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
214
26.8M
                            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
215
26.8M
                            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
216
26.8M
                            psEnc->sCmn.arch);
217
26.8M
                }
218
219
45.1M
                if ( iter == maxIter && !found_lower ) {
220
39.3k
                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
221
39.3k
                }
222
223
                /****************************************/
224
                /* Encode Parameters                    */
225
                /****************************************/
226
45.1M
                silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
227
228
                /****************************************/
229
                /* Encode Excitation Signal             */
230
                /****************************************/
231
45.1M
                silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
232
45.1M
                    psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
233
234
45.1M
                nBits = ec_tell( psRangeEnc );
235
236
                /* If we still bust after the last iteration, do some damage control. */
237
45.1M
                if ( iter == maxIter && !found_lower && nBits > maxBits ) {
238
33.7k
                    silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
239
240
                    /* Keep gains the same as the last frame. */
241
33.7k
                    psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
242
163k
                    for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
243
129k
                        psEnc->sCmn.indices.GainsIndices[ i ] = 4;
244
129k
                    }
245
33.7k
                    if (condCoding != CODE_CONDITIONALLY) {
246
24.8k
                       psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
247
24.8k
                    }
248
33.7k
                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
249
33.7k
                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
250
                    /* Clear all pulses. */
251
6.07M
                    for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
252
6.04M
                        psEnc->sCmn.pulses[ i ] = 0;
253
6.04M
                    }
254
255
33.7k
                    silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
256
257
33.7k
                    silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
258
33.7k
                        psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
259
260
33.7k
                    nBits = ec_tell( psRangeEnc );
261
33.7k
                }
262
263
45.1M
                if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
264
22.4M
                    break;
265
22.4M
                }
266
45.1M
            }
267
268
146M
            if( iter == maxIter ) {
269
20.8M
                if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
270
                    /* Restore output state from earlier iteration that did meet the bitrate budget */
271
20.7M
                    silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
272
20.7M
                    celt_assert( sRangeEnc_copy2.offs <= 1275 );
273
20.7M
                    silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
274
20.7M
                    silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy[1], sizeof( silk_nsq_state ) );
275
20.7M
                    psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
276
20.7M
                }
277
20.8M
                break;
278
20.8M
            }
279
280
125M
            if( nBits > maxBits ) {
281
936k
                if( found_lower == 0 && iter >= 2 ) {
282
                    /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
283
241k
                    sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );
284
241k
                    found_upper = 0;
285
241k
                    gainsID_upper = -1;
286
694k
                } else {
287
694k
                    found_upper = 1;
288
694k
                    nBits_upper = nBits;
289
694k
                    gainMult_upper = gainMult_Q8;
290
694k
                    gainsID_upper = gainsID;
291
694k
                }
292
124M
            } else if( nBits < maxBits - bits_margin ) {
293
124M
                found_lower = 1;
294
124M
                nBits_lower = nBits;
295
124M
                gainMult_lower = gainMult_Q8;
296
124M
                if( gainsID != gainsID_lower ) {
297
21.6M
                    gainsID_lower = gainsID;
298
                    /* Copy part of the output state */
299
21.6M
                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
300
21.6M
                    celt_assert( psRangeEnc->offs <= 1275 );
301
21.6M
                    silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
302
21.6M
                    silk_memcpy( &sNSQ_copy[1], &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
303
21.6M
                    LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
304
21.6M
                }
305
124M
            } else {
306
                /* Close enough */
307
171k
                break;
308
171k
            }
309
310
125M
            if ( !found_lower && nBits > maxBits ) {
311
636k
                int j;
312
3.02M
                for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
313
2.39M
                    int sum=0;
314
112M
                    for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
315
110M
                        sum += abs( psEnc->sCmn.pulses[j] );
316
110M
                    }
317
2.39M
                    if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
318
1.51M
                        best_sum[i] = sum;
319
1.51M
                        best_gain_mult[i] = gainMult_Q8;
320
1.51M
                    } else {
321
878k
                        gain_lock[i] = 1;
322
878k
                    }
323
2.39M
                }
324
636k
            }
325
125M
            if( ( found_lower & found_upper ) == 0 ) {
326
                /* Adjust gain according to high-rate rate/distortion curve */
327
125M
                if( nBits > maxBits ) {
328
636k
                    gainMult_Q8 = silk_min_32( 1024, gainMult_Q8*3/2 );
329
124M
                } else {
330
124M
                    gainMult_Q8 = silk_max_32( 64, gainMult_Q8*4/5 );
331
124M
                }
332
125M
            } else {
333
                /* Adjust gain by interpolating */
334
614k
                gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
335
                /* New gain multiplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
336
614k
                if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
337
93.8k
                    gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
338
93.8k
                } else
339
521k
                if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
340
150k
                    gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
341
150k
                }
342
614k
            }
343
344
523M
            for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
345
398M
                opus_int16 tmp;
346
398M
                if ( gain_lock[i] ) {
347
989k
                    tmp = best_gain_mult[i];
348
397M
                } else {
349
397M
                    tmp = gainMult_Q8;
350
397M
                }
351
398M
                sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
352
398M
            }
353
354
            /* Quantize gains */
355
125M
            psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
356
125M
            silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
357
125M
                  &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
358
359
            /* Unique identifier of gains vector */
360
125M
            gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
361
125M
        }
362
43.5M
    }
363
364
    /* Update input buffer */
365
43.5M
    silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
366
43.5M
        ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
367
368
    /* Exit without entropy coding */
369
43.5M
    if( psEnc->sCmn.prefillFlag ) {
370
        /* No payload */
371
357
        *pnBytesOut = 0;
372
357
        RESTORE_STACK;
373
357
        return ret;
374
357
    }
375
376
    /* Parameters needed for next frame */
377
43.5M
    psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
378
43.5M
    psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
379
380
    /****************************************/
381
    /* Finalize payload                     */
382
    /****************************************/
383
43.5M
    psEnc->sCmn.first_frame_after_reset = 0;
384
    /* Payload size */
385
43.5M
    *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
386
387
43.5M
    RESTORE_STACK;
388
43.5M
    return ret;
389
43.5M
}
390
391
/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate  */
392
static OPUS_INLINE void silk_LBRR_encode_FIX(
393
    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
394
    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Pointer to Silk FIX encoder control struct                                  */
395
    const opus_int16                x16[],                                  /* I    Input signal                                                                */
396
    opus_int                        condCoding                              /* I    The type of conditional coding used so far for this frame                   */
397
)
398
43.5M
{
399
43.5M
    opus_int32   TempGains_Q16[ MAX_NB_SUBFR ];
400
43.5M
    SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
401
43.5M
    VARDECL(silk_nsq_state, sNSQ_LBRR);
402
43.5M
    SAVE_STACK;
403
404
    /*******************************************/
405
    /* Control use of inband LBRR              */
406
    /*******************************************/
407
43.5M
    if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
408
        /* Using ALLOC() instead of a regular stack allocation to minimize real stack use when using the pseudostack.
409
           This is useful on some embedded systems. */
410
283k
        ALLOC(sNSQ_LBRR, 1, silk_nsq_state);
411
412
283k
        psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
413
414
        /* Copy noise shaping quantizer state and quantization indices from regular encoding */
415
283k
        silk_memcpy( &sNSQ_LBRR[0], &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
416
283k
        silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
417
418
        /* Save original gains */
419
283k
        silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
420
421
283k
        if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
422
            /* First frame in packet or previous frame not LBRR coded */
423
222k
            psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
424
425
            /* Increase Gains to get target LBRR rate */
426
222k
            psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
427
222k
            psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
428
222k
        }
429
430
        /* Decode to get gains in sync with decoder         */
431
        /* Overwrite unquantized gains with quantized gains */
432
283k
        silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
433
283k
            &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
434
435
        /*****************************************/
436
        /* Noise shaping quantization            */
437
        /*****************************************/
438
283k
        if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
439
153k
            silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR[0], psIndices_LBRR, x16,
440
153k
                psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
441
153k
                psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
442
153k
                psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
443
153k
        } else {
444
130k
            silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR[0], psIndices_LBRR, x16,
445
130k
                psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
446
130k
                psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
447
130k
                psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
448
130k
        }
449
450
        /* Restore original gains */
451
283k
        silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
452
283k
    }
453
43.5M
    RESTORE_STACK;
454
43.5M
}