ref: a355d74efb9aa0b490e0b39fd587a1f996069392
parent: 3195f6cdb985b2818683a30bdd5298895694bd2d
author: Gregory Maxwell <[email protected]>
date: Mon Oct 10 09:59:30 EDT 2011
Move a number of files and functions which are only used by fixed point builds from silk/ to silk/fixed/. I attempted to not break the msvc projects, but I can't test them.
--- a/silk/apply_sine_window.c
+++ /dev/null
@@ -1,101 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-/* Apply sine window to signal vector. */
-/* Window types: */
-/* 1 -> sine window from 0 to pi/2 */
-/* 2 -> sine window from pi/2 to pi */
-/* Every other sample is linearly interpolated, for speed. */
-/* Window length must be between 16 and 120 (incl) and a multiple of 4. */
-
-/* Matlab code for table:
- for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end
-*/
-static opus_int16 freq_table_Q16[ 27 ] = {
- 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202,
- 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422,
- 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702,
-};
-
-void silk_apply_sine_window(
- opus_int16 px_win[], /* O Pointer to windowed signal */
- const opus_int16 px[], /* I Pointer to input signal */
- const opus_int win_type, /* I Selects a window type */
- const opus_int length /* I Window length, multiple of 4 */
-)
-{
- opus_int k, f_Q16, c_Q16;
- opus_int32 S0_Q16, S1_Q16;
-
- silk_assert( win_type == 1 || win_type == 2 );
-
- /* Length must be in a range from 16 to 120 and a multiple of 4 */
- silk_assert( length >= 16 && length <= 120 );
- silk_assert( ( length & 3 ) == 0 );
-
- /* Frequency */
- k = ( length >> 2 ) - 4;
- silk_assert( k >= 0 && k <= 26 );
- f_Q16 = (opus_int)freq_table_Q16[ k ];
-
- /* Factor used for cosine approximation */
- c_Q16 = silk_SMULWB( f_Q16, -f_Q16 );
- silk_assert( c_Q16 >= -32768 );
-
- /* initialize state */
- if( win_type == 1 ) {
- /* start from 0 */
- S0_Q16 = 0;
- /* approximation of sin(f) */
- S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 );
- } else {
- /* start from 1 */
- S0_Q16 = ( 1 << 16 );
- /* approximation of cos(f) */
- S1_Q16 = ( 1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 );
- }
-
- /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
- /* 4 samples at a time */
- for( k = 0; k < length; k += 4 ) {
- px_win[ k ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] );
- px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] );
- S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;
- S0_Q16 = silk_min( S0_Q16, ( 1 << 16 ) );
-
- px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] );
- px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] );
- S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16;
- S1_Q16 = silk_min( S1_Q16, ( 1 << 16 ) );
- }
-}
--- a/silk/array_maxabs.c
+++ /dev/null
@@ -1,64 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-/* Function that returns the maximum absolut value of the input vector */
-opus_int16 silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */
- const opus_int16 *vec, /* I Input vector [len] */
- const opus_int32 len /* I Length of input vector */
-)
-{
- opus_int32 max = 0, i, lvl = 0, ind;
- if( len == 0 ) return 0;
-
- ind = len - 1;
- max = silk_SMULBB( vec[ ind ], vec[ ind ] );
- for( i = len - 2; i >= 0; i-- ) {
- lvl = silk_SMULBB( vec[ i ], vec[ i ] );
- if( lvl > max ) {
- max = lvl;
- ind = i;
- }
- }
-
- /* Do not return 32768, as it will not fit in an int16 so may lead to problems later on */
- if( max >= 1073676289 ) { /* (2^15-1)^2 = 1073676289*/
- return( silk_int16_MAX );
- } else {
- if( vec[ ind ] < 0 ) {
- return( -vec[ ind ] );
- } else {
- return( vec[ ind ] );
- }
- }
-}
-
--- a/silk/autocorr.c
+++ /dev/null
@@ -1,76 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-/* Compute autocorrelation */
-void silk_autocorr(
- opus_int32 *results, /* O Result (length correlationCount) */
- opus_int *scale, /* O Scaling of the correlation vector */
- const opus_int16 *inputData, /* I Input data to correlate */
- const opus_int inputDataSize, /* I Length of input */
- const opus_int correlationCount /* I Number of correlation taps to compute */
-)
-{
- opus_int i, lz, nRightShifts, corrCount;
- opus_int64 corr64;
-
- corrCount = silk_min_int( inputDataSize, correlationCount );
-
- /* compute energy (zero-lag correlation) */
- corr64 = silk_inner_prod16_aligned_64( inputData, inputData, inputDataSize );
-
- /* deal with all-zero input data */
- corr64 += 1;
-
- /* number of leading zeros */
- lz = silk_CLZ64( corr64 );
-
- /* scaling: number of right shifts applied to correlations */
- nRightShifts = 35 - lz;
- *scale = nRightShifts;
-
- if( nRightShifts <= 0 ) {
- results[ 0 ] = silk_LSHIFT( (opus_int32)silk_CHECK_FIT32( corr64 ), -nRightShifts );
-
- /* compute remaining correlations based on int32 inner product */
- for( i = 1; i < corrCount; i++ ) {
- results[ i ] = silk_LSHIFT( silk_inner_prod_aligned( inputData, inputData + i, inputDataSize - i ), -nRightShifts );
- }
- } else {
- results[ 0 ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr64, nRightShifts ) );
-
- /* compute remaining correlations based on int64 inner product */
- for( i = 1; i < corrCount; i++ ) {
- results[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_inner_prod16_aligned_64( inputData, inputData + i, inputDataSize - i ), nRightShifts ) );
- }
- }
-}
--- a/silk/burg_modified.c
+++ /dev/null
@@ -1,222 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/
-#define MAX_NB_SUBFR 4
-
-#define QA 25
-#define N_BITS_HEAD_ROOM 2
-#define MIN_RSHIFTS -16
-#define MAX_RSHIFTS (32 - QA)
-
-/* Compute reflection coefficients from input signal */
-void silk_burg_modified(
- opus_int32 *res_nrg, /* O residual energy */
- opus_int *res_nrg_Q, /* O residual energy Q value */
- opus_int32 A_Q16[], /* O prediction coefficients (length order) */
- const opus_int16 x[], /* I input signal, length: nb_subfr * ( D + subfr_length ) */
- const opus_int subfr_length, /* I input signal subframe length (including D preceeding samples) */
- const opus_int nb_subfr, /* I number of subframes stacked in x */
- const opus_int32 WhiteNoiseFrac_Q32, /* I fraction added to zero-lag autocorrelation */
- const opus_int D /* I order */
-)
-{
- opus_int k, n, s, lz, rshifts, rshifts_extra;
- opus_int32 C0, num, nrg, rc_Q31, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
- const opus_int16 *x_ptr;
-
- opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
- opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
- opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
-
- opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
- opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
-
- silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
- silk_assert( nb_subfr <= MAX_NB_SUBFR );
-
-
- /* Compute autocorrelations, added over subframes */
- silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
- if( rshifts > MAX_RSHIFTS ) {
- C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS );
- silk_assert( C0 > 0 );
- rshifts = MAX_RSHIFTS;
- } else {
- lz = silk_CLZ32( C0 ) - 1;
- rshifts_extra = N_BITS_HEAD_ROOM - lz;
- if( rshifts_extra > 0 ) {
- rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts );
- C0 = silk_RSHIFT32( C0, rshifts_extra );
- } else {
- rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts );
- C0 = silk_LSHIFT32( C0, -rshifts_extra );
- }
- rshifts += rshifts_extra;
- }
- silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
- if( rshifts > 0 ) {
- for( s = 0; s < nb_subfr; s++ ) {
- x_ptr = x + s * subfr_length;
- for( n = 1; n < D + 1; n++ ) {
- C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(
- silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n ), rshifts );
- }
- }
- } else {
- for( s = 0; s < nb_subfr; s++ ) {
- x_ptr = x + s * subfr_length;
- for( n = 1; n < D + 1; n++ ) {
- C_first_row[ n - 1 ] += silk_LSHIFT32(
- silk_inner_prod_aligned( x_ptr, x_ptr + n, subfr_length - n ), -rshifts );
- }
- }
- }
- silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
-
- /* Initialize */
- CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( WhiteNoiseFrac_Q32, C0 ) + 1; /* Q(-rshifts)*/
-
- for( n = 0; n < D; n++ ) {
- /* Update first row of correlation matrix (without first element) */
- /* Update last row of correlation matrix (without last element, stored in reversed order) */
- /* Update C * Af */
- /* Update C * flipud(Af) (stored in reversed order) */
- if( rshifts > -2 ) {
- for( s = 0; s < nb_subfr; s++ ) {
- x_ptr = x + s * subfr_length;
- x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts)*/
- x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts)*/
- tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16)*/
- tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16)*/
- for( k = 0; k < n; k++ ) {
- C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts )*/
- C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts )*/
- Atmp_QA = Af_QA[ k ];
- tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16)*/
- tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16)*/
- }
- tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts)*/
- tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts)*/
- for( k = 0; k <= n; k++ ) {
- CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift )*/
- CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift )*/
- }
- }
- } else {
- for( s = 0; s < nb_subfr; s++ ) {
- x_ptr = x + s * subfr_length;
- x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts )*/
- x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts )*/
- tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17*/
- tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17*/
- for( k = 0; k < n; k++ ) {
- C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts )*/
- C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts )*/
- Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17*/
- tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17*/
- tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17*/
- }
- tmp1 = -tmp1; /* Q17*/
- tmp2 = -tmp2; /* Q17*/
- for( k = 0; k <= n; k++ ) {
- CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,
- silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift )*/
- CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,
- silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) );/* Q( -rshift )*/
- }
- }
- }
-
- /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
- tmp1 = C_first_row[ n ]; /* Q( -rshifts )*/
- tmp2 = C_last_row[ n ]; /* Q( -rshifts )*/
- num = 0; /* Q( -rshifts )*/
- nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts )*/
- for( k = 0; k < n; k++ ) {
- Atmp_QA = Af_QA[ k ];
- lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;
- lz = silk_min( 32 - QA, lz );
- Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz )*/
-
- tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts )*/
- tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts )*/
- num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts )*/
- nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
- Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts )*/
- }
- CAf[ n + 1 ] = tmp1; /* Q( -rshifts )*/
- CAb[ n + 1 ] = tmp2; /* Q( -rshifts )*/
- num = silk_ADD32( num, tmp2 ); /* Q( -rshifts )*/
- num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts )*/
-
- /* Calculate the next order reflection (parcor) coefficient */
- if( silk_abs( num ) < nrg ) {
- rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );
- } else {
- /* Negative energy or ratio too high; set remaining coefficients to zero and exit loop */
- silk_memset( &Af_QA[ n ], 0, ( D - n ) * sizeof( opus_int32 ) );
- silk_assert( 0 );
- break;
- }
-
- /* Update the AR coefficients */
- for( k = 0; k < (n + 1) >> 1; k++ ) {
- tmp1 = Af_QA[ k ]; /* QA*/
- tmp2 = Af_QA[ n - k - 1 ]; /* QA*/
- Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA*/
- Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA*/
- }
- Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA*/
-
- /* Update C * Af and C * Ab */
- for( k = 0; k <= n + 1; k++ ) {
- tmp1 = CAf[ k ]; /* Q( -rshifts )*/
- tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts )*/
- CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts )*/
- CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts )*/
- }
- }
-
- /* Return residual energy */
- nrg = CAf[ 0 ]; /* Q( -rshifts )*/
- tmp1 = 1 << 16; /* Q16*/
- for( k = 0; k < D; k++ ) {
- Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16*/
- nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts )*/
- tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16*/
- A_Q16[ k ] = -Atmp1;
- }
- *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( WhiteNoiseFrac_Q32, C0 ), -tmp1 ); /* Q( -rshifts )*/
- *res_nrg_Q = -rshifts;
-}
--- /dev/null
+++ b/silk/fixed/apply_sine_window_FIX.c
@@ -1,0 +1,101 @@
+/***********************************************************************
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SigProc_FIX.h"
+
+/* Apply sine window to signal vector. */
+/* Window types: */
+/* 1 -> sine window from 0 to pi/2 */
+/* 2 -> sine window from pi/2 to pi */
+/* Every other sample is linearly interpolated, for speed. */
+/* Window length must be between 16 and 120 (incl) and a multiple of 4. */
+
+/* Matlab code for table:
+ for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end
+*/
+static opus_int16 freq_table_Q16[ 27 ] = {
+ 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202,
+ 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422,
+ 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702,
+};
+
+void silk_apply_sine_window(
+ opus_int16 px_win[], /* O Pointer to windowed signal */
+ const opus_int16 px[], /* I Pointer to input signal */
+ const opus_int win_type, /* I Selects a window type */
+ const opus_int length /* I Window length, multiple of 4 */
+)
+{
+ opus_int k, f_Q16, c_Q16;
+ opus_int32 S0_Q16, S1_Q16;
+
+ silk_assert( win_type == 1 || win_type == 2 );
+
+ /* Length must be in a range from 16 to 120 and a multiple of 4 */
+ silk_assert( length >= 16 && length <= 120 );
+ silk_assert( ( length & 3 ) == 0 );
+
+ /* Frequency */
+ k = ( length >> 2 ) - 4;
+ silk_assert( k >= 0 && k <= 26 );
+ f_Q16 = (opus_int)freq_table_Q16[ k ];
+
+ /* Factor used for cosine approximation */
+ c_Q16 = silk_SMULWB( f_Q16, -f_Q16 );
+ silk_assert( c_Q16 >= -32768 );
+
+ /* initialize state */
+ if( win_type == 1 ) {
+ /* start from 0 */
+ S0_Q16 = 0;
+ /* approximation of sin(f) */
+ S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 );
+ } else {
+ /* start from 1 */
+ S0_Q16 = ( 1 << 16 );
+ /* approximation of cos(f) */
+ S1_Q16 = ( 1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 );
+ }
+
+ /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
+ /* 4 samples at a time */
+ for( k = 0; k < length; k += 4 ) {
+ px_win[ k ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] );
+ px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] );
+ S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;
+ S0_Q16 = silk_min( S0_Q16, ( 1 << 16 ) );
+
+ px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] );
+ px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] );
+ S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16;
+ S1_Q16 = silk_min( S1_Q16, ( 1 << 16 ) );
+ }
+}
--- /dev/null
+++ b/silk/fixed/autocorr_FIX.c
@@ -1,0 +1,76 @@
+/***********************************************************************
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SigProc_FIX.h"
+
+/* Compute autocorrelation */
+void silk_autocorr(
+ opus_int32 *results, /* O Result (length correlationCount) */
+ opus_int *scale, /* O Scaling of the correlation vector */
+ const opus_int16 *inputData, /* I Input data to correlate */
+ const opus_int inputDataSize, /* I Length of input */
+ const opus_int correlationCount /* I Number of correlation taps to compute */
+)
+{
+ opus_int i, lz, nRightShifts, corrCount;
+ opus_int64 corr64;
+
+ corrCount = silk_min_int( inputDataSize, correlationCount );
+
+ /* compute energy (zero-lag correlation) */
+ corr64 = silk_inner_prod16_aligned_64( inputData, inputData, inputDataSize );
+
+ /* deal with all-zero input data */
+ corr64 += 1;
+
+ /* number of leading zeros */
+ lz = silk_CLZ64( corr64 );
+
+ /* scaling: number of right shifts applied to correlations */
+ nRightShifts = 35 - lz;
+ *scale = nRightShifts;
+
+ if( nRightShifts <= 0 ) {
+ results[ 0 ] = silk_LSHIFT( (opus_int32)silk_CHECK_FIT32( corr64 ), -nRightShifts );
+
+ /* compute remaining correlations based on int32 inner product */
+ for( i = 1; i < corrCount; i++ ) {
+ results[ i ] = silk_LSHIFT( silk_inner_prod_aligned( inputData, inputData + i, inputDataSize - i ), -nRightShifts );
+ }
+ } else {
+ results[ 0 ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr64, nRightShifts ) );
+
+ /* compute remaining correlations based on int64 inner product */
+ for( i = 1; i < corrCount; i++ ) {
+ results[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_inner_prod16_aligned_64( inputData, inputData + i, inputDataSize - i ), nRightShifts ) );
+ }
+ }
+}
--- /dev/null
+++ b/silk/fixed/burg_modified_FIX.c
@@ -1,0 +1,222 @@
+/***********************************************************************
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SigProc_FIX.h"
+
+#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/
+#define MAX_NB_SUBFR 4
+
+#define QA 25
+#define N_BITS_HEAD_ROOM 2
+#define MIN_RSHIFTS -16
+#define MAX_RSHIFTS (32 - QA)
+
+/* Compute reflection coefficients from input signal */
+void silk_burg_modified(
+ opus_int32 *res_nrg, /* O residual energy */
+ opus_int *res_nrg_Q, /* O residual energy Q value */
+ opus_int32 A_Q16[], /* O prediction coefficients (length order) */
+ const opus_int16 x[], /* I input signal, length: nb_subfr * ( D + subfr_length ) */
+ const opus_int subfr_length, /* I input signal subframe length (including D preceeding samples) */
+ const opus_int nb_subfr, /* I number of subframes stacked in x */
+ const opus_int32 WhiteNoiseFrac_Q32, /* I fraction added to zero-lag autocorrelation */
+ const opus_int D /* I order */
+)
+{
+ opus_int k, n, s, lz, rshifts, rshifts_extra;
+ opus_int32 C0, num, nrg, rc_Q31, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
+ const opus_int16 *x_ptr;
+
+ opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
+ opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
+ opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
+
+ opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
+ opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
+
+ silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
+ silk_assert( nb_subfr <= MAX_NB_SUBFR );
+
+
+ /* Compute autocorrelations, added over subframes */
+ silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
+ if( rshifts > MAX_RSHIFTS ) {
+ C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS );
+ silk_assert( C0 > 0 );
+ rshifts = MAX_RSHIFTS;
+ } else {
+ lz = silk_CLZ32( C0 ) - 1;
+ rshifts_extra = N_BITS_HEAD_ROOM - lz;
+ if( rshifts_extra > 0 ) {
+ rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts );
+ C0 = silk_RSHIFT32( C0, rshifts_extra );
+ } else {
+ rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts );
+ C0 = silk_LSHIFT32( C0, -rshifts_extra );
+ }
+ rshifts += rshifts_extra;
+ }
+ silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
+ if( rshifts > 0 ) {
+ for( s = 0; s < nb_subfr; s++ ) {
+ x_ptr = x + s * subfr_length;
+ for( n = 1; n < D + 1; n++ ) {
+ C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(
+ silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n ), rshifts );
+ }
+ }
+ } else {
+ for( s = 0; s < nb_subfr; s++ ) {
+ x_ptr = x + s * subfr_length;
+ for( n = 1; n < D + 1; n++ ) {
+ C_first_row[ n - 1 ] += silk_LSHIFT32(
+ silk_inner_prod_aligned( x_ptr, x_ptr + n, subfr_length - n ), -rshifts );
+ }
+ }
+ }
+ silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
+
+ /* Initialize */
+ CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( WhiteNoiseFrac_Q32, C0 ) + 1; /* Q(-rshifts)*/
+
+ for( n = 0; n < D; n++ ) {
+ /* Update first row of correlation matrix (without first element) */
+ /* Update last row of correlation matrix (without last element, stored in reversed order) */
+ /* Update C * Af */
+ /* Update C * flipud(Af) (stored in reversed order) */
+ if( rshifts > -2 ) {
+ for( s = 0; s < nb_subfr; s++ ) {
+ x_ptr = x + s * subfr_length;
+ x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts)*/
+ x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts)*/
+ tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16)*/
+ tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16)*/
+ for( k = 0; k < n; k++ ) {
+ C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts )*/
+ C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts )*/
+ Atmp_QA = Af_QA[ k ];
+ tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16)*/
+ tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16)*/
+ }
+ tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts)*/
+ tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts)*/
+ for( k = 0; k <= n; k++ ) {
+ CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift )*/
+ CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift )*/
+ }
+ }
+ } else {
+ for( s = 0; s < nb_subfr; s++ ) {
+ x_ptr = x + s * subfr_length;
+ x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts )*/
+ x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts )*/
+ tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17*/
+ tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17*/
+ for( k = 0; k < n; k++ ) {
+ C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts )*/
+ C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts )*/
+ Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17*/
+ tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17*/
+ tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17*/
+ }
+ tmp1 = -tmp1; /* Q17*/
+ tmp2 = -tmp2; /* Q17*/
+ for( k = 0; k <= n; k++ ) {
+ CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,
+ silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift )*/
+ CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,
+ silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) );/* Q( -rshift )*/
+ }
+ }
+ }
+
+ /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
+ tmp1 = C_first_row[ n ]; /* Q( -rshifts )*/
+ tmp2 = C_last_row[ n ]; /* Q( -rshifts )*/
+ num = 0; /* Q( -rshifts )*/
+ nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts )*/
+ for( k = 0; k < n; k++ ) {
+ Atmp_QA = Af_QA[ k ];
+ lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;
+ lz = silk_min( 32 - QA, lz );
+ Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz )*/
+
+ tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts )*/
+ tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts )*/
+ num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts )*/
+ nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
+ Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts )*/
+ }
+ CAf[ n + 1 ] = tmp1; /* Q( -rshifts )*/
+ CAb[ n + 1 ] = tmp2; /* Q( -rshifts )*/
+ num = silk_ADD32( num, tmp2 ); /* Q( -rshifts )*/
+ num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts )*/
+
+ /* Calculate the next order reflection (parcor) coefficient */
+ if( silk_abs( num ) < nrg ) {
+ rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );
+ } else {
+ /* Negative energy or ratio too high; set remaining coefficients to zero and exit loop */
+ silk_memset( &Af_QA[ n ], 0, ( D - n ) * sizeof( opus_int32 ) );
+ silk_assert( 0 );
+ break;
+ }
+
+ /* Update the AR coefficients */
+ for( k = 0; k < (n + 1) >> 1; k++ ) {
+ tmp1 = Af_QA[ k ]; /* QA*/
+ tmp2 = Af_QA[ n - k - 1 ]; /* QA*/
+ Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA*/
+ Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA*/
+ }
+ Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA*/
+
+ /* Update C * Af and C * Ab */
+ for( k = 0; k <= n + 1; k++ ) {
+ tmp1 = CAf[ k ]; /* Q( -rshifts )*/
+ tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts )*/
+ CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts )*/
+ CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts )*/
+ }
+ }
+
+ /* Return residual energy */
+ nrg = CAf[ 0 ]; /* Q( -rshifts )*/
+ tmp1 = 1 << 16; /* Q16*/
+ for( k = 0; k < D; k++ ) {
+ Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16*/
+ nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts )*/
+ tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16*/
+ A_Q16[ k ] = -Atmp1;
+ }
+ *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( WhiteNoiseFrac_Q32, C0 ), -tmp1 ); /* Q( -rshifts )*/
+ *res_nrg_Q = -rshifts;
+}
--- /dev/null
+++ b/silk/fixed/k2a_FIX.c
@@ -1,0 +1,53 @@
+/***********************************************************************
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SigProc_FIX.h"
+
+/* Step up function, converts reflection coefficients to prediction coefficients */
+void silk_k2a(
+ opus_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
+ const opus_int16 *rc_Q15, /* I: Reflection coefficients [order] Q15 */
+ const opus_int32 order /* I: Prediction order */
+)
+{
+ opus_int k, n;
+ opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
+
+ for( k = 0; k < order; k++ ) {
+ for( n = 0; n < k; n++ ) {
+ Atmp[ n ] = A_Q24[ n ];
+ }
+ for( n = 0; n < k; n++ ) {
+ A_Q24[ n ] = silk_SMLAWB( A_Q24[ n ], silk_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] );
+ }
+ A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 );
+ }
+}
--- /dev/null
+++ b/silk/fixed/k2a_Q16_FIX.c
@@ -1,0 +1,53 @@
+/***********************************************************************
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SigProc_FIX.h"
+
+/* Step up function, converts reflection coefficients to prediction coefficients */
+void silk_k2a_Q16(
+ opus_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
+ const opus_int32 *rc_Q16, /* I: Reflection coefficients [order] Q16 */
+ const opus_int32 order /* I: Prediction order */
+)
+{
+ opus_int k, n;
+ opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
+
+ for( k = 0; k < order; k++ ) {
+ for( n = 0; n < k; n++ ) {
+ Atmp[ n ] = A_Q24[ n ];
+ }
+ for( n = 0; n < k; n++ ) {
+ A_Q24[ n ] = silk_SMLAWW( A_Q24[ n ], Atmp[ k - n - 1 ], rc_Q16[ k ] );
+ }
+ A_Q24[ k ] = -silk_LSHIFT( rc_Q16[ k ], 8 );
+ }
+}
--- /dev/null
+++ b/silk/fixed/pitch_analysis_core_FIX.c
@@ -1,0 +1,748 @@
+/***********************************************************************
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/***********************************************************
+* Pitch analyser function
+********************************************************** */
+#include "SigProc_FIX.h"
+#include "pitch_est_defines.h"
+#include "debug.h"
+
+#define SCRATCH_SIZE 22
+
+/************************************************************/
+/* Internally used functions */
+/************************************************************/
+void silk_P_Ana_calc_corr_st3(
+ opus_int32 cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM correlation array */
+ const opus_int16 frame[], /* I vector to correlate */
+ opus_int start_lag, /* I lag offset to search around */
+ opus_int sf_length, /* I length of a 5 ms subframe */
+ opus_int nb_subfr, /* I number of subframes */
+ opus_int complexity /* I Complexity setting */
+);
+
+void silk_P_Ana_calc_energy_st3(
+ opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM energy array */
+ const opus_int16 frame[], /* I vector to calc energy in */
+ opus_int start_lag, /* I lag offset to search around */
+ opus_int sf_length, /* I length of one 5 ms subframe */
+ opus_int nb_subfr, /* I number of subframes */
+ opus_int complexity /* I Complexity setting */
+);
+
+opus_int32 silk_P_Ana_find_scaling(
+ const opus_int16 *frame,
+ const opus_int frame_length,
+ const opus_int sum_sqr_len
+);
+
+/*************************************************************/
+/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */
+/*************************************************************/
+opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
+ const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
+ opus_int *pitch_out, /* O 4 pitch lag values */
+ opus_int16 *lagIndex, /* O Lag Index */
+ opus_int8 *contourIndex, /* O Pitch contour Index */
+ opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */
+ opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
+ const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */
+ const opus_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */
+ const opus_int Fs_kHz, /* I Sample frequency (kHz) */
+ const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
+ const opus_int nb_subfr /* I number of 5 ms subframes */
+)
+{
+ opus_int16 frame_8kHz[ PE_MAX_FRAME_LENGTH_ST_2 ];
+ opus_int16 frame_4kHz[ PE_MAX_FRAME_LENGTH_ST_1 ];
+ opus_int32 filt_state[ 6 ];
+ opus_int32 scratch_mem[ 3 * PE_MAX_FRAME_LENGTH ];
+ opus_int16 *input_frame_ptr;
+ opus_int i, k, d, j;
+ opus_int16 C[ PE_MAX_NB_SUBFR ][ ( PE_MAX_LAG >> 1 ) + 5 ];
+ const opus_int16 *target_ptr, *basis_ptr;
+ opus_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target;
+ opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp;
+ opus_int16 d_comp[ ( PE_MAX_LAG >> 1 ) + 5 ];
+ opus_int32 sum, threshold, temp32, lag_counter;
+ opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new;
+ opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new;
+ opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
+ opus_int32 crosscorr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
+ opus_int frame_length, frame_length_8kHz, frame_length_4kHz, max_sum_sq_length;
+ opus_int sf_length, sf_length_8kHz, sf_length_4kHz;
+ opus_int min_lag, min_lag_8kHz, min_lag_4kHz;
+ opus_int max_lag, max_lag_8kHz, max_lag_4kHz;
+ opus_int32 contour_bias_Q20, diff, lz, lshift;
+ opus_int nb_cbk_search, cbk_size;
+ opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q15, corr_thres_Q15;
+ const opus_int8 *Lag_CB_ptr;
+ /* Check for valid sampling frequency */
+ silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
+
+ /* Check for valid complexity setting */
+ silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
+ silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
+
+ silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
+ silk_assert( search_thres2_Q15 >= 0 && search_thres2_Q15 <= (1<<15) );
+
+ /* Setup frame lengths max / min lag for the sampling frequency */
+ frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
+ frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
+ frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
+ sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz;
+ sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4;
+ sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8;
+ min_lag = PE_MIN_LAG_MS * Fs_kHz;
+ min_lag_4kHz = PE_MIN_LAG_MS * 4;
+ min_lag_8kHz = PE_MIN_LAG_MS * 8;
+ max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
+ max_lag_4kHz = PE_MAX_LAG_MS * 4;
+ max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1;
+
+ silk_memset( C, 0, sizeof( opus_int16 ) * nb_subfr * ( ( PE_MAX_LAG >> 1 ) + 5) );
+
+ /* Resample from input sampled at Fs_kHz to 8 kHz */
+ if( Fs_kHz == 16 ) {
+ silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
+ silk_resampler_down2( filt_state, frame_8kHz, frame, frame_length );
+ } else if ( Fs_kHz == 12 ) {
+ silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
+ silk_resampler_down2_3( filt_state, frame_8kHz, frame, frame_length );
+ } else {
+ silk_assert( Fs_kHz == 8 );
+ silk_memcpy( frame_8kHz, frame, frame_length_8kHz * sizeof(opus_int16) );
+ }
+
+ /* Decimate again to 4 kHz */
+ silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */
+ silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz );
+
+ /* Low-pass filter */
+ for( i = frame_length_4kHz - 1; i > 0; i-- ) {
+ frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
+ }
+
+ /*******************************************************************************
+ ** Scale 4 kHz signal down to prevent correlations measures from overflowing
+ ** find scaling as max scaling for each 8kHz(?) subframe
+ *******************************************************************************/
+
+ /* Inner product is calculated with different lengths, so scale for the worst case */
+ max_sum_sq_length = silk_max_32( sf_length_8kHz, silk_LSHIFT( sf_length_4kHz, 2 ) );
+ shift = silk_P_Ana_find_scaling( frame_4kHz, frame_length_4kHz, max_sum_sq_length );
+ if( shift > 0 ) {
+ for( i = 0; i < frame_length_4kHz; i++ ) {
+ frame_4kHz[ i ] = silk_RSHIFT( frame_4kHz[ i ], shift );
+ }
+ }
+
+ /******************************************************************************
+ * FIRST STAGE, operating in 4 khz
+ ******************************************************************************/
+ target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ];
+ for( k = 0; k < nb_subfr >> 1; k++ ) {
+ /* Check that we are within range of the array */
+ silk_assert( target_ptr >= frame_4kHz );
+ silk_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
+
+ basis_ptr = target_ptr - min_lag_4kHz;
+
+ /* Check that we are within range of the array */
+ silk_assert( basis_ptr >= frame_4kHz );
+ silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
+
+ /* Calculate first vector products before loop */
+ cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
+ normalizer = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz );
+ normalizer = silk_ADD_SAT32( normalizer, silk_SMULBB( sf_length_8kHz, 4000 ) );
+
+ temp32 = silk_DIV32( cross_corr, silk_SQRT_APPROX( normalizer ) + 1 );
+ C[ k ][ min_lag_4kHz ] = (opus_int16)silk_SAT16( temp32 ); /* Q0 */
+
+ /* From now on normalizer is computed recursively */
+ for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) {
+ basis_ptr--;
+
+ /* Check that we are within range of the array */
+ silk_assert( basis_ptr >= frame_4kHz );
+ silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
+
+ cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
+
+ /* Add contribution of new sample and remove contribution from oldest sample */
+ normalizer +=
+ silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) -
+ silk_SMULBB( basis_ptr[ sf_length_8kHz ], basis_ptr[ sf_length_8kHz ] );
+
+ temp32 = silk_DIV32( cross_corr, silk_SQRT_APPROX( normalizer ) + 1 );
+ C[ k ][ d ] = (opus_int16)silk_SAT16( temp32 ); /* Q0 */
+ }
+ /* Update target pointer */
+ target_ptr += sf_length_8kHz;
+ }
+
+ /* Combine two subframes into single correlation measure and apply short-lag bias */
+ if( nb_subfr == PE_MAX_NB_SUBFR ) {
+ for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
+ sum = (opus_int32)C[ 0 ][ i ] + (opus_int32)C[ 1 ][ i ]; /* Q0 */
+ silk_assert( silk_RSHIFT( sum, 1 ) == silk_SAT16( silk_RSHIFT( sum, 1 ) ) );
+ sum = silk_RSHIFT( sum, 1 ); /* Q-1 */
+ silk_assert( silk_LSHIFT( (opus_int32)-i, 4 ) == silk_SAT16( silk_LSHIFT( (opus_int32)-i, 4 ) ) );
+ sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q-1 */
+ silk_assert( sum == silk_SAT16( sum ) );
+ C[ 0 ][ i ] = (opus_int16)sum; /* Q-1 */
+ }
+ } else {
+ /* Only short-lag bias */
+ for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
+ sum = (opus_int32)C[ 0 ][ i ];
+ sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q-1 */
+ C[ 0 ][ i ] = (opus_int16)sum; /* Q-1 */
+ }
+ }
+
+ /* Sort */
+ length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 );
+ silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
+ silk_insertion_sort_decreasing_int16( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
+
+ /* Escape if correlation is very low already here */
+ target_ptr = &frame_4kHz[ silk_SMULBB( sf_length_4kHz, nb_subfr ) ];
+ energy = silk_inner_prod_aligned( target_ptr, target_ptr, silk_LSHIFT( sf_length_4kHz, 2 ) );
+ energy = silk_ADD_SAT32( energy, 1000 ); /* Q0 */
+ Cmax = (opus_int)C[ 0 ][ min_lag_4kHz ]; /* Q-1 */
+ threshold = silk_SMULBB( Cmax, Cmax ); /* Q-2 */
+
+ /* Compare in Q-2 domain */
+ if( silk_RSHIFT( energy, 4 + 2 ) > threshold ) {
+ silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
+ *LTPCorr_Q15 = 0;
+ *lagIndex = 0;
+ *contourIndex = 0;
+ return 1;
+ }
+
+ threshold = silk_SMULWB( search_thres1_Q16, Cmax );
+ for( i = 0; i < length_d_srch; i++ ) {
+ /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
+ if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) {
+ d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 );
+ } else {
+ length_d_srch = i;
+ break;
+ }
+ }
+ silk_assert( length_d_srch > 0 );
+
+ for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
+ d_comp[ i ] = 0;
+ }
+ for( i = 0; i < length_d_srch; i++ ) {
+ d_comp[ d_srch[ i ] ] = 1;
+ }
+
+ /* Convolution */
+ for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
+ d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ];
+ }
+
+ length_d_srch = 0;
+ for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) {
+ if( d_comp[ i + 1 ] > 0 ) {
+ d_srch[ length_d_srch ] = i;
+ length_d_srch++;
+ }
+ }
+
+ /* Convolution */
+ for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
+ d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ];
+ }
+
+ length_d_comp = 0;
+ for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) {
+ if( d_comp[ i ] > 0 ) {
+ d_comp[ length_d_comp ] = i - 2;
+ length_d_comp++;
+ }
+ }
+
+ /**********************************************************************************
+ ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
+ *************************************************************************************/
+
+ /******************************************************************************
+ ** Scale signal down to avoid correlations measures from overflowing
+ *******************************************************************************/
+ /* find scaling as max scaling for each subframe */
+ shift = silk_P_Ana_find_scaling( frame_8kHz, frame_length_8kHz, sf_length_8kHz );
+ if( shift > 0 ) {
+ for( i = 0; i < frame_length_8kHz; i++ ) {
+ frame_8kHz[ i ] = silk_RSHIFT( frame_8kHz[ i ], shift );
+ }
+ }
+
+ /*********************************************************************************
+ * Find energy of each subframe projected onto its history, for a range of delays
+ *********************************************************************************/
+ silk_memset( C, 0, PE_MAX_NB_SUBFR * ( ( PE_MAX_LAG >> 1 ) + 5 ) * sizeof( opus_int16 ) );
+
+ target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];
+ for( k = 0; k < nb_subfr; k++ ) {
+
+ /* Check that we are within range of the array */
+ silk_assert( target_ptr >= frame_8kHz );
+ silk_assert( target_ptr + sf_length_8kHz <= frame_8kHz + frame_length_8kHz );
+
+ energy_target = silk_inner_prod_aligned( target_ptr, target_ptr, sf_length_8kHz );
+ /* ToDo: Calculate 1 / energy_target here and save one division inside next for loop*/
+ for( j = 0; j < length_d_comp; j++ ) {
+ d = d_comp[ j ];
+ basis_ptr = target_ptr - d;
+
+ /* Check that we are within range of the array */
+ silk_assert( basis_ptr >= frame_8kHz );
+ silk_assert( basis_ptr + sf_length_8kHz <= frame_8kHz + frame_length_8kHz );
+
+ cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
+ energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz );
+ if( cross_corr > 0 ) {
+ energy = silk_max( energy_target, energy_basis ); /* Find max to make sure first division < 1.0 */
+ lz = silk_CLZ32( cross_corr );
+ lshift = silk_LIMIT_32( lz - 1, 0, 15 );
+ temp32 = silk_DIV32( silk_LSHIFT( cross_corr, lshift ), silk_RSHIFT( energy, 15 - lshift ) + 1 ); /* Q15 */
+ silk_assert( temp32 == silk_SAT16( temp32 ) );
+ temp32 = silk_SMULWB( cross_corr, temp32 ); /* Q(-1), cc * ( cc / max(b, t) ) */
+ temp32 = silk_ADD_SAT32( temp32, temp32 ); /* Q(0) */
+ lz = silk_CLZ32( temp32 );
+ lshift = silk_LIMIT_32( lz - 1, 0, 15 );
+ energy = silk_min( energy_target, energy_basis );
+ C[ k ][ d ] = silk_DIV32( silk_LSHIFT( temp32, lshift ), silk_RSHIFT( energy, 15 - lshift ) + 1 ); /* Q15*/
+ } else {
+ C[ k ][ d ] = 0;
+ }
+ }
+ target_ptr += sf_length_8kHz;
+ }
+
+ /* search over lag range and lags codebook */
+ /* scale factor for lag codebook, as a function of center lag */
+
+ CCmax = silk_int32_MIN;
+ CCmax_b = silk_int32_MIN;
+
+ CBimax = 0; /* To avoid returning undefined lag values */
+ lag = -1; /* To check if lag with strong enough correlation has been found */
+
+ if( prevLag > 0 ) {
+ if( Fs_kHz == 12 ) {
+ prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 );
+ } else if( Fs_kHz == 16 ) {
+ prevLag = silk_RSHIFT( prevLag, 1 );
+ }
+ prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag );
+ } else {
+ prevLag_log2_Q7 = 0;
+ }
+ silk_assert( search_thres2_Q15 == silk_SAT16( search_thres2_Q15 ) );
+ /* Setup stage 2 codebook based on number of subframes */
+ if( nb_subfr == PE_MAX_NB_SUBFR ) {
+ cbk_size = PE_NB_CBKS_STAGE2_EXT;
+ Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
+ if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {
+ /* If input is 8 khz use a larger codebook here because it is last stage */
+ nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;
+ } else {
+ nb_cbk_search = PE_NB_CBKS_STAGE2;
+ }
+ corr_thres_Q15 = silk_RSHIFT( silk_SMULBB( search_thres2_Q15, search_thres2_Q15 ), 13 );
+ } else {
+ cbk_size = PE_NB_CBKS_STAGE2_10MS;
+ Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
+ nb_cbk_search = PE_NB_CBKS_STAGE2_10MS;
+ corr_thres_Q15 = silk_RSHIFT( silk_SMULBB( search_thres2_Q15, search_thres2_Q15 ), 14 );
+ }
+
+ for( k = 0; k < length_d_srch; k++ ) {
+ d = d_srch[ k ];
+ for( j = 0; j < nb_cbk_search; j++ ) {
+ CC[ j ] = 0;
+ for( i = 0; i < nb_subfr; i++ ) {
+ /* Try all codebooks */
+ CC[ j ] = CC[ j ] + (opus_int32)C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )];
+ }
+ }
+ /* Find best codebook */
+ CCmax_new = silk_int32_MIN;
+ CBimax_new = 0;
+ for( i = 0; i < nb_cbk_search; i++ ) {
+ if( CC[ i ] > CCmax_new ) {
+ CCmax_new = CC[ i ];
+ CBimax_new = i;
+ }
+ }
+
+ /* Bias towards shorter lags */
+ lag_log2_Q7 = silk_lin2log( (opus_int32)d ); /* Q7 */
+ silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) );
+ silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ) ) );
+ CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ), lag_log2_Q7 ), 7 ); /* Q15 */
+
+ /* Bias towards previous lag */
+ silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ) ) );
+ if( prevLag > 0 ) {
+ delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7;
+ silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) );
+ delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 );
+ prev_lag_bias_Q15 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ), *LTPCorr_Q15 ), 15 ); /* Q15 */
+ prev_lag_bias_Q15 = silk_DIV32( silk_MUL( prev_lag_bias_Q15, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + ( 1 << 6 ) );
+ CCmax_new_b -= prev_lag_bias_Q15; /* Q15 */
+ }
+
+ if ( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
+ CCmax_new > corr_thres_Q15 && /* Correlation needs to be high enough to be voiced */
+ silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= min_lag_8kHz /* Lag must be in range */
+ ) {
+ CCmax_b = CCmax_new_b;
+ CCmax = CCmax_new;
+ lag = d;
+ CBimax = CBimax_new;
+ }
+ }
+
+ if( lag == -1 ) {
+ /* No suitable candidate found */
+ silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
+ *LTPCorr_Q15 = 0;
+ *lagIndex = 0;
+ *contourIndex = 0;
+ return 1;
+ }
+
+ if( Fs_kHz > 8 ) {
+
+ /******************************************************************************
+ ** Scale input signal down to avoid correlations measures from overflowing
+ *******************************************************************************/
+ /* find scaling as max scaling for each subframe */
+ shift = silk_P_Ana_find_scaling( frame, frame_length, sf_length );
+ if( shift > 0 ) {
+ /* Move signal to scratch mem because the input signal should be unchanged */
+ /* Reuse the 32 bit scratch mem vector, use a 16 bit pointer from now */
+ input_frame_ptr = (opus_int16*)scratch_mem;
+ for( i = 0; i < frame_length; i++ ) {
+ input_frame_ptr[ i ] = silk_RSHIFT( frame[ i ], shift );
+ }
+ } else {
+ input_frame_ptr = (opus_int16*)frame;
+ }
+ /*********************************************************************************/
+
+ /* Search in original signal */
+
+ CBimax_old = CBimax;
+ /* Compensate for decimation */
+ silk_assert( lag == silk_SAT16( lag ) );
+ if( Fs_kHz == 12 ) {
+ lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 );
+ } else if( Fs_kHz == 16 ) {
+ lag = silk_LSHIFT( lag, 1 );
+ } else {
+ lag = silk_SMULBB( lag, 3 );
+ }
+
+ lag = silk_LIMIT_int( lag, min_lag, max_lag );
+ start_lag = silk_max_int( lag - 2, min_lag );
+ end_lag = silk_min_int( lag + 2, max_lag );
+ lag_new = lag; /* to avoid undefined lag */
+ CBimax = 0; /* to avoid undefined lag */
+ silk_assert( silk_LSHIFT( CCmax, 13 ) >= 0 );
+ *LTPCorr_Q15 = (opus_int)silk_SQRT_APPROX( silk_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */
+
+ CCmax = silk_int32_MIN;
+ /* pitch lags according to second stage */
+ for( k = 0; k < nb_subfr; k++ ) {
+ pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ];
+ }
+ /* Calculate the correlations and energies needed in stage 3 */
+ silk_P_Ana_calc_corr_st3( crosscorr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity );
+ silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity );
+
+ lag_counter = 0;
+ silk_assert( lag == silk_SAT16( lag ) );
+ contour_bias_Q20 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 20 ), lag );
+
+ /* Setup cbk parameters acording to complexity setting and frame length */
+ if( nb_subfr == PE_MAX_NB_SUBFR ) {
+ nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
+ cbk_size = PE_NB_CBKS_STAGE3_MAX;
+ Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
+ } else {
+ nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
+ cbk_size = PE_NB_CBKS_STAGE3_10MS;
+ Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
+ }
+ for( d = start_lag; d <= end_lag; d++ ) {
+ for( j = 0; j < nb_cbk_search; j++ ) {
+ cross_corr = 0;
+ energy = 0;
+ for( k = 0; k < nb_subfr; k++ ) {
+ silk_assert( PE_MAX_NB_SUBFR == 4 );
+ energy += silk_RSHIFT( energies_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */
+ silk_assert( energy >= 0 );
+ cross_corr += silk_RSHIFT( crosscorr_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */
+ }
+ if( cross_corr > 0 ) {
+ /* Divide cross_corr / energy and get result in Q15 */
+ lz = silk_CLZ32( cross_corr );
+ /* Divide with result in Q13, cross_corr could be larger than energy */
+ lshift = silk_LIMIT_32( lz - 1, 0, 13 );
+ CCmax_new = silk_DIV32( silk_LSHIFT( cross_corr, lshift ), silk_RSHIFT( energy, 13 - lshift ) + 1 );
+ CCmax_new = silk_SAT16( CCmax_new );
+ CCmax_new = silk_SMULWB( cross_corr, CCmax_new );
+ /* Saturate */
+ if( CCmax_new > silk_RSHIFT( silk_int32_MAX, 3 ) ) {
+ CCmax_new = silk_int32_MAX;
+ } else {
+ CCmax_new = silk_LSHIFT( CCmax_new, 3 );
+ }
+ /* Reduce depending on flatness of contour */
+ diff = silk_int16_MAX - silk_RSHIFT( silk_MUL( contour_bias_Q20, j ), 5 ); /* Q20 -> Q15 */
+ silk_assert( diff == silk_SAT16( diff ) );
+ CCmax_new = silk_LSHIFT( silk_SMULWB( CCmax_new, diff ), 1 );
+ } else {
+ CCmax_new = 0;
+ }
+
+ if( CCmax_new > CCmax &&
+ ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag
+ ) {
+ CCmax = CCmax_new;
+ lag_new = d;
+ CBimax = j;
+ }
+ }
+ lag_counter++;
+ }
+
+ for( k = 0; k < nb_subfr; k++ ) {
+ pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
+ pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );
+ }
+ *lagIndex = (opus_int16)( lag_new - min_lag);
+ *contourIndex = (opus_int8)CBimax;
+ } else { /* Fs_kHz == 8 */
+ /* Save Lags and correlation */
+ CCmax = silk_max( CCmax, 0 );
+ *LTPCorr_Q15 = (opus_int)silk_SQRT_APPROX( silk_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */
+ for( k = 0; k < nb_subfr; k++ ) {
+ pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
+ pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * Fs_kHz );
+ }
+ *lagIndex = (opus_int16)( lag - min_lag_8kHz );
+ *contourIndex = (opus_int8)CBimax;
+ }
+ silk_assert( *lagIndex >= 0 );
+ /* return as voiced */
+ return 0;
+}
+
+/*************************************************************************/
+/* Calculates the correlations used in stage 3 search. In order to cover */
+/* the whole lag codebook for all the searched offset lags (lag +- 2), */
+/*************************************************************************/
+void silk_P_Ana_calc_corr_st3(
+ opus_int32 cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM correlation array */
+ const opus_int16 frame[], /* I vector to correlate */
+ opus_int start_lag, /* I lag offset to search around */
+ opus_int sf_length, /* I length of a 5 ms subframe */
+ opus_int nb_subfr, /* I number of subframes */
+ opus_int complexity /* I Complexity setting */
+)
+{
+ const opus_int16 *target_ptr, *basis_ptr;
+ opus_int32 cross_corr;
+ opus_int i, j, k, lag_counter, lag_low, lag_high;
+ opus_int nb_cbk_search, delta, idx, cbk_size;
+ opus_int32 scratch_mem[ SCRATCH_SIZE ];
+ const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
+
+ silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
+ silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
+
+ if( nb_subfr == PE_MAX_NB_SUBFR ){
+ Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
+ Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
+ nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
+ cbk_size = PE_NB_CBKS_STAGE3_MAX;
+ } else {
+ silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
+ Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
+ Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
+ nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
+ cbk_size = PE_NB_CBKS_STAGE3_10MS;
+ }
+
+ target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
+ for( k = 0; k < nb_subfr; k++ ) {
+ lag_counter = 0;
+
+ /* Calculate the correlations for each subframe */
+ lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 );
+ lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
+ for( j = lag_low; j <= lag_high; j++ ) {
+ basis_ptr = target_ptr - ( start_lag + j );
+ cross_corr = silk_inner_prod_aligned( (opus_int16*)target_ptr, (opus_int16*)basis_ptr, sf_length );
+ silk_assert( lag_counter < SCRATCH_SIZE );
+ scratch_mem[ lag_counter ] = cross_corr;
+ lag_counter++;
+ }
+
+ delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
+ for( i = 0; i < nb_cbk_search; i++ ) {
+ /* Fill out the 3 dim array that stores the correlations for */
+ /* each code_book vector for each start lag */
+ idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
+ for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
+ silk_assert( idx + j < SCRATCH_SIZE );
+ silk_assert( idx + j < lag_counter );
+ cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
+ }
+ }
+ target_ptr += sf_length;
+ }
+}
+
+/********************************************************************/
+/* Calculate the energies for first two subframes. The energies are */
+/* calculated recursively. */
+/********************************************************************/
+void silk_P_Ana_calc_energy_st3(
+ opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM energy array */
+ const opus_int16 frame[], /* I vector to calc energy in */
+ opus_int start_lag, /* I lag offset to search around */
+ opus_int sf_length, /* I length of one 5 ms subframe */
+ opus_int nb_subfr, /* I number of subframes */
+ opus_int complexity /* I Complexity setting */
+)
+{
+ const opus_int16 *target_ptr, *basis_ptr;
+ opus_int32 energy;
+ opus_int k, i, j, lag_counter;
+ opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff;
+ opus_int32 scratch_mem[ SCRATCH_SIZE ];
+ const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
+
+ silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
+ silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
+
+ if( nb_subfr == PE_MAX_NB_SUBFR ){
+ Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
+ Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
+ nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
+ cbk_size = PE_NB_CBKS_STAGE3_MAX;
+ } else {
+ silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
+ Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
+ Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
+ nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
+ cbk_size = PE_NB_CBKS_STAGE3_10MS;
+ }
+ target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];
+ for( k = 0; k < nb_subfr; k++ ) {
+ lag_counter = 0;
+
+ /* Calculate the energy for first lag */
+ basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );
+ energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length );
+ silk_assert( energy >= 0 );
+ scratch_mem[ lag_counter ] = energy;
+ lag_counter++;
+
+ lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );
+ for( i = 1; i < lag_diff; i++ ) {
+ /* remove part outside new window */
+ energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] );
+ silk_assert( energy >= 0 );
+
+ /* add part that comes into window */
+ energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) );
+ silk_assert( energy >= 0 );
+ silk_assert( lag_counter < SCRATCH_SIZE );
+ scratch_mem[ lag_counter ] = energy;
+ lag_counter++;
+ }
+
+ delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
+ for( i = 0; i < nb_cbk_search; i++ ) {
+ /* Fill out the 3 dim array that stores the correlations for */
+ /* each code_book vector for each start lag */
+ idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
+ for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
+ silk_assert( idx + j < SCRATCH_SIZE );
+ silk_assert( idx + j < lag_counter );
+ energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
+ silk_assert( energies_st3[ k ][ i ][ j ] >= 0 );
+ }
+ }
+ target_ptr += sf_length;
+ }
+}
+
+opus_int32 silk_P_Ana_find_scaling(
+ const opus_int16 *frame,
+ const opus_int frame_length,
+ const opus_int sum_sqr_len
+)
+{
+ opus_int32 nbits, x_max;
+
+ x_max = silk_int16_array_maxabs( frame, frame_length );
+
+ if( x_max < silk_int16_MAX ) {
+ /* Number of bits needed for the sum of the squares */
+ nbits = 32 - silk_CLZ32( silk_SMULBB( x_max, x_max ) );
+ } else {
+ /* Here we don't know if x_max should have been silk_int16_MAX + 1, so we expect the worst case */
+ nbits = 30;
+ }
+ nbits += 17 - silk_CLZ16( sum_sqr_len );
+
+ /* Without a guarantee of saturation, we need to keep the 31st bit free */
+ if( nbits < 31 ) {
+ return 0;
+ } else {
+ return( nbits - 30 );
+ }
+}
--- /dev/null
+++ b/silk/fixed/schur64_FIX.c
@@ -1,0 +1,77 @@
+/***********************************************************************
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SigProc_FIX.h"
+
+/* Slower than schur(), but more accurate. */
+/* Uses SMULL(), available on armv4 */
+opus_int32 silk_schur64( /* O: Returns residual energy */
+ opus_int32 rc_Q16[], /* O: Reflection coefficients [order] Q16 */
+ const opus_int32 c[], /* I: Correlations [order+1] */
+ opus_int32 order /* I: Prediction order */
+)
+{
+ opus_int k, n;
+ opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
+ opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31;
+
+ silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
+
+ /* Check for invalid input */
+ if( c[ 0 ] <= 0 ) {
+ silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) );
+ return 0;
+ }
+
+ for( k = 0; k < order + 1; k++ ) {
+ C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
+ }
+
+ for( k = 0; k < order; k++ ) {
+ /* Get reflection coefficient: divide two Q30 values and get result in Q31 */
+ rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 );
+
+ /* Save the output */
+ rc_Q16[ k ] = silk_RSHIFT_ROUND( rc_tmp_Q31, 15 );
+
+ /* Update correlations */
+ for( n = 0; n < order - k; n++ ) {
+ Ctmp1_Q30 = C[ n + k + 1 ][ 0 ];
+ Ctmp2_Q30 = C[ n ][ 1 ];
+
+ /* Multiply and add the highest int32 */
+ C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 );
+ C[ n ][ 1 ] = Ctmp2_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 );
+ }
+ }
+
+ return( C[ 0 ][ 1 ] );
+}
--- /dev/null
+++ b/silk/fixed/schur_FIX.c
@@ -1,0 +1,92 @@
+/***********************************************************************
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SigProc_FIX.h"
+
+/* Faster than schur64(), but much less accurate. */
+/* uses SMLAWB(), requiring armv5E and higher. */
+opus_int32 silk_schur( /* O: Returns residual energy */
+ opus_int16 *rc_Q15, /* O: reflection coefficients [order] Q15 */
+ const opus_int32 *c, /* I: correlations [order+1] */
+ const opus_int32 order /* I: prediction order */
+)
+{
+ opus_int k, n, lz;
+ opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
+ opus_int32 Ctmp1, Ctmp2, rc_tmp_Q15;
+
+ silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
+
+ /* Get number of leading zeros */
+ lz = silk_CLZ32( c[ 0 ] );
+
+ /* Copy correlations and adjust level to Q30 */
+ if( lz < 2 ) {
+ /* lz must be 1, so shift one to the right */
+ for( k = 0; k < order + 1; k++ ) {
+ C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 );
+ }
+ } else if( lz > 2 ) {
+ /* Shift to the left */
+ lz -= 2;
+ for( k = 0; k < order + 1; k++ ) {
+ C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz );
+ }
+ } else {
+ /* No need to shift */
+ for( k = 0; k < order + 1; k++ ) {
+ C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
+ }
+ }
+
+ for( k = 0; k < order; k++ ) {
+
+ /* Get reflection coefficient */
+ rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) );
+
+ /* Clip (shouldn't happen for properly conditioned inputs) */
+ rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 );
+
+ /* Store */
+ rc_Q15[ k ] = ( opus_int16 )rc_tmp_Q15;
+
+ /* Update correlations */
+ for( n = 0; n < order - k; n++ ) {
+ Ctmp1 = C[ n + k + 1 ][ 0 ];
+ Ctmp2 = C[ n ][ 1 ];
+ C[ n + k + 1 ][ 0 ] = silk_SMLAWB( Ctmp1, silk_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 );
+ C[ n ][ 1 ] = silk_SMLAWB( Ctmp2, silk_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 );
+ }
+ }
+
+ /* return residual energy */
+ return C[ 0 ][ 1 ];
+}
--- a/silk/fixed/silk_fixed.vcxproj
+++ b/silk/fixed/silk_fixed.vcxproj
@@ -102,6 +102,15 @@
<ClCompile Include="residual_energy_FIX.c" />
<ClCompile Include="solve_LS_FIX.c" />
<ClCompile Include="warped_autocorrelation_FIX.c" />
+ <ClCompile Include="k2a_FIX.c" />
+ <ClCompile Include="k2a_Q16_FIX.c" />
+ <ClCompile Include="apply_sine_window_FIX.c" />
+ <ClCompile Include="autocorr_FIX.c" />
+ <ClCompile Include="burg_modified_FIX.c" />
+ <ClCompile Include="pitch_analysis_core_FIX.c" />
+ <ClCompile Include="vector_ops_FIX.c" />
+ <ClCompile Include="schur_FIX.c" />
+ <ClCompile Include="schur64_FIX.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\win32\config.h" />
--- a/silk/fixed/silk_fixed.vcxproj.filters
+++ b/silk/fixed/silk_fixed.vcxproj.filters
@@ -66,6 +66,33 @@
<ClCompile Include="warped_autocorrelation_FIX.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="apply_sine_window_FIX.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="k2a_FIX.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="k2a_Q16_FIX.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="burg_modified_FIX.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="autocorr_FIX.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="pitch_analysis_core_FIX.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="vector_ops_FIX.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="schur_FIX.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="schur64_FIX.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\win32\config.h">
--- /dev/null
+++ b/silk/fixed/vector_ops_FIX.c
@@ -1,0 +1,128 @@
+/***********************************************************************
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SigProc_FIX.h"
+
+/* Copy and multiply a vector by a constant */
+void silk_scale_copy_vector16(
+ opus_int16 *data_out,
+ const opus_int16 *data_in,
+ opus_int32 gain_Q16, /* (I): gain in Q16 */
+ const opus_int dataSize /* (I): length */
+)
+{
+ opus_int i;
+ opus_int32 tmp32;
+
+ for( i = 0; i < dataSize; i++ ) {
+ tmp32 = silk_SMULWB( gain_Q16, data_in[ i ] );
+ data_out[ i ] = (opus_int16)silk_CHECK_FIT16( tmp32 );
+ }
+}
+
+/* Multiply a vector by a constant */
+void silk_scale_vector32_Q26_lshift_18(
+ opus_int32 *data1, /* (I/O): Q0/Q18 */
+ opus_int32 gain_Q26, /* (I): Q26 */
+ opus_int dataSize /* (I): length */
+)
+{
+ opus_int i;
+
+ for( i = 0; i < dataSize; i++ ) {
+ data1[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_SMULL( data1[ i ], gain_Q26 ), 8 ) );/* OUTPUT: Q18*/
+ }
+}
+
+/* sum= for(i=0;i<len;i++)inVec1[i]*inVec2[i]; --- inner product */
+/* Note for ARM asm: */
+/* * inVec1 and inVec2 should be at least 2 byte aligned. (Or defined as short/int16) */
+/* * len should be positive 16bit integer. */
+/* * only when len>6, memory access can be reduced by half. */
+
+opus_int32 silk_inner_prod_aligned(
+ const opus_int16 *const inVec1, /* I input vector 1 */
+ const opus_int16 *const inVec2, /* I input vector 2 */
+ const opus_int len /* I vector lengths */
+)
+{
+ opus_int i;
+ opus_int32 sum = 0;
+ for( i = 0; i < len; i++ ) {
+ sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
+ }
+ return sum;
+}
+
+opus_int64 silk_inner_prod16_aligned_64(
+ const opus_int16 *inVec1, /* I input vector 1 */
+ const opus_int16 *inVec2, /* I input vector 2 */
+ const opus_int len /* I vector lengths */
+)
+{
+ opus_int i;
+ opus_int64 sum = 0;
+ for( i = 0; i < len; i++ ) {
+ sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] );
+ }
+ return sum;
+}
+
+/* Function that returns the maximum absolut value of the input vector */
+opus_int16 silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */
+ const opus_int16 *vec, /* I Input vector [len] */
+ const opus_int32 len /* I Length of input vector */
+)
+{
+ opus_int32 max = 0, i, lvl = 0, ind;
+ if( len == 0 ) return 0;
+
+ ind = len - 1;
+ max = silk_SMULBB( vec[ ind ], vec[ ind ] );
+ for( i = len - 2; i >= 0; i-- ) {
+ lvl = silk_SMULBB( vec[ i ], vec[ i ] );
+ if( lvl > max ) {
+ max = lvl;
+ ind = i;
+ }
+ }
+
+ /* Do not return 32768, as it will not fit in an int16 so may lead to problems later on */
+ if( max >= 1073676289 ) { /* (2^15-1)^2 = 1073676289*/
+ return( silk_int16_MAX );
+ } else {
+ if( vec[ ind ] < 0 ) {
+ return( -vec[ ind ] );
+ } else {
+ return( vec[ ind ] );
+ }
+ }
+}
--- a/silk/inner_prod_aligned.c
+++ b/silk/inner_prod_aligned.c
@@ -31,26 +31,6 @@
#include "SigProc_FIX.h"
-/* sum= for(i=0;i<len;i++)inVec1[i]*inVec2[i]; --- inner product */
-/* Note for ARM asm: */
-/* * inVec1 and inVec2 should be at least 2 byte aligned. (Or defined as short/int16) */
-/* * len should be positive 16bit integer. */
-/* * only when len>6, memory access can be reduced by half. */
-
-opus_int32 silk_inner_prod_aligned(
- const opus_int16 *const inVec1, /* I input vector 1 */
- const opus_int16 *const inVec2, /* I input vector 2 */
- const opus_int len /* I vector lengths */
-)
-{
- opus_int i;
- opus_int32 sum = 0;
- for( i = 0; i < len; i++ ) {
- sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
- }
- return sum;
-}
-
opus_int32 silk_inner_prod_aligned_scale(
const opus_int16 *const inVec1, /* I input vector 1 */
const opus_int16 *const inVec2, /* I input vector 2 */
@@ -62,20 +42,6 @@
opus_int32 sum = 0;
for( i = 0; i < len; i++ ) {
sum = silk_ADD_RSHIFT32( sum, silk_SMULBB( inVec1[ i ], inVec2[ i ] ), scale );
- }
- return sum;
-}
-
-opus_int64 silk_inner_prod16_aligned_64(
- const opus_int16 *inVec1, /* I input vector 1 */
- const opus_int16 *inVec2, /* I input vector 2 */
- const opus_int len /* I vector lengths */
-)
-{
- opus_int i;
- opus_int64 sum = 0;
- for( i = 0; i < len; i++ ) {
- sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] );
}
return sum;
}
--- a/silk/k2a.c
+++ /dev/null
@@ -1,53 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-/* Step up function, converts reflection coefficients to prediction coefficients */
-void silk_k2a(
- opus_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
- const opus_int16 *rc_Q15, /* I: Reflection coefficients [order] Q15 */
- const opus_int32 order /* I: Prediction order */
-)
-{
- opus_int k, n;
- opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
-
- for( k = 0; k < order; k++ ) {
- for( n = 0; n < k; n++ ) {
- Atmp[ n ] = A_Q24[ n ];
- }
- for( n = 0; n < k; n++ ) {
- A_Q24[ n ] = silk_SMLAWB( A_Q24[ n ], silk_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] );
- }
- A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 );
- }
-}
--- a/silk/k2a_Q16.c
+++ /dev/null
@@ -1,53 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-/* Step up function, converts reflection coefficients to prediction coefficients */
-void silk_k2a_Q16(
- opus_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
- const opus_int32 *rc_Q16, /* I: Reflection coefficients [order] Q16 */
- const opus_int32 order /* I: Prediction order */
-)
-{
- opus_int k, n;
- opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
-
- for( k = 0; k < order; k++ ) {
- for( n = 0; n < k; n++ ) {
- Atmp[ n ] = A_Q24[ n ];
- }
- for( n = 0; n < k; n++ ) {
- A_Q24[ n ] = silk_SMLAWW( A_Q24[ n ], Atmp[ k - n - 1 ], rc_Q16[ k ] );
- }
- A_Q24[ k ] = -silk_LSHIFT( rc_Q16[ k ], 8 );
- }
-}
--- a/silk/pitch_analysis_core.c
+++ /dev/null
@@ -1,748 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/***********************************************************
-* Pitch analyser function
-********************************************************** */
-#include "SigProc_FIX.h"
-#include "pitch_est_defines.h"
-#include "debug.h"
-
-#define SCRATCH_SIZE 22
-
-/************************************************************/
-/* Internally used functions */
-/************************************************************/
-void silk_P_Ana_calc_corr_st3(
- opus_int32 cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM correlation array */
- const opus_int16 frame[], /* I vector to correlate */
- opus_int start_lag, /* I lag offset to search around */
- opus_int sf_length, /* I length of a 5 ms subframe */
- opus_int nb_subfr, /* I number of subframes */
- opus_int complexity /* I Complexity setting */
-);
-
-void silk_P_Ana_calc_energy_st3(
- opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM energy array */
- const opus_int16 frame[], /* I vector to calc energy in */
- opus_int start_lag, /* I lag offset to search around */
- opus_int sf_length, /* I length of one 5 ms subframe */
- opus_int nb_subfr, /* I number of subframes */
- opus_int complexity /* I Complexity setting */
-);
-
-opus_int32 silk_P_Ana_find_scaling(
- const opus_int16 *frame,
- const opus_int frame_length,
- const opus_int sum_sqr_len
-);
-
-/*************************************************************/
-/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */
-/*************************************************************/
-opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
- const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
- opus_int *pitch_out, /* O 4 pitch lag values */
- opus_int16 *lagIndex, /* O Lag Index */
- opus_int8 *contourIndex, /* O Pitch contour Index */
- opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */
- opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
- const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */
- const opus_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */
- const opus_int Fs_kHz, /* I Sample frequency (kHz) */
- const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
- const opus_int nb_subfr /* I number of 5 ms subframes */
-)
-{
- opus_int16 frame_8kHz[ PE_MAX_FRAME_LENGTH_ST_2 ];
- opus_int16 frame_4kHz[ PE_MAX_FRAME_LENGTH_ST_1 ];
- opus_int32 filt_state[ 6 ];
- opus_int32 scratch_mem[ 3 * PE_MAX_FRAME_LENGTH ];
- opus_int16 *input_frame_ptr;
- opus_int i, k, d, j;
- opus_int16 C[ PE_MAX_NB_SUBFR ][ ( PE_MAX_LAG >> 1 ) + 5 ];
- const opus_int16 *target_ptr, *basis_ptr;
- opus_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target;
- opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp;
- opus_int16 d_comp[ ( PE_MAX_LAG >> 1 ) + 5 ];
- opus_int32 sum, threshold, temp32, lag_counter;
- opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new;
- opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new;
- opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
- opus_int32 crosscorr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
- opus_int frame_length, frame_length_8kHz, frame_length_4kHz, max_sum_sq_length;
- opus_int sf_length, sf_length_8kHz, sf_length_4kHz;
- opus_int min_lag, min_lag_8kHz, min_lag_4kHz;
- opus_int max_lag, max_lag_8kHz, max_lag_4kHz;
- opus_int32 contour_bias_Q20, diff, lz, lshift;
- opus_int nb_cbk_search, cbk_size;
- opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q15, corr_thres_Q15;
- const opus_int8 *Lag_CB_ptr;
- /* Check for valid sampling frequency */
- silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
-
- /* Check for valid complexity setting */
- silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
- silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
-
- silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
- silk_assert( search_thres2_Q15 >= 0 && search_thres2_Q15 <= (1<<15) );
-
- /* Setup frame lengths max / min lag for the sampling frequency */
- frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
- frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
- frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
- sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz;
- sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4;
- sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8;
- min_lag = PE_MIN_LAG_MS * Fs_kHz;
- min_lag_4kHz = PE_MIN_LAG_MS * 4;
- min_lag_8kHz = PE_MIN_LAG_MS * 8;
- max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
- max_lag_4kHz = PE_MAX_LAG_MS * 4;
- max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1;
-
- silk_memset( C, 0, sizeof( opus_int16 ) * nb_subfr * ( ( PE_MAX_LAG >> 1 ) + 5) );
-
- /* Resample from input sampled at Fs_kHz to 8 kHz */
- if( Fs_kHz == 16 ) {
- silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
- silk_resampler_down2( filt_state, frame_8kHz, frame, frame_length );
- } else if ( Fs_kHz == 12 ) {
- silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
- silk_resampler_down2_3( filt_state, frame_8kHz, frame, frame_length );
- } else {
- silk_assert( Fs_kHz == 8 );
- silk_memcpy( frame_8kHz, frame, frame_length_8kHz * sizeof(opus_int16) );
- }
-
- /* Decimate again to 4 kHz */
- silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */
- silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz );
-
- /* Low-pass filter */
- for( i = frame_length_4kHz - 1; i > 0; i-- ) {
- frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
- }
-
- /*******************************************************************************
- ** Scale 4 kHz signal down to prevent correlations measures from overflowing
- ** find scaling as max scaling for each 8kHz(?) subframe
- *******************************************************************************/
-
- /* Inner product is calculated with different lengths, so scale for the worst case */
- max_sum_sq_length = silk_max_32( sf_length_8kHz, silk_LSHIFT( sf_length_4kHz, 2 ) );
- shift = silk_P_Ana_find_scaling( frame_4kHz, frame_length_4kHz, max_sum_sq_length );
- if( shift > 0 ) {
- for( i = 0; i < frame_length_4kHz; i++ ) {
- frame_4kHz[ i ] = silk_RSHIFT( frame_4kHz[ i ], shift );
- }
- }
-
- /******************************************************************************
- * FIRST STAGE, operating in 4 khz
- ******************************************************************************/
- target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ];
- for( k = 0; k < nb_subfr >> 1; k++ ) {
- /* Check that we are within range of the array */
- silk_assert( target_ptr >= frame_4kHz );
- silk_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
-
- basis_ptr = target_ptr - min_lag_4kHz;
-
- /* Check that we are within range of the array */
- silk_assert( basis_ptr >= frame_4kHz );
- silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
-
- /* Calculate first vector products before loop */
- cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
- normalizer = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz );
- normalizer = silk_ADD_SAT32( normalizer, silk_SMULBB( sf_length_8kHz, 4000 ) );
-
- temp32 = silk_DIV32( cross_corr, silk_SQRT_APPROX( normalizer ) + 1 );
- C[ k ][ min_lag_4kHz ] = (opus_int16)silk_SAT16( temp32 ); /* Q0 */
-
- /* From now on normalizer is computed recursively */
- for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) {
- basis_ptr--;
-
- /* Check that we are within range of the array */
- silk_assert( basis_ptr >= frame_4kHz );
- silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
-
- cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
-
- /* Add contribution of new sample and remove contribution from oldest sample */
- normalizer +=
- silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) -
- silk_SMULBB( basis_ptr[ sf_length_8kHz ], basis_ptr[ sf_length_8kHz ] );
-
- temp32 = silk_DIV32( cross_corr, silk_SQRT_APPROX( normalizer ) + 1 );
- C[ k ][ d ] = (opus_int16)silk_SAT16( temp32 ); /* Q0 */
- }
- /* Update target pointer */
- target_ptr += sf_length_8kHz;
- }
-
- /* Combine two subframes into single correlation measure and apply short-lag bias */
- if( nb_subfr == PE_MAX_NB_SUBFR ) {
- for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
- sum = (opus_int32)C[ 0 ][ i ] + (opus_int32)C[ 1 ][ i ]; /* Q0 */
- silk_assert( silk_RSHIFT( sum, 1 ) == silk_SAT16( silk_RSHIFT( sum, 1 ) ) );
- sum = silk_RSHIFT( sum, 1 ); /* Q-1 */
- silk_assert( silk_LSHIFT( (opus_int32)-i, 4 ) == silk_SAT16( silk_LSHIFT( (opus_int32)-i, 4 ) ) );
- sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q-1 */
- silk_assert( sum == silk_SAT16( sum ) );
- C[ 0 ][ i ] = (opus_int16)sum; /* Q-1 */
- }
- } else {
- /* Only short-lag bias */
- for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
- sum = (opus_int32)C[ 0 ][ i ];
- sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q-1 */
- C[ 0 ][ i ] = (opus_int16)sum; /* Q-1 */
- }
- }
-
- /* Sort */
- length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 );
- silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
- silk_insertion_sort_decreasing_int16( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
-
- /* Escape if correlation is very low already here */
- target_ptr = &frame_4kHz[ silk_SMULBB( sf_length_4kHz, nb_subfr ) ];
- energy = silk_inner_prod_aligned( target_ptr, target_ptr, silk_LSHIFT( sf_length_4kHz, 2 ) );
- energy = silk_ADD_SAT32( energy, 1000 ); /* Q0 */
- Cmax = (opus_int)C[ 0 ][ min_lag_4kHz ]; /* Q-1 */
- threshold = silk_SMULBB( Cmax, Cmax ); /* Q-2 */
-
- /* Compare in Q-2 domain */
- if( silk_RSHIFT( energy, 4 + 2 ) > threshold ) {
- silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
- *LTPCorr_Q15 = 0;
- *lagIndex = 0;
- *contourIndex = 0;
- return 1;
- }
-
- threshold = silk_SMULWB( search_thres1_Q16, Cmax );
- for( i = 0; i < length_d_srch; i++ ) {
- /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
- if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) {
- d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 );
- } else {
- length_d_srch = i;
- break;
- }
- }
- silk_assert( length_d_srch > 0 );
-
- for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
- d_comp[ i ] = 0;
- }
- for( i = 0; i < length_d_srch; i++ ) {
- d_comp[ d_srch[ i ] ] = 1;
- }
-
- /* Convolution */
- for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
- d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ];
- }
-
- length_d_srch = 0;
- for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) {
- if( d_comp[ i + 1 ] > 0 ) {
- d_srch[ length_d_srch ] = i;
- length_d_srch++;
- }
- }
-
- /* Convolution */
- for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
- d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ];
- }
-
- length_d_comp = 0;
- for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) {
- if( d_comp[ i ] > 0 ) {
- d_comp[ length_d_comp ] = i - 2;
- length_d_comp++;
- }
- }
-
- /**********************************************************************************
- ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
- *************************************************************************************/
-
- /******************************************************************************
- ** Scale signal down to avoid correlations measures from overflowing
- *******************************************************************************/
- /* find scaling as max scaling for each subframe */
- shift = silk_P_Ana_find_scaling( frame_8kHz, frame_length_8kHz, sf_length_8kHz );
- if( shift > 0 ) {
- for( i = 0; i < frame_length_8kHz; i++ ) {
- frame_8kHz[ i ] = silk_RSHIFT( frame_8kHz[ i ], shift );
- }
- }
-
- /*********************************************************************************
- * Find energy of each subframe projected onto its history, for a range of delays
- *********************************************************************************/
- silk_memset( C, 0, PE_MAX_NB_SUBFR * ( ( PE_MAX_LAG >> 1 ) + 5 ) * sizeof( opus_int16 ) );
-
- target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];
- for( k = 0; k < nb_subfr; k++ ) {
-
- /* Check that we are within range of the array */
- silk_assert( target_ptr >= frame_8kHz );
- silk_assert( target_ptr + sf_length_8kHz <= frame_8kHz + frame_length_8kHz );
-
- energy_target = silk_inner_prod_aligned( target_ptr, target_ptr, sf_length_8kHz );
- /* ToDo: Calculate 1 / energy_target here and save one division inside next for loop*/
- for( j = 0; j < length_d_comp; j++ ) {
- d = d_comp[ j ];
- basis_ptr = target_ptr - d;
-
- /* Check that we are within range of the array */
- silk_assert( basis_ptr >= frame_8kHz );
- silk_assert( basis_ptr + sf_length_8kHz <= frame_8kHz + frame_length_8kHz );
-
- cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
- energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz );
- if( cross_corr > 0 ) {
- energy = silk_max( energy_target, energy_basis ); /* Find max to make sure first division < 1.0 */
- lz = silk_CLZ32( cross_corr );
- lshift = silk_LIMIT_32( lz - 1, 0, 15 );
- temp32 = silk_DIV32( silk_LSHIFT( cross_corr, lshift ), silk_RSHIFT( energy, 15 - lshift ) + 1 ); /* Q15 */
- silk_assert( temp32 == silk_SAT16( temp32 ) );
- temp32 = silk_SMULWB( cross_corr, temp32 ); /* Q(-1), cc * ( cc / max(b, t) ) */
- temp32 = silk_ADD_SAT32( temp32, temp32 ); /* Q(0) */
- lz = silk_CLZ32( temp32 );
- lshift = silk_LIMIT_32( lz - 1, 0, 15 );
- energy = silk_min( energy_target, energy_basis );
- C[ k ][ d ] = silk_DIV32( silk_LSHIFT( temp32, lshift ), silk_RSHIFT( energy, 15 - lshift ) + 1 ); /* Q15*/
- } else {
- C[ k ][ d ] = 0;
- }
- }
- target_ptr += sf_length_8kHz;
- }
-
- /* search over lag range and lags codebook */
- /* scale factor for lag codebook, as a function of center lag */
-
- CCmax = silk_int32_MIN;
- CCmax_b = silk_int32_MIN;
-
- CBimax = 0; /* To avoid returning undefined lag values */
- lag = -1; /* To check if lag with strong enough correlation has been found */
-
- if( prevLag > 0 ) {
- if( Fs_kHz == 12 ) {
- prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 );
- } else if( Fs_kHz == 16 ) {
- prevLag = silk_RSHIFT( prevLag, 1 );
- }
- prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag );
- } else {
- prevLag_log2_Q7 = 0;
- }
- silk_assert( search_thres2_Q15 == silk_SAT16( search_thres2_Q15 ) );
- /* Setup stage 2 codebook based on number of subframes */
- if( nb_subfr == PE_MAX_NB_SUBFR ) {
- cbk_size = PE_NB_CBKS_STAGE2_EXT;
- Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
- if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {
- /* If input is 8 khz use a larger codebook here because it is last stage */
- nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;
- } else {
- nb_cbk_search = PE_NB_CBKS_STAGE2;
- }
- corr_thres_Q15 = silk_RSHIFT( silk_SMULBB( search_thres2_Q15, search_thres2_Q15 ), 13 );
- } else {
- cbk_size = PE_NB_CBKS_STAGE2_10MS;
- Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
- nb_cbk_search = PE_NB_CBKS_STAGE2_10MS;
- corr_thres_Q15 = silk_RSHIFT( silk_SMULBB( search_thres2_Q15, search_thres2_Q15 ), 14 );
- }
-
- for( k = 0; k < length_d_srch; k++ ) {
- d = d_srch[ k ];
- for( j = 0; j < nb_cbk_search; j++ ) {
- CC[ j ] = 0;
- for( i = 0; i < nb_subfr; i++ ) {
- /* Try all codebooks */
- CC[ j ] = CC[ j ] + (opus_int32)C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )];
- }
- }
- /* Find best codebook */
- CCmax_new = silk_int32_MIN;
- CBimax_new = 0;
- for( i = 0; i < nb_cbk_search; i++ ) {
- if( CC[ i ] > CCmax_new ) {
- CCmax_new = CC[ i ];
- CBimax_new = i;
- }
- }
-
- /* Bias towards shorter lags */
- lag_log2_Q7 = silk_lin2log( (opus_int32)d ); /* Q7 */
- silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) );
- silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ) ) );
- CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ), lag_log2_Q7 ), 7 ); /* Q15 */
-
- /* Bias towards previous lag */
- silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ) ) );
- if( prevLag > 0 ) {
- delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7;
- silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) );
- delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 );
- prev_lag_bias_Q15 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ), *LTPCorr_Q15 ), 15 ); /* Q15 */
- prev_lag_bias_Q15 = silk_DIV32( silk_MUL( prev_lag_bias_Q15, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + ( 1 << 6 ) );
- CCmax_new_b -= prev_lag_bias_Q15; /* Q15 */
- }
-
- if ( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
- CCmax_new > corr_thres_Q15 && /* Correlation needs to be high enough to be voiced */
- silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= min_lag_8kHz /* Lag must be in range */
- ) {
- CCmax_b = CCmax_new_b;
- CCmax = CCmax_new;
- lag = d;
- CBimax = CBimax_new;
- }
- }
-
- if( lag == -1 ) {
- /* No suitable candidate found */
- silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
- *LTPCorr_Q15 = 0;
- *lagIndex = 0;
- *contourIndex = 0;
- return 1;
- }
-
- if( Fs_kHz > 8 ) {
-
- /******************************************************************************
- ** Scale input signal down to avoid correlations measures from overflowing
- *******************************************************************************/
- /* find scaling as max scaling for each subframe */
- shift = silk_P_Ana_find_scaling( frame, frame_length, sf_length );
- if( shift > 0 ) {
- /* Move signal to scratch mem because the input signal should be unchanged */
- /* Reuse the 32 bit scratch mem vector, use a 16 bit pointer from now */
- input_frame_ptr = (opus_int16*)scratch_mem;
- for( i = 0; i < frame_length; i++ ) {
- input_frame_ptr[ i ] = silk_RSHIFT( frame[ i ], shift );
- }
- } else {
- input_frame_ptr = (opus_int16*)frame;
- }
- /*********************************************************************************/
-
- /* Search in original signal */
-
- CBimax_old = CBimax;
- /* Compensate for decimation */
- silk_assert( lag == silk_SAT16( lag ) );
- if( Fs_kHz == 12 ) {
- lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 );
- } else if( Fs_kHz == 16 ) {
- lag = silk_LSHIFT( lag, 1 );
- } else {
- lag = silk_SMULBB( lag, 3 );
- }
-
- lag = silk_LIMIT_int( lag, min_lag, max_lag );
- start_lag = silk_max_int( lag - 2, min_lag );
- end_lag = silk_min_int( lag + 2, max_lag );
- lag_new = lag; /* to avoid undefined lag */
- CBimax = 0; /* to avoid undefined lag */
- silk_assert( silk_LSHIFT( CCmax, 13 ) >= 0 );
- *LTPCorr_Q15 = (opus_int)silk_SQRT_APPROX( silk_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */
-
- CCmax = silk_int32_MIN;
- /* pitch lags according to second stage */
- for( k = 0; k < nb_subfr; k++ ) {
- pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ];
- }
- /* Calculate the correlations and energies needed in stage 3 */
- silk_P_Ana_calc_corr_st3( crosscorr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity );
- silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity );
-
- lag_counter = 0;
- silk_assert( lag == silk_SAT16( lag ) );
- contour_bias_Q20 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 20 ), lag );
-
- /* Setup cbk parameters acording to complexity setting and frame length */
- if( nb_subfr == PE_MAX_NB_SUBFR ) {
- nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
- cbk_size = PE_NB_CBKS_STAGE3_MAX;
- Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
- } else {
- nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
- cbk_size = PE_NB_CBKS_STAGE3_10MS;
- Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
- }
- for( d = start_lag; d <= end_lag; d++ ) {
- for( j = 0; j < nb_cbk_search; j++ ) {
- cross_corr = 0;
- energy = 0;
- for( k = 0; k < nb_subfr; k++ ) {
- silk_assert( PE_MAX_NB_SUBFR == 4 );
- energy += silk_RSHIFT( energies_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */
- silk_assert( energy >= 0 );
- cross_corr += silk_RSHIFT( crosscorr_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */
- }
- if( cross_corr > 0 ) {
- /* Divide cross_corr / energy and get result in Q15 */
- lz = silk_CLZ32( cross_corr );
- /* Divide with result in Q13, cross_corr could be larger than energy */
- lshift = silk_LIMIT_32( lz - 1, 0, 13 );
- CCmax_new = silk_DIV32( silk_LSHIFT( cross_corr, lshift ), silk_RSHIFT( energy, 13 - lshift ) + 1 );
- CCmax_new = silk_SAT16( CCmax_new );
- CCmax_new = silk_SMULWB( cross_corr, CCmax_new );
- /* Saturate */
- if( CCmax_new > silk_RSHIFT( silk_int32_MAX, 3 ) ) {
- CCmax_new = silk_int32_MAX;
- } else {
- CCmax_new = silk_LSHIFT( CCmax_new, 3 );
- }
- /* Reduce depending on flatness of contour */
- diff = silk_int16_MAX - silk_RSHIFT( silk_MUL( contour_bias_Q20, j ), 5 ); /* Q20 -> Q15 */
- silk_assert( diff == silk_SAT16( diff ) );
- CCmax_new = silk_LSHIFT( silk_SMULWB( CCmax_new, diff ), 1 );
- } else {
- CCmax_new = 0;
- }
-
- if( CCmax_new > CCmax &&
- ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag
- ) {
- CCmax = CCmax_new;
- lag_new = d;
- CBimax = j;
- }
- }
- lag_counter++;
- }
-
- for( k = 0; k < nb_subfr; k++ ) {
- pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
- pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );
- }
- *lagIndex = (opus_int16)( lag_new - min_lag);
- *contourIndex = (opus_int8)CBimax;
- } else { /* Fs_kHz == 8 */
- /* Save Lags and correlation */
- CCmax = silk_max( CCmax, 0 );
- *LTPCorr_Q15 = (opus_int)silk_SQRT_APPROX( silk_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */
- for( k = 0; k < nb_subfr; k++ ) {
- pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
- pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * Fs_kHz );
- }
- *lagIndex = (opus_int16)( lag - min_lag_8kHz );
- *contourIndex = (opus_int8)CBimax;
- }
- silk_assert( *lagIndex >= 0 );
- /* return as voiced */
- return 0;
-}
-
-/*************************************************************************/
-/* Calculates the correlations used in stage 3 search. In order to cover */
-/* the whole lag codebook for all the searched offset lags (lag +- 2), */
-/*************************************************************************/
-void silk_P_Ana_calc_corr_st3(
- opus_int32 cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM correlation array */
- const opus_int16 frame[], /* I vector to correlate */
- opus_int start_lag, /* I lag offset to search around */
- opus_int sf_length, /* I length of a 5 ms subframe */
- opus_int nb_subfr, /* I number of subframes */
- opus_int complexity /* I Complexity setting */
-)
-{
- const opus_int16 *target_ptr, *basis_ptr;
- opus_int32 cross_corr;
- opus_int i, j, k, lag_counter, lag_low, lag_high;
- opus_int nb_cbk_search, delta, idx, cbk_size;
- opus_int32 scratch_mem[ SCRATCH_SIZE ];
- const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
-
- silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
- silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
-
- if( nb_subfr == PE_MAX_NB_SUBFR ){
- Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
- Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
- nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
- cbk_size = PE_NB_CBKS_STAGE3_MAX;
- } else {
- silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
- Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
- Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
- nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
- cbk_size = PE_NB_CBKS_STAGE3_10MS;
- }
-
- target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
- for( k = 0; k < nb_subfr; k++ ) {
- lag_counter = 0;
-
- /* Calculate the correlations for each subframe */
- lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 );
- lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
- for( j = lag_low; j <= lag_high; j++ ) {
- basis_ptr = target_ptr - ( start_lag + j );
- cross_corr = silk_inner_prod_aligned( (opus_int16*)target_ptr, (opus_int16*)basis_ptr, sf_length );
- silk_assert( lag_counter < SCRATCH_SIZE );
- scratch_mem[ lag_counter ] = cross_corr;
- lag_counter++;
- }
-
- delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
- for( i = 0; i < nb_cbk_search; i++ ) {
- /* Fill out the 3 dim array that stores the correlations for */
- /* each code_book vector for each start lag */
- idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
- for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
- silk_assert( idx + j < SCRATCH_SIZE );
- silk_assert( idx + j < lag_counter );
- cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
- }
- }
- target_ptr += sf_length;
- }
-}
-
-/********************************************************************/
-/* Calculate the energies for first two subframes. The energies are */
-/* calculated recursively. */
-/********************************************************************/
-void silk_P_Ana_calc_energy_st3(
- opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM energy array */
- const opus_int16 frame[], /* I vector to calc energy in */
- opus_int start_lag, /* I lag offset to search around */
- opus_int sf_length, /* I length of one 5 ms subframe */
- opus_int nb_subfr, /* I number of subframes */
- opus_int complexity /* I Complexity setting */
-)
-{
- const opus_int16 *target_ptr, *basis_ptr;
- opus_int32 energy;
- opus_int k, i, j, lag_counter;
- opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff;
- opus_int32 scratch_mem[ SCRATCH_SIZE ];
- const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
-
- silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
- silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
-
- if( nb_subfr == PE_MAX_NB_SUBFR ){
- Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
- Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
- nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
- cbk_size = PE_NB_CBKS_STAGE3_MAX;
- } else {
- silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
- Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
- Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
- nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
- cbk_size = PE_NB_CBKS_STAGE3_10MS;
- }
- target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];
- for( k = 0; k < nb_subfr; k++ ) {
- lag_counter = 0;
-
- /* Calculate the energy for first lag */
- basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );
- energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length );
- silk_assert( energy >= 0 );
- scratch_mem[ lag_counter ] = energy;
- lag_counter++;
-
- lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );
- for( i = 1; i < lag_diff; i++ ) {
- /* remove part outside new window */
- energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] );
- silk_assert( energy >= 0 );
-
- /* add part that comes into window */
- energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) );
- silk_assert( energy >= 0 );
- silk_assert( lag_counter < SCRATCH_SIZE );
- scratch_mem[ lag_counter ] = energy;
- lag_counter++;
- }
-
- delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
- for( i = 0; i < nb_cbk_search; i++ ) {
- /* Fill out the 3 dim array that stores the correlations for */
- /* each code_book vector for each start lag */
- idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
- for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
- silk_assert( idx + j < SCRATCH_SIZE );
- silk_assert( idx + j < lag_counter );
- energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
- silk_assert( energies_st3[ k ][ i ][ j ] >= 0 );
- }
- }
- target_ptr += sf_length;
- }
-}
-
-opus_int32 silk_P_Ana_find_scaling(
- const opus_int16 *frame,
- const opus_int frame_length,
- const opus_int sum_sqr_len
-)
-{
- opus_int32 nbits, x_max;
-
- x_max = silk_int16_array_maxabs( frame, frame_length );
-
- if( x_max < silk_int16_MAX ) {
- /* Number of bits needed for the sum of the squares */
- nbits = 32 - silk_CLZ32( silk_SMULBB( x_max, x_max ) );
- } else {
- /* Here we don't know if x_max should have been silk_int16_MAX + 1, so we expect the worst case */
- nbits = 30;
- }
- nbits += 17 - silk_CLZ16( sum_sqr_len );
-
- /* Without a guarantee of saturation, we need to keep the 31st bit free */
- if( nbits < 31 ) {
- return 0;
- } else {
- return( nbits - 30 );
- }
-}
--- a/silk/scale_copy_vector16.c
+++ /dev/null
@@ -1,49 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-/* Copy and multiply a vector by a constant */
-void silk_scale_copy_vector16(
- opus_int16 *data_out,
- const opus_int16 *data_in,
- opus_int32 gain_Q16, /* (I): gain in Q16 */
- const opus_int dataSize /* (I): length */
-)
-{
- opus_int i;
- opus_int32 tmp32;
-
- for( i = 0; i < dataSize; i++ ) {
- tmp32 = silk_SMULWB( gain_Q16, data_in[ i ] );
- data_out[ i ] = (opus_int16)silk_CHECK_FIT16( tmp32 );
- }
-}
--- a/silk/scale_vector.c
+++ /dev/null
@@ -1,46 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-/* Multiply a vector by a constant */
-void silk_scale_vector32_Q26_lshift_18(
- opus_int32 *data1, /* (I/O): Q0/Q18 */
- opus_int32 gain_Q26, /* (I): Q26 */
- opus_int dataSize /* (I): length */
-)
-{
- opus_int i;
-
- for( i = 0; i < dataSize; i++ ) {
- data1[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_SMULL( data1[ i ], gain_Q26 ), 8 ) );/* OUTPUT: Q18*/
- }
-}
--- a/silk/schur.c
+++ /dev/null
@@ -1,92 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-/* Faster than schur64(), but much less accurate. */
-/* uses SMLAWB(), requiring armv5E and higher. */
-opus_int32 silk_schur( /* O: Returns residual energy */
- opus_int16 *rc_Q15, /* O: reflection coefficients [order] Q15 */
- const opus_int32 *c, /* I: correlations [order+1] */
- const opus_int32 order /* I: prediction order */
-)
-{
- opus_int k, n, lz;
- opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
- opus_int32 Ctmp1, Ctmp2, rc_tmp_Q15;
-
- silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
-
- /* Get number of leading zeros */
- lz = silk_CLZ32( c[ 0 ] );
-
- /* Copy correlations and adjust level to Q30 */
- if( lz < 2 ) {
- /* lz must be 1, so shift one to the right */
- for( k = 0; k < order + 1; k++ ) {
- C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 );
- }
- } else if( lz > 2 ) {
- /* Shift to the left */
- lz -= 2;
- for( k = 0; k < order + 1; k++ ) {
- C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz );
- }
- } else {
- /* No need to shift */
- for( k = 0; k < order + 1; k++ ) {
- C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
- }
- }
-
- for( k = 0; k < order; k++ ) {
-
- /* Get reflection coefficient */
- rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) );
-
- /* Clip (shouldn't happen for properly conditioned inputs) */
- rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 );
-
- /* Store */
- rc_Q15[ k ] = ( opus_int16 )rc_tmp_Q15;
-
- /* Update correlations */
- for( n = 0; n < order - k; n++ ) {
- Ctmp1 = C[ n + k + 1 ][ 0 ];
- Ctmp2 = C[ n ][ 1 ];
- C[ n + k + 1 ][ 0 ] = silk_SMLAWB( Ctmp1, silk_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 );
- C[ n ][ 1 ] = silk_SMLAWB( Ctmp2, silk_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 );
- }
- }
-
- /* return residual energy */
- return C[ 0 ][ 1 ];
-}
--- a/silk/schur64.c
+++ /dev/null
@@ -1,77 +1,0 @@
-/***********************************************************************
-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-/* Slower than schur(), but more accurate. */
-/* Uses SMULL(), available on armv4 */
-opus_int32 silk_schur64( /* O: Returns residual energy */
- opus_int32 rc_Q16[], /* O: Reflection coefficients [order] Q16 */
- const opus_int32 c[], /* I: Correlations [order+1] */
- opus_int32 order /* I: Prediction order */
-)
-{
- opus_int k, n;
- opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
- opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31;
-
- silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
-
- /* Check for invalid input */
- if( c[ 0 ] <= 0 ) {
- silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) );
- return 0;
- }
-
- for( k = 0; k < order + 1; k++ ) {
- C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
- }
-
- for( k = 0; k < order; k++ ) {
- /* Get reflection coefficient: divide two Q30 values and get result in Q31 */
- rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 );
-
- /* Save the output */
- rc_Q16[ k ] = silk_RSHIFT_ROUND( rc_tmp_Q31, 15 );
-
- /* Update correlations */
- for( n = 0; n < order - k; n++ ) {
- Ctmp1_Q30 = C[ n + k + 1 ][ 0 ];
- Ctmp2_Q30 = C[ n ][ 1 ];
-
- /* Multiply and add the highest int32 */
- C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 );
- C[ n ][ 1 ] = Ctmp2_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 );
- }
- }
-
- return( C[ 0 ][ 1 ] );
-}
--- a/silk/silk_common.vcxproj
+++ b/silk/silk_common.vcxproj
@@ -88,11 +88,7 @@
<ItemGroup>
<ClCompile Include="A2NLSF.c" />
<ClCompile Include="ana_filt_bank_1.c" />
- <ClCompile Include="apply_sine_window.c" />
- <ClCompile Include="array_maxabs.c" />
- <ClCompile Include="autocorr.c" />
<ClCompile Include="biquad_alt.c" />
- <ClCompile Include="burg_modified.c" />
<ClCompile Include="bwexpander.c" />
<ClCompile Include="bwexpander_32.c" />
<ClCompile Include="check_control_input.c" />
@@ -119,8 +115,6 @@
<ClCompile Include="init_encoder.c" />
<ClCompile Include="inner_prod_aligned.c" />
<ClCompile Include="interpolate.c" />
- <ClCompile Include="k2a.c" />
- <ClCompile Include="k2a_Q16.c" />
<ClCompile Include="lin2log.c" />
<ClCompile Include="log2lin.c" />
<ClCompile Include="LPC_analysis_filter.c" />
@@ -137,7 +131,6 @@
<ClCompile Include="NLSF_VQ_weights_laroia.c" />
<ClCompile Include="NSQ.c" />
<ClCompile Include="NSQ_del_dec.c" />
- <ClCompile Include="pitch_analysis_core.c" />
<ClCompile Include="pitch_est_tables.c" />
<ClCompile Include="PLC.c" />
<ClCompile Include="process_NLSFs.c" />
@@ -150,10 +143,6 @@
<ClCompile Include="resampler_private_IIR_FIR.c" />
<ClCompile Include="resampler_private_up2_HQ.c" />
<ClCompile Include="resampler_rom.c" />
- <ClCompile Include="scale_copy_vector16.c" />
- <ClCompile Include="scale_vector.c" />
- <ClCompile Include="schur.c" />
- <ClCompile Include="schur64.c" />
<ClCompile Include="shell_coder.c" />
<ClCompile Include="sigm_Q15.c" />
<ClCompile Include="sort.c" />
--- a/silk/silk_common.vcxproj.filters
+++ b/silk/silk_common.vcxproj.filters
@@ -24,21 +24,9 @@
<ClCompile Include="ana_filt_bank_1.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="apply_sine_window.c">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="array_maxabs.c">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="autocorr.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="biquad_alt.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="burg_modified.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="bwexpander.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -117,12 +105,6 @@
<ClCompile Include="interpolate.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="k2a.c">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="k2a_Q16.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="lin2log.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -171,9 +153,6 @@
<ClCompile Include="NSQ_del_dec.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="pitch_analysis_core.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="pitch_est_tables.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -208,18 +187,6 @@
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="resampler_rom.c">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="scale_copy_vector16.c">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="scale_vector.c">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="schur.c">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="schur64.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="shell_coder.c">
--- a/silk_sources.mk
+++ b/silk_sources.mk
@@ -45,18 +45,12 @@
silk/control_codec.c \
silk/A2NLSF.c \
silk/ana_filt_bank_1.c \
-silk/apply_sine_window.c \
-silk/array_maxabs.c \
-silk/autocorr.c \
silk/biquad_alt.c \
-silk/burg_modified.c \
silk/bwexpander_32.c \
silk/bwexpander.c \
silk/debug.c \
silk/decode_pitch.c \
silk/inner_prod_aligned.c \
-silk/k2a.c \
-silk/k2a_Q16.c \
silk/lin2log.c \
silk/log2lin.c \
silk/LPC_analysis_filter.c \
@@ -65,7 +59,6 @@
silk/NLSF2A.c \
silk/NLSF_stabilize.c \
silk/NLSF_VQ_weights_laroia.c \
-silk/pitch_analysis_core.c \
silk/pitch_est_tables.c \
silk/resampler.c \
silk/resampler_down2_3.c \
@@ -75,10 +68,6 @@
silk/resampler_private_IIR_FIR.c \
silk/resampler_private_up2_HQ.c \
silk/resampler_rom.c \
-silk/scale_copy_vector16.c \
-silk/scale_vector.c \
-silk/schur64.c \
-silk/schur.c \
silk/sigm_Q15.c \
silk/sort.c \
silk/sum_sqr_shift.c \
@@ -104,7 +93,16 @@
silk/fixed/residual_energy16_FIX.c \
silk/fixed/residual_energy_FIX.c \
silk/fixed/solve_LS_FIX.c \
-silk/fixed/warped_autocorrelation_FIX.c
+silk/fixed/warped_autocorrelation_FIX.c \
+silk/fixed/apply_sine_window_FIX.c \
+silk/fixed/autocorr_FIX.c \
+silk/fixed/burg_modified_FIX.c \
+silk/fixed/k2a_FIX.c \
+silk/fixed/k2a_Q16_FIX.c \
+silk/fixed/pitch_analysis_core_FIX.c \
+silk/fixed/vector_ops_FIX.c \
+silk/fixed/schur64_FIX.c \
+silk/fixed/schur_FIX.c
SILK_SOURCES_FLOAT = \
silk/float/apply_sine_window_FLP.c \