1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*********************************************************************** 2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgCopyright (c) 2006-2011, Skype Limited. All rights reserved. 3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgRedistribution and use in source and binary forms, with or without 4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgmodification, are permitted provided that the following conditions 5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgare met: 6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org- Redistributions of source code must retain the above copyright notice, 7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgthis list of conditions and the following disclaimer. 8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org- Redistributions in binary form must reproduce the above copyright 9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgnotice, this list of conditions and the following disclaimer in the 10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgdocumentation and/or other materials provided with the distribution. 11e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org- Neither the name of Internet Society, IETF or IETF Trust, nor the 12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgnames of specific contributors, may be used to endorse or promote 13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgproducts derived from this software without specific prior written 14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgpermission. 15e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgPOSSIBILITY OF SUCH DAMAGE. 26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org***********************************************************************/ 27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H 29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h" 30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "main_FLP.h" 33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Find LPC and LTP coefficients */ 35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid silk_find_pred_coefs_FLP( 36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ 37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ 38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const silk_float res_pitch[], /* I Residual from pitch analysis */ 39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const silk_float x[], /* I Speech signal */ 40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int condCoding /* I The type of conditional coding to use */ 41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org) 42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int i; 44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; 45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_float invGains[ MAX_NB_SUBFR ], Wght[ MAX_NB_SUBFR ]; 46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; 47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const silk_float *x_ptr; 48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; 49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_float minInvGain; 50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Weighting for weighted least squares */ 52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { 53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_assert( psEncCtrl->Gains[ i ] > 0.0f ); 54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ]; 55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Wght[ i ] = invGains[ i ] * invGains[ i ]; 56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { 59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /**********/ 60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* VOICED */ 61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /**********/ 62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); 63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* LTP analysis */ 65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_find_LTP_FLP( psEncCtrl->LTPCoef, WLTP, &psEncCtrl->LTPredCodGain, res_pitch, 66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org psEncCtrl->pitchL, Wght, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length ); 67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Quantize LTP gain parameters */ 69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, 703c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr ); 71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Control LTP scaling */ 73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding ); 74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Create LTP residual */ 76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_LTP_analysis_filter_FLP( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef, 77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); 78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /************/ 80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* UNVOICED */ 81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /************/ 82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Create signal with prepended subframes, scaled by inverse gains */ 83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_ptr = x - psEnc->sCmn.predictLPCOrder; 84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_pre_ptr = LPC_in_pre; 85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { 86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ], 87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); 88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; 89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_ptr += psEnc->sCmn.subfr_length; 90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) ); 92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org psEncCtrl->LTPredCodGain = 0.0f; 933c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com psEnc->sCmn.sum_log_gain_Q7 = 0; 94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Limit on total predictive coding gain */ 97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if( psEnc->sCmn.first_frame_after_reset ) { 98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET; 99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org minInvGain = (silk_float)pow( 2, psEncCtrl->LTPredCodGain / 3 ) / MAX_PREDICTION_POWER_GAIN; 101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org minInvGain /= 0.25f + 0.75f * psEncCtrl->coding_quality; 102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ 105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_find_LPC_FLP( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain ); 106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Quantize LSFs */ 108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); 109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Calculate residual energy using quantized LPC coefficients */ 111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains, 112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); 113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Copy to prediction struct for use in next frame for interpolation */ 115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); 116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 118