Hardening asserts for SILK float
[opus.git] / silk / float / encode_frame_FLP.c
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_FLP.h"
34 #include "tuning_parameters.h"
35
36 /* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */
37 static OPUS_INLINE void silk_LBRR_encode_FLP(
38     silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */
39     silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */
40     const silk_float                xfw[],                              /* I    Input signal                                */
41     opus_int                        condCoding                          /* I    The type of conditional coding used so far for this frame */
42 );
43
44 void silk_encode_do_VAD_FLP(
45     silk_encoder_state_FLP          *psEnc                              /* I/O  Encoder state FLP                           */
46 )
47 {
48     /****************************/
49     /* Voice Activity Detection */
50     /****************************/
51     silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
52
53     /**************************************************/
54     /* Convert speech activity into VAD and DTX flags */
55     /**************************************************/
56     if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
57         psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
58         psEnc->sCmn.noSpeechCounter++;
59         if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
60             psEnc->sCmn.inDTX = 0;
61         } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
62             psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
63             psEnc->sCmn.inDTX           = 0;
64         }
65         psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
66     } else {
67         psEnc->sCmn.noSpeechCounter    = 0;
68         psEnc->sCmn.inDTX              = 0;
69         psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
70         psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
71     }
72 }
73
74 /****************/
75 /* Encode frame */
76 /****************/
77 opus_int silk_encode_frame_FLP(
78     silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */
79     opus_int32                      *pnBytesOut,                        /* O    Number of payload bytes;                    */
80     ec_enc                          *psRangeEnc,                        /* I/O  compressor data structure                   */
81     opus_int                        condCoding,                         /* I    The type of conditional coding to use       */
82     opus_int                        maxBits,                            /* I    If > 0: maximum number of output bits       */
83     opus_int                        useCBR                              /* I    Flag to force constant-bitrate operation    */
84 )
85 {
86     silk_encoder_control_FLP sEncCtrl;
87     opus_int     i, iter, maxIter, found_upper, found_lower, ret = 0;
88     silk_float   *x_frame, *res_pitch_frame;
89     silk_float   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
90     ec_enc       sRangeEnc_copy, sRangeEnc_copy2;
91     silk_nsq_state sNSQ_copy, sNSQ_copy2;
92     opus_int32   seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
93     opus_int32   gainsID, gainsID_lower, gainsID_upper;
94     opus_int16   gainMult_Q8;
95     opus_int16   ec_prevLagIndex_copy;
96     opus_int     ec_prevSignalType_copy;
97     opus_int8    LastGainIndex_copy2;
98     opus_int32   pGains_Q16[ MAX_NB_SUBFR ];
99     opus_uint8   ec_buf_copy[ 1275 ];
100     opus_int     gain_lock[ MAX_NB_SUBFR ] = {0};
101     opus_int16   best_gain_mult[ MAX_NB_SUBFR ];
102     opus_int     best_sum[ MAX_NB_SUBFR ];
103
104     /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
105     LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
106
107     psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
108
109     /**************************************************************/
110     /* Set up Input Pointers, and insert frame in input buffer    */
111     /**************************************************************/
112     /* pointers aligned with start of frame to encode */
113     x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */
114     res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */
115
116     /***************************************/
117     /* Ensure smooth bandwidth transitions */
118     /***************************************/
119     silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
120
121     /*******************************************/
122     /* Copy new frame to front of input buffer */
123     /*******************************************/
124     silk_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
125
126     /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */
127     for( i = 0; i < 8; i++ ) {
128         x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f;
129     }
130
131     if( !psEnc->sCmn.prefillFlag ) {
132         /*****************************************/
133         /* Find pitch lags, initial LPC analysis */
134         /*****************************************/
135         silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );
136
137         /************************/
138         /* Noise shape analysis */
139         /************************/
140         silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
141
142         /***************************************************/
143         /* Find linear prediction coefficients (LPC + LTP) */
144         /***************************************************/
145         silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
146
147         /****************************************/
148         /* Process gains                        */
149         /****************************************/
150         silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding );
151
152         /****************************************/
153         /* Low Bitrate Redundant Encoding       */
154         /****************************************/
155         silk_LBRR_encode_FLP( psEnc, &sEncCtrl, x_frame, condCoding );
156
157         /* Loop over quantizer and entroy coding to control bitrate */
158         maxIter = 6;
159         gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
160         found_lower = 0;
161         found_upper = 0;
162         gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
163         gainsID_lower = -1;
164         gainsID_upper = -1;
165         /* Copy part of the input state */
166         silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
167         silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
168         seed_copy = psEnc->sCmn.indices.Seed;
169         ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
170         ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
171         for( iter = 0; ; iter++ ) {
172             if( gainsID == gainsID_lower ) {
173                 nBits = nBits_lower;
174             } else if( gainsID == gainsID_upper ) {
175                 nBits = nBits_upper;
176             } else {
177                 /* Restore part of the input state */
178                 if( iter > 0 ) {
179                     silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
180                     silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
181                     psEnc->sCmn.indices.Seed = seed_copy;
182                     psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
183                     psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
184                 }
185
186                 /*****************************************/
187                 /* Noise shaping quantization            */
188                 /*****************************************/
189                 silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, x_frame );
190
191                 if ( iter == maxIter && !found_lower ) {
192                     silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
193                 }
194
195                 /****************************************/
196                 /* Encode Parameters                    */
197                 /****************************************/
198                 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
199
200                 /****************************************/
201                 /* Encode Excitation Signal             */
202                 /****************************************/
203                 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
204                       psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
205
206                 nBits = ec_tell( psRangeEnc );
207
208                 /* If we still bust after the last iteration, do some damage control. */
209                 if ( iter == maxIter && !found_lower && nBits > maxBits ) {
210                     silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
211
212                     /* Keep gains the same as the last frame. */
213                     psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
214                     for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
215                         psEnc->sCmn.indices.GainsIndices[ i ] = 4;
216                     }
217                     if (condCoding != CODE_CONDITIONALLY) {
218                        psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
219                     }
220                     psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
221                     psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
222                     /* Clear all pulses. */
223                     for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
224                         psEnc->sCmn.pulses[ i ] = 0;
225                     }
226
227                     silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
228
229                     silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
230                         psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
231
232                     nBits = ec_tell( psRangeEnc );
233                 }
234
235                 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
236                     break;
237                 }
238             }
239
240             if( iter == maxIter ) {
241                 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
242                     /* Restore output state from earlier iteration that did meet the bitrate budget */
243                     silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
244                     celt_assert( sRangeEnc_copy2.offs <= 1275 );
245                     silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
246                     silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
247                     psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
248                 }
249                 break;
250             }
251
252             if( nBits > maxBits ) {
253                 if( found_lower == 0 && iter >= 2 ) {
254                     /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
255                     sEncCtrl.Lambda = silk_max_float(sEncCtrl.Lambda*1.5f, 1.5f);
256                     /* Reducing dithering can help us hit the target. */
257                     psEnc->sCmn.indices.quantOffsetType = 0;
258                     found_upper = 0;
259                     gainsID_upper = -1;
260                 } else {
261                     found_upper = 1;
262                     nBits_upper = nBits;
263                     gainMult_upper = gainMult_Q8;
264                     gainsID_upper = gainsID;
265                 }
266             } else if( nBits < maxBits - 5 ) {
267                 found_lower = 1;
268                 nBits_lower = nBits;
269                 gainMult_lower = gainMult_Q8;
270                 if( gainsID != gainsID_lower ) {
271                     gainsID_lower = gainsID;
272                     /* Copy part of the output state */
273                     silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
274                     celt_assert( psRangeEnc->offs <= 1275 );
275                     silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
276                     silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
277                     LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
278                 }
279             } else {
280                 /* Within 5 bits of budget: close enough */
281                 break;
282             }
283
284             if ( !found_lower && nBits > maxBits ) {
285                 int j;
286                 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
287                     int sum=0;
288                     for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
289                         sum += abs( psEnc->sCmn.pulses[j] );
290                     }
291                     if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
292                         best_sum[i] = sum;
293                         best_gain_mult[i] = gainMult_Q8;
294                     } else {
295                         gain_lock[i] = 1;
296                     }
297                 }
298             }
299             if( ( found_lower & found_upper ) == 0 ) {
300                 /* Adjust gain according to high-rate rate/distortion curve */
301                 if( nBits > maxBits ) {
302                     if (gainMult_Q8 < 16384) {
303                         gainMult_Q8 *= 2;
304                     } else {
305                         gainMult_Q8 = 32767;
306                     }
307                 } else {
308                     opus_int32 gain_factor_Q16;
309                     gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
310                     gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
311                 }
312             } else {
313                 /* Adjust gain by interpolating */
314                 gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower );
315                 /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
316                 if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
317                     gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
318                 } else
319                 if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
320                     gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
321                 }
322             }
323
324             for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
325                 opus_int16 tmp;
326                 if ( gain_lock[i] ) {
327                     tmp = best_gain_mult[i];
328                 } else {
329                     tmp = gainMult_Q8;
330                 }
331                 pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
332             }
333
334             /* Quantize gains */
335             psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
336             silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16,
337                   &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
338
339             /* Unique identifier of gains vector */
340             gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
341
342             /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
343             for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
344                 sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f;
345             }
346         }
347     }
348
349     /* Update input buffer */
350     silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
351         ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( silk_float ) );
352
353     /* Exit without entropy coding */
354     if( psEnc->sCmn.prefillFlag ) {
355         /* No payload */
356         *pnBytesOut = 0;
357         return ret;
358     }
359
360     /* Parameters needed for next frame */
361     psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
362     psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
363
364     /****************************************/
365     /* Finalize payload                     */
366     /****************************************/
367     psEnc->sCmn.first_frame_after_reset = 0;
368     /* Payload size */
369     *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
370
371     return ret;
372 }
373
374 /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate  */
375 static OPUS_INLINE void silk_LBRR_encode_FLP(
376     silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */
377     silk_encoder_control_FLP        *psEncCtrl,                         /* I/O  Encoder control FLP                         */
378     const silk_float                xfw[],                              /* I    Input signal                                */
379     opus_int                        condCoding                          /* I    The type of conditional coding used so far for this frame */
380 )
381 {
382     opus_int     k;
383     opus_int32   Gains_Q16[ MAX_NB_SUBFR ];
384     silk_float   TempGains[ MAX_NB_SUBFR ];
385     SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
386     silk_nsq_state sNSQ_LBRR;
387
388     /*******************************************/
389     /* Control use of inband LBRR              */
390     /*******************************************/
391     if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
392         psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
393
394         /* Copy noise shaping quantizer state and quantization indices from regular encoding */
395         silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
396         silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
397
398         /* Save original gains */
399         silk_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );
400
401         if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
402             /* First frame in packet or previous frame not LBRR coded */
403             psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
404
405             /* Increase Gains to get target LBRR rate */
406             psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases;
407             psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
408         }
409
410         /* Decode to get gains in sync with decoder */
411         silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices,
412             &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
413
414         /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
415         for( k = 0; k <  psEnc->sCmn.nb_subfr; k++ ) {
416             psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f );
417         }
418
419         /*****************************************/
420         /* Noise shaping quantization            */
421         /*****************************************/
422         silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR,
423             psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw );
424
425         /* Restore original gains */
426         silk_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );
427     }
428 }