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: Chris@69: /* Compute number of bits to right shift the sum of squares of a vector */ Chris@69: /* of int16s to make it fit in an int32 */ Chris@69: void silk_sum_sqr_shift( Chris@69: opus_int32 *energy, /* O Energy of x, after shifting to the right */ Chris@69: opus_int *shift, /* O Number of bits right shift applied to energy */ Chris@69: const opus_int16 *x, /* I Input vector */ Chris@69: opus_int len /* I Length of input vector */ Chris@69: ) Chris@69: { Chris@69: opus_int i, shft; Chris@69: opus_uint32 nrg_tmp; Chris@69: opus_int32 nrg; Chris@69: Chris@69: /* Do a first run with the maximum shift we could have. */ Chris@69: shft = 31-silk_CLZ32(len); Chris@69: /* Let's be conservative with rounding and start with nrg=len. */ Chris@69: nrg = len; Chris@69: for( i = 0; i < len - 1; i += 2 ) { Chris@69: nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); Chris@69: nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); Chris@69: nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); Chris@69: } Chris@69: if( i < len ) { Chris@69: /* One sample left to process */ Chris@69: nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); Chris@69: nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); Chris@69: } Chris@69: silk_assert( nrg >= 0 ); Chris@69: /* Make sure the result will fit in a 32-bit signed integer with two bits Chris@69: of headroom. */ Chris@69: shft = silk_max_32(0, shft+3 - silk_CLZ32(nrg)); Chris@69: nrg = 0; Chris@69: for( i = 0 ; i < len - 1; i += 2 ) { Chris@69: nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); Chris@69: nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); Chris@69: nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); Chris@69: } Chris@69: if( i < len ) { Chris@69: /* One sample left to process */ Chris@69: nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); Chris@69: nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); Chris@69: } Chris@69: Chris@69: silk_assert( nrg >= 0 ); Chris@69: Chris@69: /* Output arguments */ Chris@69: *shift = shft; Chris@69: *energy = nrg; Chris@69: } Chris@69: