Coverage Report

Created: 2023-09-25 08:12

/src/opus/silk/fixed/encode_frame_FIX.c
Line
Count
Source (jump to first uncovered line)
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
21.5M
{
50
21.5M
    const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
51
52
    /****************************/
53
    /* Voice Activity Detection */
54
    /****************************/
55
21.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
21.5M
    if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
58
488
        psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
59
488
    }
60
61
    /**************************************************/
62
    /* Convert speech activity into VAD and DTX flags */
63
    /**************************************************/
64
21.5M
    if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
65
20.7M
        psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
66
20.7M
        psEnc->sCmn.noSpeechCounter++;
67
20.7M
        if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
68
155k
            psEnc->sCmn.inDTX = 0;
69
20.6M
        } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
70
979k
            psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
71
979k
            psEnc->sCmn.inDTX           = 0;
72
979k
        }
73
20.7M
        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
74
20.7M
    } else {
75
773k
        psEnc->sCmn.noSpeechCounter    = 0;
76
773k
        psEnc->sCmn.inDTX              = 0;
77
773k
        psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
78
773k
        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
79
773k
    }
80
21.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
21.5M
{
94
21.5M
    silk_encoder_control_FIX sEncCtrl;
95
21.5M
    opus_int     i, iter, maxIter, found_upper, found_lower, ret = 0;
96
21.5M
    opus_int16   *x_frame;
97
21.5M
    ec_enc       sRangeEnc_copy, sRangeEnc_copy2;
98
21.5M
    silk_nsq_state sNSQ_copy, sNSQ_copy2;
99
21.5M
    opus_int32   seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
100
21.5M
    opus_int32   gainsID, gainsID_lower, gainsID_upper;
101
21.5M
    opus_int16   gainMult_Q8;
102
21.5M
    opus_int16   ec_prevLagIndex_copy;
103
21.5M
    opus_int     ec_prevSignalType_copy;
104
21.5M
    opus_int8    LastGainIndex_copy2;
105
21.5M
    opus_int     gain_lock[ MAX_NB_SUBFR ] = {0};
106
21.5M
    opus_int16   best_gain_mult[ MAX_NB_SUBFR ];
107
21.5M
    opus_int     best_sum[ MAX_NB_SUBFR ];
108
21.5M
    SAVE_STACK;
109
110
    /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
111
21.5M
    LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
112
113
21.5M
    psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
114
115
    /**************************************************************/
116
    /* Set up Input Pointers, and insert frame in input buffer   */
117
    /*************************************************************/
118
    /* start of frame to encode */
119
21.5M
    x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;
120
121
    /***************************************/
122
    /* Ensure smooth bandwidth transitions */
123
    /***************************************/
124
21.5M
    silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
125
126
    /*******************************************/
127
    /* Copy new frame to front of input buffer */
128
    /*******************************************/
129
21.5M
    silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
130
131
21.5M
    if( !psEnc->sCmn.prefillFlag ) {
132
21.5M
        VARDECL( opus_int16, res_pitch );
133
21.5M
        VARDECL( opus_uint8, ec_buf_copy );
134
21.5M
        opus_int16 *res_pitch_frame;
135
136
21.5M
        ALLOC( res_pitch,
137
21.5M
               psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length
138
21.5M
                   + psEnc->sCmn.ltp_mem_length, opus_int16 );
139
        /* start of pitch LPC residual frame */
140
21.5M
        res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;
141
142
        /*****************************************/
143
        /* Find pitch lags, initial LPC analysis */
144
        /*****************************************/
145
21.5M
        silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch );
146
147
        /************************/
148
        /* Noise shape analysis */
149
        /************************/
150
21.5M
        silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch );
151
152
        /***************************************************/
153
        /* Find linear prediction coefficients (LPC + LTP) */
154
        /***************************************************/
155
21.5M
        silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
156
157
        /****************************************/
158
        /* Process gains                        */
159
        /****************************************/
160
21.5M
        silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
161
162
        /****************************************/
163
        /* Low Bitrate Redundant Encoding       */
164
        /****************************************/
165
21.5M
        silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding );
166
167
        /* Loop over quantizer and entropy coding to control bitrate */
168
21.5M
        maxIter = 6;
169
21.5M
        gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
170
21.5M
        found_lower = 0;
171
21.5M
        found_upper = 0;
172
21.5M
        gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
173
21.5M
        gainsID_lower = -1;
174
21.5M
        gainsID_upper = -1;
175
        /* Copy part of the input state */
176
21.5M
        silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
177
21.5M
        silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
178
21.5M
        seed_copy = psEnc->sCmn.indices.Seed;
179
21.5M
        ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
180
21.5M
        ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
181
21.5M
        ALLOC( ec_buf_copy, 1275, opus_uint8 );
182
79.5M
        for( iter = 0; ; iter++ ) {
183
79.5M
            if( gainsID == gainsID_lower ) {
184
56.5M
                nBits = nBits_lower;
185
56.5M
            } else if( gainsID == gainsID_upper ) {
186
252k
                nBits = nBits_upper;
187
22.7M
            } else {
188
                /* Restore part of the input state */
189
22.7M
                if( iter > 0 ) {
190
1.24M
                    silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
191
1.24M
                    silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
192
1.24M
                    psEnc->sCmn.indices.Seed = seed_copy;
193
1.24M
                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
194
1.24M
                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
195
1.24M
                }
196
197
                /*****************************************/
198
                /* Noise shaping quantization            */
199
                /*****************************************/
200
22.7M
                if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
201
12.9M
                    silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
202
12.9M
                           sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
203
12.9M
                           sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
204
12.9M
                           psEnc->sCmn.arch );
205
12.9M
                } else {
206
9.82M
                    silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
207
9.82M
                            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
208
9.82M
                            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
209
9.82M
                            psEnc->sCmn.arch);
210
9.82M
                }
211
212
22.7M
                if ( iter == maxIter && !found_lower ) {
213
23.6k
                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
214
23.6k
                }
215
216
                /****************************************/
217
                /* Encode Parameters                    */
218
                /****************************************/
219
22.7M
                silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
220
221
                /****************************************/
222
                /* Encode Excitation Signal             */
223
                /****************************************/
224
22.7M
                silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
225
22.7M
                    psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
226
227
22.7M
                nBits = ec_tell( psRangeEnc );
228
229
                /* If we still bust after the last iteration, do some damage control. */
230
22.7M
                if ( iter == maxIter && !found_lower && nBits > maxBits ) {
231
22.1k
                    silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
232
233
                    /* Keep gains the same as the last frame. */
234
22.1k
                    psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
235
106k
                    for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
236
84.1k
                        psEnc->sCmn.indices.GainsIndices[ i ] = 4;
237
84.1k
                    }
238
22.1k
                    if (condCoding != CODE_CONDITIONALLY) {
239
17.4k
                       psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
240
17.4k
                    }
241
22.1k
                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
242
22.1k
                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
243
                    /* Clear all pulses. */
244
3.91M
                    for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
245
3.89M
                        psEnc->sCmn.pulses[ i ] = 0;
246
3.89M
                    }
247
248
22.1k
                    silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
249
250
22.1k
                    silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
251
22.1k
                        psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
252
253
22.1k
                    nBits = ec_tell( psRangeEnc );
254
22.1k
                }
255
256
22.7M
                if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
257
11.8M
                    break;
258
11.8M
                }
259
22.7M
            }
260
261
67.7M
            if( iter == maxIter ) {
262
9.63M
                if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
263
                    /* Restore output state from earlier iteration that did meet the bitrate budget */
264
9.57M
                    silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
265
9.57M
                    celt_assert( sRangeEnc_copy2.offs <= 1275 );
266
9.57M
                    silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
267
9.57M
                    silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
268
9.57M
                    psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
269
9.57M
                }
270
9.63M
                break;
271
9.63M
            }
272
273
58.1M
            if( nBits > maxBits ) {
274
750k
                if( found_lower == 0 && iter >= 2 ) {
275
                    /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
276
126k
                    sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );
277
126k
                    found_upper = 0;
278
126k
                    gainsID_upper = -1;
279
624k
                } else {
280
624k
                    found_upper = 1;
281
624k
                    nBits_upper = nBits;
282
624k
                    gainMult_upper = gainMult_Q8;
283
624k
                    gainsID_upper = gainsID;
284
624k
                }
285
57.3M
            } else if( nBits < maxBits - 5 ) {
286
57.2M
                found_lower = 1;
287
57.2M
                nBits_lower = nBits;
288
57.2M
                gainMult_lower = gainMult_Q8;
289
57.2M
                if( gainsID != gainsID_lower ) {
290
10.2M
                    gainsID_lower = gainsID;
291
                    /* Copy part of the output state */
292
10.2M
                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
293
10.2M
                    celt_assert( psRangeEnc->offs <= 1275 );
294
10.2M
                    silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
295
10.2M
                    silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
296
10.2M
                    LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
297
10.2M
                }
298
57.2M
            } else {
299
                /* Within 5 bits of budget: close enough */
300
92.1k
                break;
301
92.1k
            }
302
303
58.0M
            if ( !found_lower && nBits > maxBits ) {
304
410k
                int j;
305
1.86M
                for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
306
1.45M
                    int sum=0;
307
73.9M
                    for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
308
72.5M
                        sum += abs( psEnc->sCmn.pulses[j] );
309
72.5M
                    }
310
1.45M
                    if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
311
976k
                        best_sum[i] = sum;
312
976k
                        best_gain_mult[i] = gainMult_Q8;
313
976k
                    } else {
314
476k
                        gain_lock[i] = 1;
315
476k
                    }
316
1.45M
                }
317
410k
            }
318
58.0M
            if( ( found_lower & found_upper ) == 0 ) {
319
                /* Adjust gain according to high-rate rate/distortion curve */
320
57.1M
                if( nBits > maxBits ) {
321
410k
                    if (gainMult_Q8 < 16384) {
322
410k
                        gainMult_Q8 *= 2;
323
410k
                    } else {
324
0
                        gainMult_Q8 = 32767;
325
0
                    }
326
56.7M
                } else {
327
56.7M
                    opus_int32 gain_factor_Q16;
328
56.7M
                    gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
329
56.7M
                    gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
330
56.7M
                }
331
332
57.1M
            } else {
333
                /* Adjust gain by interpolating */
334
873k
                gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
335
                /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
336
873k
                if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
337
177k
                    gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
338
177k
                } else
339
695k
                if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
340
204k
                    gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
341
204k
                }
342
873k
            }
343
344
238M
            for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
345
180M
                opus_int16 tmp;
346
180M
                if ( gain_lock[i] ) {
347
581k
                    tmp = best_gain_mult[i];
348
179M
                } else {
349
179M
                    tmp = gainMult_Q8;
350
179M
                }
351
180M
                sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
352
180M
            }
353
354
            /* Quantize gains */
355
58.0M
            psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
356
58.0M
            silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
357
58.0M
                  &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
358
359
            /* Unique identifier of gains vector */
360
58.0M
            gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
361
58.0M
        }
362
21.5M
    }
363
364
    /* Update input buffer */
365
21.5M
    silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
366
21.5M
        ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
367
368
    /* Exit without entropy coding */
369
21.5M
    if( psEnc->sCmn.prefillFlag ) {
370
        /* No payload */
371
272
        *pnBytesOut = 0;
372
272
        RESTORE_STACK;
373
272
        return ret;
374
272
    }
375
376
    /* Parameters needed for next frame */
377
21.5M
    psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
378
21.5M
    psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
379
380
    /****************************************/
381
    /* Finalize payload                     */
382
    /****************************************/
383
21.5M
    psEnc->sCmn.first_frame_after_reset = 0;
384
    /* Payload size */
385
21.5M
    *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
386
387
21.5M
    RESTORE_STACK;
388
21.5M
    return ret;
389
21.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
21.5M
{
399
21.5M
    opus_int32   TempGains_Q16[ MAX_NB_SUBFR ];
400
21.5M
    SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
401
21.5M
    silk_nsq_state sNSQ_LBRR;
402
403
    /*******************************************/
404
    /* Control use of inband LBRR              */
405
    /*******************************************/
406
21.5M
    if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
407
259k
        psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
408
409
        /* Copy noise shaping quantizer state and quantization indices from regular encoding */
410
259k
        silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
411
259k
        silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
412
413
        /* Save original gains */
414
259k
        silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
415
416
259k
        if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
417
            /* First frame in packet or previous frame not LBRR coded */
418
202k
            psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
419
420
            /* Increase Gains to get target LBRR rate */
421
202k
            psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
422
202k
            psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
423
202k
        }
424
425
        /* Decode to get gains in sync with decoder         */
426
        /* Overwrite unquantized gains with quantized gains */
427
259k
        silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
428
259k
            &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
429
430
        /*****************************************/
431
        /* Noise shaping quantization            */
432
        /*****************************************/
433
259k
        if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
434
135k
            silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
435
135k
                psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
436
135k
                psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
437
135k
                psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
438
135k
        } else {
439
124k
            silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
440
124k
                psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
441
124k
                psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
442
124k
                psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
443
124k
        }
444
445
        /* Restore original gains */
446
259k
        silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
447
259k
    }
448
21.5M
}