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
28 #include "SKP_Silk_main_FIX.h"
\r
29 #include "SKP_Silk_tuning_parameters.h"
\r
34 SKP_int SKP_Silk_encode_frame_FIX(
\r
35 SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
\r
36 SKP_int32 *pnBytesOut, /* O Number of payload bytes */
\r
37 ec_enc *psRangeEnc /* I/O compressor data structure */
\r
40 SKP_Silk_encoder_control_FIX sEncCtrl;
\r
42 SKP_int16 *x_frame, *res_pitch_frame;
\r
43 SKP_int16 xfw[ MAX_FRAME_LENGTH ];
\r
44 SKP_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
\r
48 psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
\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
57 /****************************/
\r
58 /* Voice Activity Detection */
\r
59 /****************************/
\r
61 ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf );
\r
64 /**************************************************/
\r
65 /* Convert speech activity into VAD and DTX flags */
\r
66 /**************************************************/
\r
67 if( psEnc->sCmn.nFramesAnalyzed == 0 ) {
\r
68 psEnc->sCmn.inDTX = psEnc->sCmn.useDTX;
\r
70 if( psEnc->sCmn.speech_activity_Q8 < SKP_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
79 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesAnalyzed ] = 0;
\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.nFramesAnalyzed ] = 1;
\r
87 /*******************************************/
\r
88 /* High-pass filtering of the input signal */
\r
89 /*******************************************/
\r
91 SKP_Silk_HP_variable_cutoff( &psEnc->sCmn, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf, psEnc->sCmn.frame_length );
\r
94 /* Ensure smooth bandwidth transitions */
\r
95 SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length );
\r
97 /*****************************************/
\r
98 /* Find pitch lags, initial LPC analysis */
\r
99 /*****************************************/
\r
101 SKP_Silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );
\r
104 /************************/
\r
105 /* Noise shape analysis */
\r
106 /************************/
\r
107 TIC(NOISE_SHAPE_ANALYSIS)
\r
108 SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
\r
109 TOC(NOISE_SHAPE_ANALYSIS)
\r
111 /*****************************************/
\r
112 /* Prefiltering for noise shaper */
\r
113 /*****************************************/
\r
115 SKP_Silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );
\r
118 /***************************************************/
\r
119 /* Find linear prediction coefficients (LPC + LTP) */
\r
120 /***************************************************/
\r
121 TIC(FIND_PRED_COEF)
\r
122 SKP_Silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );
\r
123 TOC(FIND_PRED_COEF)
\r
125 /****************************************/
\r
126 /* Process gains */
\r
127 /****************************************/
\r
129 SKP_Silk_process_gains_FIX( psEnc, &sEncCtrl );
\r
132 /****************************************/
\r
133 /* Low Bitrate Redundant Encoding */
\r
134 /****************************************/
\r
136 SKP_Silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw );
\r
139 /*****************************************/
\r
140 /* Noise shaping quantization */
\r
141 /*****************************************/
\r
143 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
\r
144 SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
\r
145 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
\r
146 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
\r
148 SKP_Silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
\r
149 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
\r
150 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
\r
154 /* Update input buffer */
\r
155 SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
\r
156 ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_int16 ) );
\r
158 /* Parameters needed for next frame */
\r
159 psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
\r
160 psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
\r
162 /* Exit without entropy coding */
\r
163 if( psEnc->sCmn.prefillFlag ) {
\r
169 /****************************************/
\r
170 /* Encode Parameters */
\r
171 /****************************************/
\r
173 SKP_Silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesAnalyzed, 0 );
\r
176 /****************************************/
\r
177 /* Encode Excitation Signal */
\r
178 /****************************************/
\r
180 SKP_Silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
\r
181 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
\r
184 /****************************************/
\r
185 /* Finalize payload */
\r
186 /****************************************/
\r
187 psEnc->sCmn.first_frame_after_reset = 0;
\r
188 if( ++psEnc->sCmn.nFramesAnalyzed >= psEnc->sCmn.nFramesPerPacket ) {
\r
190 *pnBytesOut = SKP_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
\r
192 /* Reset the number of frames in payload buffer */
\r
193 psEnc->sCmn.nFramesAnalyzed = 0;
\r
195 /* No payload this time */
\r
200 #ifdef SAVE_ALL_INTERNAL_DATA
\r
202 SKP_float tmp[ MAX_NB_SUBFR * LTP_ORDER ];
\r
204 DEBUG_STORE_DATA( xf.dat, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );
\r
205 DEBUG_STORE_DATA( xfw.dat, xfw, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );
\r
206 DEBUG_STORE_DATA( pitchL.dat, sEncCtrl.pitchL, psEnc->sCmn.nb_subfr * sizeof( SKP_int ) );
\r
207 for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {
\r
208 tmp[ i ] = (SKP_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f;
\r
210 DEBUG_STORE_DATA( pitchG_quantized.dat, tmp, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) );
\r
211 for( i = 0; i <psEnc->sCmn.predictLPCOrder; i++ ) {
\r
212 tmp[ i ] = (SKP_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f;
\r
214 DEBUG_STORE_DATA( PredCoef.dat, tmp, psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );
\r
216 tmp[ 0 ] = (SKP_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f;
\r
217 DEBUG_STORE_DATA( LTPredCodGain.dat, tmp, sizeof( SKP_float ) );
\r
218 tmp[ 0 ] = (SKP_float)psEnc->LTPCorr_Q15 / 32768.0f;
\r
219 DEBUG_STORE_DATA( LTPcorr.dat, tmp, sizeof( SKP_float ) );
\r
220 tmp[ 0 ] = (SKP_float)psEnc->sCmn.input_tilt_Q15 / 32768.0f;
\r
221 DEBUG_STORE_DATA( tilt.dat, tmp, sizeof( SKP_float ) );
\r
222 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
\r
223 tmp[ i ] = (SKP_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f;
\r
225 DEBUG_STORE_DATA( gains.dat, tmp, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );
\r
226 DEBUG_STORE_DATA( gains_indices.dat, &psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr * sizeof( SKP_int ) );
\r
227 tmp[ 0 ] = (SKP_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f;
\r
228 DEBUG_STORE_DATA( current_SNR_db.dat, tmp, sizeof( SKP_float ) );
\r
229 DEBUG_STORE_DATA( quantOffsetType.dat, &psEnc->sCmn.indices.quantOffsetType, sizeof( SKP_int ) );
\r
230 tmp[ 0 ] = (SKP_float)psEnc->sCmn.speech_activity_Q8 / 256.0f;
\r
231 DEBUG_STORE_DATA( speech_activity.dat, tmp, sizeof( SKP_float ) );
\r
232 for( i = 0; i < VAD_N_BANDS; i++ ) {
\r
233 tmp[ i ] = (SKP_float)psEnc->sCmn.input_quality_bands_Q15[ i ] / 32768.0f;
\r
235 DEBUG_STORE_DATA( input_quality_bands.dat, tmp, VAD_N_BANDS * sizeof( SKP_float ) );
\r
236 DEBUG_STORE_DATA( signalType.dat, &psEnc->sCmn.indices.signalType, sizeof( SKP_int8) );
\r
237 DEBUG_STORE_DATA( lag_index.dat, &psEnc->sCmn.indices.lagIndex, sizeof( SKP_int16 ) );
\r
238 DEBUG_STORE_DATA( contour_index.dat, &psEnc->sCmn.indices.contourIndex, sizeof( SKP_int8 ) );
\r
239 DEBUG_STORE_DATA( per_index.dat, &psEnc->sCmn.indices.PERIndex, sizeof( SKP_int8) );
\r
245 /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */
\r
246 void SKP_Silk_LBRR_encode_FIX(
\r
247 SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
\r
248 SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
\r
249 const SKP_int16 xfw[] /* I Input signal */
\r
252 SKP_int32 TempGains_Q16[ MAX_NB_SUBFR ];
\r
253 SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesAnalyzed ];
\r
254 SKP_Silk_nsq_state sNSQ_LBRR;
\r
256 /*******************************************/
\r
257 /* Control use of inband LBRR */
\r
258 /*******************************************/
\r
259 if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
\r
260 psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesAnalyzed ] = 1;
\r
262 /* Copy noise shaping quantizer state and quantization indices from regular encoding */
\r
263 SKP_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( SKP_Silk_nsq_state ) );
\r
264 SKP_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
\r
266 /* Save original gains */
\r
267 SKP_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( SKP_int32 ) );
\r
269 if( psEnc->sCmn.nFramesAnalyzed == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesAnalyzed - 1 ] == 0 ) {
\r
270 /* First frame in packet or previous frame not LBRR coded */
\r
271 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
\r
273 /* Increase Gains to get target LBRR rate */
\r
274 psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
\r
275 psIndices_LBRR->GainsIndices[ 0 ] = SKP_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
\r
278 /* Decode to get gains in sync with decoder */
\r
279 /* Overwrite unquantized gains with quantized gains */
\r
280 SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
\r
281 &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesAnalyzed, psEnc->sCmn.nb_subfr );
\r
283 /*****************************************/
\r
284 /* Noise shaping quantization */
\r
285 /*****************************************/
\r
286 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
\r
287 SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw,
\r
288 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesAnalyzed ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
\r
289 psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
\r
290 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
\r
292 SKP_Silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw,
\r
293 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesAnalyzed ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
\r
294 psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
\r
295 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
\r
298 /* Restore original gains */
\r
299 SKP_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( SKP_int32 ) );
\r