Fixes a crash on fixed-point stereo voice and some valgrind uninitialized errors
[opus.git] / silk / float / silk_encode_frame_FLP.c
1 /***********************************************************************\r
2 Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
3 Redistribution and use in source and binary forms, with or without \r
4 modification, (subject to the limitations in the disclaimer below) \r
5 are permitted provided that the following conditions are met:\r
6 - Redistributions of source code must retain the above copyright notice,\r
7 this list of conditions and the following disclaimer.\r
8 - Redistributions in binary form must reproduce the above copyright \r
9 notice, this list of conditions and the following disclaimer in the \r
10 documentation and/or other materials provided with the distribution.\r
11 - Neither the name of Skype Limited, nor the names of specific \r
12 contributors, may be used to endorse or promote products derived from \r
13 this software without specific prior written permission.\r
14 NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
15 BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
16 CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
17 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
18 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
19 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
22 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
23 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
26 ***********************************************************************/\r
27 \r
28 #include "silk_main_FLP.h"\r
29 #include "silk_tuning_parameters.h"\r
30 \r
31 /****************/\r
32 /* Encode frame */\r
33 /****************/\r
34 SKP_int silk_encode_frame_FLP( \r
35     silk_encoder_state_FLP          *psEnc,             /* I/O  Encoder state FLP                       */\r
36     SKP_int32                       *pnBytesOut,        /*   O  Number of payload bytes                 */\r
37     ec_enc                          *psRangeEnc         /* I/O  compressor data structure               */\r
38 )\r
39 {\r
40     silk_encoder_control_FLP sEncCtrl;\r
41     SKP_int     i, ret = 0;\r
42     SKP_float   *x_frame, *res_pitch_frame;\r
43     SKP_float   xfw[ MAX_FRAME_LENGTH ];\r
44     SKP_float   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];\r
45 \r
46 TIC(ENCODE_FRAME)\r
47 \r
48     psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;\r
49 \r
50     /**************************************************************/\r
51     /* Setup Input Pointers, and insert frame in input buffer    */\r
52     /*************************************************************/\r
53     /* pointers aligned with start of frame to encode */\r
54     x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */\r
55     res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */\r
56 \r
57     /****************************/\r
58     /* Voice Activity Detection */\r
59     /****************************/\r
60 TIC(VAD)\r
61     ret = silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf - 1 );\r
62 TOC(VAD)\r
63 \r
64     /**************************************************/\r
65     /* Convert speech activity into VAD and DTX flags */\r
66     /**************************************************/\r
67     if( psEnc->sCmn.nFramesEncoded == 0 ) {\r
68         psEnc->sCmn.inDTX = psEnc->sCmn.useDTX;\r
69     }\r
70     if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {\r
71         psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;\r
72         psEnc->sCmn.noSpeechCounter++;\r
73         if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {\r
74             psEnc->sCmn.inDTX = 0;\r
75         } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {\r
76             psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;\r
77             psEnc->sCmn.inDTX           = 0;\r
78         }\r
79         psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;\r
80     } else {\r
81         psEnc->sCmn.noSpeechCounter    = 0;\r
82         psEnc->sCmn.inDTX              = 0;\r
83         psEnc->sCmn.indices.signalType = TYPE_UNVOICED;\r
84         psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;\r
85     }\r
86 \r
87     /***************************************/\r
88     /* Ensure smooth bandwidth transitions */\r
89     /***************************************/\r
90     silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf - 1, psEnc->sCmn.frame_length );\r
91 \r
92     /*******************************************/\r
93     /* Copy new frame to front of input buffer */\r
94     /*******************************************/\r
95     SKP_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf - 1, psEnc->sCmn.frame_length );\r
96 \r
97     /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */\r
98     for( i = 0; i < 8; i++ ) {\r
99         x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f;\r
100     }\r
101 \r
102     /*****************************************/\r
103     /* Find pitch lags, initial LPC analysis */\r
104     /*****************************************/\r
105 TIC(FIND_PITCH)\r
106     silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame );\r
107 TOC(FIND_PITCH)\r
108 \r
109     /************************/\r
110     /* Noise shape analysis */\r
111     /************************/\r
112 TIC(NOISE_SHAPE_ANALYSIS)\r
113     silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame );\r
114 TOC(NOISE_SHAPE_ANALYSIS)\r
115 \r
116     /***************************************************/\r
117     /* Find linear prediction coefficients (LPC + LTP) */\r
118     /***************************************************/\r
119 TIC(FIND_PRED_COEF)\r
120     silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame );\r
121 TOC(FIND_PRED_COEF)\r
122 \r
123     /****************************************/\r
124     /* Process gains                        */\r
125     /****************************************/\r
126 TIC(PROCESS_GAINS)\r
127     silk_process_gains_FLP( psEnc, &sEncCtrl );\r
128 TOC(PROCESS_GAINS)\r
129 \r
130     /*****************************************/\r
131     /* Prefiltering for noise shaper         */\r
132     /*****************************************/\r
133 TIC(PREFILTER)\r
134     silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame );\r
135 TOC(PREFILTER)\r
136 \r
137     /****************************************/\r
138     /* Low Bitrate Redundant Encoding       */\r
139     /****************************************/\r
140 TIC(LBRR)\r
141     silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw );\r
142 TOC(LBRR)\r
143 \r
144     /*****************************************/\r
145     /* Noise shaping quantization            */\r
146     /*****************************************/\r
147 TIC(NSQ)\r
148     silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw );\r
149 TOC(NSQ)\r
150 \r
151     /* Update input buffer */\r
152     SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], \r
153         ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_float ) );\r
154 \r
155     /* Parameters needed for next frame */\r
156     psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];\r
157     psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;\r
158 \r
159     /* Exit without entropy coding */\r
160     if( psEnc->sCmn.prefillFlag ) {\r
161         /* No payload */\r
162         *pnBytesOut = 0;\r
163         return ret;\r
164     }\r
165 \r
166     /****************************************/\r
167     /* Encode Parameters                    */\r
168     /****************************************/\r
169 TIC(ENCODE_PARAMS)\r
170     silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0 );\r
171 TOC(ENCODE_PARAMS)\r
172 \r
173     /****************************************/\r
174     /* Encode Excitation Signal             */\r
175     /****************************************/\r
176 TIC(ENCODE_PULSES)\r
177     silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, \r
178         psEnc->sCmn.pulses, psEnc->sCmn.frame_length );\r
179 TOC(ENCODE_PULSES)\r
180 \r
181     /****************************************/\r
182     /* Finalize payload                     */\r
183     /****************************************/\r
184     psEnc->sCmn.first_frame_after_reset = 0;\r
185     if( ++psEnc->sCmn.nFramesEncoded >= psEnc->sCmn.nFramesPerPacket ) {\r
186         /* Payload size */\r
187         *pnBytesOut = SKP_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );\r
188 \r
189         /* Reset the number of frames in payload buffer */\r
190         psEnc->sCmn.nFramesEncoded = 0;\r
191     } else {\r
192         /* No payload this time */\r
193         *pnBytesOut = 0;\r
194     }\r
195 TOC(ENCODE_FRAME)\r
196 \r
197 #ifdef SAVE_ALL_INTERNAL_DATA\r
198     //DEBUG_STORE_DATA( xf.dat,                   pIn_HP_LP,                           psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );\r
199     //DEBUG_STORE_DATA( xfw.dat,                  xfw,                                 psEnc->sCmn.frame_length * sizeof( SKP_float ) );\r
200     DEBUG_STORE_DATA( pitchL.dat,               sEncCtrl.pitchL,                                 MAX_NB_SUBFR * sizeof( SKP_int   ) );\r
201     DEBUG_STORE_DATA( pitchG_quantized.dat,     sEncCtrl.LTPCoef,            psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) );\r
202     DEBUG_STORE_DATA( LTPcorr.dat,              &psEnc->LTPCorr,                                                sizeof( SKP_float ) );\r
203     DEBUG_STORE_DATA( gains.dat,                sEncCtrl.Gains,                          psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
204     DEBUG_STORE_DATA( gains_indices.dat,        &psEnc->sCmn.indices.GainsIndices,       psEnc->sCmn.nb_subfr * sizeof( SKP_int8  ) );\r
205     DEBUG_STORE_DATA( quantOffsetType.dat,      &psEnc->sCmn.indices.quantOffsetType,                           sizeof( SKP_int8  ) );\r
206     DEBUG_STORE_DATA( speech_activity_q8.dat,   &psEnc->sCmn.speech_activity_Q8,                                sizeof( SKP_int   ) );\r
207     DEBUG_STORE_DATA( signalType.dat,           &psEnc->sCmn.indices.signalType,                                sizeof( SKP_int8  ) ); \r
208     DEBUG_STORE_DATA( lag_index.dat,            &psEnc->sCmn.indices.lagIndex,                                  sizeof( SKP_int16 ) ); \r
209     DEBUG_STORE_DATA( contour_index.dat,        &psEnc->sCmn.indices.contourIndex,                              sizeof( SKP_int8  ) ); \r
210     DEBUG_STORE_DATA( per_index.dat,            &psEnc->sCmn.indices.PERIndex,                                  sizeof( SKP_int8  ) );\r
211     DEBUG_STORE_DATA( PredCoef.dat,             &sEncCtrl.PredCoef[ 1 ],          psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );\r
212     DEBUG_STORE_DATA( ltp_scale_idx.dat,        &psEnc->sCmn.indices.LTP_scaleIndex,                            sizeof( SKP_int8   ) );\r
213 //  DEBUG_STORE_DATA( xq.dat,                   psEnc->sCmn.sNSQ.xqBuf,                psEnc->sCmn.frame_length * sizeof( SKP_float ) );\r
214 #endif\r
215     return ret;\r
216 }\r
217 \r
218 /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate  */\r
219 void silk_LBRR_encode_FLP(\r
220     silk_encoder_state_FLP          *psEnc,             /* I/O  Encoder state FLP                       */\r
221     silk_encoder_control_FLP        *psEncCtrl,         /* I/O  Encoder control FLP                     */\r
222     const SKP_float                 xfw[]               /* I    Input signal                            */\r
223 )\r
224 {\r
225     SKP_int     k;\r
226     SKP_int32   Gains_Q16[ MAX_NB_SUBFR ];\r
227     SKP_float   TempGains[ MAX_NB_SUBFR ];\r
228     SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];\r
229     silk_nsq_state sNSQ_LBRR;\r
230 \r
231     /*******************************************/\r
232     /* Control use of inband LBRR              */\r
233     /*******************************************/\r
234     if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {\r
235         psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;\r
236 \r
237         /* Copy noise shaping quantizer state and quantization indices from regular encoding */\r
238         SKP_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );\r
239         SKP_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );\r
240 \r
241         /* Save original gains */\r
242         SKP_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
243 \r
244         if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {\r
245             /* First frame in packet or previous frame not LBRR coded */\r
246             psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;\r
247 \r
248             /* Increase Gains to get target LBRR rate */\r
249             psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases;\r
250             psIndices_LBRR->GainsIndices[ 0 ] = SKP_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );\r
251         }\r
252 \r
253         /* Decode to get gains in sync with decoder */\r
254         silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices, \r
255             &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesEncoded, psEnc->sCmn.nb_subfr );\r
256 \r
257         /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */\r
258         for( k = 0; k <  psEnc->sCmn.nb_subfr; k++ ) {\r
259             psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f );\r
260         }\r
261 \r
262         /*****************************************/\r
263         /* Noise shaping quantization            */\r
264         /*****************************************/\r
265         silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR, \r
266             psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw );\r
267 \r
268         /* Restore original gains */\r
269         SKP_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
270     }\r
271 }\r