Chris@69: /*********************************************************************** Chris@69: Copyright (c) 2006-2011, Skype Limited. All rights reserved. Chris@69: Redistribution and use in source and binary forms, with or without Chris@69: modification, are permitted provided that the following conditions Chris@69: are met: Chris@69: - Redistributions of source code must retain the above copyright notice, Chris@69: this list of conditions and the following disclaimer. Chris@69: - Redistributions in binary form must reproduce the above copyright Chris@69: notice, this list of conditions and the following disclaimer in the Chris@69: documentation and/or other materials provided with the distribution. Chris@69: - Neither the name of Internet Society, IETF or IETF Trust, nor the Chris@69: names of specific contributors, may be used to endorse or promote Chris@69: products derived from this software without specific prior written Chris@69: permission. Chris@69: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" Chris@69: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE Chris@69: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE Chris@69: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE Chris@69: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR Chris@69: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF Chris@69: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS Chris@69: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN Chris@69: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) Chris@69: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE Chris@69: POSSIBILITY OF SUCH DAMAGE. Chris@69: ***********************************************************************/ Chris@69: Chris@69: #ifdef HAVE_CONFIG_H Chris@69: #include "config.h" Chris@69: #endif Chris@69: Chris@69: #include "SigProc_FIX.h" Chris@69: #include "SigProc_FLP.h" Chris@69: #include "define.h" Chris@69: Chris@69: /* compute inverse of LPC prediction gain, and */ Chris@69: /* test if LPC coefficients are stable (all poles within unit circle) */ Chris@69: /* this code is based on silk_a2k_FLP() */ Chris@69: silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */ Chris@69: const silk_float *A, /* I prediction coefficients [order] */ Chris@69: opus_int32 order /* I prediction order */ Chris@69: ) Chris@69: { Chris@69: opus_int k, n; Chris@69: double invGain, rc, rc_mult1, rc_mult2, tmp1, tmp2; Chris@69: silk_float Atmp[ SILK_MAX_ORDER_LPC ]; Chris@69: Chris@69: silk_memcpy( Atmp, A, order * sizeof(silk_float) ); Chris@69: Chris@69: invGain = 1.0; Chris@69: for( k = order - 1; k > 0; k-- ) { Chris@69: rc = -Atmp[ k ]; Chris@69: rc_mult1 = 1.0f - rc * rc; Chris@69: invGain *= rc_mult1; Chris@69: if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) { Chris@69: return 0.0f; Chris@69: } Chris@69: rc_mult2 = 1.0f / rc_mult1; Chris@69: for( n = 0; n < (k + 1) >> 1; n++ ) { Chris@69: tmp1 = Atmp[ n ]; Chris@69: tmp2 = Atmp[ k - n - 1 ]; Chris@69: Atmp[ n ] = (silk_float)( ( tmp1 - tmp2 * rc ) * rc_mult2 ); Chris@69: Atmp[ k - n - 1 ] = (silk_float)( ( tmp2 - tmp1 * rc ) * rc_mult2 ); Chris@69: } Chris@69: } Chris@69: rc = -Atmp[ 0 ]; Chris@69: rc_mult1 = 1.0f - rc * rc; Chris@69: invGain *= rc_mult1; Chris@69: if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) { Chris@69: return 0.0f; Chris@69: } Chris@69: return (silk_float)invGain; Chris@69: }