blob: c3da9bcfd136179f137f5f932c7587b19f3d96c4 [file] [log] [blame]
Gregory Maxwellae231142011-07-30 08:18:48 -04001/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, (subject to the limitations in the disclaimer below)
5are permitted provided that the following conditions are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Skype Limited, nor the names of specific
12contributors, may be used to endorse or promote products derived from
13this software without specific prior written permission.
14NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
15BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
16CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
17BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
Jean-Marc Valin5a484122011-08-15 10:49:53 -040028#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
Jean-Marc Valin1c2f5632011-09-16 01:16:53 -070032#include "main_FIX.h"
33#include "tuning_parameters.h"
Gregory Maxwellae231142011-07-30 08:18:48 -040034
35/****************/
36/* Encode frame */
37/****************/
38opus_int silk_encode_frame_FIX(
39 silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
40 opus_int32 *pnBytesOut, /* O Number of payload bytes */
Timothy B. Terriberry53cc1a02011-10-14 13:38:24 -070041 ec_enc *psRangeEnc, /* I/O compressor data structure */
42 opus_int condCoding /* I The type of conditional coding to use */
Gregory Maxwellae231142011-07-30 08:18:48 -040043)
44{
45 silk_encoder_control_FIX sEncCtrl;
46 opus_int ret = 0;
47 opus_int16 *x_frame, *res_pitch_frame;
48 opus_int16 xfw[ MAX_FRAME_LENGTH ];
49 opus_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
50
51TIC(ENCODE_FRAME)
52
53 psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
54
55 /**************************************************************/
56 /* Setup Input Pointers, and insert frame in input buffer */
57 /*************************************************************/
58 /* pointers aligned with start of frame to encode */
59 x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */
60 res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */
61
62 /****************************/
63 /* Voice Activity Detection */
64 /****************************/
65TIC(VAD)
Gregory Maxwell16b25e92011-09-06 22:58:01 -040066 ret = silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1 );
Gregory Maxwellae231142011-07-30 08:18:48 -040067TOC(VAD)
68
69 /**************************************************/
70 /* Convert speech activity into VAD and DTX flags */
71 /**************************************************/
72 if( psEnc->sCmn.nFramesEncoded == 0 ) {
73 psEnc->sCmn.inDTX = psEnc->sCmn.useDTX;
74 }
75 if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
76 psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
77 psEnc->sCmn.noSpeechCounter++;
78 if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {
79 psEnc->sCmn.inDTX = 0;
80 } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
81 psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
82 psEnc->sCmn.inDTX = 0;
83 }
84 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
85 } else {
86 psEnc->sCmn.noSpeechCounter = 0;
87 psEnc->sCmn.inDTX = 0;
88 psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
89 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
90 }
91
92 /***************************************/
93 /* Ensure smooth bandwidth transitions */
94 /***************************************/
Gregory Maxwell16b25e92011-09-06 22:58:01 -040095 silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
Gregory Maxwellae231142011-07-30 08:18:48 -040096
97 /*******************************************/
98 /* Copy new frame to front of input buffer */
99 /*******************************************/
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700100 silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400101
102 /*****************************************/
103 /* Find pitch lags, initial LPC analysis */
104 /*****************************************/
105TIC(FIND_PITCH)
106 silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );
107TOC(FIND_PITCH)
108
109 /************************/
110 /* Noise shape analysis */
111 /************************/
112TIC(NOISE_SHAPE_ANALYSIS)
113 silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
114TOC(NOISE_SHAPE_ANALYSIS)
115
116 /***************************************************/
117 /* Find linear prediction coefficients (LPC + LTP) */
118 /***************************************************/
119TIC(FIND_PRED_COEF)
Timothy B. Terriberry53cc1a02011-10-14 13:38:24 -0700120 silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
Gregory Maxwellae231142011-07-30 08:18:48 -0400121TOC(FIND_PRED_COEF)
122
123 /****************************************/
124 /* Process gains */
125 /****************************************/
126TIC(PROCESS_GAINS)
127 silk_process_gains_FIX( psEnc, &sEncCtrl );
128TOC(PROCESS_GAINS)
129
130 /*****************************************/
131 /* Prefiltering for noise shaper */
132 /*****************************************/
133TIC(PREFILTER)
134 silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );
135TOC(PREFILTER)
136
137 /****************************************/
138 /* Low Bitrate Redundant Encoding */
139 /****************************************/
140TIC(LBRR)
Timothy B. Terriberry53cc1a02011-10-14 13:38:24 -0700141 silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw, condCoding );
Gregory Maxwellae231142011-07-30 08:18:48 -0400142TOC(LBRR)
143
144 /*****************************************/
145 /* Noise shaping quantization */
146 /*****************************************/
147TIC(NSQ)
148 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
149 silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
150 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
151 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
152 } else {
153 silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
154 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
155 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
156 }
157TOC(NSQ)
158
159 /* Update input buffer */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700160 silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
Gregory Maxwellae231142011-07-30 08:18:48 -0400161 ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
162
163 /* Parameters needed for next frame */
164 psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
165 psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
166
167 /* Exit without entropy coding */
168 if( psEnc->sCmn.prefillFlag ) {
169 /* No payload */
170 *pnBytesOut = 0;
171 return ret;
172 }
173
174 /****************************************/
175 /* Encode Parameters */
176 /****************************************/
177TIC(ENCODE_PARAMS)
Timothy B. Terriberry53cc1a02011-10-14 13:38:24 -0700178 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
Gregory Maxwellae231142011-07-30 08:18:48 -0400179TOC(ENCODE_PARAMS)
180
181 /****************************************/
182 /* Encode Excitation Signal */
183 /****************************************/
184TIC(ENCODE_PULSES)
185 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
186 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
187TOC(ENCODE_PULSES)
188
189 /****************************************/
190 /* Finalize payload */
191 /****************************************/
192 psEnc->sCmn.first_frame_after_reset = 0;
Jean-Marc Valine4de8a92011-09-28 14:23:01 -0400193 /* Payload size */
194 *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400195TOC(ENCODE_FRAME)
196
197#ifdef SAVE_ALL_INTERNAL_DATA
198 {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700199 silk_float tmp[ MAX_NB_SUBFR * LTP_ORDER ];
Gregory Maxwellae231142011-07-30 08:18:48 -0400200 int i;
201 DEBUG_STORE_DATA( xf.dat, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
202 DEBUG_STORE_DATA( xfw.dat, xfw, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
203 DEBUG_STORE_DATA( pitchL.dat, sEncCtrl.pitchL, psEnc->sCmn.nb_subfr * sizeof( opus_int ) );
204 for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700205 tmp[ i ] = (silk_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f;
Gregory Maxwellae231142011-07-30 08:18:48 -0400206 }
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700207 DEBUG_STORE_DATA( pitchG_quantized.dat, tmp, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400208 for( i = 0; i <psEnc->sCmn.predictLPCOrder; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700209 tmp[ i ] = (silk_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f;
Gregory Maxwellae231142011-07-30 08:18:48 -0400210 }
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700211 DEBUG_STORE_DATA( PredCoef.dat, tmp, psEnc->sCmn.predictLPCOrder * sizeof( silk_float ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400212
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700213 tmp[ 0 ] = (silk_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f;
214 DEBUG_STORE_DATA( LTPredCodGain.dat, tmp, sizeof( silk_float ) );
215 tmp[ 0 ] = (silk_float)psEnc->LTPCorr_Q15 / 32768.0f;
216 DEBUG_STORE_DATA( LTPcorr.dat, tmp, sizeof( silk_float ) );
217 tmp[ 0 ] = (silk_float)psEnc->sCmn.input_tilt_Q15 / 32768.0f;
218 DEBUG_STORE_DATA( tilt.dat, tmp, sizeof( silk_float ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400219 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700220 tmp[ i ] = (silk_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f;
Gregory Maxwellae231142011-07-30 08:18:48 -0400221 }
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700222 DEBUG_STORE_DATA( gains.dat, tmp, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400223 DEBUG_STORE_DATA( gains_indices.dat, &psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr * sizeof( opus_int ) );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700224 tmp[ 0 ] = (silk_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f;
225 DEBUG_STORE_DATA( current_SNR_db.dat, tmp, sizeof( silk_float ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400226 DEBUG_STORE_DATA( quantOffsetType.dat, &psEnc->sCmn.indices.quantOffsetType, sizeof( opus_int ) );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700227 tmp[ 0 ] = (silk_float)psEnc->sCmn.speech_activity_Q8 / 256.0f;
228 DEBUG_STORE_DATA( speech_activity.dat, tmp, sizeof( silk_float ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400229 for( i = 0; i < VAD_N_BANDS; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700230 tmp[ i ] = (silk_float)psEnc->sCmn.input_quality_bands_Q15[ i ] / 32768.0f;
Gregory Maxwellae231142011-07-30 08:18:48 -0400231 }
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700232 DEBUG_STORE_DATA( input_quality_bands.dat, tmp, VAD_N_BANDS * sizeof( silk_float ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400233 DEBUG_STORE_DATA( signalType.dat, &psEnc->sCmn.indices.signalType, sizeof( opus_int8) );
234 DEBUG_STORE_DATA( lag_index.dat, &psEnc->sCmn.indices.lagIndex, sizeof( opus_int16 ) );
235 DEBUG_STORE_DATA( contour_index.dat, &psEnc->sCmn.indices.contourIndex, sizeof( opus_int8 ) );
236 DEBUG_STORE_DATA( per_index.dat, &psEnc->sCmn.indices.PERIndex, sizeof( opus_int8) );
237 }
238#endif
239 return ret;
240}
241
242/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */
243void silk_LBRR_encode_FIX(
244 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
245 silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
Timothy B. Terriberry53cc1a02011-10-14 13:38:24 -0700246 const opus_int16 xfw[], /* I Input signal */
247 opus_int condCoding /* I The type of conditional coding used so far for this frame */
Gregory Maxwellae231142011-07-30 08:18:48 -0400248)
249{
250 opus_int32 TempGains_Q16[ MAX_NB_SUBFR ];
251 SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
252 silk_nsq_state sNSQ_LBRR;
253
254 /*******************************************/
255 /* Control use of inband LBRR */
256 /*******************************************/
257 if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
258 psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
259
260 /* Copy noise shaping quantizer state and quantization indices from regular encoding */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700261 silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
262 silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400263
264 /* Save original gains */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700265 silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400266
267 if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
268 /* First frame in packet or previous frame not LBRR coded */
269 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
270
271 /* Increase Gains to get target LBRR rate */
272 psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700273 psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400274 }
275
276 /* Decode to get gains in sync with decoder */
277 /* Overwrite unquantized gains with quantized gains */
278 silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
Timothy B. Terriberry53cc1a02011-10-14 13:38:24 -0700279 &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
Gregory Maxwellae231142011-07-30 08:18:48 -0400280
281 /*****************************************/
282 /* Noise shaping quantization */
283 /*****************************************/
284 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
285 silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw,
286 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
287 psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
288 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
289 } else {
290 silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw,
291 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
292 psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
293 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
294 }
295
296 /* Restore original gains */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700297 silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400298 }
299}