Coverage Report

Created: 2025-12-14 07:08

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