Convert all CRLF in the SILK code, tabs to spaces, and trailing
authorGregory Maxwell <greg@xiph.org>
Sat, 30 Jul 2011 12:18:48 +0000 (08:18 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Sun, 31 Jul 2011 01:55:16 +0000 (21:55 -0400)
whitespace.

165 files changed:
silk/fixed/silk_LTP_analysis_filter_FIX.c
silk/fixed/silk_LTP_scale_ctrl_FIX.c
silk/fixed/silk_corrMatrix_FIX.c
silk/fixed/silk_encode_frame_FIX.c
silk/fixed/silk_find_LPC_FIX.c
silk/fixed/silk_find_LTP_FIX.c
silk/fixed/silk_find_pitch_lags_FIX.c
silk/fixed/silk_find_pred_coefs_FIX.c
silk/fixed/silk_main_FIX.h
silk/fixed/silk_noise_shape_analysis_FIX.c
silk/fixed/silk_prefilter_FIX.c
silk/fixed/silk_process_gains_FIX.c
silk/fixed/silk_regularize_correlations_FIX.c
silk/fixed/silk_residual_energy16_FIX.c
silk/fixed/silk_residual_energy_FIX.c
silk/fixed/silk_solve_LS_FIX.c
silk/fixed/silk_structs_FIX.h
silk/fixed/silk_warped_autocorrelation_FIX.c
silk/float/silk_LPC_analysis_filter_FLP.c
silk/float/silk_LPC_inv_pred_gain_FLP.c
silk/float/silk_LTP_analysis_filter_FLP.c
silk/float/silk_LTP_scale_ctrl_FLP.c
silk/float/silk_SigProc_FLP.h
silk/float/silk_apply_sine_window_FLP.c
silk/float/silk_autocorrelation_FLP.c
silk/float/silk_burg_modified_FLP.c
silk/float/silk_bwexpander_FLP.c
silk/float/silk_corrMatrix_FLP.c
silk/float/silk_encode_frame_FLP.c
silk/float/silk_energy_FLP.c
silk/float/silk_find_LPC_FLP.c
silk/float/silk_find_LTP_FLP.c
silk/float/silk_find_pitch_lags_FLP.c
silk/float/silk_find_pred_coefs_FLP.c
silk/float/silk_inner_product_FLP.c
silk/float/silk_k2a_FLP.c
silk/float/silk_levinsondurbin_FLP.c
silk/float/silk_main_FLP.h
silk/float/silk_noise_shape_analysis_FLP.c
silk/float/silk_pitch_analysis_core_FLP.c
silk/float/silk_prefilter_FLP.c
silk/float/silk_process_gains_FLP.c
silk/float/silk_regularize_correlations_FLP.c
silk/float/silk_residual_energy_FLP.c
silk/float/silk_scale_copy_vector_FLP.c
silk/float/silk_scale_vector_FLP.c
silk/float/silk_schur_FLP.c
silk/float/silk_solve_LS_FLP.c
silk/float/silk_sort_FLP.c
silk/float/silk_structs_FLP.h
silk/float/silk_warped_autocorrelation_FLP.c
silk/float/silk_wrappers_FLP.c
silk/silk_A2NLSF.c
silk/silk_API.h
silk/silk_CNG.c
silk/silk_HP_variable_cutoff.c
silk/silk_Inlines.h
silk/silk_LPC_analysis_filter.c
silk/silk_LPC_inv_pred_gain.c
silk/silk_LP_variable_cutoff.c
silk/silk_MacroCount.h
silk/silk_MacroDebug.h
silk/silk_NLSF2A.c
silk/silk_NLSF_VQ.c
silk/silk_NLSF_VQ_weights_laroia.c
silk/silk_NLSF_decode.c
silk/silk_NLSF_del_dec_quant.c
silk/silk_NLSF_encode.c
silk/silk_NLSF_stabilize.c
silk/silk_NLSF_unpack.c
silk/silk_NSQ.c
silk/silk_NSQ_del_dec.c
silk/silk_PLC.c
silk/silk_PLC.h
silk/silk_SigProc_FIX.h
silk/silk_VAD.c
silk/silk_VQ_WMat_EC.c
silk/silk_ana_filt_bank_1.c
silk/silk_apply_sine_window.c
silk/silk_array_maxabs.c
silk/silk_autocorr.c
silk/silk_biquad_alt.c
silk/silk_burg_modified.c
silk/silk_bwexpander.c
silk/silk_bwexpander_32.c
silk/silk_check_control_input.c
silk/silk_code_signs.c
silk/silk_control.h
silk/silk_control_SNR.c
silk/silk_control_audio_bandwidth.c
silk/silk_control_codec.c
silk/silk_create_init_destroy.c
silk/silk_debug.c
silk/silk_debug.h
silk/silk_dec_API.c
silk/silk_decode_core.c
silk/silk_decode_frame.c
silk/silk_decode_indices.c
silk/silk_decode_parameters.c
silk/silk_decode_pitch.c
silk/silk_decode_pulses.c
silk/silk_decoder_set_fs.c
silk/silk_define.h
silk/silk_enc_API.c
silk/silk_encode_indices.c
silk/silk_encode_pulses.c
silk/silk_errors.h
silk/silk_gain_quant.c
silk/silk_init_encoder.c
silk/silk_inner_prod_aligned.c
silk/silk_interpolate.c
silk/silk_k2a.c
silk/silk_k2a_Q16.c
silk/silk_lin2log.c
silk/silk_log2lin.c
silk/silk_macros.h
silk/silk_main.h
silk/silk_pitch_analysis_core.c
silk/silk_pitch_est_defines.h
silk/silk_pitch_est_tables.c
silk/silk_process_NLSFs.c
silk/silk_quant_LTP_gains.c
silk/silk_resampler.c
silk/silk_resampler_down2.c
silk/silk_resampler_down2_3.c
silk/silk_resampler_down3.c
silk/silk_resampler_private.h
silk/silk_resampler_private_AR2.c
silk/silk_resampler_private_ARMA4.c
silk/silk_resampler_private_IIR_FIR.c
silk/silk_resampler_private_copy.c
silk/silk_resampler_private_down4.c
silk/silk_resampler_private_down_FIR.c
silk/silk_resampler_private_up2_HQ.c
silk/silk_resampler_private_up4.c
silk/silk_resampler_rom.c
silk/silk_resampler_rom.h
silk/silk_resampler_structs.h
silk/silk_resampler_up2.c
silk/silk_scale_copy_vector16.c
silk/silk_scale_vector.c
silk/silk_schur.c
silk/silk_schur64.c
silk/silk_shell_coder.c
silk/silk_sigm_Q15.c
silk/silk_sort.c
silk/silk_stereo_LR_to_MS.c
silk/silk_stereo_MS_to_LR.c
silk/silk_stereo_decode_pred.c
silk/silk_stereo_encode_pred.c
silk/silk_stereo_find_predictor.c
silk/silk_stereo_quant_pred.c
silk/silk_structs.h
silk/silk_sum_sqr_shift.c
silk/silk_table_LSF_cos.c
silk/silk_tables.h
silk/silk_tables_LTP.c
silk/silk_tables_NLSF_CB_NB_MB.c
silk/silk_tables_NLSF_CB_WB.c
silk/silk_tables_gain.c
silk/silk_tables_other.c
silk/silk_tables_pitch_lag.c
silk/silk_tables_pulses_per_block.c
silk/silk_tuning_parameters.h
silk/silk_typedef.h

index e4664de..9c46ab6 100644 (file)
@@ -1,81 +1,81 @@
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-\r
-void silk_LTP_analysis_filter_FIX(\r
-    opus_int16       *LTP_res,                               /* O:   LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length )  */\r
-    const opus_int16 *x,                                     /* I:   Pointer to input signal with at least max( pitchL ) preceeding samples      */\r
-    const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I:   LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe                   */\r
-    const opus_int   pitchL[ MAX_NB_SUBFR ],                 /* I:   Pitch lag, one for each subframe                                            */\r
-    const opus_int32 invGains_Q16[ MAX_NB_SUBFR ],           /* I:   Inverse quantization gains, one for each subframe                           */\r
-    const opus_int   subfr_length,                           /* I:   Length of each subframe                                                     */\r
-    const opus_int   nb_subfr,                               /* I:   Number of subframes                                                         */\r
-    const opus_int   pre_length                              /* I:   Length of the preceeding samples starting at &x[0] for each subframe        */\r
-)\r
-{\r
-    const opus_int16 *x_ptr, *x_lag_ptr;\r
-    opus_int16   Btmp_Q14[ LTP_ORDER ];\r
-    opus_int16   *LTP_res_ptr;\r
-    opus_int     k, i, j;\r
-    opus_int32   LTP_est;\r
-\r
-    x_ptr = x;\r
-    LTP_res_ptr = LTP_res;\r
-    for( k = 0; k < nb_subfr; k++ ) {\r
-\r
-        x_lag_ptr = x_ptr - pitchL[ k ];\r
-        for( i = 0; i < LTP_ORDER; i++ ) {\r
-            Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ];\r
-        }\r
-\r
-        /* LTP analysis FIR filter */\r
-        for( i = 0; i < subfr_length + pre_length; i++ ) {\r
-            LTP_res_ptr[ i ] = x_ptr[ i ];\r
-            \r
-            /* Long-term prediction */\r
-            LTP_est = SKP_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );\r
-            for( j = 1; j < LTP_ORDER; j++ ) {\r
-                LTP_est = SKP_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] );\r
-                       }\r
-            LTP_est = SKP_RSHIFT_ROUND( LTP_est, 14 ); // round and -> Q0\r
-\r
-            /* Subtract long-term prediction */\r
-            LTP_res_ptr[ i ] = ( opus_int16 )SKP_SAT16( ( opus_int32 )x_ptr[ i ] - LTP_est );\r
-\r
-            /* Scale residual */\r
-            LTP_res_ptr[ i ] = SKP_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );\r
-\r
-            x_lag_ptr++;\r
-        }\r
-\r
-        /* Update pointers */\r
-        LTP_res_ptr += subfr_length + pre_length; \r
-        x_ptr       += subfr_length;\r
-    }\r
-}\r
-\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+
+void silk_LTP_analysis_filter_FIX(
+    opus_int16       *LTP_res,                               /* O:   LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length )  */
+    const opus_int16 *x,                                     /* I:   Pointer to input signal with at least max( pitchL ) preceeding samples      */
+    const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I:   LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe                   */
+    const opus_int   pitchL[ MAX_NB_SUBFR ],                 /* I:   Pitch lag, one for each subframe                                            */
+    const opus_int32 invGains_Q16[ MAX_NB_SUBFR ],           /* I:   Inverse quantization gains, one for each subframe                           */
+    const opus_int   subfr_length,                           /* I:   Length of each subframe                                                     */
+    const opus_int   nb_subfr,                               /* I:   Number of subframes                                                         */
+    const opus_int   pre_length                              /* I:   Length of the preceeding samples starting at &x[0] for each subframe        */
+)
+{
+    const opus_int16 *x_ptr, *x_lag_ptr;
+    opus_int16   Btmp_Q14[ LTP_ORDER ];
+    opus_int16   *LTP_res_ptr;
+    opus_int     k, i, j;
+    opus_int32   LTP_est;
+
+    x_ptr = x;
+    LTP_res_ptr = LTP_res;
+    for( k = 0; k < nb_subfr; k++ ) {
+
+        x_lag_ptr = x_ptr - pitchL[ k ];
+        for( i = 0; i < LTP_ORDER; i++ ) {
+            Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ];
+        }
+
+        /* LTP analysis FIR filter */
+        for( i = 0; i < subfr_length + pre_length; i++ ) {
+            LTP_res_ptr[ i ] = x_ptr[ i ];
+
+            /* Long-term prediction */
+            LTP_est = SKP_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );
+            for( j = 1; j < LTP_ORDER; j++ ) {
+                LTP_est = SKP_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] );
+            }
+            LTP_est = SKP_RSHIFT_ROUND( LTP_est, 14 ); // round and -> Q0
+
+            /* Subtract long-term prediction */
+            LTP_res_ptr[ i ] = ( opus_int16 )SKP_SAT16( ( opus_int32 )x_ptr[ i ] - LTP_est );
+
+            /* Scale residual */
+            LTP_res_ptr[ i ] = SKP_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );
+
+            x_lag_ptr++;
+        }
+
+        /* Update pointers */
+        LTP_res_ptr += subfr_length + pre_length;
+        x_ptr       += subfr_length;
+    }
+}
+
index d3535c7..3043d8a 100644 (file)
@@ -1,52 +1,52 @@
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-\r
-void silk_LTP_scale_ctrl_FIX(\r
-    silk_encoder_state_FIX      *psEnc,     /* I/O  encoder state FIX                           */\r
-    silk_encoder_control_FIX    *psEncCtrl  /* I/O  encoder control FIX                         */\r
-)\r
-{\r
-    opus_int round_loss;\r
-\r
-    /* 1st order high-pass filter */\r
-    psEnc->HPLTPredCodGain_Q7 = SKP_max_int( psEncCtrl->LTPredCodGain_Q7 - SKP_RSHIFT( psEnc->prevLTPredCodGain_Q7, 1 ), 0 ) \r
-        + SKP_RSHIFT( psEnc->HPLTPredCodGain_Q7, 1 );\r
-    psEnc->prevLTPredCodGain_Q7 = psEncCtrl->LTPredCodGain_Q7;\r
-\r
-    /* Only scale if first frame in packet */\r
-    if( psEnc->sCmn.nFramesEncoded == 0 ) {\r
-        round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket - 1;\r
-        psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)SKP_LIMIT( \r
-            SKP_SMULWB( SKP_SMULBB( round_loss, psEnc->HPLTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 );\r
-    } else {\r
-        /* Default is minimum scaling */\r
-        psEnc->sCmn.indices.LTP_scaleIndex = 0;\r
-    }\r
-    psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ];\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+
+void silk_LTP_scale_ctrl_FIX(
+    silk_encoder_state_FIX      *psEnc,     /* I/O  encoder state FIX                           */
+    silk_encoder_control_FIX    *psEncCtrl  /* I/O  encoder control FIX                         */
+)
+{
+    opus_int round_loss;
+
+    /* 1st order high-pass filter */
+    psEnc->HPLTPredCodGain_Q7 = SKP_max_int( psEncCtrl->LTPredCodGain_Q7 - SKP_RSHIFT( psEnc->prevLTPredCodGain_Q7, 1 ), 0 )
+        + SKP_RSHIFT( psEnc->HPLTPredCodGain_Q7, 1 );
+    psEnc->prevLTPredCodGain_Q7 = psEncCtrl->LTPredCodGain_Q7;
+
+    /* Only scale if first frame in packet */
+    if( psEnc->sCmn.nFramesEncoded == 0 ) {
+        round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket - 1;
+        psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)SKP_LIMIT(
+            SKP_SMULWB( SKP_SMULBB( round_loss, psEnc->HPLTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 );
+    } else {
+        /* Default is minimum scaling */
+        psEnc->sCmn.indices.LTP_scaleIndex = 0;
+    }
+    psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ];
+}
index 619546f..6bf4fd9 100644 (file)
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-/**********************************************************************\r
- * Correlation Matrix Computations for LS estimate. \r
- **********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-\r
-/* Calculates correlation vector X'*t */\r
-void silk_corrVector_FIX(\r
-    const opus_int16                 *x,         /* I    x vector [L + order - 1] used to form data matrix X */\r
-    const opus_int16                 *t,         /* I    target vector [L]                                   */\r
-    const opus_int                   L,          /* I    Length of vectors                                   */\r
-    const opus_int                   order,      /* I    Max lag for correlation                             */\r
-    opus_int32                       *Xt,        /* O    Pointer to X'*t correlation vector [order]          */\r
-    const opus_int                   rshifts     /* I    Right shifts of correlations                        */\r
-)\r
-{\r
-    opus_int         lag, i;\r
-    const opus_int16 *ptr1, *ptr2;\r
-    opus_int32       inner_prod;\r
-\r
-    ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */\r
-    ptr2 = t;\r
-    /* Calculate X'*t */\r
-    if( rshifts > 0 ) {\r
-        /* Right shifting used */\r
-        for( lag = 0; lag < order; lag++ ) {\r
-            inner_prod = 0;\r
-            for( i = 0; i < L; i++ ) {\r
-                inner_prod += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );\r
-            }\r
-            Xt[ lag ] = inner_prod; /* X[:,lag]'*t */\r
-            ptr1--; /* Go to next column of X */\r
-        }\r
-    } else {\r
-        SKP_assert( rshifts == 0 );\r
-        for( lag = 0; lag < order; lag++ ) {\r
-            Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */\r
-            ptr1--; /* Go to next column of X */\r
-        }\r
-    }\r
-}\r
-\r
-/* Calculates correlation matrix X'*X */\r
-void silk_corrMatrix_FIX(\r
-    const opus_int16                 *x,         /* I    x vector [L + order - 1] used to form data matrix X */\r
-    const opus_int                   L,          /* I    Length of vectors                                   */\r
-    const opus_int                   order,      /* I    Max lag for correlation                             */\r
-    const opus_int                   head_room,  /* I    Desired headroom                                    */\r
-    opus_int32                       *XX,        /* O    Pointer to X'*X correlation matrix [ order x order ]*/\r
-    opus_int                         *rshifts    /* I/O  Right shifts of correlations                        */\r
-)\r
-{\r
-    opus_int         i, j, lag, rshifts_local, head_room_rshifts;\r
-    opus_int32       energy;\r
-    const opus_int16 *ptr1, *ptr2;\r
-\r
-    /* Calculate energy to find shift used to fit in 32 bits */\r
-    silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 );\r
-    /* Add shifts to get the desired head room */\r
-    head_room_rshifts = SKP_max( head_room - silk_CLZ32( energy ), 0 );\r
-    \r
-    energy = SKP_RSHIFT32( energy, head_room_rshifts );\r
-    rshifts_local += head_room_rshifts;\r
-\r
-    /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */\r
-    /* Remove contribution of first order - 1 samples */\r
-    for( i = 0; i < order - 1; i++ ) {\r
-        energy -= SKP_RSHIFT32( SKP_SMULBB( x[ i ], x[ i ] ), rshifts_local );\r
-    }\r
-    if( rshifts_local < *rshifts ) {\r
-        /* Adjust energy */\r
-        energy = SKP_RSHIFT32( energy, *rshifts - rshifts_local );\r
-        rshifts_local = *rshifts;\r
-    }\r
-\r
-    /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */\r
-    /* Fill out the diagonal of the correlation matrix */\r
-    matrix_ptr( XX, 0, 0, order ) = energy;\r
-    ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */\r
-    for( j = 1; j < order; j++ ) {\r
-        energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) );\r
-        energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) );\r
-        matrix_ptr( XX, j, j, order ) = energy;\r
-    }\r
-\r
-    ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */\r
-    /* Calculate the remaining elements of the correlation matrix */\r
-    if( rshifts_local > 0 ) {\r
-        /* Right shifting used */\r
-        for( lag = 1; lag < order; lag++ ) {\r
-            /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */\r
-            energy = 0;\r
-            for( i = 0; i < L; i++ ) {\r
-                energy += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local );\r
-            }\r
-            /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */\r
-            matrix_ptr( XX, lag, 0, order ) = energy;\r
-            matrix_ptr( XX, 0, lag, order ) = energy;\r
-            for( j = 1; j < ( order - lag ); j++ ) {\r
-                energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) );\r
-                energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) );\r
-                matrix_ptr( XX, lag + j, j, order ) = energy;\r
-                matrix_ptr( XX, j, lag + j, order ) = energy;\r
-            }\r
-            ptr2--; /* Update pointer to first sample of next column (lag) in X */\r
-        }\r
-    } else {\r
-        for( lag = 1; lag < order; lag++ ) {\r
-            /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */\r
-            energy = silk_inner_prod_aligned( ptr1, ptr2, L );\r
-            matrix_ptr( XX, lag, 0, order ) = energy;\r
-            matrix_ptr( XX, 0, lag, order ) = energy;\r
-            /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */\r
-            for( j = 1; j < ( order - lag ); j++ ) {\r
-                energy = SKP_SUB32( energy, SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) );\r
-                energy = SKP_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] );\r
-                matrix_ptr( XX, lag + j, j, order ) = energy;\r
-                matrix_ptr( XX, j, lag + j, order ) = energy;\r
-            }\r
-            ptr2--;/* Update pointer to first sample of next column (lag) in X */\r
-        }\r
-    }\r
-    *rshifts = rshifts_local;\r
-}\r
-\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+/**********************************************************************
+ * Correlation Matrix Computations for LS estimate.
+ **********************************************************************/
+
+#include "silk_main_FIX.h"
+
+/* Calculates correlation vector X'*t */
+void silk_corrVector_FIX(
+    const opus_int16                 *x,         /* I    x vector [L + order - 1] used to form data matrix X */
+    const opus_int16                 *t,         /* I    target vector [L]                                   */
+    const opus_int                   L,          /* I    Length of vectors                                   */
+    const opus_int                   order,      /* I    Max lag for correlation                             */
+    opus_int32                       *Xt,        /* O    Pointer to X'*t correlation vector [order]          */
+    const opus_int                   rshifts     /* I    Right shifts of correlations                        */
+)
+{
+    opus_int         lag, i;
+    const opus_int16 *ptr1, *ptr2;
+    opus_int32       inner_prod;
+
+    ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
+    ptr2 = t;
+    /* Calculate X'*t */
+    if( rshifts > 0 ) {
+        /* Right shifting used */
+        for( lag = 0; lag < order; lag++ ) {
+            inner_prod = 0;
+            for( i = 0; i < L; i++ ) {
+                inner_prod += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
+            }
+            Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
+            ptr1--; /* Go to next column of X */
+        }
+    } else {
+        SKP_assert( rshifts == 0 );
+        for( lag = 0; lag < order; lag++ ) {
+            Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */
+            ptr1--; /* Go to next column of X */
+        }
+    }
+}
+
+/* Calculates correlation matrix X'*X */
+void silk_corrMatrix_FIX(
+    const opus_int16                 *x,         /* I    x vector [L + order - 1] used to form data matrix X */
+    const opus_int                   L,          /* I    Length of vectors                                   */
+    const opus_int                   order,      /* I    Max lag for correlation                             */
+    const opus_int                   head_room,  /* I    Desired headroom                                    */
+    opus_int32                       *XX,        /* O    Pointer to X'*X correlation matrix [ order x order ]*/
+    opus_int                         *rshifts    /* I/O  Right shifts of correlations                        */
+)
+{
+    opus_int         i, j, lag, rshifts_local, head_room_rshifts;
+    opus_int32       energy;
+    const opus_int16 *ptr1, *ptr2;
+
+    /* Calculate energy to find shift used to fit in 32 bits */
+    silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 );
+    /* Add shifts to get the desired head room */
+    head_room_rshifts = SKP_max( head_room - silk_CLZ32( energy ), 0 );
+
+    energy = SKP_RSHIFT32( energy, head_room_rshifts );
+    rshifts_local += head_room_rshifts;
+
+    /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */
+    /* Remove contribution of first order - 1 samples */
+    for( i = 0; i < order - 1; i++ ) {
+        energy -= SKP_RSHIFT32( SKP_SMULBB( x[ i ], x[ i ] ), rshifts_local );
+    }
+    if( rshifts_local < *rshifts ) {
+        /* Adjust energy */
+        energy = SKP_RSHIFT32( energy, *rshifts - rshifts_local );
+        rshifts_local = *rshifts;
+    }
+
+    /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */
+    /* Fill out the diagonal of the correlation matrix */
+    matrix_ptr( XX, 0, 0, order ) = energy;
+    ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */
+    for( j = 1; j < order; j++ ) {
+        energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) );
+        energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) );
+        matrix_ptr( XX, j, j, order ) = energy;
+    }
+
+    ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */
+    /* Calculate the remaining elements of the correlation matrix */
+    if( rshifts_local > 0 ) {
+        /* Right shifting used */
+        for( lag = 1; lag < order; lag++ ) {
+            /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
+            energy = 0;
+            for( i = 0; i < L; i++ ) {
+                energy += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local );
+            }
+            /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
+            matrix_ptr( XX, lag, 0, order ) = energy;
+            matrix_ptr( XX, 0, lag, order ) = energy;
+            for( j = 1; j < ( order - lag ); j++ ) {
+                energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) );
+                energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) );
+                matrix_ptr( XX, lag + j, j, order ) = energy;
+                matrix_ptr( XX, j, lag + j, order ) = energy;
+            }
+            ptr2--; /* Update pointer to first sample of next column (lag) in X */
+        }
+    } else {
+        for( lag = 1; lag < order; lag++ ) {
+            /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
+            energy = silk_inner_prod_aligned( ptr1, ptr2, L );
+            matrix_ptr( XX, lag, 0, order ) = energy;
+            matrix_ptr( XX, 0, lag, order ) = energy;
+            /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
+            for( j = 1; j < ( order - lag ); j++ ) {
+                energy = SKP_SUB32( energy, SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) );
+                energy = SKP_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] );
+                matrix_ptr( XX, lag + j, j, order ) = energy;
+                matrix_ptr( XX, j, lag + j, order ) = energy;
+            }
+            ptr2--;/* Update pointer to first sample of next column (lag) in X */
+        }
+    }
+    *rshifts = rshifts_local;
+}
+
index ea05aa7..eb1710f 100644 (file)
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-#include "silk_tuning_parameters.h"\r
-\r
-/****************/\r
-/* Encode frame */\r
-/****************/\r
-opus_int silk_encode_frame_FIX( \r
-    silk_encoder_state_FIX          *psEnc,             /* I/O  Encoder state FIX                       */\r
-    opus_int32                       *pnBytesOut,        /*   O  Number of payload bytes                 */\r
-    ec_enc                          *psRangeEnc         /* I/O  compressor data structure               */\r
-)\r
-{\r
-    silk_encoder_control_FIX sEncCtrl;\r
-    opus_int     ret = 0;\r
-    opus_int16   *x_frame, *res_pitch_frame;\r
-    opus_int16   xfw[ MAX_FRAME_LENGTH ];\r
-    opus_int16   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];\r
-\r
-TIC(ENCODE_FRAME)\r
-\r
-    psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;\r
-\r
-    /**************************************************************/\r
-    /* Setup Input Pointers, and insert frame in input buffer    */\r
-    /*************************************************************/\r
-    /* pointers aligned with start of frame to encode */\r
-    x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */\r
-    res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */\r
-\r
-    /****************************/\r
-    /* Voice Activity Detection */\r
-    /****************************/\r
-TIC(VAD)\r
-    ret = silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf - 1 );\r
-TOC(VAD)\r
-\r
-    /**************************************************/\r
-    /* Convert speech activity into VAD and DTX flags */\r
-    /**************************************************/\r
-    if( psEnc->sCmn.nFramesEncoded == 0 ) {\r
-        psEnc->sCmn.inDTX = psEnc->sCmn.useDTX;\r
-    }\r
-    if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {\r
-        psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;\r
-        psEnc->sCmn.noSpeechCounter++;\r
-        if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {\r
-            psEnc->sCmn.inDTX = 0;\r
-        } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {\r
-            psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;\r
-            psEnc->sCmn.inDTX           = 0;\r
-        }\r
-        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;\r
-    } else {\r
-        psEnc->sCmn.noSpeechCounter    = 0;\r
-        psEnc->sCmn.inDTX              = 0;\r
-        psEnc->sCmn.indices.signalType = TYPE_UNVOICED;\r
-        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;\r
-    }\r
-\r
-    /***************************************/\r
-    /* Ensure smooth bandwidth transitions */\r
-    /***************************************/\r
-    silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf - 1, psEnc->sCmn.frame_length );\r
-    \r
-    /*******************************************/\r
-    /* Copy new frame to front of input buffer */\r
-    /*******************************************/\r
-    SKP_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf - 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );\r
-\r
-    /*****************************************/\r
-    /* Find pitch lags, initial LPC analysis */\r
-    /*****************************************/\r
-TIC(FIND_PITCH)\r
-    silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );\r
-TOC(FIND_PITCH)\r
-\r
-    /************************/\r
-    /* Noise shape analysis */\r
-    /************************/\r
-TIC(NOISE_SHAPE_ANALYSIS)\r
-    silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );\r
-TOC(NOISE_SHAPE_ANALYSIS)\r
-\r
-    /***************************************************/\r
-    /* Find linear prediction coefficients (LPC + LTP) */\r
-    /***************************************************/\r
-TIC(FIND_PRED_COEF)\r
-    silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );\r
-TOC(FIND_PRED_COEF)\r
-\r
-    /****************************************/\r
-    /* Process gains                        */\r
-    /****************************************/\r
-TIC(PROCESS_GAINS)\r
-    silk_process_gains_FIX( psEnc, &sEncCtrl );\r
-TOC(PROCESS_GAINS)\r
-    \r
-    /*****************************************/\r
-    /* Prefiltering for noise shaper         */\r
-    /*****************************************/\r
-TIC(PREFILTER)\r
-    silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );\r
-TOC(PREFILTER)\r
-\r
-    /****************************************/\r
-    /* Low Bitrate Redundant Encoding       */\r
-    /****************************************/\r
-TIC(LBRR)\r
-    silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw );\r
-TOC(LBRR)\r
-\r
-    /*****************************************/\r
-    /* Noise shaping quantization            */\r
-    /*****************************************/\r
-TIC(NSQ)\r
-    if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {\r
-        silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses, \r
-            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
-            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );\r
-    } else {\r
-        silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses, \r
-            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
-            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );\r
-    }\r
-TOC(NSQ)\r
-\r
-    /* Update input buffer */\r
-    SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], \r
-        ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );\r
-\r
-    /* Parameters needed for next frame */\r
-    psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];\r
-    psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;\r
-\r
-    /* Exit without entropy coding */\r
-    if( psEnc->sCmn.prefillFlag ) {\r
-        /* No payload */\r
-        *pnBytesOut = 0;\r
-        return ret;\r
-    }\r
-\r
-    /****************************************/\r
-    /* Encode Parameters                    */\r
-    /****************************************/\r
-TIC(ENCODE_PARAMS)\r
-    silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0 );\r
-TOC(ENCODE_PARAMS)\r
-\r
-    /****************************************/\r
-    /* Encode Excitation Signal             */\r
-    /****************************************/\r
-TIC(ENCODE_PULSES)\r
-    silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, \r
-        psEnc->sCmn.pulses, psEnc->sCmn.frame_length );\r
-TOC(ENCODE_PULSES)\r
-\r
-    /****************************************/\r
-    /* Finalize payload                     */\r
-    /****************************************/\r
-    psEnc->sCmn.first_frame_after_reset = 0;\r
-    if( ++psEnc->sCmn.nFramesEncoded >= psEnc->sCmn.nFramesPerPacket ) {\r
-        /* Payload size */\r
-        *pnBytesOut = SKP_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );\r
-\r
-        /* Reset the number of frames in payload buffer */\r
-        psEnc->sCmn.nFramesEncoded = 0;\r
-    } else {\r
-        /* No payload this time */\r
-        *pnBytesOut = 0;\r
-    }\r
-TOC(ENCODE_FRAME)\r
-\r
-#ifdef SAVE_ALL_INTERNAL_DATA\r
-    {\r
-        SKP_float tmp[ MAX_NB_SUBFR * LTP_ORDER ];\r
-        int i;\r
-        DEBUG_STORE_DATA( xf.dat,                   x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );\r
-        DEBUG_STORE_DATA( xfw.dat,                  xfw,                            psEnc->sCmn.frame_length    * sizeof( opus_int16 ) );\r
-        DEBUG_STORE_DATA( pitchL.dat,               sEncCtrl.pitchL,                psEnc->sCmn.nb_subfr        * sizeof( opus_int ) );\r
-        for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {\r
-            tmp[ i ] = (SKP_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f;\r
-        }\r
-        DEBUG_STORE_DATA( pitchG_quantized.dat,     tmp,                            psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) );\r
-        for( i = 0; i <psEnc->sCmn.predictLPCOrder; i++ ) {\r
-            tmp[ i ] = (SKP_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f;\r
-        }\r
-        DEBUG_STORE_DATA( PredCoef.dat,             tmp,                            psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );\r
-        \r
-        tmp[ 0 ] = (SKP_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f;\r
-        DEBUG_STORE_DATA( LTPredCodGain.dat,        tmp,                            sizeof( SKP_float ) );\r
-        tmp[ 0 ] = (SKP_float)psEnc->LTPCorr_Q15 / 32768.0f;\r
-        DEBUG_STORE_DATA( LTPcorr.dat,              tmp,                            sizeof( SKP_float ) );\r
-        tmp[ 0 ] = (SKP_float)psEnc->sCmn.input_tilt_Q15 / 32768.0f;\r
-        DEBUG_STORE_DATA( tilt.dat,                 tmp,                            sizeof( SKP_float ) );\r
-        for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\r
-            tmp[ i ] = (SKP_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f;\r
-        }\r
-        DEBUG_STORE_DATA( gains.dat,                tmp,                            psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
-        DEBUG_STORE_DATA( gains_indices.dat,        &psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr * sizeof( opus_int ) );\r
-        tmp[ 0 ] = (SKP_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f;\r
-        DEBUG_STORE_DATA( current_SNR_db.dat,       tmp,                            sizeof( SKP_float ) );\r
-        DEBUG_STORE_DATA( quantOffsetType.dat,      &psEnc->sCmn.indices.quantOffsetType, sizeof( opus_int ) );\r
-        tmp[ 0 ] = (SKP_float)psEnc->sCmn.speech_activity_Q8 / 256.0f;\r
-        DEBUG_STORE_DATA( speech_activity.dat,      tmp,                            sizeof( SKP_float ) );\r
-        for( i = 0; i < VAD_N_BANDS; i++ ) {\r
-            tmp[ i ] = (SKP_float)psEnc->sCmn.input_quality_bands_Q15[ i ] / 32768.0f;\r
-        }\r
-        DEBUG_STORE_DATA( input_quality_bands.dat,  tmp,                       VAD_N_BANDS * sizeof( SKP_float ) );\r
-        DEBUG_STORE_DATA( signalType.dat,           &psEnc->sCmn.indices.signalType,         sizeof( opus_int8) ); \r
-        DEBUG_STORE_DATA( lag_index.dat,            &psEnc->sCmn.indices.lagIndex,           sizeof( opus_int16 ) ); \r
-        DEBUG_STORE_DATA( contour_index.dat,        &psEnc->sCmn.indices.contourIndex,       sizeof( opus_int8 ) ); \r
-        DEBUG_STORE_DATA( per_index.dat,            &psEnc->sCmn.indices.PERIndex,           sizeof( opus_int8) ); \r
-    }\r
-#endif\r
-    return ret;\r
-}\r
-\r
-/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate  */\r
-void silk_LBRR_encode_FIX(\r
-    silk_encoder_state_FIX          *psEnc,         /* I/O  Pointer to Silk FIX encoder state           */\r
-    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  Pointer to Silk FIX encoder control struct  */\r
-    const opus_int16                 xfw[]           /* I    Input signal                                */\r
-)\r
-{\r
-    opus_int32   TempGains_Q16[ MAX_NB_SUBFR ];\r
-    SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];\r
-    silk_nsq_state sNSQ_LBRR;\r
-\r
-    /*******************************************/\r
-    /* Control use of inband LBRR              */\r
-    /*******************************************/\r
-    if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {\r
-        psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;\r
-\r
-        /* Copy noise shaping quantizer state and quantization indices from regular encoding */\r
-        SKP_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );\r
-        SKP_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );\r
-\r
-        /* Save original gains */\r
-        SKP_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );\r
-\r
-        if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {\r
-            /* First frame in packet or previous frame not LBRR coded */\r
-            psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;\r
-\r
-            /* Increase Gains to get target LBRR rate */\r
-            psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;\r
-            psIndices_LBRR->GainsIndices[ 0 ] = SKP_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );\r
-        }\r
-\r
-        /* Decode to get gains in sync with decoder         */\r
-        /* Overwrite unquantized gains with quantized gains */\r
-        silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, \r
-            &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesEncoded, psEnc->sCmn.nb_subfr );\r
-\r
-        /*****************************************/\r
-        /* Noise shaping quantization            */\r
-        /*****************************************/\r
-        if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {\r
-            silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw, \r
-                psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
-                psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
-                psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
-        } else {\r
-            silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw, \r
-                psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
-                psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
-                psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
-        }\r
-\r
-        /* Restore original gains */\r
-        SKP_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );\r
-    }\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+#include "silk_tuning_parameters.h"
+
+/****************/
+/* Encode frame */
+/****************/
+opus_int silk_encode_frame_FIX(
+    silk_encoder_state_FIX          *psEnc,             /* I/O  Encoder state FIX                       */
+    opus_int32                       *pnBytesOut,        /*   O  Number of payload bytes                 */
+    ec_enc                          *psRangeEnc         /* I/O  compressor data structure               */
+)
+{
+    silk_encoder_control_FIX sEncCtrl;
+    opus_int     ret = 0;
+    opus_int16   *x_frame, *res_pitch_frame;
+    opus_int16   xfw[ MAX_FRAME_LENGTH ];
+    opus_int16   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
+
+TIC(ENCODE_FRAME)
+
+    psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
+
+    /**************************************************************/
+    /* Setup Input Pointers, and insert frame in input buffer    */
+    /*************************************************************/
+    /* pointers aligned with start of frame to encode */
+    x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */
+    res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */
+
+    /****************************/
+    /* Voice Activity Detection */
+    /****************************/
+TIC(VAD)
+    ret = silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf - 1 );
+TOC(VAD)
+
+    /**************************************************/
+    /* Convert speech activity into VAD and DTX flags */
+    /**************************************************/
+    if( psEnc->sCmn.nFramesEncoded == 0 ) {
+        psEnc->sCmn.inDTX = psEnc->sCmn.useDTX;
+    }
+    if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
+        psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
+        psEnc->sCmn.noSpeechCounter++;
+        if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {
+            psEnc->sCmn.inDTX = 0;
+        } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
+            psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
+            psEnc->sCmn.inDTX           = 0;
+        }
+        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
+    } else {
+        psEnc->sCmn.noSpeechCounter    = 0;
+        psEnc->sCmn.inDTX              = 0;
+        psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
+        psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
+    }
+
+    /***************************************/
+    /* Ensure smooth bandwidth transitions */
+    /***************************************/
+    silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf - 1, psEnc->sCmn.frame_length );
+
+    /*******************************************/
+    /* Copy new frame to front of input buffer */
+    /*******************************************/
+    SKP_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf - 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
+
+    /*****************************************/
+    /* Find pitch lags, initial LPC analysis */
+    /*****************************************/
+TIC(FIND_PITCH)
+    silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );
+TOC(FIND_PITCH)
+
+    /************************/
+    /* Noise shape analysis */
+    /************************/
+TIC(NOISE_SHAPE_ANALYSIS)
+    silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
+TOC(NOISE_SHAPE_ANALYSIS)
+
+    /***************************************************/
+    /* Find linear prediction coefficients (LPC + LTP) */
+    /***************************************************/
+TIC(FIND_PRED_COEF)
+    silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );
+TOC(FIND_PRED_COEF)
+
+    /****************************************/
+    /* Process gains                        */
+    /****************************************/
+TIC(PROCESS_GAINS)
+    silk_process_gains_FIX( psEnc, &sEncCtrl );
+TOC(PROCESS_GAINS)
+
+    /*****************************************/
+    /* Prefiltering for noise shaper         */
+    /*****************************************/
+TIC(PREFILTER)
+    silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );
+TOC(PREFILTER)
+
+    /****************************************/
+    /* Low Bitrate Redundant Encoding       */
+    /****************************************/
+TIC(LBRR)
+    silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw );
+TOC(LBRR)
+
+    /*****************************************/
+    /* Noise shaping quantization            */
+    /*****************************************/
+TIC(NSQ)
+    if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
+        silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
+            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
+            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
+    } else {
+        silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
+            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
+            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
+    }
+TOC(NSQ)
+
+    /* Update input buffer */
+    SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
+        ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
+
+    /* Parameters needed for next frame */
+    psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
+    psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
+
+    /* Exit without entropy coding */
+    if( psEnc->sCmn.prefillFlag ) {
+        /* No payload */
+        *pnBytesOut = 0;
+        return ret;
+    }
+
+    /****************************************/
+    /* Encode Parameters                    */
+    /****************************************/
+TIC(ENCODE_PARAMS)
+    silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0 );
+TOC(ENCODE_PARAMS)
+
+    /****************************************/
+    /* Encode Excitation Signal             */
+    /****************************************/
+TIC(ENCODE_PULSES)
+    silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
+        psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
+TOC(ENCODE_PULSES)
+
+    /****************************************/
+    /* Finalize payload                     */
+    /****************************************/
+    psEnc->sCmn.first_frame_after_reset = 0;
+    if( ++psEnc->sCmn.nFramesEncoded >= psEnc->sCmn.nFramesPerPacket ) {
+        /* Payload size */
+        *pnBytesOut = SKP_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
+
+        /* Reset the number of frames in payload buffer */
+        psEnc->sCmn.nFramesEncoded = 0;
+    } else {
+        /* No payload this time */
+        *pnBytesOut = 0;
+    }
+TOC(ENCODE_FRAME)
+
+#ifdef SAVE_ALL_INTERNAL_DATA
+    {
+        SKP_float tmp[ MAX_NB_SUBFR * LTP_ORDER ];
+        int i;
+        DEBUG_STORE_DATA( xf.dat,                   x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
+        DEBUG_STORE_DATA( xfw.dat,                  xfw,                            psEnc->sCmn.frame_length    * sizeof( opus_int16 ) );
+        DEBUG_STORE_DATA( pitchL.dat,               sEncCtrl.pitchL,                psEnc->sCmn.nb_subfr        * sizeof( opus_int ) );
+        for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {
+            tmp[ i ] = (SKP_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f;
+        }
+        DEBUG_STORE_DATA( pitchG_quantized.dat,     tmp,                            psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) );
+        for( i = 0; i <psEnc->sCmn.predictLPCOrder; i++ ) {
+            tmp[ i ] = (SKP_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f;
+        }
+        DEBUG_STORE_DATA( PredCoef.dat,             tmp,                            psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );
+
+        tmp[ 0 ] = (SKP_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f;
+        DEBUG_STORE_DATA( LTPredCodGain.dat,        tmp,                            sizeof( SKP_float ) );
+        tmp[ 0 ] = (SKP_float)psEnc->LTPCorr_Q15 / 32768.0f;
+        DEBUG_STORE_DATA( LTPcorr.dat,              tmp,                            sizeof( SKP_float ) );
+        tmp[ 0 ] = (SKP_float)psEnc->sCmn.input_tilt_Q15 / 32768.0f;
+        DEBUG_STORE_DATA( tilt.dat,                 tmp,                            sizeof( SKP_float ) );
+        for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
+            tmp[ i ] = (SKP_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f;
+        }
+        DEBUG_STORE_DATA( gains.dat,                tmp,                            psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );
+        DEBUG_STORE_DATA( gains_indices.dat,        &psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr * sizeof( opus_int ) );
+        tmp[ 0 ] = (SKP_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f;
+        DEBUG_STORE_DATA( current_SNR_db.dat,       tmp,                            sizeof( SKP_float ) );
+        DEBUG_STORE_DATA( quantOffsetType.dat,      &psEnc->sCmn.indices.quantOffsetType, sizeof( opus_int ) );
+        tmp[ 0 ] = (SKP_float)psEnc->sCmn.speech_activity_Q8 / 256.0f;
+        DEBUG_STORE_DATA( speech_activity.dat,      tmp,                            sizeof( SKP_float ) );
+        for( i = 0; i < VAD_N_BANDS; i++ ) {
+            tmp[ i ] = (SKP_float)psEnc->sCmn.input_quality_bands_Q15[ i ] / 32768.0f;
+        }
+        DEBUG_STORE_DATA( input_quality_bands.dat,  tmp,                       VAD_N_BANDS * sizeof( SKP_float ) );
+        DEBUG_STORE_DATA( signalType.dat,           &psEnc->sCmn.indices.signalType,         sizeof( opus_int8) );
+        DEBUG_STORE_DATA( lag_index.dat,            &psEnc->sCmn.indices.lagIndex,           sizeof( opus_int16 ) );
+        DEBUG_STORE_DATA( contour_index.dat,        &psEnc->sCmn.indices.contourIndex,       sizeof( opus_int8 ) );
+        DEBUG_STORE_DATA( per_index.dat,            &psEnc->sCmn.indices.PERIndex,           sizeof( opus_int8) );
+    }
+#endif
+    return ret;
+}
+
+/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate  */
+void silk_LBRR_encode_FIX(
+    silk_encoder_state_FIX          *psEnc,         /* I/O  Pointer to Silk FIX encoder state           */
+    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  Pointer to Silk FIX encoder control struct  */
+    const opus_int16                 xfw[]           /* I    Input signal                                */
+)
+{
+    opus_int32   TempGains_Q16[ MAX_NB_SUBFR ];
+    SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
+    silk_nsq_state sNSQ_LBRR;
+
+    /*******************************************/
+    /* Control use of inband LBRR              */
+    /*******************************************/
+    if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
+        psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
+
+        /* Copy noise shaping quantizer state and quantization indices from regular encoding */
+        SKP_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
+        SKP_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
+
+        /* Save original gains */
+        SKP_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
+
+        if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
+            /* First frame in packet or previous frame not LBRR coded */
+            psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
+
+            /* Increase Gains to get target LBRR rate */
+            psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
+            psIndices_LBRR->GainsIndices[ 0 ] = SKP_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
+        }
+
+        /* Decode to get gains in sync with decoder         */
+        /* Overwrite unquantized gains with quantized gains */
+        silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
+            &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesEncoded, psEnc->sCmn.nb_subfr );
+
+        /*****************************************/
+        /* Noise shaping quantization            */
+        /*****************************************/
+        if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
+            silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw,
+                psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
+                psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
+                psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
+        } else {
+            silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw,
+                psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
+                psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
+                psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
+        }
+
+        /* Restore original gains */
+        SKP_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
+    }
+}
index f1a0434..02a4318 100644 (file)
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-#include "silk_tuning_parameters.h"\r
-\r
-/* Finds LPC vector from correlations, and converts to NLSF */\r
-void silk_find_LPC_FIX(\r
-    opus_int16                       NLSF_Q15[],             /* O    NLSFs                                                           */\r
-    opus_int8                        *interpIndex,           /* O    NLSF interpolation index, only used for NLSF interpolation      */\r
-    const opus_int16                 prev_NLSFq_Q15[],       /* I    previous NLSFs, only used for NLSF interpolation                */\r
-    const opus_int                   useInterpNLSFs,         /* I    Flag                                                            */\r
-    const opus_int                   firstFrameAfterReset,   /* I    Flag                                                            */\r
-    const opus_int                   LPC_order,              /* I    LPC order                                                       */\r
-    const opus_int16                 x[],                    /* I    Input signal                                                    */\r
-    const opus_int                   subfr_length,           /* I    Input signal subframe length including preceeding samples       */\r
-    const opus_int                   nb_subfr                /* I:   Number of subframes                                             */\r
-)\r
-{\r
-    opus_int     k;\r
-    opus_int32   a_Q16[ MAX_LPC_ORDER ];\r
-    opus_int     isInterpLower, shift;\r
-    opus_int32   res_nrg0, res_nrg1;\r
-    opus_int     rshift0, rshift1; \r
-\r
-    /* Used only for LSF interpolation */\r
-    opus_int32   a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg, res_nrg_2nd;\r
-    opus_int     res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q, res_nrg_2nd_Q;\r
-    opus_int16   a_tmp_Q12[ MAX_LPC_ORDER ];\r
-    opus_int16   NLSF0_Q15[ MAX_LPC_ORDER ];\r
-    opus_int16   LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ];\r
-\r
-    /* Default: no interpolation */\r
-    *interpIndex = 4;\r
-\r
-    /* Burg AR analysis for the full frame */\r
-    silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, subfr_length, nb_subfr, SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order );\r
-\r
-    if( firstFrameAfterReset ) {\r
-        silk_bwexpander_32( a_Q16, LPC_order, SILK_FIX_CONST( FIND_LPC_CHIRP_FIRST_FRAME, 16 ) );\r
-    } else {\r
-        silk_bwexpander_32( a_Q16, LPC_order, SILK_FIX_CONST( FIND_LPC_CHIRP, 16 ) );\r
-    }\r
-\r
-    if( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) {\r
-\r
-        /* Optimal solution for last 10 ms */\r
-        silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + ( MAX_NB_SUBFR >> 1 ) * subfr_length, \r
-            subfr_length, ( MAX_NB_SUBFR >> 1 ), SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order );\r
-\r
-        silk_bwexpander_32( a_tmp_Q16, LPC_order, SILK_FIX_CONST( FIND_LPC_CHIRP, 16 ) );\r
-\r
-        /* subtract residual energy here, as that's easier than adding it to the    */\r
-        /* residual energy of the first 10 ms in each iteration of the search below */\r
-        shift = res_tmp_nrg_Q - res_nrg_Q;\r
-        if( shift >= 0 ) {\r
-            if( shift < 32 ) { \r
-                res_nrg = res_nrg - SKP_RSHIFT( res_tmp_nrg, shift );\r
-            }\r
-        } else {\r
-            SKP_assert( shift > -32 ); \r
-            res_nrg   = SKP_RSHIFT( res_nrg, -shift ) - res_tmp_nrg;\r
-            res_nrg_Q = res_tmp_nrg_Q; \r
-        }\r
-        \r
-        /* Convert to NLSFs */\r
-        silk_A2NLSF( NLSF_Q15, a_tmp_Q16, LPC_order );\r
-\r
-        /* Search over interpolation indices to find the one with lowest residual energy */\r
-        res_nrg_2nd = SKP_int32_MAX;\r
-        for( k = 3; k >= 0; k-- ) {\r
-            /* Interpolate NLSFs for first half */\r
-            silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order );\r
-\r
-            /* Convert to LPC for residual energy evaluation */\r
-            silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, LPC_order );\r
-\r
-            /* Calculate residual energy with NLSF interpolation */\r
-            silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, LPC_order );\r
-\r
-            silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + LPC_order,                subfr_length - LPC_order );\r
-            silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + LPC_order + subfr_length, subfr_length - LPC_order );\r
-\r
-            /* Add subframe energies from first half frame */\r
-            shift = rshift0 - rshift1;\r
-            if( shift >= 0 ) {\r
-                res_nrg1         = SKP_RSHIFT( res_nrg1, shift );\r
-                res_nrg_interp_Q = -rshift0;\r
-            } else {\r
-                res_nrg0         = SKP_RSHIFT( res_nrg0, -shift );\r
-                res_nrg_interp_Q = -rshift1;\r
-            }\r
-            res_nrg_interp = SKP_ADD32( res_nrg0, res_nrg1 );\r
-\r
-            /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */\r
-            shift = res_nrg_interp_Q - res_nrg_Q;\r
-            if( shift >= 0 ) {\r
-                if( SKP_RSHIFT( res_nrg_interp, shift ) < res_nrg ) {\r
-                    isInterpLower = SKP_TRUE;\r
-                } else {\r
-                    isInterpLower = SKP_FALSE;\r
-                }\r
-            } else {\r
-                if( -shift < 32 ) { \r
-                    if( res_nrg_interp < SKP_RSHIFT( res_nrg, -shift ) ) {\r
-                        isInterpLower = SKP_TRUE;\r
-                    } else {\r
-                        isInterpLower = SKP_FALSE;\r
-                    }\r
-                } else {\r
-                    isInterpLower = SKP_FALSE;\r
-                }\r
-            }\r
-\r
-            /* Determine whether current interpolated NLSFs are best so far */\r
-            if( isInterpLower == SKP_TRUE ) {\r
-                /* Interpolation has lower residual energy */\r
-                res_nrg   = res_nrg_interp;\r
-                res_nrg_Q = res_nrg_interp_Q;\r
-                *interpIndex = (opus_int8)k;\r
-            }\r
-            res_nrg_2nd   = res_nrg_interp;\r
-            res_nrg_2nd_Q = res_nrg_interp_Q;\r
-        }\r
-    }\r
-\r
-    if( *interpIndex == 4 ) {\r
-        /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */\r
-        silk_A2NLSF( NLSF_Q15, a_Q16, LPC_order );\r
-    }\r
-\r
-    SKP_assert( *interpIndex == 4 || ( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) );\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+#include "silk_tuning_parameters.h"
+
+/* Finds LPC vector from correlations, and converts to NLSF */
+void silk_find_LPC_FIX(
+    opus_int16                       NLSF_Q15[],             /* O    NLSFs                                                           */
+    opus_int8                        *interpIndex,           /* O    NLSF interpolation index, only used for NLSF interpolation      */
+    const opus_int16                 prev_NLSFq_Q15[],       /* I    previous NLSFs, only used for NLSF interpolation                */
+    const opus_int                   useInterpNLSFs,         /* I    Flag                                                            */
+    const opus_int                   firstFrameAfterReset,   /* I    Flag                                                            */
+    const opus_int                   LPC_order,              /* I    LPC order                                                       */
+    const opus_int16                 x[],                    /* I    Input signal                                                    */
+    const opus_int                   subfr_length,           /* I    Input signal subframe length including preceeding samples       */
+    const opus_int                   nb_subfr                /* I:   Number of subframes                                             */
+)
+{
+    opus_int     k;
+    opus_int32   a_Q16[ MAX_LPC_ORDER ];
+    opus_int     isInterpLower, shift;
+    opus_int32   res_nrg0, res_nrg1;
+    opus_int     rshift0, rshift1;
+
+    /* Used only for LSF interpolation */
+    opus_int32   a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg, res_nrg_2nd;
+    opus_int     res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q, res_nrg_2nd_Q;
+    opus_int16   a_tmp_Q12[ MAX_LPC_ORDER ];
+    opus_int16   NLSF0_Q15[ MAX_LPC_ORDER ];
+    opus_int16   LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ];
+
+    /* Default: no interpolation */
+    *interpIndex = 4;
+
+    /* Burg AR analysis for the full frame */
+    silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, subfr_length, nb_subfr, SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order );
+
+    if( firstFrameAfterReset ) {
+        silk_bwexpander_32( a_Q16, LPC_order, SILK_FIX_CONST( FIND_LPC_CHIRP_FIRST_FRAME, 16 ) );
+    } else {
+        silk_bwexpander_32( a_Q16, LPC_order, SILK_FIX_CONST( FIND_LPC_CHIRP, 16 ) );
+    }
+
+    if( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) {
+
+        /* Optimal solution for last 10 ms */
+        silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + ( MAX_NB_SUBFR >> 1 ) * subfr_length,
+            subfr_length, ( MAX_NB_SUBFR >> 1 ), SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order );
+
+        silk_bwexpander_32( a_tmp_Q16, LPC_order, SILK_FIX_CONST( FIND_LPC_CHIRP, 16 ) );
+
+        /* subtract residual energy here, as that's easier than adding it to the    */
+        /* residual energy of the first 10 ms in each iteration of the search below */
+        shift = res_tmp_nrg_Q - res_nrg_Q;
+        if( shift >= 0 ) {
+            if( shift < 32 ) {
+                res_nrg = res_nrg - SKP_RSHIFT( res_tmp_nrg, shift );
+            }
+        } else {
+            SKP_assert( shift > -32 );
+            res_nrg   = SKP_RSHIFT( res_nrg, -shift ) - res_tmp_nrg;
+            res_nrg_Q = res_tmp_nrg_Q;
+        }
+
+        /* Convert to NLSFs */
+        silk_A2NLSF( NLSF_Q15, a_tmp_Q16, LPC_order );
+
+        /* Search over interpolation indices to find the one with lowest residual energy */
+        res_nrg_2nd = SKP_int32_MAX;
+        for( k = 3; k >= 0; k-- ) {
+            /* Interpolate NLSFs for first half */
+            silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order );
+
+            /* Convert to LPC for residual energy evaluation */
+            silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, LPC_order );
+
+            /* Calculate residual energy with NLSF interpolation */
+            silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, LPC_order );
+
+            silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + LPC_order,                subfr_length - LPC_order );
+            silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + LPC_order + subfr_length, subfr_length - LPC_order );
+
+            /* Add subframe energies from first half frame */
+            shift = rshift0 - rshift1;
+            if( shift >= 0 ) {
+                res_nrg1         = SKP_RSHIFT( res_nrg1, shift );
+                res_nrg_interp_Q = -rshift0;
+            } else {
+                res_nrg0         = SKP_RSHIFT( res_nrg0, -shift );
+                res_nrg_interp_Q = -rshift1;
+            }
+            res_nrg_interp = SKP_ADD32( res_nrg0, res_nrg1 );
+
+            /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */
+            shift = res_nrg_interp_Q - res_nrg_Q;
+            if( shift >= 0 ) {
+                if( SKP_RSHIFT( res_nrg_interp, shift ) < res_nrg ) {
+                    isInterpLower = SKP_TRUE;
+                } else {
+                    isInterpLower = SKP_FALSE;
+                }
+            } else {
+                if( -shift < 32 ) {
+                    if( res_nrg_interp < SKP_RSHIFT( res_nrg, -shift ) ) {
+                        isInterpLower = SKP_TRUE;
+                    } else {
+                        isInterpLower = SKP_FALSE;
+                    }
+                } else {
+                    isInterpLower = SKP_FALSE;
+                }
+            }
+
+            /* Determine whether current interpolated NLSFs are best so far */
+            if( isInterpLower == SKP_TRUE ) {
+                /* Interpolation has lower residual energy */
+                res_nrg   = res_nrg_interp;
+                res_nrg_Q = res_nrg_interp_Q;
+                *interpIndex = (opus_int8)k;
+            }
+            res_nrg_2nd   = res_nrg_interp;
+            res_nrg_2nd_Q = res_nrg_interp_Q;
+        }
+    }
+
+    if( *interpIndex == 4 ) {
+        /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
+        silk_A2NLSF( NLSF_Q15, a_Q16, LPC_order );
+    }
+
+    SKP_assert( *interpIndex == 4 || ( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) );
+}
index e88dda4..657462d 100644 (file)
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-#include "silk_tuning_parameters.h"\r
-\r
-/* Head room for correlations                           */\r
-#define LTP_CORRS_HEAD_ROOM                             2\r
-\r
-void silk_fit_LTP(\r
-    opus_int32 LTP_coefs_Q16[ LTP_ORDER ],\r
-    opus_int16 LTP_coefs_Q14[ LTP_ORDER ]\r
-);\r
-\r
-void silk_find_LTP_FIX(\r
-    opus_int16           b_Q14[ MAX_NB_SUBFR * LTP_ORDER ],              /* O    LTP coefs                                                   */\r
-    opus_int32           WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ],   /* O    Weight for LTP quantization                                 */\r
-    opus_int             *LTPredCodGain_Q7,                              /* O    LTP coding gain                                             */\r
-    const opus_int16     r_lpc[]  ,                                      /* I    residual signal after LPC signal + state for first 10 ms    */\r
-    const opus_int       lag[ MAX_NB_SUBFR ],                            /* I    LTP lags                                                    */\r
-    const opus_int32     Wght_Q15[ MAX_NB_SUBFR ],                       /* I    weights                                                     */\r
-    const opus_int       subfr_length,                                   /* I    subframe length                                             */\r
-    const opus_int       nb_subfr,                                       /* I    number of subframes                                         */\r
-    const opus_int       mem_offset,                                     /* I    number of samples in LTP memory                             */\r
-    opus_int             corr_rshifts[ MAX_NB_SUBFR ]                    /* O    right shifts applied to correlations                        */\r
-)\r
-{\r
-    opus_int   i, k, lshift;\r
-    const opus_int16 *r_ptr, *lag_ptr;\r
-    opus_int16 *b_Q14_ptr;\r
-\r
-    opus_int32 regu;\r
-    opus_int32 *WLTP_ptr;\r
-    opus_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], g_Q26;\r
-    opus_int32 w[ MAX_NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits;\r
-\r
-    opus_int32 temp32, denom32;\r
-    opus_int   extra_shifts;\r
-    opus_int   rr_shifts, maxRshifts, maxRshifts_wxtra, LZs;\r
-    opus_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16;\r
-    opus_int32 Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ];\r
-    opus_int32 wd, m_Q12;\r
-    \r
-    b_Q14_ptr = b_Q14;\r
-    WLTP_ptr  = WLTP;\r
-    r_ptr     = &r_lpc[ mem_offset ];\r
-    for( k = 0; k < nb_subfr; k++ ) {\r
-        lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );\r
-\r
-        silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */\r
-\r
-        /* Assure headroom */\r
-        LZs = silk_CLZ32( rr[k] );\r
-        if( LZs < LTP_CORRS_HEAD_ROOM ) {\r
-            rr[ k ] = SKP_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs );\r
-            rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs );\r
-        }\r
-        corr_rshifts[ k ] = rr_shifts;\r
-        silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ] );  /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */\r
-\r
-        /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */\r
-        silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ] );  /* Rr_fix_ptr   in Q( -corr_rshifts[ k ] ) */\r
-        if( corr_rshifts[ k ] > rr_shifts ) {\r
-            rr[ k ] = SKP_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */\r
-        }\r
-        SKP_assert( rr[ k ] >= 0 );\r
-\r
-        regu = 1;\r
-        regu = SKP_SMLAWB( regu, rr[ k ], SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );\r
-        regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );\r
-        regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );\r
-        silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER );\r
-\r
-        silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */\r
-\r
-        /* Limit and store in Q14 */\r
-        silk_fit_LTP( b_Q16, b_Q14_ptr );\r
-\r
-        /* Calculate residual energy */\r
-        nrg[ k ] = silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */\r
-\r
-        /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */\r
-        extra_shifts = SKP_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM );\r
-        denom32 = SKP_LSHIFT_SAT32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */\r
-            SKP_RSHIFT( SKP_SMULWB( subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts );    /* Q( -corr_rshifts[ k ] + extra_shifts ) */\r
-        denom32 = SKP_max( denom32, 1 );\r
-        SKP_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < SKP_int32_MAX );                        /* Wght always < 0.5 in Q0 */\r
-        temp32 = SKP_DIV32( SKP_LSHIFT( ( opus_int32 )Wght_Q15[ k ], 16 ), denom32 );            /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */\r
-        temp32 = SKP_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 );              /* Q26 */\r
-        \r
-        /* Limit temp such that the below scaling never wraps around */\r
-        WLTP_max = 0;\r
-        for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {\r
-            WLTP_max = SKP_max( WLTP_ptr[ i ], WLTP_max );\r
-        }\r
-        lshift = silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */\r
-        SKP_assert( 26 - 18 + lshift >= 0 );\r
-        if( 26 - 18 + lshift < 31 ) {\r
-            temp32 = SKP_min_32( temp32, SKP_LSHIFT( ( opus_int32 )1, 26 - 18 + lshift ) );\r
-        }\r
-\r
-        silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */\r
-        \r
-        w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER/2, LTP_ORDER/2, LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */\r
-        SKP_assert( w[k] >= 0 );\r
-\r
-        r_ptr     += subfr_length;\r
-        b_Q14_ptr += LTP_ORDER;\r
-        WLTP_ptr  += LTP_ORDER * LTP_ORDER;\r
-    }\r
-\r
-    maxRshifts = 0;\r
-    for( k = 0; k < nb_subfr; k++ ) {\r
-        maxRshifts = SKP_max_int( corr_rshifts[ k ], maxRshifts );\r
-    }\r
-\r
-    /* Compute LTP coding gain */\r
-    if( LTPredCodGain_Q7 != NULL ) {\r
-        LPC_LTP_res_nrg = 0;\r
-        LPC_res_nrg     = 0;\r
-        SKP_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */\r
-        for( k = 0; k < nb_subfr; k++ ) {\r
-            LPC_res_nrg     = SKP_ADD32( LPC_res_nrg,     SKP_RSHIFT( SKP_ADD32( SKP_SMULWB(  rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /*  Q( -maxRshifts ) */\r
-            LPC_LTP_res_nrg = SKP_ADD32( LPC_LTP_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /*  Q( -maxRshifts ) */\r
-        }\r
-        LPC_LTP_res_nrg = SKP_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */\r
-\r
-        div_Q16 = silk_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 );\r
-        *LTPredCodGain_Q7 = ( opus_int )SKP_SMULBB( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) );\r
-\r
-        SKP_assert( *LTPredCodGain_Q7 == ( opus_int )SKP_SAT16( SKP_MUL( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) );\r
-    }\r
-\r
-    /* smoothing */\r
-    /* d = sum( B, 1 ); */\r
-    b_Q14_ptr = b_Q14;\r
-    for( k = 0; k < nb_subfr; k++ ) {\r
-        d_Q14[ k ] = 0;\r
-        for( i = 0; i < LTP_ORDER; i++ ) {\r
-            d_Q14[ k ] += b_Q14_ptr[ i ];\r
-        }\r
-        b_Q14_ptr += LTP_ORDER;\r
-    }\r
-\r
-    /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */\r
-        \r
-    /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */\r
-    max_abs_d_Q14 = 0;\r
-    max_w_bits    = 0;\r
-    for( k = 0; k < nb_subfr; k++ ) {\r
-        max_abs_d_Q14 = SKP_max_32( max_abs_d_Q14, SKP_abs( d_Q14[ k ] ) );\r
-        /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */\r
-        /* Find bits needed in Q( 18 - maxRshifts ) */\r
-        max_w_bits = SKP_max_32( max_w_bits, 32 - silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts ); \r
-    }\r
-\r
-    /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -SKP_int16_MIN */\r
-    SKP_assert( max_abs_d_Q14 <= ( 5 << 15 ) );\r
-\r
-    /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */\r
-    extra_shifts = max_w_bits + 32 - silk_CLZ32( max_abs_d_Q14 ) - 14;\r
-    \r
-    /* Subtract what we got available; bits in output var plus maxRshifts */\r
-    extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */\r
-    extra_shifts = SKP_max_int( extra_shifts, 0 );\r
-\r
-    maxRshifts_wxtra = maxRshifts + extra_shifts;\r
-    \r
-    temp32 = SKP_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */\r
-    wd = 0;\r
-    for( k = 0; k < nb_subfr; k++ ) {\r
-        /* w has at least 2 bits of headroom so no overflow should happen */\r
-        temp32 = SKP_ADD32( temp32,                     SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) );                    /* Q( 18 - maxRshifts_wxtra ) */\r
-        wd     = SKP_ADD32( wd, SKP_LSHIFT( SKP_SMULWW( SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */\r
-    }\r
-    m_Q12 = silk_DIV32_varQ( wd, temp32, 12 );\r
-\r
-    b_Q14_ptr = b_Q14;\r
-    for( k = 0; k < nb_subfr; k++ ) {\r
-        /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */\r
-        if( 2 - corr_rshifts[k] > 0 ) {\r
-            temp32 = SKP_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] );\r
-        } else {\r
-            temp32 = SKP_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 );\r
-        }\r
-\r
-        g_Q26 = SKP_MUL( \r
-            SKP_DIV32( \r
-                SILK_FIX_CONST( LTP_SMOOTHING, 26 ), \r
-                SKP_RSHIFT( SILK_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ),                                       /* Q10 */ \r
-            SKP_LSHIFT_SAT32( SKP_SUB_SAT32( ( opus_int32 )m_Q12, SKP_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) );  /* Q16 */\r
-\r
-        temp32 = 0;\r
-        for( i = 0; i < LTP_ORDER; i++ ) {\r
-            delta_b_Q14[ i ] = SKP_max_16( b_Q14_ptr[ i ], 1638 );  /* 1638_Q14 = 0.1_Q0 */\r
-            temp32 += delta_b_Q14[ i ];                          /* Q14 */\r
-        }\r
-        temp32 = SKP_DIV32( g_Q26, temp32 ); /* Q14->Q12 */\r
-        for( i = 0; i < LTP_ORDER; i++ ) {\r
-            b_Q14_ptr[ i ] = SKP_LIMIT_32( ( opus_int32 )b_Q14_ptr[ i ] + SKP_SMULWB( SKP_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 );\r
-        }\r
-        b_Q14_ptr += LTP_ORDER;\r
-    }\r
-TOC(find_LTP_FIX)\r
-}\r
-\r
-void silk_fit_LTP(\r
-    opus_int32 LTP_coefs_Q16[ LTP_ORDER ],\r
-    opus_int16 LTP_coefs_Q14[ LTP_ORDER ]\r
-)\r
-{\r
-    opus_int i;\r
-\r
-    for( i = 0; i < LTP_ORDER; i++ ) {\r
-        LTP_coefs_Q14[ i ] = ( opus_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) );\r
-    }\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+#include "silk_tuning_parameters.h"
+
+/* Head room for correlations                           */
+#define LTP_CORRS_HEAD_ROOM                             2
+
+void silk_fit_LTP(
+    opus_int32 LTP_coefs_Q16[ LTP_ORDER ],
+    opus_int16 LTP_coefs_Q14[ LTP_ORDER ]
+);
+
+void silk_find_LTP_FIX(
+    opus_int16           b_Q14[ MAX_NB_SUBFR * LTP_ORDER ],              /* O    LTP coefs                                                   */
+    opus_int32           WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ],   /* O    Weight for LTP quantization                                 */
+    opus_int             *LTPredCodGain_Q7,                              /* O    LTP coding gain                                             */
+    const opus_int16     r_lpc[]  ,                                      /* I    residual signal after LPC signal + state for first 10 ms    */
+    const opus_int       lag[ MAX_NB_SUBFR ],                            /* I    LTP lags                                                    */
+    const opus_int32     Wght_Q15[ MAX_NB_SUBFR ],                       /* I    weights                                                     */
+    const opus_int       subfr_length,                                   /* I    subframe length                                             */
+    const opus_int       nb_subfr,                                       /* I    number of subframes                                         */
+    const opus_int       mem_offset,                                     /* I    number of samples in LTP memory                             */
+    opus_int             corr_rshifts[ MAX_NB_SUBFR ]                    /* O    right shifts applied to correlations                        */
+)
+{
+    opus_int   i, k, lshift;
+    const opus_int16 *r_ptr, *lag_ptr;
+    opus_int16 *b_Q14_ptr;
+
+    opus_int32 regu;
+    opus_int32 *WLTP_ptr;
+    opus_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], g_Q26;
+    opus_int32 w[ MAX_NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits;
+
+    opus_int32 temp32, denom32;
+    opus_int   extra_shifts;
+    opus_int   rr_shifts, maxRshifts, maxRshifts_wxtra, LZs;
+    opus_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16;
+    opus_int32 Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ];
+    opus_int32 wd, m_Q12;
+
+    b_Q14_ptr = b_Q14;
+    WLTP_ptr  = WLTP;
+    r_ptr     = &r_lpc[ mem_offset ];
+    for( k = 0; k < nb_subfr; k++ ) {
+        lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
+
+        silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */
+
+        /* Assure headroom */
+        LZs = silk_CLZ32( rr[k] );
+        if( LZs < LTP_CORRS_HEAD_ROOM ) {
+            rr[ k ] = SKP_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs );
+            rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs );
+        }
+        corr_rshifts[ k ] = rr_shifts;
+        silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ] );  /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */
+
+        /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */
+        silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ] );  /* Rr_fix_ptr   in Q( -corr_rshifts[ k ] ) */
+        if( corr_rshifts[ k ] > rr_shifts ) {
+            rr[ k ] = SKP_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */
+        }
+        SKP_assert( rr[ k ] >= 0 );
+
+        regu = 1;
+        regu = SKP_SMLAWB( regu, rr[ k ], SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
+        regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
+        regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
+        silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER );
+
+        silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */
+
+        /* Limit and store in Q14 */
+        silk_fit_LTP( b_Q16, b_Q14_ptr );
+
+        /* Calculate residual energy */
+        nrg[ k ] = silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */
+
+        /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */
+        extra_shifts = SKP_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM );
+        denom32 = SKP_LSHIFT_SAT32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */
+            SKP_RSHIFT( SKP_SMULWB( subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts );    /* Q( -corr_rshifts[ k ] + extra_shifts ) */
+        denom32 = SKP_max( denom32, 1 );
+        SKP_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < SKP_int32_MAX );                        /* Wght always < 0.5 in Q0 */
+        temp32 = SKP_DIV32( SKP_LSHIFT( ( opus_int32 )Wght_Q15[ k ], 16 ), denom32 );            /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */
+        temp32 = SKP_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 );              /* Q26 */
+
+        /* Limit temp such that the below scaling never wraps around */
+        WLTP_max = 0;
+        for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
+            WLTP_max = SKP_max( WLTP_ptr[ i ], WLTP_max );
+        }
+        lshift = silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */
+        SKP_assert( 26 - 18 + lshift >= 0 );
+        if( 26 - 18 + lshift < 31 ) {
+            temp32 = SKP_min_32( temp32, SKP_LSHIFT( ( opus_int32 )1, 26 - 18 + lshift ) );
+        }
+
+        silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */
+
+        w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER/2, LTP_ORDER/2, LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */
+        SKP_assert( w[k] >= 0 );
+
+        r_ptr     += subfr_length;
+        b_Q14_ptr += LTP_ORDER;
+        WLTP_ptr  += LTP_ORDER * LTP_ORDER;
+    }
+
+    maxRshifts = 0;
+    for( k = 0; k < nb_subfr; k++ ) {
+        maxRshifts = SKP_max_int( corr_rshifts[ k ], maxRshifts );
+    }
+
+    /* Compute LTP coding gain */
+    if( LTPredCodGain_Q7 != NULL ) {
+        LPC_LTP_res_nrg = 0;
+        LPC_res_nrg     = 0;
+        SKP_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */
+        for( k = 0; k < nb_subfr; k++ ) {
+            LPC_res_nrg     = SKP_ADD32( LPC_res_nrg,     SKP_RSHIFT( SKP_ADD32( SKP_SMULWB(  rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /*  Q( -maxRshifts ) */
+            LPC_LTP_res_nrg = SKP_ADD32( LPC_LTP_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /*  Q( -maxRshifts ) */
+        }
+        LPC_LTP_res_nrg = SKP_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */
+
+        div_Q16 = silk_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 );
+        *LTPredCodGain_Q7 = ( opus_int )SKP_SMULBB( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) );
+
+        SKP_assert( *LTPredCodGain_Q7 == ( opus_int )SKP_SAT16( SKP_MUL( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) );
+    }
+
+    /* smoothing */
+    /* d = sum( B, 1 ); */
+    b_Q14_ptr = b_Q14;
+    for( k = 0; k < nb_subfr; k++ ) {
+        d_Q14[ k ] = 0;
+        for( i = 0; i < LTP_ORDER; i++ ) {
+            d_Q14[ k ] += b_Q14_ptr[ i ];
+        }
+        b_Q14_ptr += LTP_ORDER;
+    }
+
+    /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */
+
+    /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */
+    max_abs_d_Q14 = 0;
+    max_w_bits    = 0;
+    for( k = 0; k < nb_subfr; k++ ) {
+        max_abs_d_Q14 = SKP_max_32( max_abs_d_Q14, SKP_abs( d_Q14[ k ] ) );
+        /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */
+        /* Find bits needed in Q( 18 - maxRshifts ) */
+        max_w_bits = SKP_max_32( max_w_bits, 32 - silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts );
+    }
+
+    /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -SKP_int16_MIN */
+    SKP_assert( max_abs_d_Q14 <= ( 5 << 15 ) );
+
+    /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */
+    extra_shifts = max_w_bits + 32 - silk_CLZ32( max_abs_d_Q14 ) - 14;
+
+    /* Subtract what we got available; bits in output var plus maxRshifts */
+    extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */
+    extra_shifts = SKP_max_int( extra_shifts, 0 );
+
+    maxRshifts_wxtra = maxRshifts + extra_shifts;
+
+    temp32 = SKP_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */
+    wd = 0;
+    for( k = 0; k < nb_subfr; k++ ) {
+        /* w has at least 2 bits of headroom so no overflow should happen */
+        temp32 = SKP_ADD32( temp32,                     SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) );                    /* Q( 18 - maxRshifts_wxtra ) */
+        wd     = SKP_ADD32( wd, SKP_LSHIFT( SKP_SMULWW( SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */
+    }
+    m_Q12 = silk_DIV32_varQ( wd, temp32, 12 );
+
+    b_Q14_ptr = b_Q14;
+    for( k = 0; k < nb_subfr; k++ ) {
+        /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */
+        if( 2 - corr_rshifts[k] > 0 ) {
+            temp32 = SKP_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] );
+        } else {
+            temp32 = SKP_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 );
+        }
+
+        g_Q26 = SKP_MUL(
+            SKP_DIV32(
+                SILK_FIX_CONST( LTP_SMOOTHING, 26 ),
+                SKP_RSHIFT( SILK_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ),                                       /* Q10 */
+            SKP_LSHIFT_SAT32( SKP_SUB_SAT32( ( opus_int32 )m_Q12, SKP_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) );  /* Q16 */
+
+        temp32 = 0;
+        for( i = 0; i < LTP_ORDER; i++ ) {
+            delta_b_Q14[ i ] = SKP_max_16( b_Q14_ptr[ i ], 1638 );  /* 1638_Q14 = 0.1_Q0 */
+            temp32 += delta_b_Q14[ i ];                          /* Q14 */
+        }
+        temp32 = SKP_DIV32( g_Q26, temp32 ); /* Q14->Q12 */
+        for( i = 0; i < LTP_ORDER; i++ ) {
+            b_Q14_ptr[ i ] = SKP_LIMIT_32( ( opus_int32 )b_Q14_ptr[ i ] + SKP_SMULWB( SKP_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 );
+        }
+        b_Q14_ptr += LTP_ORDER;
+    }
+TOC(find_LTP_FIX)
+}
+
+void silk_fit_LTP(
+    opus_int32 LTP_coefs_Q16[ LTP_ORDER ],
+    opus_int16 LTP_coefs_Q14[ LTP_ORDER ]
+)
+{
+    opus_int i;
+
+    for( i = 0; i < LTP_ORDER; i++ ) {
+        LTP_coefs_Q14[ i ] = ( opus_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) );
+    }
+}
index 866f1d7..5bda555 100644 (file)
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-#include "silk_tuning_parameters.h"\r
-\r
-/* Find pitch lags */\r
-void silk_find_pitch_lags_FIX(\r
-    silk_encoder_state_FIX          *psEnc,         /* I/O  encoder state                               */\r
-    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  encoder control                             */\r
-    opus_int16                       res[],          /* O    residual                                    */\r
-    const opus_int16                 x[]             /* I    Speech signal                               */\r
-)\r
-{\r
-    opus_int   buf_len, i, scale;\r
-    opus_int32 thrhld_Q15, res_nrg;\r
-    const opus_int16 *x_buf, *x_buf_ptr;\r
-    opus_int16 Wsig[      FIND_PITCH_LPC_WIN_MAX ], *Wsig_ptr;\r
-    opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];\r
-    opus_int16 rc_Q15[    MAX_FIND_PITCH_LPC_ORDER ];\r
-    opus_int32 A_Q24[     MAX_FIND_PITCH_LPC_ORDER ];\r
-    opus_int16 A_Q12[     MAX_FIND_PITCH_LPC_ORDER ];\r
-\r
-    /******************************************/\r
-    /* Setup buffer lengths etc based on Fs   */\r
-    /******************************************/\r
-    buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;\r
-\r
-    /* Safty check */\r
-    SKP_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );\r
-\r
-    x_buf = x - psEnc->sCmn.ltp_mem_length;\r
-\r
-    /*************************************/\r
-    /* Estimate LPC AR coefficients      */\r
-    /*************************************/\r
-    \r
-    /* Calculate windowed signal */\r
-    \r
-    /* First LA_LTP samples */\r
-    x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;\r
-    Wsig_ptr  = Wsig;\r
-    silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );\r
-\r
-    /* Middle un - windowed samples */\r
-    Wsig_ptr  += psEnc->sCmn.la_pitch;\r
-    x_buf_ptr += psEnc->sCmn.la_pitch;\r
-    SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );\r
-\r
-    /* Last LA_LTP samples */\r
-    Wsig_ptr  += psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 );\r
-    x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 );\r
-    silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );\r
-\r
-    /* Calculate autocorrelation sequence */\r
-    silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); \r
-        \r
-    /* Add white noise, as fraction of energy */\r
-    auto_corr[ 0 ] = SKP_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1;\r
-\r
-    /* Calculate the reflection coefficients using schur */\r
-    res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );\r
-\r
-    /* Prediction gain */\r
-    psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], SKP_max_int( res_nrg, 1 ), 16 );\r
-\r
-    /* Convert reflection coefficients to prediction coefficients */\r
-    silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder );\r
-    \r
-    /* Convert From 32 bit Q24 to 16 bit Q12 coefs */\r
-    for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {\r
-        A_Q12[ i ] = ( opus_int16 )SKP_SAT16( SKP_RSHIFT( A_Q24[ i ], 12 ) );\r
-    }\r
-\r
-    /* Do BWE */\r
-    silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWITH_EXPANSION, 16 ) );\r
-    \r
-    /*****************************************/\r
-    /* LPC analysis filtering                */\r
-    /*****************************************/\r
-    silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder );\r
-\r
-    if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {\r
-        /* Threshold for pitch estimator */\r
-        thrhld_Q15 = SILK_FIX_CONST( 0.6, 15 );\r
-        thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.004, 15 ), psEnc->sCmn.pitchEstimationLPCOrder );\r
-        thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.1,   7  ), psEnc->sCmn.speech_activity_Q8 );\r
-        thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.15,  15 ), SKP_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) );\r
-        thrhld_Q15 = SKP_SMLAWB( thrhld_Q15, SILK_FIX_CONST( -0.1,   16 ), psEnc->sCmn.input_tilt_Q15 );\r
-        thrhld_Q15 = SKP_SAT16(  thrhld_Q15 );\r
-\r
-        /*****************************************/\r
-        /* Call pitch estimator                  */\r
-        /*****************************************/\r
-        if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, \r
-                &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, \r
-                ( opus_int16 )thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 ) \r
-        {\r
-            psEnc->sCmn.indices.signalType = TYPE_VOICED;\r
-        } else {\r
-            psEnc->sCmn.indices.signalType = TYPE_UNVOICED;\r
-        }\r
-    } else {\r
-        SKP_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) );\r
-        psEnc->sCmn.indices.lagIndex = 0;\r
-        psEnc->sCmn.indices.contourIndex = 0;\r
-        psEnc->LTPCorr_Q15 = 0;\r
-    }\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+#include "silk_tuning_parameters.h"
+
+/* Find pitch lags */
+void silk_find_pitch_lags_FIX(
+    silk_encoder_state_FIX          *psEnc,         /* I/O  encoder state                               */
+    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  encoder control                             */
+    opus_int16                       res[],          /* O    residual                                    */
+    const opus_int16                 x[]             /* I    Speech signal                               */
+)
+{
+    opus_int   buf_len, i, scale;
+    opus_int32 thrhld_Q15, res_nrg;
+    const opus_int16 *x_buf, *x_buf_ptr;
+    opus_int16 Wsig[      FIND_PITCH_LPC_WIN_MAX ], *Wsig_ptr;
+    opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
+    opus_int16 rc_Q15[    MAX_FIND_PITCH_LPC_ORDER ];
+    opus_int32 A_Q24[     MAX_FIND_PITCH_LPC_ORDER ];
+    opus_int16 A_Q12[     MAX_FIND_PITCH_LPC_ORDER ];
+
+    /******************************************/
+    /* Setup buffer lengths etc based on Fs   */
+    /******************************************/
+    buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
+
+    /* Safty check */
+    SKP_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
+
+    x_buf = x - psEnc->sCmn.ltp_mem_length;
+
+    /*************************************/
+    /* Estimate LPC AR coefficients      */
+    /*************************************/
+
+    /* Calculate windowed signal */
+
+    /* First LA_LTP samples */
+    x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;
+    Wsig_ptr  = Wsig;
+    silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );
+
+    /* Middle un - windowed samples */
+    Wsig_ptr  += psEnc->sCmn.la_pitch;
+    x_buf_ptr += psEnc->sCmn.la_pitch;
+    SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );
+
+    /* Last LA_LTP samples */
+    Wsig_ptr  += psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 );
+    x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 );
+    silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );
+
+    /* Calculate autocorrelation sequence */
+    silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 );
+
+    /* Add white noise, as fraction of energy */
+    auto_corr[ 0 ] = SKP_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1;
+
+    /* Calculate the reflection coefficients using schur */
+    res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );
+
+    /* Prediction gain */
+    psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], SKP_max_int( res_nrg, 1 ), 16 );
+
+    /* Convert reflection coefficients to prediction coefficients */
+    silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder );
+
+    /* Convert From 32 bit Q24 to 16 bit Q12 coefs */
+    for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {
+        A_Q12[ i ] = ( opus_int16 )SKP_SAT16( SKP_RSHIFT( A_Q24[ i ], 12 ) );
+    }
+
+    /* Do BWE */
+    silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWITH_EXPANSION, 16 ) );
+
+    /*****************************************/
+    /* LPC analysis filtering                */
+    /*****************************************/
+    silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder );
+
+    if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {
+        /* Threshold for pitch estimator */
+        thrhld_Q15 = SILK_FIX_CONST( 0.6, 15 );
+        thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.004, 15 ), psEnc->sCmn.pitchEstimationLPCOrder );
+        thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.1,   7  ), psEnc->sCmn.speech_activity_Q8 );
+        thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.15,  15 ), SKP_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) );
+        thrhld_Q15 = SKP_SMLAWB( thrhld_Q15, SILK_FIX_CONST( -0.1,   16 ), psEnc->sCmn.input_tilt_Q15 );
+        thrhld_Q15 = SKP_SAT16(  thrhld_Q15 );
+
+        /*****************************************/
+        /* Call pitch estimator                  */
+        /*****************************************/
+        if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex,
+                &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16,
+                ( opus_int16 )thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 )
+        {
+            psEnc->sCmn.indices.signalType = TYPE_VOICED;
+        } else {
+            psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
+        }
+    } else {
+        SKP_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) );
+        psEnc->sCmn.indices.lagIndex = 0;
+        psEnc->sCmn.indices.contourIndex = 0;
+        psEnc->LTPCorr_Q15 = 0;
+    }
+}
index ae95372..6571953 100644 (file)
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-\r
-void silk_find_pred_coefs_FIX(\r
-    silk_encoder_state_FIX          *psEnc,         /* I/O  encoder state                               */\r
-    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  encoder control                             */\r
-    const opus_int16                 res_pitch[],    /* I    Residual from pitch analysis                */\r
-    const opus_int16                 x[]             /* I    Speech signal                               */\r
-)\r
-{\r
-    opus_int         i;\r
-    opus_int32       WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];\r
-    opus_int32       invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ];\r
-    opus_int16       NLSF_Q15[ MAX_LPC_ORDER ];\r
-    const opus_int16 *x_ptr;\r
-    opus_int16       *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];\r
-    opus_int32       tmp, min_gain_Q16;\r
-    opus_int         LTP_corrs_rshift[ MAX_NB_SUBFR ];\r
-\r
-    /* weighting for weighted least squares */\r
-    min_gain_Q16 = SKP_int32_MAX >> 6;\r
-    for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\r
-        min_gain_Q16 = SKP_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] );\r
-    }\r
-    for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\r
-        /* Divide to Q16 */\r
-        SKP_assert( psEncCtrl->Gains_Q16[ i ] > 0 );\r
-        /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */\r
-        invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 );\r
-\r
-        /* Ensure Wght_Q15 a minimum value 1 */\r
-        invGains_Q16[ i ] = SKP_max( invGains_Q16[ i ], 363 ); \r
-        \r
-        /* Square the inverted gains */\r
-        SKP_assert( invGains_Q16[ i ] == SKP_SAT16( invGains_Q16[ i ] ) );\r
-        tmp = SKP_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] );\r
-        Wght_Q15[ i ] = SKP_RSHIFT( tmp, 1 );\r
-\r
-        /* Invert the inverted and normalized gains */\r
-        local_gains[ i ] = SKP_DIV32( ( 1 << 16 ), invGains_Q16[ i ] );\r
-    }\r
-\r
-    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\r
-        /**********/\r
-        /* VOICED */\r
-        /**********/\r
-        SKP_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );\r
-\r
-        /* LTP analysis */\r
-        silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7, \r
-            res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length, \r
-            psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length, LTP_corrs_rshift );\r
-\r
-        /* Quantize LTP gain parameters */\r
-        silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, \r
-            WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr);\r
-\r
-        /* Control LTP scaling */\r
-        silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl );\r
-\r
-        /* Create LTP residual */\r
-        silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14, \r
-            psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );\r
-\r
-    } else {\r
-        /************/\r
-        /* UNVOICED */\r
-        /************/\r
-        /* Create signal with prepended subframes, scaled by inverse gains */\r
-        x_ptr     = x - psEnc->sCmn.predictLPCOrder;\r
-        x_pre_ptr = LPC_in_pre;\r
-        for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\r
-            silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ], \r
-                psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );\r
-            x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;\r
-            x_ptr     += psEnc->sCmn.subfr_length;\r
-        }\r
-\r
-        SKP_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) );\r
-        psEncCtrl->LTPredCodGain_Q7 = 0;\r
-    }\r
-\r
-    /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */\r
-    TIC(FIND_LPC)\r
-    silk_find_LPC_FIX( NLSF_Q15, &psEnc->sCmn.indices.NLSFInterpCoef_Q2, psEnc->sCmn.prev_NLSFq_Q15, \r
-        psEnc->sCmn.useInterpolatedNLSFs, psEnc->sCmn.first_frame_after_reset, psEnc->sCmn.predictLPCOrder, \r
-        LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder, psEnc->sCmn.nb_subfr );\r
-    TOC(FIND_LPC)\r
-\r
-    /* Quantize LSFs */\r
-    TIC(PROCESS_LSFS)\r
-    silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );\r
-    TOC(PROCESS_LSFS)\r
-\r
-    /* Calculate residual energy using quantized LPC coefficients */\r
-    silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains,\r
-        psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );\r
-\r
-    /* Copy to prediction struct for use in next frame for fluctuation reduction */\r
-    SKP_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+
+void silk_find_pred_coefs_FIX(
+    silk_encoder_state_FIX          *psEnc,         /* I/O  encoder state                               */
+    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  encoder control                             */
+    const opus_int16                 res_pitch[],    /* I    Residual from pitch analysis                */
+    const opus_int16                 x[]             /* I    Speech signal                               */
+)
+{
+    opus_int         i;
+    opus_int32       WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
+    opus_int32       invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ];
+    opus_int16       NLSF_Q15[ MAX_LPC_ORDER ];
+    const opus_int16 *x_ptr;
+    opus_int16       *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
+    opus_int32       tmp, min_gain_Q16;
+    opus_int         LTP_corrs_rshift[ MAX_NB_SUBFR ];
+
+    /* weighting for weighted least squares */
+    min_gain_Q16 = SKP_int32_MAX >> 6;
+    for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
+        min_gain_Q16 = SKP_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] );
+    }
+    for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
+        /* Divide to Q16 */
+        SKP_assert( psEncCtrl->Gains_Q16[ i ] > 0 );
+        /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */
+        invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 );
+
+        /* Ensure Wght_Q15 a minimum value 1 */
+        invGains_Q16[ i ] = SKP_max( invGains_Q16[ i ], 363 );
+
+        /* Square the inverted gains */
+        SKP_assert( invGains_Q16[ i ] == SKP_SAT16( invGains_Q16[ i ] ) );
+        tmp = SKP_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] );
+        Wght_Q15[ i ] = SKP_RSHIFT( tmp, 1 );
+
+        /* Invert the inverted and normalized gains */
+        local_gains[ i ] = SKP_DIV32( ( 1 << 16 ), invGains_Q16[ i ] );
+    }
+
+    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+        /**********/
+        /* VOICED */
+        /**********/
+        SKP_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
+
+        /* LTP analysis */
+        silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7,
+            res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length,
+            psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length, LTP_corrs_rshift );
+
+        /* Quantize LTP gain parameters */
+        silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
+            WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr);
+
+        /* Control LTP scaling */
+        silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl );
+
+        /* Create LTP residual */
+        silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14,
+            psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
+
+    } else {
+        /************/
+        /* UNVOICED */
+        /************/
+        /* Create signal with prepended subframes, scaled by inverse gains */
+        x_ptr     = x - psEnc->sCmn.predictLPCOrder;
+        x_pre_ptr = LPC_in_pre;
+        for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
+            silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ],
+                psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
+            x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
+            x_ptr     += psEnc->sCmn.subfr_length;
+        }
+
+        SKP_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) );
+        psEncCtrl->LTPredCodGain_Q7 = 0;
+    }
+
+    /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
+    TIC(FIND_LPC)
+    silk_find_LPC_FIX( NLSF_Q15, &psEnc->sCmn.indices.NLSFInterpCoef_Q2, psEnc->sCmn.prev_NLSFq_Q15,
+        psEnc->sCmn.useInterpolatedNLSFs, psEnc->sCmn.first_frame_after_reset, psEnc->sCmn.predictLPCOrder,
+        LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder, psEnc->sCmn.nb_subfr );
+    TOC(FIND_LPC)
+
+    /* Quantize LSFs */
+    TIC(PROCESS_LSFS)
+    silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
+    TOC(PROCESS_LSFS)
+
+    /* Calculate residual energy using quantized LPC coefficients */
+    silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains,
+        psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
+
+    /* Copy to prediction struct for use in next frame for fluctuation reduction */
+    SKP_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
+}
index fb31ae6..88a9a4a 100644 (file)
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#ifndef SILK_MAIN_FIX_H\r
-#define SILK_MAIN_FIX_H\r
-\r
-#include "silk_SigProc_FIX.h"\r
-#include "silk_structs_FIX.h"\r
-#include "silk_control.h"\r
-#include "silk_main.h"\r
-#include "silk_PLC.h"\r
-#include "silk_debug.h"\r
-#include "entenc.h"\r
-\r
-#ifndef FORCE_CPP_BUILD\r
-#ifdef __cplusplus\r
-extern "C"\r
-{\r
-#endif\r
-#endif\r
-\r
-#define silk_encoder_state_Fxx      silk_encoder_state_FIX\r
-#define silk_encode_frame_Fxx       silk_encode_frame_FIX\r
-\r
-/*********************/\r
-/* Encoder Functions */\r
-/*********************/\r
-\r
-/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */\r
-void silk_HP_variable_cutoff(\r
-    silk_encoder_state_Fxx          state_Fxx[],    /* I/O  Encoder states                              */\r
-    const opus_int                   nChannels       /* I    Number of channels                          */\r
-);\r
-\r
-/* Encoder main function */\r
-opus_int silk_encode_frame_FIX( \r
-    silk_encoder_state_FIX          *psEnc,             /* I/O  Pointer to Silk FIX encoder state       */\r
-    opus_int32                       *pnBytesOut,        /*   O  Pointer to number of payload bytes;     */\r
-    ec_enc                          *psRangeEnc         /* I/O  compressor data structure               */\r
-);\r
-\r
-/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate           */\r
-void silk_LBRR_encode_FIX(\r
-    silk_encoder_state_FIX          *psEnc,             /* I/O  Pointer to Silk FIX encoder state           */\r
-    silk_encoder_control_FIX        *psEncCtrl,         /* I/O  Pointer to Silk FIX encoder control struct  */\r
-    const opus_int16                 xfw[]               /* I    Input signal                                */\r
-);\r
-\r
-/* Initializes the Silk encoder state */\r
-opus_int silk_init_encoder(\r
-    silk_encoder_state_FIX          *psEnc              /* I/O  Pointer to Silk FIX encoder state           */\r
-);\r
-\r
-/* Control the Silk encoder */\r
-opus_int silk_control_encoder( \r
-    silk_encoder_state_FIX          *psEnc,             /* I/O  Pointer to Silk encoder state           */\r
-    silk_EncControlStruct           *encControl,        /* I:   Control structure                       */\r
-    const opus_int32                 TargetRate_bps,     /* I    Target max bitrate (bps)                */\r
-    const opus_int                   allow_bw_switch,    /* I    Flag to allow switching audio bandwidth */\r
-    const opus_int                   channelNb           /* I    Channel number                          */\r
-);\r
-\r
-/****************/\r
-/* Prefiltering */\r
-/****************/\r
-void silk_prefilter_FIX(\r
-    silk_encoder_state_FIX              *psEnc,         /* I/O  Encoder state                               */\r
-    const silk_encoder_control_FIX      *psEncCtrl,     /* I    Encoder control                             */\r
-    opus_int16                           xw[],           /* O    Weighted signal                             */\r
-    const opus_int16                     x[]             /* I    Speech signal                               */\r
-);\r
-\r
-/**************************/\r
-/* Noise shaping analysis */\r
-/**************************/\r
-/* Compute noise shaping coefficients and initial gain values */\r
-void silk_noise_shape_analysis_FIX(\r
-    silk_encoder_state_FIX          *psEnc,         /* I/O  Encoder state FIX                           */\r
-    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  Encoder control FIX                         */\r
-    const opus_int16                 *pitch_res,     /* I    LPC residual from pitch analysis            */\r
-    const opus_int16                 *x              /* I    Input signal [ frame_length + la_shape ]    */\r
-);\r
-\r
-/* Autocorrelations for a warped frequency axis */\r
-void silk_warped_autocorrelation_FIX(\r
-          opus_int32                 *corr,              /* O    Result [order + 1]                      */\r
-          opus_int                   *scale,             /* O    Scaling of the correlation vector       */\r
-    const opus_int16                 *input,             /* I    Input data to correlate                 */\r
-    const opus_int                   warping_Q16,        /* I    Warping coefficient                     */\r
-    const opus_int                   length,             /* I    Length of input                         */\r
-    const opus_int                   order               /* I    Correlation order (even)                */\r
-);\r
-\r
-/* Calculation of LTP state scaling */\r
-void silk_LTP_scale_ctrl_FIX(\r
-    silk_encoder_state_FIX          *psEnc,         /* I/O  encoder state                               */\r
-    silk_encoder_control_FIX        *psEncCtrl      /* I/O  encoder control                             */\r
-);\r
-\r
-/**********************************************/\r
-/* Prediction Analysis                        */\r
-/**********************************************/\r
-/* Find pitch lags */\r
-void silk_find_pitch_lags_FIX(\r
-    silk_encoder_state_FIX          *psEnc,         /* I/O  encoder state                               */\r
-    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  encoder control                             */\r
-    opus_int16                       res[],          /* O    residual                                    */\r
-    const opus_int16                 x[]             /* I    Speech signal                               */\r
-);\r
-\r
-/* Find LPC and LTP coefficients */\r
-void silk_find_pred_coefs_FIX(\r
-    silk_encoder_state_FIX          *psEnc,         /* I/O  encoder state                               */\r
-    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  encoder control                             */\r
-    const opus_int16                 res_pitch[],    /* I    Residual from pitch analysis                */\r
-    const opus_int16                 x[]             /* I    Speech signal                               */\r
-);\r
-\r
-/* LPC analysis */\r
-void silk_find_LPC_FIX(\r
-    opus_int16                       NLSF_Q15[],             /* O    NLSFs                                                           */\r
-    opus_int8                        *interpIndex,           /* O    NLSF interpolation index, only used for NLSF interpolation      */\r
-    const opus_int16                 prev_NLSFq_Q15[],       /* I    previous NLSFs, only used for NLSF interpolation                */\r
-    const opus_int                   useInterpNLSFs,         /* I    Flag                                                            */\r
-    const opus_int                   firstFrameAfterReset,   /* I    Flag                                                            */\r
-    const opus_int                   LPC_order,              /* I    LPC order                                                       */\r
-    const opus_int16                 x[],                    /* I    Input signal                                                    */\r
-    const opus_int                   subfr_length,           /* I    Input signal subframe length including preceeding samples       */\r
-    const opus_int                   nb_subfr                /* I:   Number of subframes                                             */\r
-);\r
-\r
-/* LTP analysis */\r
-void silk_find_LTP_FIX(\r
-    opus_int16           b_Q14[ MAX_NB_SUBFR * LTP_ORDER ],              /* O    LTP coefs                                                   */\r
-    opus_int32           WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ],   /* O    Weight for LTP quantization                                 */\r
-    opus_int             *LTPredCodGain_Q7,                              /* O    LTP coding gain                                             */\r
-    const opus_int16     r_lpc[],                                        /* I    residual signal after LPC signal + state for first 10 ms    */\r
-    const opus_int       lag[ MAX_NB_SUBFR ],                            /* I    LTP lags                                                    */\r
-    const opus_int32     Wght_Q15[ MAX_NB_SUBFR ],                       /* I    weights                                                     */\r
-    const opus_int       subfr_length,                                   /* I    subframe length                                             */\r
-    const opus_int       nb_subfr,                                       /* I    number of subframes                                         */\r
-    const opus_int       mem_offset,                                     /* I    number of samples in LTP memory                             */\r
-    opus_int             corr_rshifts[ MAX_NB_SUBFR ]                    /* O    right shifts applied to correlations                        */\r
-);\r
-\r
-void silk_LTP_analysis_filter_FIX(\r
-    opus_int16           *LTP_res,                               /* O:   LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length )  */\r
-    const opus_int16     *x,                                     /* I:   Pointer to input signal with at least max( pitchL ) preceeding samples      */\r
-    const opus_int16     LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I:   LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe                   */\r
-    const opus_int       pitchL[ MAX_NB_SUBFR ],                 /* I:   Pitch lag, one for each subframe                                            */\r
-    const opus_int32     invGains_Q16[ MAX_NB_SUBFR ],           /* I:   Inverse quantization gains, one for each subframe                           */\r
-    const opus_int       subfr_length,                           /* I:   Length of each subframe                                                     */\r
-    const opus_int       nb_subfr,                               /* I:   Number of subframes                                                         */\r
-    const opus_int       pre_length                              /* I:   Length of the preceeding samples starting at &x[0] for each subframe        */\r
-);\r
-\r
-/* Calculates residual energies of input subframes where all subframes have LPC_order   */\r
-/* of preceeding samples                                                                */\r
-void silk_residual_energy_FIX(\r
-          opus_int32 nrgs[ MAX_NB_SUBFR ],           /* O    Residual energy per subframe    */\r
-          opus_int   nrgsQ[ MAX_NB_SUBFR ],          /* O    Q value per subframe            */\r
-    const opus_int16 x[],                            /* I    Input signal                    */\r
-          opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ],    /* I    AR coefs for each frame half    */\r
-    const opus_int32 gains[ MAX_NB_SUBFR ],          /* I    Quantization gains              */\r
-    const opus_int   subfr_length,                   /* I    Subframe length                 */\r
-    const opus_int   nb_subfr,                       /* I    Number of subframes             */\r
-    const opus_int   LPC_order                       /* I    LPC order                       */\r
-);\r
-\r
-/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */\r
-opus_int32 silk_residual_energy16_covar_FIX(\r
-    const opus_int16                 *c,                 /* I    Prediction vector                           */\r
-    const opus_int32                 *wXX,               /* I    Correlation matrix                          */\r
-    const opus_int32                 *wXx,               /* I    Correlation vector                          */\r
-    opus_int32                       wxx,                /* I    Signal energy                               */\r
-    opus_int                         D,                  /* I    Dimension                                   */\r
-    opus_int                         cQ                  /* I    Q value for c vector 0 - 15                 */\r
-);\r
-\r
-/* Processing of gains */\r
-void silk_process_gains_FIX(\r
-    silk_encoder_state_FIX          *psEnc,         /* I/O  Encoder state                               */\r
-    silk_encoder_control_FIX        *psEncCtrl      /* I/O  Encoder control                             */\r
-);\r
-\r
-/******************/\r
-/* Linear Algebra */\r
-/******************/\r
-/* Calculates correlation matrix X'*X */\r
-void silk_corrMatrix_FIX(\r
-    const opus_int16                 *x,         /* I    x vector [L + order - 1] used to form data matrix X */\r
-    const opus_int                   L,          /* I    Length of vectors                                   */\r
-    const opus_int                   order,      /* I    Max lag for correlation                             */\r
-    const opus_int                   head_room,  /* I    Desired headroom                                    */\r
-    opus_int32                       *XX,        /* O    Pointer to X'*X correlation matrix [ order x order ]*/\r
-    opus_int                         *rshifts    /* I/O  Right shifts of correlations                        */\r
-);\r
-\r
-/* Calculates correlation vector X'*t */\r
-void silk_corrVector_FIX(\r
-    const opus_int16                 *x,         /* I    x vector [L + order - 1] used to form data matrix X */\r
-    const opus_int16                 *t,         /* I    Target vector [L]                                   */\r
-    const opus_int                   L,          /* I    Length of vectors                                   */\r
-    const opus_int                   order,      /* I    Max lag for correlation                             */\r
-    opus_int32                       *Xt,        /* O    Pointer to X'*t correlation vector [order]          */\r
-    const opus_int                   rshifts     /* I    Right shifts of correlations                        */\r
-);\r
-\r
-/* Add noise to matrix diagonal */\r
-void silk_regularize_correlations_FIX(\r
-    opus_int32                       *XX,                /* I/O  Correlation matrices                        */\r
-    opus_int32                       *xx,                /* I/O  Correlation values                          */\r
-    opus_int32                       noise,              /* I    Noise to add                                */\r
-    opus_int                         D                   /* I    Dimension of XX                             */\r
-);\r
-\r
-/* Solves Ax = b, assuming A is symmetric */\r
-void silk_solve_LDL_FIX(\r
-    opus_int32                       *A,                 /* I    Pointer to symetric square matrix A         */\r
-    opus_int                         M,                  /* I    Size of matrix                              */\r
-    const opus_int32                 *b,                 /* I    Pointer to b vector                         */\r
-    opus_int32                       *x_Q16              /* O    Pointer to x solution vector                */\r
-);\r
-\r
-#ifndef FORCE_CPP_BUILD\r
-#ifdef __cplusplus\r
-}\r
-#endif /* __cplusplus */\r
-#endif /* FORCE_CPP_BUILD */\r
-#endif /* SILK_MAIN_FIX_H */\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef SILK_MAIN_FIX_H
+#define SILK_MAIN_FIX_H
+
+#include "silk_SigProc_FIX.h"
+#include "silk_structs_FIX.h"
+#include "silk_control.h"
+#include "silk_main.h"
+#include "silk_PLC.h"
+#include "silk_debug.h"
+#include "entenc.h"
+
+#ifndef FORCE_CPP_BUILD
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#endif
+
+#define silk_encoder_state_Fxx      silk_encoder_state_FIX
+#define silk_encode_frame_Fxx       silk_encode_frame_FIX
+
+/*********************/
+/* Encoder Functions */
+/*********************/
+
+/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
+void silk_HP_variable_cutoff(
+    silk_encoder_state_Fxx          state_Fxx[],    /* I/O  Encoder states                              */
+    const opus_int                   nChannels       /* I    Number of channels                          */
+);
+
+/* Encoder main function */
+opus_int silk_encode_frame_FIX(
+    silk_encoder_state_FIX          *psEnc,             /* I/O  Pointer to Silk FIX encoder state       */
+    opus_int32                       *pnBytesOut,        /*   O  Pointer to number of payload bytes;     */
+    ec_enc                          *psRangeEnc         /* I/O  compressor data structure               */
+);
+
+/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate           */
+void silk_LBRR_encode_FIX(
+    silk_encoder_state_FIX          *psEnc,             /* I/O  Pointer to Silk FIX encoder state           */
+    silk_encoder_control_FIX        *psEncCtrl,         /* I/O  Pointer to Silk FIX encoder control struct  */
+    const opus_int16                 xfw[]               /* I    Input signal                                */
+);
+
+/* Initializes the Silk encoder state */
+opus_int silk_init_encoder(
+    silk_encoder_state_FIX          *psEnc              /* I/O  Pointer to Silk FIX encoder state           */
+);
+
+/* Control the Silk encoder */
+opus_int silk_control_encoder(
+    silk_encoder_state_FIX          *psEnc,             /* I/O  Pointer to Silk encoder state           */
+    silk_EncControlStruct           *encControl,        /* I:   Control structure                       */
+    const opus_int32                 TargetRate_bps,     /* I    Target max bitrate (bps)                */
+    const opus_int                   allow_bw_switch,    /* I    Flag to allow switching audio bandwidth */
+    const opus_int                   channelNb           /* I    Channel number                          */
+);
+
+/****************/
+/* Prefiltering */
+/****************/
+void silk_prefilter_FIX(
+    silk_encoder_state_FIX              *psEnc,         /* I/O  Encoder state                               */
+    const silk_encoder_control_FIX      *psEncCtrl,     /* I    Encoder control                             */
+    opus_int16                           xw[],           /* O    Weighted signal                             */
+    const opus_int16                     x[]             /* I    Speech signal                               */
+);
+
+/**************************/
+/* Noise shaping analysis */
+/**************************/
+/* Compute noise shaping coefficients and initial gain values */
+void silk_noise_shape_analysis_FIX(
+    silk_encoder_state_FIX          *psEnc,         /* I/O  Encoder state FIX                           */
+    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  Encoder control FIX                         */
+    const opus_int16                 *pitch_res,     /* I    LPC residual from pitch analysis            */
+    const opus_int16                 *x              /* I    Input signal [ frame_length + la_shape ]    */
+);
+
+/* Autocorrelations for a warped frequency axis */
+void silk_warped_autocorrelation_FIX(
+          opus_int32                 *corr,              /* O    Result [order + 1]                      */
+          opus_int                   *scale,             /* O    Scaling of the correlation vector       */
+    const opus_int16                 *input,             /* I    Input data to correlate                 */
+    const opus_int                   warping_Q16,        /* I    Warping coefficient                     */
+    const opus_int                   length,             /* I    Length of input                         */
+    const opus_int                   order               /* I    Correlation order (even)                */
+);
+
+/* Calculation of LTP state scaling */
+void silk_LTP_scale_ctrl_FIX(
+    silk_encoder_state_FIX          *psEnc,         /* I/O  encoder state                               */
+    silk_encoder_control_FIX        *psEncCtrl      /* I/O  encoder control                             */
+);
+
+/**********************************************/
+/* Prediction Analysis                        */
+/**********************************************/
+/* Find pitch lags */
+void silk_find_pitch_lags_FIX(
+    silk_encoder_state_FIX          *psEnc,         /* I/O  encoder state                               */
+    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  encoder control                             */
+    opus_int16                       res[],          /* O    residual                                    */
+    const opus_int16                 x[]             /* I    Speech signal                               */
+);
+
+/* Find LPC and LTP coefficients */
+void silk_find_pred_coefs_FIX(
+    silk_encoder_state_FIX          *psEnc,         /* I/O  encoder state                               */
+    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  encoder control                             */
+    const opus_int16                 res_pitch[],    /* I    Residual from pitch analysis                */
+    const opus_int16                 x[]             /* I    Speech signal                               */
+);
+
+/* LPC analysis */
+void silk_find_LPC_FIX(
+    opus_int16                       NLSF_Q15[],             /* O    NLSFs                                                           */
+    opus_int8                        *interpIndex,           /* O    NLSF interpolation index, only used for NLSF interpolation      */
+    const opus_int16                 prev_NLSFq_Q15[],       /* I    previous NLSFs, only used for NLSF interpolation                */
+    const opus_int                   useInterpNLSFs,         /* I    Flag                                                            */
+    const opus_int                   firstFrameAfterReset,   /* I    Flag                                                            */
+    const opus_int                   LPC_order,              /* I    LPC order                                                       */
+    const opus_int16                 x[],                    /* I    Input signal                                                    */
+    const opus_int                   subfr_length,           /* I    Input signal subframe length including preceeding samples       */
+    const opus_int                   nb_subfr                /* I:   Number of subframes                                             */
+);
+
+/* LTP analysis */
+void silk_find_LTP_FIX(
+    opus_int16           b_Q14[ MAX_NB_SUBFR * LTP_ORDER ],              /* O    LTP coefs                                                   */
+    opus_int32           WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ],   /* O    Weight for LTP quantization                                 */
+    opus_int             *LTPredCodGain_Q7,                              /* O    LTP coding gain                                             */
+    const opus_int16     r_lpc[],                                        /* I    residual signal after LPC signal + state for first 10 ms    */
+    const opus_int       lag[ MAX_NB_SUBFR ],                            /* I    LTP lags                                                    */
+    const opus_int32     Wght_Q15[ MAX_NB_SUBFR ],                       /* I    weights                                                     */
+    const opus_int       subfr_length,                                   /* I    subframe length                                             */
+    const opus_int       nb_subfr,                                       /* I    number of subframes                                         */
+    const opus_int       mem_offset,                                     /* I    number of samples in LTP memory                             */
+    opus_int             corr_rshifts[ MAX_NB_SUBFR ]                    /* O    right shifts applied to correlations                        */
+);
+
+void silk_LTP_analysis_filter_FIX(
+    opus_int16           *LTP_res,                               /* O:   LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length )  */
+    const opus_int16     *x,                                     /* I:   Pointer to input signal with at least max( pitchL ) preceeding samples      */
+    const opus_int16     LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I:   LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe                   */
+    const opus_int       pitchL[ MAX_NB_SUBFR ],                 /* I:   Pitch lag, one for each subframe                                            */
+    const opus_int32     invGains_Q16[ MAX_NB_SUBFR ],           /* I:   Inverse quantization gains, one for each subframe                           */
+    const opus_int       subfr_length,                           /* I:   Length of each subframe                                                     */
+    const opus_int       nb_subfr,                               /* I:   Number of subframes                                                         */
+    const opus_int       pre_length                              /* I:   Length of the preceeding samples starting at &x[0] for each subframe        */
+);
+
+/* Calculates residual energies of input subframes where all subframes have LPC_order   */
+/* of preceeding samples                                                                */
+void silk_residual_energy_FIX(
+          opus_int32 nrgs[ MAX_NB_SUBFR ],           /* O    Residual energy per subframe    */
+          opus_int   nrgsQ[ MAX_NB_SUBFR ],          /* O    Q value per subframe            */
+    const opus_int16 x[],                            /* I    Input signal                    */
+          opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ],    /* I    AR coefs for each frame half    */
+    const opus_int32 gains[ MAX_NB_SUBFR ],          /* I    Quantization gains              */
+    const opus_int   subfr_length,                   /* I    Subframe length                 */
+    const opus_int   nb_subfr,                       /* I    Number of subframes             */
+    const opus_int   LPC_order                       /* I    LPC order                       */
+);
+
+/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
+opus_int32 silk_residual_energy16_covar_FIX(
+    const opus_int16                 *c,                 /* I    Prediction vector                           */
+    const opus_int32                 *wXX,               /* I    Correlation matrix                          */
+    const opus_int32                 *wXx,               /* I    Correlation vector                          */
+    opus_int32                       wxx,                /* I    Signal energy                               */
+    opus_int                         D,                  /* I    Dimension                                   */
+    opus_int                         cQ                  /* I    Q value for c vector 0 - 15                 */
+);
+
+/* Processing of gains */
+void silk_process_gains_FIX(
+    silk_encoder_state_FIX          *psEnc,         /* I/O  Encoder state                               */
+    silk_encoder_control_FIX        *psEncCtrl      /* I/O  Encoder control                             */
+);
+
+/******************/
+/* Linear Algebra */
+/******************/
+/* Calculates correlation matrix X'*X */
+void silk_corrMatrix_FIX(
+    const opus_int16                 *x,         /* I    x vector [L + order - 1] used to form data matrix X */
+    const opus_int                   L,          /* I    Length of vectors                                   */
+    const opus_int                   order,      /* I    Max lag for correlation                             */
+    const opus_int                   head_room,  /* I    Desired headroom                                    */
+    opus_int32                       *XX,        /* O    Pointer to X'*X correlation matrix [ order x order ]*/
+    opus_int                         *rshifts    /* I/O  Right shifts of correlations                        */
+);
+
+/* Calculates correlation vector X'*t */
+void silk_corrVector_FIX(
+    const opus_int16                 *x,         /* I    x vector [L + order - 1] used to form data matrix X */
+    const opus_int16                 *t,         /* I    Target vector [L]                                   */
+    const opus_int                   L,          /* I    Length of vectors                                   */
+    const opus_int                   order,      /* I    Max lag for correlation                             */
+    opus_int32                       *Xt,        /* O    Pointer to X'*t correlation vector [order]          */
+    const opus_int                   rshifts     /* I    Right shifts of correlations                        */
+);
+
+/* Add noise to matrix diagonal */
+void silk_regularize_correlations_FIX(
+    opus_int32                       *XX,                /* I/O  Correlation matrices                        */
+    opus_int32                       *xx,                /* I/O  Correlation values                          */
+    opus_int32                       noise,              /* I    Noise to add                                */
+    opus_int                         D                   /* I    Dimension of XX                             */
+);
+
+/* Solves Ax = b, assuming A is symmetric */
+void silk_solve_LDL_FIX(
+    opus_int32                       *A,                 /* I    Pointer to symetric square matrix A         */
+    opus_int                         M,                  /* I    Size of matrix                              */
+    const opus_int32                 *b,                 /* I    Pointer to b vector                         */
+    opus_int32                       *x_Q16              /* O    Pointer to x solution vector                */
+);
+
+#ifndef FORCE_CPP_BUILD
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* FORCE_CPP_BUILD */
+#endif /* SILK_MAIN_FIX_H */
index fb2bcc9..1ce1ea6 100644 (file)
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-#include "silk_tuning_parameters.h"\r
-\r
-/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a     */\r
-/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.)   */\r
-SKP_INLINE opus_int32 warped_gain( // gain in Q16\r
-    const opus_int32     *coefs_Q24, \r
-    opus_int             lambda_Q16, \r
-    opus_int             order \r
-) {\r
-    opus_int   i;\r
-    opus_int32 gain_Q24;\r
-\r
-    lambda_Q16 = -lambda_Q16;\r
-    gain_Q24 = coefs_Q24[ order - 1 ];\r
-    for( i = order - 2; i >= 0; i-- ) {\r
-        gain_Q24 = SKP_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 );\r
-    }\r
-    gain_Q24  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 );\r
-    return silk_INVERSE32_varQ( gain_Q24, 40 );\r
-}\r
-\r
-/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum     */\r
-/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */\r
-SKP_INLINE void limit_warped_coefs( \r
-    opus_int32           *coefs_syn_Q24,\r
-    opus_int32           *coefs_ana_Q24,\r
-    opus_int             lambda_Q16,\r
-    opus_int32           limit_Q24,\r
-    opus_int             order\r
-) {\r
-    opus_int   i, iter, ind = 0;\r
-    opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16;\r
-    opus_int32 nom_Q16, den_Q24;\r
-\r
-    /* Convert to monic coefficients */\r
-    lambda_Q16 = -lambda_Q16;\r
-    for( i = order - 1; i > 0; i-- ) {\r
-        coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );\r
-        coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );\r
-    }\r
-    lambda_Q16 = -lambda_Q16;\r
-    nom_Q16  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -lambda_Q16,        lambda_Q16 );\r
-    den_Q24  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );\r
-    gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );\r
-    den_Q24  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );\r
-    gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );\r
-    for( i = 0; i < order; i++ ) {\r
-        coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );\r
-        coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );\r
-    }\r
-\r
-    for( iter = 0; iter < 10; iter++ ) {\r
-        /* Find maximum absolute value */\r
-        maxabs_Q24 = -1;\r
-        for( i = 0; i < order; i++ ) {\r
-            tmp = SKP_max( SKP_abs_int32( coefs_syn_Q24[ i ] ), SKP_abs_int32( coefs_ana_Q24[ i ] ) );\r
-            if( tmp > maxabs_Q24 ) {\r
-                maxabs_Q24 = tmp;\r
-                ind = i;\r
-            }\r
-        }\r
-        if( maxabs_Q24 <= limit_Q24 ) {\r
-            /* Coefficients are within range - done */\r
-            return;\r
-        }\r
-\r
-        /* Convert back to true warped coefficients */\r
-        for( i = 1; i < order; i++ ) {\r
-            coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );\r
-            coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );\r
-        }\r
-        gain_syn_Q16 = silk_INVERSE32_varQ( gain_syn_Q16, 32 );\r
-        gain_ana_Q16 = silk_INVERSE32_varQ( gain_ana_Q16, 32 );\r
-        for( i = 0; i < order; i++ ) {\r
-            coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );\r
-            coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );\r
-        }\r
-\r
-        /* Apply bandwidth expansion */\r
-        chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(\r
-            SKP_SMULWB( maxabs_Q24 - limit_Q24, SKP_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ), \r
-            SKP_MUL( maxabs_Q24, ind + 1 ), 22 );\r
-        silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 );\r
-        silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 );\r
-\r
-        /* Convert to monic warped coefficients */\r
-        lambda_Q16 = -lambda_Q16;\r
-        for( i = order - 1; i > 0; i-- ) {\r
-            coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );\r
-            coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );\r
-        }\r
-        lambda_Q16 = -lambda_Q16;\r
-        nom_Q16  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -lambda_Q16,        lambda_Q16 );\r
-        den_Q24  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );\r
-        gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );\r
-        den_Q24  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );\r
-        gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );\r
-        for( i = 0; i < order; i++ ) {\r
-            coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );\r
-            coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );\r
-        }\r
-    }\r
-       SKP_assert( 0 );\r
-}\r
-\r
-/**************************************************************/\r
-/* Compute noise shaping coefficients and initial gain values */\r
-/**************************************************************/\r
-void silk_noise_shape_analysis_FIX(\r
-    silk_encoder_state_FIX          *psEnc,         /* I/O  Encoder state FIX                           */\r
-    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  Encoder control FIX                         */\r
-    const opus_int16                 *pitch_res,     /* I    LPC residual from pitch analysis            */\r
-    const opus_int16                 *x              /* I    Input signal [ frame_length + la_shape ]    */\r
-)\r
-{\r
-    silk_shape_state_FIX *psShapeSt = &psEnc->sShape;\r
-    opus_int     k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;\r
-    opus_int32   SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;\r
-    opus_int32   nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;\r
-    opus_int32   delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;\r
-    opus_int32   auto_corr[     MAX_SHAPE_LPC_ORDER + 1 ];\r
-    opus_int32   refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];\r
-    opus_int32   AR1_Q24[       MAX_SHAPE_LPC_ORDER ];\r
-    opus_int32   AR2_Q24[       MAX_SHAPE_LPC_ORDER ];\r
-    opus_int16   x_windowed[    SHAPE_LPC_WIN_MAX ];\r
-    opus_int32   sqrt_nrg[ MAX_NB_SUBFR ], Qnrg_vec[ MAX_NB_SUBFR ];\r
-    const opus_int16 *x_ptr, *pitch_res_ptr;\r
-\r
-    /* Point to start of first LPC analysis block */\r
-    x_ptr = x - psEnc->sCmn.la_shape;\r
-\r
-    /****************/\r
-    /* GAIN CONTROL */\r
-    /****************/\r
-    SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;\r
-\r
-    /* Input quality is the average of the quality in the lowest two VAD bands */\r
-    psEncCtrl->input_quality_Q14 = ( opus_int )SKP_RSHIFT( ( opus_int32 )psEnc->sCmn.input_quality_bands_Q15[ 0 ] \r
-        + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );\r
-\r
-    /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */\r
-    psEncCtrl->coding_quality_Q14 = SKP_RSHIFT( silk_sigm_Q15( SKP_RSHIFT_ROUND( SNR_adj_dB_Q7 - \r
-        SILK_FIX_CONST( 18.0, 7 ), 4 ) ), 1 );\r
-\r
-    /* Reduce coding SNR during low speech activity */\r
-    if( psEnc->sCmn.useCBR == 0 ) {\r
-        b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;\r
-        b_Q8 = SKP_SMULWB( SKP_LSHIFT( b_Q8, 8 ), b_Q8 );\r
-        SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7,\r
-            SKP_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ),                                       // Q11\r
-            SKP_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) );     // Q12\r
-    }\r
-\r
-    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\r
-        /* Reduce gains for periodic signals */\r
-        SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );\r
-    } else { \r
-        /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */\r
-        SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, \r
-            SKP_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),\r
-            SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );\r
-    }\r
-\r
-    /*************************/\r
-    /* SPARSENESS PROCESSING */\r
-    /*************************/\r
-    /* Set quantizer offset */\r
-    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\r
-        /* Initally set to 0; may be overruled in process_gains(..) */\r
-        psEnc->sCmn.indices.quantOffsetType = 0;\r
-        psEncCtrl->sparseness_Q8 = 0;\r
-    } else {\r
-        /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */\r
-        nSamples = SKP_LSHIFT( psEnc->sCmn.fs_kHz, 1 );\r
-        energy_variation_Q7 = 0;\r
-        log_energy_prev_Q7  = 0;\r
-        pitch_res_ptr = pitch_res;\r
-        for( k = 0; k < SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {\r
-            silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );\r
-            nrg += SKP_RSHIFT( nSamples, scale );           // Q(-scale)\r
-            \r
-            log_energy_Q7 = silk_lin2log( nrg );\r
-            if( k > 0 ) {\r
-                energy_variation_Q7 += SKP_abs( log_energy_Q7 - log_energy_prev_Q7 );\r
-            }\r
-            log_energy_prev_Q7 = log_energy_Q7;\r
-            pitch_res_ptr += nSamples;\r
-        }\r
-\r
-        psEncCtrl->sparseness_Q8 = SKP_RSHIFT( silk_sigm_Q15( SKP_SMULWB( energy_variation_Q7 - \r
-            SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );\r
-\r
-        /* Set quantization offset depending on sparseness measure */\r
-        if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {\r
-            psEnc->sCmn.indices.quantOffsetType = 0;\r
-        } else {\r
-            psEnc->sCmn.indices.quantOffsetType = 1;\r
-        }\r
-        \r
-        /* Increase coding SNR for sparse signals */\r
-        SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) );\r
-    }\r
-\r
-    /*******************************/\r
-    /* Control bandwidth expansion */\r
-    /*******************************/\r
-    /* More BWE for signals with high prediction gain */\r
-    strength_Q16 = SKP_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );\r
-    BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), \r
-        SKP_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );\r
-    delta_Q16  = SKP_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SKP_SMULBB( 3, psEncCtrl->coding_quality_Q14 ), \r
-        SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );\r
-    BWExp1_Q16 = SKP_SUB32( BWExp1_Q16, delta_Q16 );\r
-    BWExp2_Q16 = SKP_ADD32( BWExp2_Q16, delta_Q16 );\r
-    /* BWExp1 will be applied after BWExp2, so make it relative */\r
-    BWExp1_Q16 = SKP_DIV32_16( SKP_LSHIFT( BWExp1_Q16, 14 ), SKP_RSHIFT( BWExp2_Q16, 2 ) );\r
-\r
-    if( psEnc->sCmn.warping_Q16 > 0 ) {\r
-        /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */\r
-        warping_Q16 = SKP_SMLAWB( psEnc->sCmn.warping_Q16, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );\r
-    } else {\r
-        warping_Q16 = 0;\r
-    }\r
-\r
-    /********************************************/\r
-    /* Compute noise shaping AR coefs and gains */\r
-    /********************************************/\r
-    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\r
-        /* Apply window: sine slope followed by flat part followed by cosine slope */\r
-        opus_int shift, slope_part, flat_part;\r
-        flat_part = psEnc->sCmn.fs_kHz * 3;\r
-        slope_part = SKP_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );\r
-\r
-        silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );\r
-        shift = slope_part;\r
-        SKP_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );\r
-        shift += flat_part;\r
-        silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );\r
-\r
-        /* Update pointer: next LPC analysis block */\r
-        x_ptr += psEnc->sCmn.subfr_length;\r
-\r
-        if( psEnc->sCmn.warping_Q16 > 0 ) {\r
-            /* Calculate warped auto correlation */\r
-            silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); \r
-        } else {\r
-            /* Calculate regular auto correlation */\r
-            silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 );\r
-        }\r
-\r
-        /* Add white noise, as a fraction of energy */\r
-        auto_corr[0] = SKP_ADD32( auto_corr[0], SKP_max_32( SKP_SMULWB( SKP_RSHIFT( auto_corr[ 0 ], 4 ), \r
-            SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); \r
-\r
-        /* Calculate the reflection coefficients using schur */\r
-        nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );\r
-        SKP_assert( nrg >= 0 );\r
-\r
-        /* Convert reflection coefficients to prediction coefficients */\r
-        silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );\r
-\r
-        Qnrg = -scale;          // range: -12...30\r
-        SKP_assert( Qnrg >= -12 );\r
-        SKP_assert( Qnrg <=  30 );\r
-\r
-        /* Make sure that Qnrg is an even number */\r
-        if( Qnrg & 1 ) {\r
-            Qnrg -= 1;\r
-            nrg >>= 1;\r
-        }\r
-\r
-        tmp32 = silk_SQRT_APPROX( nrg );\r
-        Qnrg >>= 1;             // range: -6...15\r
-\r
-        sqrt_nrg[ k ] = tmp32;\r
-        Qnrg_vec[ k ] = Qnrg;\r
-\r
-        psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( tmp32, 16 - Qnrg );\r
-\r
-        if( psEnc->sCmn.warping_Q16 > 0 ) {\r
-            /* Adjust gain for warping */\r
-            gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );\r
-            SKP_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );\r
-            psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );\r
-            if( psEncCtrl->Gains_Q16[ k ] < 0 ) {\r
-                psEncCtrl->Gains_Q16[ k ] = SKP_int32_MAX;\r
-            }\r
-        }\r
-\r
-        /* Bandwidth expansion for synthesis filter shaping */\r
-        silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );\r
-\r
-        /* Compute noise shaping filter coefficients */\r
-        SKP_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );\r
-\r
-        /* Bandwidth expansion for analysis filter shaping */\r
-        SKP_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );\r
-        silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );\r
-\r
-        /* Ratio of prediction gains, in energy domain */\r
-        silk_LPC_inverse_pred_gain_Q24( &pre_nrg_Q30, AR2_Q24, psEnc->sCmn.shapingLPCOrder );\r
-        silk_LPC_inverse_pred_gain_Q24( &nrg,         AR1_Q24, psEnc->sCmn.shapingLPCOrder );\r
-\r
-        //psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;\r
-        pre_nrg_Q30 = SKP_LSHIFT32( SKP_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );\r
-        psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );\r
-\r
-        /* Convert to monic warped prediction coefficients and limit absolute values */\r
-        limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );\r
-\r
-        /* Convert from Q24 to Q13 and store in int16 */\r
-        for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {\r
-            psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );\r
-            psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );\r
-        }\r
-    }\r
-\r
-    /*****************/\r
-    /* Gain tweaking */\r
-    /*****************/\r
-    /* Increase gains during low speech activity and put lower limit on gains */\r
-    gain_mult_Q16 = silk_log2lin( -SKP_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );\r
-    gain_add_Q16  = silk_log2lin(  SKP_SMLAWB(  SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) );\r
-    SKP_assert( gain_mult_Q16 > 0 );\r
-    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\r
-        psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );\r
-        SKP_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );\r
-        psEncCtrl->Gains_Q16[ k ] = SKP_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );\r
-    }\r
-\r
-    gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + SKP_RSHIFT_ROUND( SKP_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ), \r
-        psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );\r
-    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\r
-        psEncCtrl->GainsPre_Q14[ k ] = SKP_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );\r
-    }\r
-\r
-    /************************************************/\r
-    /* Control low-frequency shaping and noise tilt */\r
-    /************************************************/\r
-    /* Less low frequency shaping for noisy inputs */\r
-    strength_Q16 = SKP_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), SKP_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),\r
-        SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );\r
-    strength_Q16 = SKP_RSHIFT( SKP_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );\r
-    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\r
-        /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */\r
-        /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/\r
-        opus_int fs_kHz_inv = SKP_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );\r
-        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\r
-            b_Q14 = fs_kHz_inv + SKP_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); \r
-            /* Pack two coefficients in one int32 */\r
-            psEncCtrl->LF_shp_Q14[ k ]  = SKP_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - SKP_SMULWB( strength_Q16, b_Q14 ), 16 );\r
-            psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );\r
-        }\r
-        SKP_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); // Guarantees that second argument to SMULWB() is within range of an opus_int16\r
-        Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) - \r
-            SKP_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ), \r
-                SKP_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );\r
-    } else {\r
-        b_Q14 = SKP_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); // 1.3_Q0 = 21299_Q14\r
-        /* Pack two coefficients in one int32 */\r
-        psEncCtrl->LF_shp_Q14[ 0 ]  = SKP_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - \r
-            SKP_SMULWB( strength_Q16, SKP_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );\r
-        psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );\r
-        for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {\r
-            psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];\r
-        }\r
-        Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );\r
-    }\r
-\r
-    /****************************/\r
-    /* HARMONIC SHAPING CONTROL */\r
-    /****************************/\r
-    /* Control boosting of harmonic frequencies */\r
-    HarmBoost_Q16 = SKP_SMULWB( SKP_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ), \r
-        psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );\r
-\r
-    /* More harmonic boost for noisy input signals */\r
-    HarmBoost_Q16 = SKP_SMLAWB( HarmBoost_Q16, \r
-        SILK_FIX_CONST( 1.0, 16 ) - SKP_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );\r
-\r
-    if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\r
-        /* More harmonic noise shaping for high bitrates or noisy input */\r
-        HarmShapeGain_Q16 = SKP_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ), \r
-                SILK_FIX_CONST( 1.0, 16 ) - SKP_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),\r
-                psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );\r
-\r
-        /* Less harmonic noise shaping for less periodic signals */\r
-        HarmShapeGain_Q16 = SKP_SMULWB( SKP_LSHIFT( HarmShapeGain_Q16, 1 ), \r
-            silk_SQRT_APPROX( SKP_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );\r
-    } else {\r
-        HarmShapeGain_Q16 = 0;\r
-    }\r
-\r
-    /*************************/\r
-    /* Smooth over subframes */\r
-    /*************************/\r
-    for( k = 0; k < MAX_NB_SUBFR; k++ ) {\r
-        psShapeSt->HarmBoost_smth_Q16 =\r
-            SKP_SMLAWB( psShapeSt->HarmBoost_smth_Q16,     HarmBoost_Q16     - psShapeSt->HarmBoost_smth_Q16,     SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );\r
-        psShapeSt->HarmShapeGain_smth_Q16 =\r
-            SKP_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );\r
-        psShapeSt->Tilt_smth_Q16 =\r
-            SKP_SMLAWB( psShapeSt->Tilt_smth_Q16,          Tilt_Q16          - psShapeSt->Tilt_smth_Q16,          SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );\r
-\r
-        psEncCtrl->HarmBoost_Q14[ k ]     = ( opus_int )SKP_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16,     2 );\r
-        psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )SKP_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );\r
-        psEncCtrl->Tilt_Q14[ k ]          = ( opus_int )SKP_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16,          2 );\r
-    }\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+#include "silk_tuning_parameters.h"
+
+/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a     */
+/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.)   */
+SKP_INLINE opus_int32 warped_gain( // gain in Q16
+    const opus_int32     *coefs_Q24,
+    opus_int             lambda_Q16,
+    opus_int             order
+) {
+    opus_int   i;
+    opus_int32 gain_Q24;
+
+    lambda_Q16 = -lambda_Q16;
+    gain_Q24 = coefs_Q24[ order - 1 ];
+    for( i = order - 2; i >= 0; i-- ) {
+        gain_Q24 = SKP_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 );
+    }
+    gain_Q24  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 );
+    return silk_INVERSE32_varQ( gain_Q24, 40 );
+}
+
+/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum     */
+/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
+SKP_INLINE void limit_warped_coefs(
+    opus_int32           *coefs_syn_Q24,
+    opus_int32           *coefs_ana_Q24,
+    opus_int             lambda_Q16,
+    opus_int32           limit_Q24,
+    opus_int             order
+) {
+    opus_int   i, iter, ind = 0;
+    opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16;
+    opus_int32 nom_Q16, den_Q24;
+
+    /* Convert to monic coefficients */
+    lambda_Q16 = -lambda_Q16;
+    for( i = order - 1; i > 0; i-- ) {
+        coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
+        coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
+    }
+    lambda_Q16 = -lambda_Q16;
+    nom_Q16  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -lambda_Q16,        lambda_Q16 );
+    den_Q24  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );
+    gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
+    den_Q24  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );
+    gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
+    for( i = 0; i < order; i++ ) {
+        coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
+        coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
+    }
+
+    for( iter = 0; iter < 10; iter++ ) {
+        /* Find maximum absolute value */
+        maxabs_Q24 = -1;
+        for( i = 0; i < order; i++ ) {
+            tmp = SKP_max( SKP_abs_int32( coefs_syn_Q24[ i ] ), SKP_abs_int32( coefs_ana_Q24[ i ] ) );
+            if( tmp > maxabs_Q24 ) {
+                maxabs_Q24 = tmp;
+                ind = i;
+            }
+        }
+        if( maxabs_Q24 <= limit_Q24 ) {
+            /* Coefficients are within range - done */
+            return;
+        }
+
+        /* Convert back to true warped coefficients */
+        for( i = 1; i < order; i++ ) {
+            coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
+            coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
+        }
+        gain_syn_Q16 = silk_INVERSE32_varQ( gain_syn_Q16, 32 );
+        gain_ana_Q16 = silk_INVERSE32_varQ( gain_ana_Q16, 32 );
+        for( i = 0; i < order; i++ ) {
+            coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
+            coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
+        }
+
+        /* Apply bandwidth expansion */
+        chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(
+            SKP_SMULWB( maxabs_Q24 - limit_Q24, SKP_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
+            SKP_MUL( maxabs_Q24, ind + 1 ), 22 );
+        silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 );
+        silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 );
+
+        /* Convert to monic warped coefficients */
+        lambda_Q16 = -lambda_Q16;
+        for( i = order - 1; i > 0; i-- ) {
+            coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
+            coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
+        }
+        lambda_Q16 = -lambda_Q16;
+        nom_Q16  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -lambda_Q16,        lambda_Q16 );
+        den_Q24  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );
+        gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
+        den_Q24  = SKP_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );
+        gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
+        for( i = 0; i < order; i++ ) {
+            coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
+            coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
+        }
+    }
+    SKP_assert( 0 );
+}
+
+/**************************************************************/
+/* Compute noise shaping coefficients and initial gain values */
+/**************************************************************/
+void silk_noise_shape_analysis_FIX(
+    silk_encoder_state_FIX          *psEnc,         /* I/O  Encoder state FIX                           */
+    silk_encoder_control_FIX        *psEncCtrl,     /* I/O  Encoder control FIX                         */
+    const opus_int16                 *pitch_res,     /* I    LPC residual from pitch analysis            */
+    const opus_int16                 *x              /* I    Input signal [ frame_length + la_shape ]    */
+)
+{
+    silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
+    opus_int     k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
+    opus_int32   SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
+    opus_int32   nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
+    opus_int32   delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
+    opus_int32   auto_corr[     MAX_SHAPE_LPC_ORDER + 1 ];
+    opus_int32   refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
+    opus_int32   AR1_Q24[       MAX_SHAPE_LPC_ORDER ];
+    opus_int32   AR2_Q24[       MAX_SHAPE_LPC_ORDER ];
+    opus_int16   x_windowed[    SHAPE_LPC_WIN_MAX ];
+    opus_int32   sqrt_nrg[ MAX_NB_SUBFR ], Qnrg_vec[ MAX_NB_SUBFR ];
+    const opus_int16 *x_ptr, *pitch_res_ptr;
+
+    /* Point to start of first LPC analysis block */
+    x_ptr = x - psEnc->sCmn.la_shape;
+
+    /****************/
+    /* GAIN CONTROL */
+    /****************/
+    SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
+
+    /* Input quality is the average of the quality in the lowest two VAD bands */
+    psEncCtrl->input_quality_Q14 = ( opus_int )SKP_RSHIFT( ( opus_int32 )psEnc->sCmn.input_quality_bands_Q15[ 0 ]
+        + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
+
+    /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
+    psEncCtrl->coding_quality_Q14 = SKP_RSHIFT( silk_sigm_Q15( SKP_RSHIFT_ROUND( SNR_adj_dB_Q7 -
+        SILK_FIX_CONST( 18.0, 7 ), 4 ) ), 1 );
+
+    /* Reduce coding SNR during low speech activity */
+    if( psEnc->sCmn.useCBR == 0 ) {
+        b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
+        b_Q8 = SKP_SMULWB( SKP_LSHIFT( b_Q8, 8 ), b_Q8 );
+        SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7,
+            SKP_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ),                                       // Q11
+            SKP_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) );     // Q12
+    }
+
+    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+        /* Reduce gains for periodic signals */
+        SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
+    } else {
+        /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
+        SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7,
+            SKP_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
+            SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
+    }
+
+    /*************************/
+    /* SPARSENESS PROCESSING */
+    /*************************/
+    /* Set quantizer offset */
+    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+        /* Initally set to 0; may be overruled in process_gains(..) */
+        psEnc->sCmn.indices.quantOffsetType = 0;
+        psEncCtrl->sparseness_Q8 = 0;
+    } else {
+        /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
+        nSamples = SKP_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
+        energy_variation_Q7 = 0;
+        log_energy_prev_Q7  = 0;
+        pitch_res_ptr = pitch_res;
+        for( k = 0; k < SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
+            silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
+            nrg += SKP_RSHIFT( nSamples, scale );           // Q(-scale)
+
+            log_energy_Q7 = silk_lin2log( nrg );
+            if( k > 0 ) {
+                energy_variation_Q7 += SKP_abs( log_energy_Q7 - log_energy_prev_Q7 );
+            }
+            log_energy_prev_Q7 = log_energy_Q7;
+            pitch_res_ptr += nSamples;
+        }
+
+        psEncCtrl->sparseness_Q8 = SKP_RSHIFT( silk_sigm_Q15( SKP_SMULWB( energy_variation_Q7 -
+            SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );
+
+        /* Set quantization offset depending on sparseness measure */
+        if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {
+            psEnc->sCmn.indices.quantOffsetType = 0;
+        } else {
+            psEnc->sCmn.indices.quantOffsetType = 1;
+        }
+
+        /* Increase coding SNR for sparse signals */
+        SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) );
+    }
+
+    /*******************************/
+    /* Control bandwidth expansion */
+    /*******************************/
+    /* More BWE for signals with high prediction gain */
+    strength_Q16 = SKP_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
+    BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
+        SKP_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
+    delta_Q16  = SKP_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SKP_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),
+        SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );
+    BWExp1_Q16 = SKP_SUB32( BWExp1_Q16, delta_Q16 );
+    BWExp2_Q16 = SKP_ADD32( BWExp2_Q16, delta_Q16 );
+    /* BWExp1 will be applied after BWExp2, so make it relative */
+    BWExp1_Q16 = SKP_DIV32_16( SKP_LSHIFT( BWExp1_Q16, 14 ), SKP_RSHIFT( BWExp2_Q16, 2 ) );
+
+    if( psEnc->sCmn.warping_Q16 > 0 ) {
+        /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
+        warping_Q16 = SKP_SMLAWB( psEnc->sCmn.warping_Q16, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
+    } else {
+        warping_Q16 = 0;
+    }
+
+    /********************************************/
+    /* Compute noise shaping AR coefs and gains */
+    /********************************************/
+    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+        /* Apply window: sine slope followed by flat part followed by cosine slope */
+        opus_int shift, slope_part, flat_part;
+        flat_part = psEnc->sCmn.fs_kHz * 3;
+        slope_part = SKP_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
+
+        silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
+        shift = slope_part;
+        SKP_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
+        shift += flat_part;
+        silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
+
+        /* Update pointer: next LPC analysis block */
+        x_ptr += psEnc->sCmn.subfr_length;
+
+        if( psEnc->sCmn.warping_Q16 > 0 ) {
+            /* Calculate warped auto correlation */
+            silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
+        } else {
+            /* Calculate regular auto correlation */
+            silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 );
+        }
+
+        /* Add white noise, as a fraction of energy */
+        auto_corr[0] = SKP_ADD32( auto_corr[0], SKP_max_32( SKP_SMULWB( SKP_RSHIFT( auto_corr[ 0 ], 4 ),
+            SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
+
+        /* Calculate the reflection coefficients using schur */
+        nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
+        SKP_assert( nrg >= 0 );
+
+        /* Convert reflection coefficients to prediction coefficients */
+        silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
+
+        Qnrg = -scale;          // range: -12...30
+        SKP_assert( Qnrg >= -12 );
+        SKP_assert( Qnrg <=  30 );
+
+        /* Make sure that Qnrg is an even number */
+        if( Qnrg & 1 ) {
+            Qnrg -= 1;
+            nrg >>= 1;
+        }
+
+        tmp32 = silk_SQRT_APPROX( nrg );
+        Qnrg >>= 1;             // range: -6...15
+
+        sqrt_nrg[ k ] = tmp32;
+        Qnrg_vec[ k ] = Qnrg;
+
+        psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( tmp32, 16 - Qnrg );
+
+        if( psEnc->sCmn.warping_Q16 > 0 ) {
+            /* Adjust gain for warping */
+            gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
+            SKP_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
+            psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
+            if( psEncCtrl->Gains_Q16[ k ] < 0 ) {
+                psEncCtrl->Gains_Q16[ k ] = SKP_int32_MAX;
+            }
+        }
+
+        /* Bandwidth expansion for synthesis filter shaping */
+        silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );
+
+        /* Compute noise shaping filter coefficients */
+        SKP_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );
+
+        /* Bandwidth expansion for analysis filter shaping */
+        SKP_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );
+        silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
+
+        /* Ratio of prediction gains, in energy domain */
+        silk_LPC_inverse_pred_gain_Q24( &pre_nrg_Q30, AR2_Q24, psEnc->sCmn.shapingLPCOrder );
+        silk_LPC_inverse_pred_gain_Q24( &nrg,         AR1_Q24, psEnc->sCmn.shapingLPCOrder );
+
+        //psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;
+        pre_nrg_Q30 = SKP_LSHIFT32( SKP_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
+        psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );
+
+        /* Convert to monic warped prediction coefficients and limit absolute values */
+        limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
+
+        /* Convert from Q24 to Q13 and store in int16 */
+        for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
+            psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );
+            psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );
+        }
+    }
+
+    /*****************/
+    /* Gain tweaking */
+    /*****************/
+    /* Increase gains during low speech activity and put lower limit on gains */
+    gain_mult_Q16 = silk_log2lin( -SKP_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
+    gain_add_Q16  = silk_log2lin(  SKP_SMLAWB(  SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) );
+    SKP_assert( gain_mult_Q16 > 0 );
+    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+        psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
+        SKP_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
+        psEncCtrl->Gains_Q16[ k ] = SKP_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
+    }
+
+    gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + SKP_RSHIFT_ROUND( SKP_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ),
+        psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );
+    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+        psEncCtrl->GainsPre_Q14[ k ] = SKP_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );
+    }
+
+    /************************************************/
+    /* Control low-frequency shaping and noise tilt */
+    /************************************************/
+    /* Less low frequency shaping for noisy inputs */
+    strength_Q16 = SKP_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), SKP_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
+        SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
+    strength_Q16 = SKP_RSHIFT( SKP_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
+    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+        /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
+        /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
+        opus_int fs_kHz_inv = SKP_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
+        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+            b_Q14 = fs_kHz_inv + SKP_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );
+            /* Pack two coefficients in one int32 */
+            psEncCtrl->LF_shp_Q14[ k ]  = SKP_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - SKP_SMULWB( strength_Q16, b_Q14 ), 16 );
+            psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
+        }
+        SKP_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); // Guarantees that second argument to SMULWB() is within range of an opus_int16
+        Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
+            SKP_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
+                SKP_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
+    } else {
+        b_Q14 = SKP_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); // 1.3_Q0 = 21299_Q14
+        /* Pack two coefficients in one int32 */
+        psEncCtrl->LF_shp_Q14[ 0 ]  = SKP_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
+            SKP_SMULWB( strength_Q16, SKP_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
+        psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
+        for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
+            psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
+        }
+        Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
+    }
+
+    /****************************/
+    /* HARMONIC SHAPING CONTROL */
+    /****************************/
+    /* Control boosting of harmonic frequencies */
+    HarmBoost_Q16 = SKP_SMULWB( SKP_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),
+        psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );
+
+    /* More harmonic boost for noisy input signals */
+    HarmBoost_Q16 = SKP_SMLAWB( HarmBoost_Q16,
+        SILK_FIX_CONST( 1.0, 16 ) - SKP_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );
+
+    if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+        /* More harmonic noise shaping for high bitrates or noisy input */
+        HarmShapeGain_Q16 = SKP_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
+                SILK_FIX_CONST( 1.0, 16 ) - SKP_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
+                psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
+
+        /* Less harmonic noise shaping for less periodic signals */
+        HarmShapeGain_Q16 = SKP_SMULWB( SKP_LSHIFT( HarmShapeGain_Q16, 1 ),
+            silk_SQRT_APPROX( SKP_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
+    } else {
+        HarmShapeGain_Q16 = 0;
+    }
+
+    /*************************/
+    /* Smooth over subframes */
+    /*************************/
+    for( k = 0; k < MAX_NB_SUBFR; k++ ) {
+        psShapeSt->HarmBoost_smth_Q16 =
+            SKP_SMLAWB( psShapeSt->HarmBoost_smth_Q16,     HarmBoost_Q16     - psShapeSt->HarmBoost_smth_Q16,     SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
+        psShapeSt->HarmShapeGain_smth_Q16 =
+            SKP_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
+        psShapeSt->Tilt_smth_Q16 =
+            SKP_SMLAWB( psShapeSt->Tilt_smth_Q16,          Tilt_Q16          - psShapeSt->Tilt_smth_Q16,          SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
+
+        psEncCtrl->HarmBoost_Q14[ k ]     = ( opus_int )SKP_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16,     2 );
+        psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )SKP_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
+        psEncCtrl->Tilt_Q14[ k ]          = ( opus_int )SKP_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16,          2 );
+    }
+}
index 368aeda..fd4746b 100644 (file)
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-#include "silk_tuning_parameters.h"\r
-\r
-/* silk_prefilter. Prefilter for finding Quantizer input signal */\r
-SKP_INLINE void silk_prefilt_FIX(\r
-    silk_prefilter_state_FIX *P,                    /* I/O state                          */\r
-    opus_int32   st_res_Q12[],                           /* I short term residual signal       */\r
-    opus_int16   xw[],                                   /* O prefiltered signal               */\r
-    opus_int32   HarmShapeFIRPacked_Q12,                 /* I Harmonic shaping coeficients     */\r
-    opus_int     Tilt_Q14,                               /* I Tilt shaping coeficient          */\r
-    opus_int32   LF_shp_Q14,                             /* I Low-frequancy shaping coeficients*/\r
-    opus_int     lag,                                    /* I Lag for harmonic shaping         */\r
-    opus_int     length                                  /* I Length of signals                */\r
-);\r
-\r
-void silk_warped_LPC_analysis_filter_FIX(\r
-          opus_int32                 state[],            /* I/O  State [order + 1]                       */\r
-          opus_int16                 res[],              /* O    Residual signal [length]                */\r
-    const opus_int16                 coef_Q13[],         /* I    Coefficients [order]                    */\r
-    const opus_int16                 input[],            /* I    Input signal [length]                   */\r
-    const opus_int16                 lambda_Q16,         /* I    Warping factor                          */\r
-    const opus_int                   length,             /* I    Length of input signal                  */\r
-    const opus_int                   order               /* I    Filter order (even)                     */\r
-)\r
-{\r
-    opus_int     n, i;\r
-    opus_int32   acc_Q11, tmp1, tmp2;\r
-\r
-    /* Order must be even */\r
-    SKP_assert( ( order & 1 ) == 0 );\r
-\r
-    for( n = 0; n < length; n++ ) {\r
-        /* Output of lowpass section */  \r
-        tmp2 = SKP_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );\r
-        state[ 0 ] = SKP_LSHIFT( input[ n ], 14 );\r
-        /* Output of allpass section */\r
-        tmp1 = SKP_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );\r
-        state[ 1 ] = tmp2;\r
-        acc_Q11 = SKP_SMULWB( tmp2, coef_Q13[ 0 ] );\r
-        /* Loop over allpass sections */\r
-        for( i = 2; i < order; i += 2 ) {\r
-            /* Output of allpass section */\r
-            tmp2 = SKP_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );\r
-            state[ i ] = tmp1;\r
-            acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );\r
-            /* Output of allpass section */\r
-            tmp1 = SKP_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );\r
-            state[ i + 1 ] = tmp2;\r
-            acc_Q11 = SKP_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );\r
-        }\r
-        state[ order ] = tmp1;\r
-        acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );\r
-        res[ n ] = ( opus_int16 )SKP_SAT16( ( opus_int32 )input[ n ] - SKP_RSHIFT_ROUND( acc_Q11, 11 ) );\r
-    }\r
-}\r
-\r
-void silk_prefilter_FIX(\r
-    silk_encoder_state_FIX              *psEnc,         /* I/O  Encoder state FIX                           */\r
-    const silk_encoder_control_FIX      *psEncCtrl,     /* I    Encoder control FIX                         */\r
-    opus_int16                           xw[],           /* O    Weighted signal                             */\r
-    const opus_int16                     x[]             /* I    Speech signal                               */\r
-)\r
-{\r
-    silk_prefilter_state_FIX *P = &psEnc->sPrefilt;\r
-    opus_int   j, k, lag;\r
-    opus_int32 tmp_32;\r
-    const opus_int16 *AR1_shp_Q13;\r
-    const opus_int16 *px;\r
-    opus_int16 *pxw;\r
-    opus_int   HarmShapeGain_Q12, Tilt_Q14;\r
-    opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14;\r
-    opus_int32 x_filt_Q12[ MAX_FRAME_LENGTH / MAX_NB_SUBFR ];\r
-    opus_int16 st_res[ ( MAX_FRAME_LENGTH / MAX_NB_SUBFR ) + MAX_LPC_ORDER ];\r
-    opus_int16 B_Q12[ 2 ];\r
-\r
-    /* Setup pointers */\r
-    px  = x;\r
-    pxw = xw;\r
-    lag = P->lagPrev;\r
-    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\r
-        /* Update Variables that change per sub frame */\r
-        if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\r
-            lag = psEncCtrl->pitchL[ k ];\r
-        }\r
-\r
-        /* Noise shape parameters */\r
-        HarmShapeGain_Q12 = SKP_SMULWB( psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] );\r
-        SKP_assert( HarmShapeGain_Q12 >= 0 );\r
-        HarmShapeFIRPacked_Q12  =                          SKP_RSHIFT( HarmShapeGain_Q12, 2 );\r
-        HarmShapeFIRPacked_Q12 |= SKP_LSHIFT( ( opus_int32 )SKP_RSHIFT( HarmShapeGain_Q12, 1 ), 16 );\r
-        Tilt_Q14    = psEncCtrl->Tilt_Q14[   k ];\r
-        LF_shp_Q14  = psEncCtrl->LF_shp_Q14[ k ];\r
-        AR1_shp_Q13 = &psEncCtrl->AR1_Q13[   k * MAX_SHAPE_LPC_ORDER ];\r
-\r
-        /* Short term FIR filtering*/\r
-        silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res, AR1_shp_Q13, px, \r
-            psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );\r
-\r
-        /* reduce (mainly) low frequencies during harmonic emphasis */\r
-        B_Q12[ 0 ] = SKP_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 2 );\r
-        tmp_32 = SKP_SMLABB( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 );   /* Q26 */\r
-        tmp_32 = SKP_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) );    /* Q26 */\r
-        tmp_32 = SKP_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] );                                               /* Q24 */\r
-        tmp_32 = SKP_RSHIFT_ROUND( tmp_32, 12 );                                                                    /* Q12 */\r
-        B_Q12[ 1 ]= SKP_SAT16( tmp_32 );\r
-\r
-        x_filt_Q12[ 0 ] = SKP_SMLABB( SKP_SMULBB( st_res[ 0 ], B_Q12[ 0 ] ), P->sHarmHP, B_Q12[ 1 ] );\r
-        for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {\r
-            x_filt_Q12[ j ] = SKP_SMLABB( SKP_SMULBB( st_res[ j ], B_Q12[ 0 ] ), st_res[ j - 1 ], B_Q12[ 1 ] );\r
-        }\r
-        P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ];\r
-\r
-        silk_prefilt_FIX( P, x_filt_Q12, pxw, HarmShapeFIRPacked_Q12, Tilt_Q14, \r
-            LF_shp_Q14, lag, psEnc->sCmn.subfr_length );\r
-\r
-        px  += psEnc->sCmn.subfr_length;\r
-        pxw += psEnc->sCmn.subfr_length;\r
-    }\r
-\r
-    P->lagPrev = psEncCtrl->pitchL[ MAX_NB_SUBFR - 1 ];\r
-}\r
-\r
-/* silk_prefilter. Prefilter for finding Quantizer input signal                           */\r
-SKP_INLINE void silk_prefilt_FIX(\r
-    silk_prefilter_state_FIX *P,                    /* I/O state                          */\r
-    opus_int32   st_res_Q12[],                           /* I short term residual signal       */\r
-    opus_int16   xw[],                                   /* O prefiltered signal               */\r
-    opus_int32   HarmShapeFIRPacked_Q12,                 /* I Harmonic shaping coeficients     */\r
-    opus_int     Tilt_Q14,                               /* I Tilt shaping coeficient          */\r
-    opus_int32   LF_shp_Q14,                             /* I Low-frequancy shaping coeficients*/\r
-    opus_int     lag,                                    /* I Lag for harmonic shaping         */\r
-    opus_int     length                                  /* I Length of signals                */\r
-)\r
-{\r
-    opus_int   i, idx, LTP_shp_buf_idx;\r
-    opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;\r
-    opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;\r
-    opus_int16 *LTP_shp_buf;\r
-\r
-    /* To speed up use temp variables instead of using the struct */\r
-    LTP_shp_buf     = P->sLTP_shp;\r
-    LTP_shp_buf_idx = P->sLTP_shp_buf_idx;\r
-    sLF_AR_shp_Q12  = P->sLF_AR_shp_Q12;\r
-    sLF_MA_shp_Q12  = P->sLF_MA_shp_Q12;\r
-\r
-    for( i = 0; i < length; i++ ) {\r
-        if( lag > 0 ) {\r
-            /* unrolled loop */\r
-            SKP_assert( HARM_SHAPE_FIR_TAPS == 3 );\r
-            idx = lag + LTP_shp_buf_idx;\r
-            n_LTP_Q12 = SKP_SMULBB(            LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );\r
-            n_LTP_Q12 = SKP_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2    ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );\r
-            n_LTP_Q12 = SKP_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );\r
-        } else {\r
-            n_LTP_Q12 = 0;\r
-        }\r
-\r
-        n_Tilt_Q10 = SKP_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );\r
-        n_LF_Q10   = SKP_SMLAWB( SKP_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );\r
-\r
-        sLF_AR_shp_Q12 = SKP_SUB32( st_res_Q12[ i ], SKP_LSHIFT( n_Tilt_Q10, 2 ) );\r
-        sLF_MA_shp_Q12 = SKP_SUB32( sLF_AR_shp_Q12,  SKP_LSHIFT( n_LF_Q10,   2 ) );\r
-\r
-        LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;\r
-        LTP_shp_buf[ LTP_shp_buf_idx ] = ( opus_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );\r
-\r
-        xw[i] = ( opus_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 12 ) );\r
-    }\r
-\r
-    /* Copy temp variable back to state */\r
-    P->sLF_AR_shp_Q12   = sLF_AR_shp_Q12;\r
-    P->sLF_MA_shp_Q12   = sLF_MA_shp_Q12;\r
-    P->sLTP_shp_buf_idx = LTP_shp_buf_idx;\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+#include "silk_tuning_parameters.h"
+
+/* silk_prefilter. Prefilter for finding Quantizer input signal */
+SKP_INLINE void silk_prefilt_FIX(
+    silk_prefilter_state_FIX *P,                    /* I/O state                          */
+    opus_int32   st_res_Q12[],                           /* I short term residual signal       */
+    opus_int16   xw[],                                   /* O prefiltered signal               */
+    opus_int32   HarmShapeFIRPacked_Q12,                 /* I Harmonic shaping coeficients     */
+    opus_int     Tilt_Q14,                               /* I Tilt shaping coeficient          */
+    opus_int32   LF_shp_Q14,                             /* I Low-frequancy shaping coeficients*/
+    opus_int     lag,                                    /* I Lag for harmonic shaping         */
+    opus_int     length                                  /* I Length of signals                */
+);
+
+void silk_warped_LPC_analysis_filter_FIX(
+          opus_int32                 state[],            /* I/O  State [order + 1]                       */
+          opus_int16                 res[],              /* O    Residual signal [length]                */
+    const opus_int16                 coef_Q13[],         /* I    Coefficients [order]                    */
+    const opus_int16                 input[],            /* I    Input signal [length]                   */
+    const opus_int16                 lambda_Q16,         /* I    Warping factor                          */
+    const opus_int                   length,             /* I    Length of input signal                  */
+    const opus_int                   order               /* I    Filter order (even)                     */
+)
+{
+    opus_int     n, i;
+    opus_int32   acc_Q11, tmp1, tmp2;
+
+    /* Order must be even */
+    SKP_assert( ( order & 1 ) == 0 );
+
+    for( n = 0; n < length; n++ ) {
+        /* Output of lowpass section */
+        tmp2 = SKP_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
+        state[ 0 ] = SKP_LSHIFT( input[ n ], 14 );
+        /* Output of allpass section */
+        tmp1 = SKP_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
+        state[ 1 ] = tmp2;
+        acc_Q11 = SKP_SMULWB( tmp2, coef_Q13[ 0 ] );
+        /* Loop over allpass sections */
+        for( i = 2; i < order; i += 2 ) {
+            /* Output of allpass section */
+            tmp2 = SKP_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
+            state[ i ] = tmp1;
+            acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
+            /* Output of allpass section */
+            tmp1 = SKP_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
+            state[ i + 1 ] = tmp2;
+            acc_Q11 = SKP_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
+        }
+        state[ order ] = tmp1;
+        acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
+        res[ n ] = ( opus_int16 )SKP_SAT16( ( opus_int32 )input[ n ] - SKP_RSHIFT_ROUND( acc_Q11, 11 ) );
+    }
+}
+
+void silk_prefilter_FIX(
+    silk_encoder_state_FIX              *psEnc,         /* I/O  Encoder state FIX                           */
+    const silk_encoder_control_FIX      *psEncCtrl,     /* I    Encoder control FIX                         */
+    opus_int16                           xw[],           /* O    Weighted signal                             */
+    const opus_int16                     x[]             /* I    Speech signal                               */
+)
+{
+    silk_prefilter_state_FIX *P = &psEnc->sPrefilt;
+    opus_int   j, k, lag;
+    opus_int32 tmp_32;
+    const opus_int16 *AR1_shp_Q13;
+    const opus_int16 *px;
+    opus_int16 *pxw;
+    opus_int   HarmShapeGain_Q12, Tilt_Q14;
+    opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14;
+    opus_int32 x_filt_Q12[ MAX_FRAME_LENGTH / MAX_NB_SUBFR ];
+    opus_int16 st_res[ ( MAX_FRAME_LENGTH / MAX_NB_SUBFR ) + MAX_LPC_ORDER ];
+    opus_int16 B_Q12[ 2 ];
+
+    /* Setup pointers */
+    px  = x;
+    pxw = xw;
+    lag = P->lagPrev;
+    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+        /* Update Variables that change per sub frame */
+        if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+            lag = psEncCtrl->pitchL[ k ];
+        }
+
+        /* Noise shape parameters */
+        HarmShapeGain_Q12 = SKP_SMULWB( psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] );
+        SKP_assert( HarmShapeGain_Q12 >= 0 );
+        HarmShapeFIRPacked_Q12  =                          SKP_RSHIFT( HarmShapeGain_Q12, 2 );
+        HarmShapeFIRPacked_Q12 |= SKP_LSHIFT( ( opus_int32 )SKP_RSHIFT( HarmShapeGain_Q12, 1 ), 16 );
+        Tilt_Q14    = psEncCtrl->Tilt_Q14[   k ];
+        LF_shp_Q14  = psEncCtrl->LF_shp_Q14[ k ];
+        AR1_shp_Q13 = &psEncCtrl->AR1_Q13[   k * MAX_SHAPE_LPC_ORDER ];
+
+        /* Short term FIR filtering*/
+        silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res, AR1_shp_Q13, px,
+            psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );
+
+        /* reduce (mainly) low frequencies during harmonic emphasis */
+        B_Q12[ 0 ] = SKP_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 2 );
+        tmp_32 = SKP_SMLABB( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 );   /* Q26 */
+        tmp_32 = SKP_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) );    /* Q26 */
+        tmp_32 = SKP_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] );                                               /* Q24 */
+        tmp_32 = SKP_RSHIFT_ROUND( tmp_32, 12 );                                                                    /* Q12 */
+        B_Q12[ 1 ]= SKP_SAT16( tmp_32 );
+
+        x_filt_Q12[ 0 ] = SKP_SMLABB( SKP_SMULBB( st_res[ 0 ], B_Q12[ 0 ] ), P->sHarmHP, B_Q12[ 1 ] );
+        for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
+            x_filt_Q12[ j ] = SKP_SMLABB( SKP_SMULBB( st_res[ j ], B_Q12[ 0 ] ), st_res[ j - 1 ], B_Q12[ 1 ] );
+        }
+        P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ];
+
+        silk_prefilt_FIX( P, x_filt_Q12, pxw, HarmShapeFIRPacked_Q12, Tilt_Q14,
+            LF_shp_Q14, lag, psEnc->sCmn.subfr_length );
+
+        px  += psEnc->sCmn.subfr_length;
+        pxw += psEnc->sCmn.subfr_length;
+    }
+
+    P->lagPrev = psEncCtrl->pitchL[ MAX_NB_SUBFR - 1 ];
+}
+
+/* silk_prefilter. Prefilter for finding Quantizer input signal                           */
+SKP_INLINE void silk_prefilt_FIX(
+    silk_prefilter_state_FIX *P,                    /* I/O state                          */
+    opus_int32   st_res_Q12[],                           /* I short term residual signal       */
+    opus_int16   xw[],                                   /* O prefiltered signal               */
+    opus_int32   HarmShapeFIRPacked_Q12,                 /* I Harmonic shaping coeficients     */
+    opus_int     Tilt_Q14,                               /* I Tilt shaping coeficient          */
+    opus_int32   LF_shp_Q14,                             /* I Low-frequancy shaping coeficients*/
+    opus_int     lag,                                    /* I Lag for harmonic shaping         */
+    opus_int     length                                  /* I Length of signals                */
+)
+{
+    opus_int   i, idx, LTP_shp_buf_idx;
+    opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
+    opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
+    opus_int16 *LTP_shp_buf;
+
+    /* To speed up use temp variables instead of using the struct */
+    LTP_shp_buf     = P->sLTP_shp;
+    LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
+    sLF_AR_shp_Q12  = P->sLF_AR_shp_Q12;
+    sLF_MA_shp_Q12  = P->sLF_MA_shp_Q12;
+
+    for( i = 0; i < length; i++ ) {
+        if( lag > 0 ) {
+            /* unrolled loop */
+            SKP_assert( HARM_SHAPE_FIR_TAPS == 3 );
+            idx = lag + LTP_shp_buf_idx;
+            n_LTP_Q12 = SKP_SMULBB(            LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+            n_LTP_Q12 = SKP_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2    ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+            n_LTP_Q12 = SKP_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+        } else {
+            n_LTP_Q12 = 0;
+        }
+
+        n_Tilt_Q10 = SKP_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
+        n_LF_Q10   = SKP_SMLAWB( SKP_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
+
+        sLF_AR_shp_Q12 = SKP_SUB32( st_res_Q12[ i ], SKP_LSHIFT( n_Tilt_Q10, 2 ) );
+        sLF_MA_shp_Q12 = SKP_SUB32( sLF_AR_shp_Q12,  SKP_LSHIFT( n_LF_Q10,   2 ) );
+
+        LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
+        LTP_shp_buf[ LTP_shp_buf_idx ] = ( opus_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
+
+        xw[i] = ( opus_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 12 ) );
+    }
+
+    /* Copy temp variable back to state */
+    P->sLF_AR_shp_Q12   = sLF_AR_shp_Q12;
+    P->sLF_MA_shp_Q12   = sLF_MA_shp_Q12;
+    P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
+}
index 4341ac0..771bff3 100644 (file)
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-#include "silk_tuning_parameters.h"\r
-\r
-/* Processing of gains */\r
-void silk_process_gains_FIX(\r
-    silk_encoder_state_FIX      *psEnc,         /* I/O  Encoder state_FIX                           */\r
-    silk_encoder_control_FIX    *psEncCtrl      /* I/O  Encoder control_FIX                         */\r
-)\r
-{\r
-    silk_shape_state_FIX    *psShapeSt = &psEnc->sShape;\r
-    opus_int     k;\r
-    opus_int32   s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10;\r
-\r
-    /* Gain reduction when LTP coding gain is high */\r
-    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\r
-        /*s = -0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */\r
-        s_Q16 = -silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) );\r
-        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\r
-            psEncCtrl->Gains_Q16[ k ] = SKP_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 );\r
-        }\r
-    }\r
-\r
-    /* Limit the quantized signal */\r
-    /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */\r
-    InvMaxSqrVal_Q16 = SKP_DIV32_16( silk_log2lin( \r
-        SKP_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length );\r
-\r
-    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {\r
-        /* Soft limit on ratio residual energy and squared gains */\r
-        ResNrg     = psEncCtrl->ResNrg[ k ];\r
-        ResNrgPart = SKP_SMULWW( ResNrg, InvMaxSqrVal_Q16 );\r
-        if( psEncCtrl->ResNrgQ[ k ] > 0 ) {\r
-            ResNrgPart = SKP_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] );\r
-        } else {\r
-            if( ResNrgPart >= SKP_RSHIFT( SKP_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) {\r
-                ResNrgPart = SKP_int32_MAX;\r
-            } else {\r
-                ResNrgPart = SKP_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] );\r
-            }\r
-        }\r
-        gain = psEncCtrl->Gains_Q16[ k ];\r
-        gain_squared = SKP_ADD_SAT32( ResNrgPart, SKP_SMMUL( gain, gain ) );\r
-        if( gain_squared < SKP_int16_MAX ) {\r
-            /* recalculate with higher precision */\r
-            gain_squared = SKP_SMLAWW( SKP_LSHIFT( ResNrgPart, 16 ), gain, gain );\r
-            SKP_assert( gain_squared > 0 );\r
-            gain = silk_SQRT_APPROX( gain_squared );                    /* Q8   */\r
-            gain = SKP_min( gain, SKP_int32_MAX >> 8 );\r
-            psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 8 );        /* Q16  */\r
-        } else {\r
-            gain = silk_SQRT_APPROX( gain_squared );                    /* Q0   */\r
-            gain = SKP_min( gain, SKP_int32_MAX >> 16 );\r
-            psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 16 );       /* Q16  */\r
-        }\r
-    }\r
-\r
-    /* Noise shaping quantization */\r
-    silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16, \r
-        &psShapeSt->LastGainIndex, psEnc->sCmn.nFramesEncoded, psEnc->sCmn.nb_subfr );\r
-\r
-    /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */\r
-    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {\r
-        if( psEncCtrl->LTPredCodGain_Q7 + SKP_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) {\r
-            psEnc->sCmn.indices.quantOffsetType = 0;\r
-        } else {\r
-            psEnc->sCmn.indices.quantOffsetType = 1;\r
-        }\r
-    }\r
-\r
-    /* Quantizer boundary adjustment */\r
-    quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ];\r
-    psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 )\r
-                          + SKP_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision )\r
-                          + SKP_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT,        18 ), psEnc->sCmn.speech_activity_Q8     )\r
-                          + SKP_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY,     12 ), psEncCtrl->input_quality_Q14       )\r
-                          + SKP_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY,    12 ), psEncCtrl->coding_quality_Q14      )\r
-                          + SKP_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET,      16 ), quant_offset_Q10                   );\r
-\r
-    SKP_assert( psEncCtrl->Lambda_Q10 > 0 );\r
-    SKP_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) );\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+#include "silk_tuning_parameters.h"
+
+/* Processing of gains */
+void silk_process_gains_FIX(
+    silk_encoder_state_FIX      *psEnc,         /* I/O  Encoder state_FIX                           */
+    silk_encoder_control_FIX    *psEncCtrl      /* I/O  Encoder control_FIX                         */
+)
+{
+    silk_shape_state_FIX    *psShapeSt = &psEnc->sShape;
+    opus_int     k;
+    opus_int32   s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10;
+
+    /* Gain reduction when LTP coding gain is high */
+    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+        /*s = -0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */
+        s_Q16 = -silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) );
+        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+            psEncCtrl->Gains_Q16[ k ] = SKP_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 );
+        }
+    }
+
+    /* Limit the quantized signal */
+    /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */
+    InvMaxSqrVal_Q16 = SKP_DIV32_16( silk_log2lin(
+        SKP_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length );
+
+    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+        /* Soft limit on ratio residual energy and squared gains */
+        ResNrg     = psEncCtrl->ResNrg[ k ];
+        ResNrgPart = SKP_SMULWW( ResNrg, InvMaxSqrVal_Q16 );
+        if( psEncCtrl->ResNrgQ[ k ] > 0 ) {
+            ResNrgPart = SKP_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] );
+        } else {
+            if( ResNrgPart >= SKP_RSHIFT( SKP_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) {
+                ResNrgPart = SKP_int32_MAX;
+            } else {
+                ResNrgPart = SKP_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] );
+            }
+        }
+        gain = psEncCtrl->Gains_Q16[ k ];
+        gain_squared = SKP_ADD_SAT32( ResNrgPart, SKP_SMMUL( gain, gain ) );
+        if( gain_squared < SKP_int16_MAX ) {
+            /* recalculate with higher precision */
+            gain_squared = SKP_SMLAWW( SKP_LSHIFT( ResNrgPart, 16 ), gain, gain );
+            SKP_assert( gain_squared > 0 );
+            gain = silk_SQRT_APPROX( gain_squared );                    /* Q8   */
+            gain = SKP_min( gain, SKP_int32_MAX >> 8 );
+            psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 8 );        /* Q16  */
+        } else {
+            gain = silk_SQRT_APPROX( gain_squared );                    /* Q0   */
+            gain = SKP_min( gain, SKP_int32_MAX >> 16 );
+            psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 16 );       /* Q16  */
+        }
+    }
+
+    /* Noise shaping quantization */
+    silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16,
+        &psShapeSt->LastGainIndex, psEnc->sCmn.nFramesEncoded, psEnc->sCmn.nb_subfr );
+
+    /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */
+    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+        if( psEncCtrl->LTPredCodGain_Q7 + SKP_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) {
+            psEnc->sCmn.indices.quantOffsetType = 0;
+        } else {
+            psEnc->sCmn.indices.quantOffsetType = 1;
+        }
+    }
+
+    /* Quantizer boundary adjustment */
+    quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ];
+    psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 )
+                          + SKP_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision )
+                          + SKP_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT,        18 ), psEnc->sCmn.speech_activity_Q8     )
+                          + SKP_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY,     12 ), psEncCtrl->input_quality_Q14       )
+                          + SKP_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY,    12 ), psEncCtrl->coding_quality_Q14      )
+                          + SKP_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET,      16 ), quant_offset_Q10                   );
+
+    SKP_assert( psEncCtrl->Lambda_Q10 > 0 );
+    SKP_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) );
+}
index 8cca332..1fd899e 100644 (file)
@@ -1,43 +1,43 @@
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-\r
-/* Add noise to matrix diagonal */\r
-void silk_regularize_correlations_FIX(\r
-    opus_int32                       *XX,                /* I/O  Correlation matrices                        */\r
-    opus_int32                       *xx,                /* I/O  Correlation values                          */\r
-    opus_int32                       noise,              /* I    Noise to add                                */\r
-    opus_int                         D                   /* I    Dimension of XX                             */\r
-)\r
-{\r
-    opus_int i;\r
-    for( i = 0; i < D; i++ ) {\r
-        matrix_ptr( &XX[ 0 ], i, i, D ) = SKP_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise );\r
-    }\r
-    xx[ 0 ] += noise;\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+
+/* Add noise to matrix diagonal */
+void silk_regularize_correlations_FIX(
+    opus_int32                       *XX,                /* I/O  Correlation matrices                        */
+    opus_int32                       *xx,                /* I/O  Correlation values                          */
+    opus_int32                       noise,              /* I    Noise to add                                */
+    opus_int                         D                   /* I    Dimension of XX                             */
+)
+{
+    opus_int i;
+    for( i = 0; i < D; i++ ) {
+        matrix_ptr( &XX[ 0 ], i, i, D ) = SKP_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise );
+    }
+    xx[ 0 ] += noise;
+}
index c3b571c..c364ffb 100644 (file)
@@ -1,99 +1,99 @@
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-\r
-/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */\r
-opus_int32 silk_residual_energy16_covar_FIX(\r
-    const opus_int16                 *c,                 /* I    Prediction vector                           */\r
-    const opus_int32                 *wXX,               /* I    Correlation matrix                          */\r
-    const opus_int32                 *wXx,               /* I    Correlation vector                          */\r
-    opus_int32                       wxx,                /* I    Signal energy                               */\r
-    opus_int                         D,                  /* I    Dimension                                   */\r
-    opus_int                         cQ                  /* I    Q value for c vector 0 - 15                 */\r
-)\r
-{\r
-    opus_int   i, j, lshifts, Qxtra;\r
-    opus_int32 c_max, w_max, tmp, tmp2, nrg;\r
-    opus_int   cn[ MAX_MATRIX_SIZE ]; \r
-    const opus_int32 *pRow;\r
-\r
-    /* Safety checks */\r
-    SKP_assert( D >=  0 );\r
-    SKP_assert( D <= 16 );\r
-    SKP_assert( cQ >  0 );\r
-    SKP_assert( cQ < 16 );\r
-\r
-    lshifts = 16 - cQ;\r
-    Qxtra = lshifts;\r
-\r
-    c_max = 0;\r
-    for( i = 0; i < D; i++ ) {\r
-        c_max = SKP_max_32( c_max, SKP_abs( ( opus_int32 )c[ i ] ) );\r
-    }\r
-    Qxtra = SKP_min_int( Qxtra, silk_CLZ32( c_max ) - 17 );\r
-\r
-    w_max = SKP_max_32( wXX[ 0 ], wXX[ D * D - 1 ] );\r
-    Qxtra = SKP_min_int( Qxtra, silk_CLZ32( SKP_MUL( D, SKP_RSHIFT( SKP_SMULWB( w_max, c_max ), 4 ) ) ) - 5 );\r
-    Qxtra = SKP_max_int( Qxtra, 0 );\r
-    for( i = 0; i < D; i++ ) {\r
-        cn[ i ] = SKP_LSHIFT( ( opus_int )c[ i ], Qxtra );\r
-        SKP_assert( SKP_abs(cn[i]) <= ( SKP_int16_MAX + 1 ) ); /* Check that SKP_SMLAWB can be used */\r
-    }\r
-    lshifts -= Qxtra;\r
-\r
-    /* Compute wxx - 2 * wXx * c */\r
-    tmp = 0;\r
-    for( i = 0; i < D; i++ ) {\r
-        tmp = SKP_SMLAWB( tmp, wXx[ i ], cn[ i ] );\r
-    }\r
-    nrg = SKP_RSHIFT( wxx, 1 + lshifts ) - tmp;                         /* Q: -lshifts - 1 */\r
-\r
-    /* Add c' * wXX * c, assuming wXX is symmetric */\r
-    tmp2 = 0;\r
-    for( i = 0; i < D; i++ ) {\r
-        tmp = 0;\r
-        pRow = &wXX[ i * D ];\r
-        for( j = i + 1; j < D; j++ ) {\r
-            tmp = SKP_SMLAWB( tmp, pRow[ j ], cn[ j ] );\r
-        }\r
-        tmp  = SKP_SMLAWB( tmp,  SKP_RSHIFT( pRow[ i ], 1 ), cn[ i ] );\r
-        tmp2 = SKP_SMLAWB( tmp2, tmp,                        cn[ i ] );\r
-    }\r
-    nrg = SKP_ADD_LSHIFT32( nrg, tmp2, lshifts );                       /* Q: -lshifts - 1 */\r
-\r
-    /* Keep one bit free always, because we add them for LSF interpolation */\r
-    if( nrg < 1 ) {\r
-        nrg = 1;\r
-    } else if( nrg > SKP_RSHIFT( SKP_int32_MAX, lshifts + 2 ) ) {\r
-        nrg = SKP_int32_MAX >> 1;\r
-    } else {\r
-        nrg = SKP_LSHIFT( nrg, lshifts + 1 );                           /* Q0 */\r
-    }\r
-    return nrg;\r
-\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+
+/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
+opus_int32 silk_residual_energy16_covar_FIX(
+    const opus_int16                 *c,                 /* I    Prediction vector                           */
+    const opus_int32                 *wXX,               /* I    Correlation matrix                          */
+    const opus_int32                 *wXx,               /* I    Correlation vector                          */
+    opus_int32                       wxx,                /* I    Signal energy                               */
+    opus_int                         D,                  /* I    Dimension                                   */
+    opus_int                         cQ                  /* I    Q value for c vector 0 - 15                 */
+)
+{
+    opus_int   i, j, lshifts, Qxtra;
+    opus_int32 c_max, w_max, tmp, tmp2, nrg;
+    opus_int   cn[ MAX_MATRIX_SIZE ];
+    const opus_int32 *pRow;
+
+    /* Safety checks */
+    SKP_assert( D >=  0 );
+    SKP_assert( D <= 16 );
+    SKP_assert( cQ >  0 );
+    SKP_assert( cQ < 16 );
+
+    lshifts = 16 - cQ;
+    Qxtra = lshifts;
+
+    c_max = 0;
+    for( i = 0; i < D; i++ ) {
+        c_max = SKP_max_32( c_max, SKP_abs( ( opus_int32 )c[ i ] ) );
+    }
+    Qxtra = SKP_min_int( Qxtra, silk_CLZ32( c_max ) - 17 );
+
+    w_max = SKP_max_32( wXX[ 0 ], wXX[ D * D - 1 ] );
+    Qxtra = SKP_min_int( Qxtra, silk_CLZ32( SKP_MUL( D, SKP_RSHIFT( SKP_SMULWB( w_max, c_max ), 4 ) ) ) - 5 );
+    Qxtra = SKP_max_int( Qxtra, 0 );
+    for( i = 0; i < D; i++ ) {
+        cn[ i ] = SKP_LSHIFT( ( opus_int )c[ i ], Qxtra );
+        SKP_assert( SKP_abs(cn[i]) <= ( SKP_int16_MAX + 1 ) ); /* Check that SKP_SMLAWB can be used */
+    }
+    lshifts -= Qxtra;
+
+    /* Compute wxx - 2 * wXx * c */
+    tmp = 0;
+    for( i = 0; i < D; i++ ) {
+        tmp = SKP_SMLAWB( tmp, wXx[ i ], cn[ i ] );
+    }
+    nrg = SKP_RSHIFT( wxx, 1 + lshifts ) - tmp;                         /* Q: -lshifts - 1 */
+
+    /* Add c' * wXX * c, assuming wXX is symmetric */
+    tmp2 = 0;
+    for( i = 0; i < D; i++ ) {
+        tmp = 0;
+        pRow = &wXX[ i * D ];
+        for( j = i + 1; j < D; j++ ) {
+            tmp = SKP_SMLAWB( tmp, pRow[ j ], cn[ j ] );
+        }
+        tmp  = SKP_SMLAWB( tmp,  SKP_RSHIFT( pRow[ i ], 1 ), cn[ i ] );
+        tmp2 = SKP_SMLAWB( tmp2, tmp,                        cn[ i ] );
+    }
+    nrg = SKP_ADD_LSHIFT32( nrg, tmp2, lshifts );                       /* Q: -lshifts - 1 */
+
+    /* Keep one bit free always, because we add them for LSF interpolation */
+    if( nrg < 1 ) {
+        nrg = 1;
+    } else if( nrg > SKP_RSHIFT( SKP_int32_MAX, lshifts + 2 ) ) {
+        nrg = SKP_int32_MAX >> 1;
+    } else {
+        nrg = SKP_LSHIFT( nrg, lshifts + 1 );                           /* Q0 */
+    }
+    return nrg;
+
+}
index e156b36..3342770 100644 (file)
@@ -1,87 +1,87 @@
-/***********************************************************************\r
-Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
-Redistribution and use in source and binary forms, with or without \r
-modification, (subject to the limitations in the disclaimer below) \r
-are permitted provided that the following conditions are met:\r
-- Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-- Redistributions in binary form must reproduce the above copyright \r
-notice, this list of conditions and the following disclaimer in the \r
-documentation and/or other materials provided with the distribution.\r
-- Neither the name of Skype Limited, nor the names of specific \r
-contributors, may be used to endorse or promote products derived from \r
-this software without specific prior written permission.\r
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-***********************************************************************/\r
-\r
-#include "silk_main_FIX.h"\r
-\r
-/* Calculates residual energies of input subframes where all subframes have LPC_order   */\r
-/* of preceeding samples                                                                */\r
-void silk_residual_energy_FIX(\r
-          opus_int32 nrgs[ MAX_NB_SUBFR ],           /* O    Residual energy per subframe    */\r
-          opus_int   nrgsQ[ MAX_NB_SUBFR ],          /* O    Q value per subframe            */\r
-    const opus_int16 x[],                            /* I    Input signal                    */\r
-          opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ],    /* I    AR coefs for each frame half    */\r
-    const opus_int32 gains[ MAX_NB_SUBFR ],          /* I    Quantization gains              */\r
-    const opus_int   subfr_length,                   /* I    Subframe length                 */\r
-    const opus_int   nb_subfr,                       /* I    Number of subframes             */\r
-    const opus_int   LPC_order                       /* I    LPC order                       */\r
-)\r
-{\r
-    opus_int         offset, i, j, rshift, lz1, lz2;\r
-    opus_int16       *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ];\r
-    const opus_int16 *x_ptr;\r
-    opus_int32       tmp32;\r
-\r
-    x_ptr  = x;\r
-    offset = LPC_order + subfr_length;\r
-    \r
-    /* Filter input to create the LPC residual for each frame half, and measure subframe energies */\r
-    for( i = 0; i < nb_subfr >> 1; i++ ) {\r
-        /* Calculate half frame LPC residual signal including preceeding samples */\r
-        silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order );\r
-\r
-        /* Point to first subframe of the just calculated LPC residual signal */\r
-        LPC_res_ptr = LPC_res + LPC_order;\r
-        for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) {\r
-            /* Measure subframe energy */\r
-            silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length ); \r
-            \r
-            /* Set Q values for the measured energy */\r
-            nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift;\r
-            \r
-            /* Move to next subframe */\r
-            LPC_res_ptr += offset;\r
-        }\r
-        /* Move to next frame half */\r
-        x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset;\r
-    }\r
-\r
-    /* Apply the squared subframe gains */\r
-    for( i = 0; i < nb_subfr; i++ ) {\r
-        /* Fully upscale gains and energies */\r
-        lz1 = silk_CLZ32( nrgs[  i ] ) - 1; \r
-        lz2 = silk_CLZ32( gains[ i ] ) - 1; \r
-        \r
-        tmp32 = SKP_LSHIFT32( gains[ i ], lz2 );\r
-\r
-        /* Find squared gains */\r
-        tmp32 = SKP_SMMUL( tmp32, tmp32 ); // Q( 2 * lz2 - 32 )\r
-\r
-        /* Scale energies */\r
-        nrgs[ i ] = SKP_SMMUL( tmp32, SKP_LSHIFT32( nrgs[ i ], lz1 ) ); // Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )\r
-        nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32;\r
-    }\r
-}\r
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#include "silk_main_FIX.h"
+
+/* Calculates residual energies of input subframes where all subframes have LPC_order   */
+/* of preceeding samples                                          &nbs