Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
90
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/LTP_analysis_filter_FIX.c
vendored
Normal file
90
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/LTP_analysis_filter_FIX.c
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
|
||||
void silk_LTP_analysis_filter_FIX(
|
||||
opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */
|
||||
const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */
|
||||
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */
|
||||
const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */
|
||||
const opus_int subfr_length, /* I Length of each subframe */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */
|
||||
)
|
||||
{
|
||||
const opus_int16 *x_ptr, *x_lag_ptr;
|
||||
opus_int16 Btmp_Q14[ LTP_ORDER ];
|
||||
opus_int16 *LTP_res_ptr;
|
||||
opus_int k, i;
|
||||
opus_int32 LTP_est;
|
||||
|
||||
x_ptr = x;
|
||||
LTP_res_ptr = LTP_res;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
|
||||
x_lag_ptr = x_ptr - pitchL[ k ];
|
||||
|
||||
Btmp_Q14[ 0 ] = LTPCoef_Q14[ k * LTP_ORDER ];
|
||||
Btmp_Q14[ 1 ] = LTPCoef_Q14[ k * LTP_ORDER + 1 ];
|
||||
Btmp_Q14[ 2 ] = LTPCoef_Q14[ k * LTP_ORDER + 2 ];
|
||||
Btmp_Q14[ 3 ] = LTPCoef_Q14[ k * LTP_ORDER + 3 ];
|
||||
Btmp_Q14[ 4 ] = LTPCoef_Q14[ k * LTP_ORDER + 4 ];
|
||||
|
||||
/* LTP analysis FIR filter */
|
||||
for( i = 0; i < subfr_length + pre_length; i++ ) {
|
||||
LTP_res_ptr[ i ] = x_ptr[ i ];
|
||||
|
||||
/* Long-term prediction */
|
||||
LTP_est = silk_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );
|
||||
LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 1 ], Btmp_Q14[ 1 ] );
|
||||
LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 0 ], Btmp_Q14[ 2 ] );
|
||||
LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -1 ], Btmp_Q14[ 3 ] );
|
||||
LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -2 ], Btmp_Q14[ 4 ] );
|
||||
|
||||
LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/
|
||||
|
||||
/* Subtract long-term prediction */
|
||||
LTP_res_ptr[ i ] = (opus_int16)silk_SAT16( (opus_int32)x_ptr[ i ] - LTP_est );
|
||||
|
||||
/* Scale residual */
|
||||
LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );
|
||||
|
||||
x_lag_ptr++;
|
||||
}
|
||||
|
||||
/* Update pointers */
|
||||
LTP_res_ptr += subfr_length + pre_length;
|
||||
x_ptr += subfr_length;
|
||||
}
|
||||
}
|
||||
|
53
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/LTP_scale_ctrl_FIX.c
vendored
Normal file
53
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/LTP_scale_ctrl_FIX.c
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
|
||||
/* Calculation of LTP state scaling */
|
||||
void silk_LTP_scale_ctrl_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
)
|
||||
{
|
||||
opus_int round_loss;
|
||||
|
||||
if( condCoding == CODE_INDEPENDENTLY ) {
|
||||
/* Only scale if first frame in packet */
|
||||
round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
|
||||
psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT(
|
||||
silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 );
|
||||
} else {
|
||||
/* Default is minimum scaling */
|
||||
psEnc->sCmn.indices.LTP_scaleIndex = 0;
|
||||
}
|
||||
psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ];
|
||||
}
|
101
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/apply_sine_window_FIX.c
vendored
Normal file
101
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/apply_sine_window_FIX.c
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 const 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;
|
||||
|
||||
celt_assert( win_type == 1 || win_type == 2 );
|
||||
|
||||
/* Length must be in a range from 16 to 120 and a multiple of 4 */
|
||||
celt_assert( length >= 16 && length <= 120 );
|
||||
celt_assert( ( length & 3 ) == 0 );
|
||||
|
||||
/* Frequency */
|
||||
k = ( length >> 2 ) - 4;
|
||||
celt_assert( k >= 0 && k <= 26 );
|
||||
f_Q16 = (opus_int)freq_table_Q16[ k ];
|
||||
|
||||
/* Factor used for cosine approximation */
|
||||
c_Q16 = silk_SMULWB( (opus_int32)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 = ( (opus_int32)1 << 16 );
|
||||
/* approximation of cos(f) */
|
||||
S1_Q16 = ( (opus_int32)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, ( (opus_int32)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, ( (opus_int32)1 << 16 ) );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2017 Google Inc.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_WARPED_AUTOCORRELATION_FIX_ARM_H
|
||||
# define SILK_WARPED_AUTOCORRELATION_FIX_ARM_H
|
||||
|
||||
# include "celt/arm/armcpu.h"
|
||||
|
||||
# if defined(FIXED_POINT)
|
||||
|
||||
# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
|
||||
void silk_warped_autocorrelation_FIX_neon(
|
||||
opus_int32 *corr, /* O Result [order + 1] */
|
||||
opus_int *scale, /* O Scaling of the correlation vector */
|
||||
const opus_int16 *input, /* I Input data to correlate */
|
||||
const opus_int warping_Q16, /* I Warping coefficient */
|
||||
const opus_int length, /* I Length of input */
|
||||
const opus_int order /* I Correlation order (even) */
|
||||
);
|
||||
|
||||
# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
|
||||
# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
|
||||
# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
|
||||
((void)(arch), PRESUME_NEON(silk_warped_autocorrelation_FIX)(corr, scale, input, warping_Q16, length, order))
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
|
||||
/*Is run-time CPU detection enabled on this platform?*/
|
||||
# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
|
||||
extern void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK+1])(opus_int32*, opus_int*, const opus_int16*, const opus_int, const opus_int, const opus_int);
|
||||
# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
|
||||
# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
|
||||
((*SILK_WARPED_AUTOCORRELATION_FIX_IMPL[(arch)&OPUS_ARCHMASK])(corr, scale, input, warping_Q16, length, order))
|
||||
# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
|
||||
# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
|
||||
# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
|
||||
((void)(arch), silk_warped_autocorrelation_FIX_neon(corr, scale, input, warping_Q16, length, order))
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# endif /* end FIXED_POINT */
|
||||
|
||||
#endif /* end SILK_WARPED_AUTOCORRELATION_FIX_ARM_H */
|
|
@ -0,0 +1,260 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2017 Google Inc., Jean-Marc Valin
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 <arm_neon.h>
|
||||
#ifdef OPUS_CHECK_ASM
|
||||
# include <string.h>
|
||||
#endif
|
||||
#include "stack_alloc.h"
|
||||
#include "main_FIX.h"
|
||||
|
||||
static OPUS_INLINE void calc_corr( const opus_int32 *const input_QS, opus_int64 *const corr_QC, const opus_int offset, const int32x4_t state_QS_s32x4 )
|
||||
{
|
||||
int64x2_t corr_QC_s64x2[ 2 ], t_s64x2[ 2 ];
|
||||
const int32x4_t input_QS_s32x4 = vld1q_s32( input_QS + offset );
|
||||
corr_QC_s64x2[ 0 ] = vld1q_s64( corr_QC + offset + 0 );
|
||||
corr_QC_s64x2[ 1 ] = vld1q_s64( corr_QC + offset + 2 );
|
||||
t_s64x2[ 0 ] = vmull_s32( vget_low_s32( state_QS_s32x4 ), vget_low_s32( input_QS_s32x4 ) );
|
||||
t_s64x2[ 1 ] = vmull_s32( vget_high_s32( state_QS_s32x4 ), vget_high_s32( input_QS_s32x4 ) );
|
||||
corr_QC_s64x2[ 0 ] = vsraq_n_s64( corr_QC_s64x2[ 0 ], t_s64x2[ 0 ], 2 * QS - QC );
|
||||
corr_QC_s64x2[ 1 ] = vsraq_n_s64( corr_QC_s64x2[ 1 ], t_s64x2[ 1 ], 2 * QS - QC );
|
||||
vst1q_s64( corr_QC + offset + 0, corr_QC_s64x2[ 0 ] );
|
||||
vst1q_s64( corr_QC + offset + 2, corr_QC_s64x2[ 1 ] );
|
||||
}
|
||||
|
||||
static OPUS_INLINE int32x4_t calc_state( const int32x4_t state_QS0_s32x4, const int32x4_t state_QS0_1_s32x4, const int32x4_t state_QS1_1_s32x4, const int32x4_t warping_Q16_s32x4 )
|
||||
{
|
||||
int32x4_t t_s32x4 = vsubq_s32( state_QS0_s32x4, state_QS0_1_s32x4 );
|
||||
t_s32x4 = vqdmulhq_s32( t_s32x4, warping_Q16_s32x4 );
|
||||
return vaddq_s32( state_QS1_1_s32x4, t_s32x4 );
|
||||
}
|
||||
|
||||
void silk_warped_autocorrelation_FIX_neon(
|
||||
opus_int32 *corr, /* O Result [order + 1] */
|
||||
opus_int *scale, /* O Scaling of the correlation vector */
|
||||
const opus_int16 *input, /* I Input data to correlate */
|
||||
const opus_int warping_Q16, /* I Warping coefficient */
|
||||
const opus_int length, /* I Length of input */
|
||||
const opus_int order /* I Correlation order (even) */
|
||||
)
|
||||
{
|
||||
if( ( MAX_SHAPE_LPC_ORDER > 24 ) || ( order < 6 ) ) {
|
||||
silk_warped_autocorrelation_FIX_c( corr, scale, input, warping_Q16, length, order );
|
||||
} else {
|
||||
opus_int n, i, lsh;
|
||||
opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* In reverse order */
|
||||
opus_int64 corr_QC_orderT;
|
||||
int64x2_t lsh_s64x2;
|
||||
const opus_int orderT = ( order + 3 ) & ~3;
|
||||
opus_int64 *corr_QCT;
|
||||
opus_int32 *input_QS;
|
||||
VARDECL( opus_int32, input_QST );
|
||||
VARDECL( opus_int32, state );
|
||||
SAVE_STACK;
|
||||
|
||||
/* Order must be even */
|
||||
silk_assert( ( order & 1 ) == 0 );
|
||||
silk_assert( 2 * QS - QC >= 0 );
|
||||
|
||||
ALLOC( input_QST, length + 2 * MAX_SHAPE_LPC_ORDER, opus_int32 );
|
||||
|
||||
input_QS = input_QST;
|
||||
/* input_QS has zero paddings in the beginning and end. */
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
|
||||
/* Loop over samples */
|
||||
for( n = 0; n < length - 7; n += 8, input_QS += 8 ) {
|
||||
const int16x8_t t0_s16x4 = vld1q_s16( input + n );
|
||||
vst1q_s32( input_QS + 0, vshll_n_s16( vget_low_s16( t0_s16x4 ), QS ) );
|
||||
vst1q_s32( input_QS + 4, vshll_n_s16( vget_high_s16( t0_s16x4 ), QS ) );
|
||||
}
|
||||
for( ; n < length; n++, input_QS++ ) {
|
||||
input_QS[ 0 ] = silk_LSHIFT32( (opus_int32)input[ n ], QS );
|
||||
}
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS += 4;
|
||||
vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
|
||||
input_QS = input_QST + MAX_SHAPE_LPC_ORDER - orderT;
|
||||
|
||||
/* The following loop runs ( length + order ) times, with ( order ) extra epilogues. */
|
||||
/* The zero paddings in input_QS guarantee corr_QC's correctness even with the extra epilogues. */
|
||||
/* The values of state_QS will be polluted by the extra epilogues, however they are temporary values. */
|
||||
|
||||
/* Keep the C code here to help understand the intrinsics optimization. */
|
||||
/*
|
||||
{
|
||||
opus_int32 state_QS[ 2 ][ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
||||
opus_int32 *state_QST[ 3 ];
|
||||
state_QST[ 0 ] = state_QS[ 0 ];
|
||||
state_QST[ 1 ] = state_QS[ 1 ];
|
||||
for( n = 0; n < length + order; n++, input_QS++ ) {
|
||||
state_QST[ 0 ][ orderT ] = input_QS[ orderT ];
|
||||
for( i = 0; i < orderT; i++ ) {
|
||||
corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( state_QST[ 0 ][ i ], input_QS[ i ] ), 2 * QS - QC );
|
||||
state_QST[ 1 ][ i ] = silk_SMLAWB( state_QST[ 1 ][ i + 1 ], state_QST[ 0 ][ i ] - state_QST[ 0 ][ i + 1 ], warping_Q16 );
|
||||
}
|
||||
state_QST[ 2 ] = state_QST[ 0 ];
|
||||
state_QST[ 0 ] = state_QST[ 1 ];
|
||||
state_QST[ 1 ] = state_QST[ 2 ];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
{
|
||||
const int32x4_t warping_Q16_s32x4 = vdupq_n_s32( warping_Q16 << 15 );
|
||||
const opus_int32 *in = input_QS + orderT;
|
||||
opus_int o = orderT;
|
||||
int32x4_t state_QS_s32x4[ 3 ][ 2 ];
|
||||
|
||||
ALLOC( state, length + orderT, opus_int32 );
|
||||
state_QS_s32x4[ 2 ][ 1 ] = vdupq_n_s32( 0 );
|
||||
|
||||
/* Calculate 8 taps of all inputs in each loop. */
|
||||
do {
|
||||
state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 0 ][ 1 ] =
|
||||
state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 1 ][ 1 ] = vdupq_n_s32( 0 );
|
||||
n = 0;
|
||||
do {
|
||||
calc_corr( input_QS + n, corr_QC, o - 8, state_QS_s32x4[ 0 ][ 0 ] );
|
||||
calc_corr( input_QS + n, corr_QC, o - 4, state_QS_s32x4[ 0 ][ 1 ] );
|
||||
state_QS_s32x4[ 2 ][ 1 ] = vld1q_s32( in + n );
|
||||
vst1q_lane_s32( state + n, state_QS_s32x4[ 0 ][ 0 ], 0 );
|
||||
state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 0 ][ 1 ], 1 );
|
||||
state_QS_s32x4[ 2 ][ 1 ] = vextq_s32( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], 1 );
|
||||
state_QS_s32x4[ 0 ][ 0 ] = calc_state( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], state_QS_s32x4[ 1 ][ 0 ], warping_Q16_s32x4 );
|
||||
state_QS_s32x4[ 0 ][ 1 ] = calc_state( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], state_QS_s32x4[ 1 ][ 1 ], warping_Q16_s32x4 );
|
||||
state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ];
|
||||
state_QS_s32x4[ 1 ][ 1 ] = state_QS_s32x4[ 2 ][ 1 ];
|
||||
} while( ++n < ( length + order ) );
|
||||
in = state;
|
||||
o -= 8;
|
||||
} while( o > 4 );
|
||||
|
||||
if( o ) {
|
||||
/* Calculate the last 4 taps of all inputs. */
|
||||
opus_int32 *stateT = state;
|
||||
silk_assert( o == 4 );
|
||||
state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 1 ][ 0 ] = vdupq_n_s32( 0 );
|
||||
n = length + order;
|
||||
do {
|
||||
calc_corr( input_QS, corr_QC, 0, state_QS_s32x4[ 0 ][ 0 ] );
|
||||
state_QS_s32x4[ 2 ][ 0 ] = vld1q_s32( stateT );
|
||||
vst1q_lane_s32( stateT, state_QS_s32x4[ 0 ][ 0 ], 0 );
|
||||
state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], 1 );
|
||||
state_QS_s32x4[ 0 ][ 0 ] = calc_state( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], state_QS_s32x4[ 1 ][ 0 ], warping_Q16_s32x4 );
|
||||
state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ];
|
||||
input_QS++;
|
||||
stateT++;
|
||||
} while( --n );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const opus_int16 *inputT = input;
|
||||
int32x4_t t_s32x4;
|
||||
int64x1_t t_s64x1;
|
||||
int64x2_t t_s64x2 = vdupq_n_s64( 0 );
|
||||
for( n = 0; n <= length - 8; n += 8 ) {
|
||||
int16x8_t input_s16x8 = vld1q_s16( inputT );
|
||||
t_s32x4 = vmull_s16( vget_low_s16( input_s16x8 ), vget_low_s16( input_s16x8 ) );
|
||||
t_s32x4 = vmlal_s16( t_s32x4, vget_high_s16( input_s16x8 ), vget_high_s16( input_s16x8 ) );
|
||||
t_s64x2 = vaddw_s32( t_s64x2, vget_low_s32( t_s32x4 ) );
|
||||
t_s64x2 = vaddw_s32( t_s64x2, vget_high_s32( t_s32x4 ) );
|
||||
inputT += 8;
|
||||
}
|
||||
t_s64x1 = vadd_s64( vget_low_s64( t_s64x2 ), vget_high_s64( t_s64x2 ) );
|
||||
corr_QC_orderT = vget_lane_s64( t_s64x1, 0 );
|
||||
for( ; n < length; n++ ) {
|
||||
corr_QC_orderT += silk_SMULL( input[ n ], input[ n ] );
|
||||
}
|
||||
corr_QC_orderT = silk_LSHIFT64( corr_QC_orderT, QC );
|
||||
corr_QC[ orderT ] = corr_QC_orderT;
|
||||
}
|
||||
|
||||
corr_QCT = corr_QC + orderT - order;
|
||||
lsh = silk_CLZ64( corr_QC_orderT ) - 35;
|
||||
lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
|
||||
*scale = -( QC + lsh );
|
||||
silk_assert( *scale >= -30 && *scale <= 12 );
|
||||
lsh_s64x2 = vdupq_n_s64( lsh );
|
||||
for( i = 0; i <= order - 3; i += 4 ) {
|
||||
int32x4_t corr_s32x4;
|
||||
int64x2_t corr_QC0_s64x2, corr_QC1_s64x2;
|
||||
corr_QC0_s64x2 = vld1q_s64( corr_QCT + i );
|
||||
corr_QC1_s64x2 = vld1q_s64( corr_QCT + i + 2 );
|
||||
corr_QC0_s64x2 = vshlq_s64( corr_QC0_s64x2, lsh_s64x2 );
|
||||
corr_QC1_s64x2 = vshlq_s64( corr_QC1_s64x2, lsh_s64x2 );
|
||||
corr_s32x4 = vcombine_s32( vmovn_s64( corr_QC1_s64x2 ), vmovn_s64( corr_QC0_s64x2 ) );
|
||||
corr_s32x4 = vrev64q_s32( corr_s32x4 );
|
||||
vst1q_s32( corr + order - i - 3, corr_s32x4 );
|
||||
}
|
||||
if( lsh >= 0 ) {
|
||||
for( ; i < order + 1; i++ ) {
|
||||
corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QCT[ i ], lsh ) );
|
||||
}
|
||||
} else {
|
||||
for( ; i < order + 1; i++ ) {
|
||||
corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QCT[ i ], -lsh ) );
|
||||
}
|
||||
}
|
||||
silk_assert( corr_QCT[ order ] >= 0 ); /* If breaking, decrease QC*/
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
#ifdef OPUS_CHECK_ASM
|
||||
{
|
||||
opus_int32 corr_c[ MAX_SHAPE_LPC_ORDER + 1 ];
|
||||
opus_int scale_c;
|
||||
silk_warped_autocorrelation_FIX_c( corr_c, &scale_c, input, warping_Q16, length, order );
|
||||
silk_assert( !memcmp( corr_c, corr, sizeof( corr_c[ 0 ] ) * ( order + 1 ) ) );
|
||||
silk_assert( scale_c == *scale );
|
||||
}
|
||||
#endif
|
||||
}
|
48
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/autocorr_FIX.c
vendored
Normal file
48
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/autocorr_FIX.c
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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"
|
||||
#include "celt_lpc.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 */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int corrCount;
|
||||
corrCount = silk_min_int( inputDataSize, correlationCount );
|
||||
*scale = _celt_autocorr(inputData, results, NULL, 0, corrCount-1, inputDataSize, arch);
|
||||
}
|
280
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/burg_modified_FIX.c
vendored
Normal file
280
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/burg_modified_FIX.c
vendored
Normal file
|
@ -0,0 +1,280 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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"
|
||||
#include "define.h"
|
||||
#include "tuning_parameters.h"
|
||||
#include "pitch.h"
|
||||
|
||||
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
|
||||
|
||||
#define QA 25
|
||||
#define N_BITS_HEAD_ROOM 3
|
||||
#define MIN_RSHIFTS -16
|
||||
#define MAX_RSHIFTS (32 - QA)
|
||||
|
||||
/* Compute reflection coefficients from input signal */
|
||||
void silk_burg_modified_c(
|
||||
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_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
|
||||
const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
|
||||
const opus_int nb_subfr, /* I Number of subframes stacked in x */
|
||||
const opus_int D, /* I Order */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int k, n, s, lz, rshifts, reached_max_gain;
|
||||
opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, 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 ];
|
||||
opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int64 C0_64;
|
||||
|
||||
celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||
|
||||
/* Compute autocorrelations, added over subframes */
|
||||
C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch );
|
||||
lz = silk_CLZ64(C0_64);
|
||||
rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz;
|
||||
if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS;
|
||||
if (rshifts < MIN_RSHIFTS) rshifts = MIN_RSHIFTS;
|
||||
|
||||
if (rshifts > 0) {
|
||||
C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts );
|
||||
} else {
|
||||
C0 = silk_LSHIFT32((opus_int32)C0_64, -rshifts );
|
||||
}
|
||||
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||
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, arch ), rshifts );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
int i;
|
||||
opus_int32 d;
|
||||
x_ptr = x + s * subfr_length;
|
||||
celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch );
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ )
|
||||
d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] );
|
||||
xcorr[ n - 1 ] += d;
|
||||
}
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts );
|
||||
}
|
||||
}
|
||||
}
|
||||
silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
||||
|
||||
/* Initialize */
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||
|
||||
invGain_Q30 = (opus_int32)1 << 30;
|
||||
reached_max_gain = 0;
|
||||
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 */
|
||||
/* We sometimes have get overflows in the multiplications (even beyond +/- 2^32),
|
||||
but they cancel each other and the real result seems to always fit in a 32-bit
|
||||
signed integer. This was determined experimentally, not theoretically (unfortunately). */
|
||||
tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
|
||||
tmp2 = silk_MLA_ovflw( 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 {
|
||||
rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;
|
||||
}
|
||||
|
||||
/* Update inverse prediction gain */
|
||||
tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
|
||||
tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );
|
||||
if( tmp1 <= minInvGain_Q30 ) {
|
||||
/* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
|
||||
tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
|
||||
rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
|
||||
if( rc_Q31 > 0 ) {
|
||||
/* Newton-Raphson iteration */
|
||||
rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
|
||||
rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
|
||||
if( num < 0 ) {
|
||||
/* Ensure adjusted reflection coefficients has the original sign */
|
||||
rc_Q31 = -rc_Q31;
|
||||
}
|
||||
}
|
||||
invGain_Q30 = minInvGain_Q30;
|
||||
reached_max_gain = 1;
|
||||
} else {
|
||||
invGain_Q30 = tmp1;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
||||
if( reached_max_gain ) {
|
||||
/* Reached max prediction gain; set remaining coefficients to zero and exit loop */
|
||||
for( k = n + 1; k < D; k++ ) {
|
||||
Af_QA[ k ] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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 ) */
|
||||
}
|
||||
}
|
||||
|
||||
if( reached_max_gain ) {
|
||||
for( k = 0; k < D; k++ ) {
|
||||
/* Scale coefficients */
|
||||
A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
|
||||
}
|
||||
/* Subtract energy of preceding samples from C0 */
|
||||
if( rshifts > 0 ) {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch), -rshifts);
|
||||
}
|
||||
}
|
||||
/* Approximate residual energy */
|
||||
*res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );
|
||||
*res_nrg_Q = -rshifts;
|
||||
} else {
|
||||
/* Return residual energy */
|
||||
nrg = CAf[ 0 ]; /* Q( -rshifts ) */
|
||||
tmp1 = (opus_int32)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( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
|
||||
*res_nrg_Q = -rshifts;
|
||||
}
|
||||
}
|
150
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/corrMatrix_FIX.c
vendored
Normal file
150
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/corrMatrix_FIX.c
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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
|
||||
|
||||
/**********************************************************************
|
||||
* Correlation Matrix Computations for LS estimate.
|
||||
**********************************************************************/
|
||||
|
||||
#include "main_FIX.h"
|
||||
|
||||
/* Calculates correlation vector X'*t */
|
||||
void silk_corrVector_FIX(
|
||||
const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
|
||||
const opus_int16 *t, /* I Target vector [L] */
|
||||
const opus_int L, /* I Length of vectors */
|
||||
const opus_int order, /* I Max lag for correlation */
|
||||
opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
|
||||
const opus_int rshifts, /* I Right shifts of correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int lag, i;
|
||||
const opus_int16 *ptr1, *ptr2;
|
||||
opus_int32 inner_prod;
|
||||
|
||||
ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
|
||||
ptr2 = t;
|
||||
/* Calculate X'*t */
|
||||
if( rshifts > 0 ) {
|
||||
/* Right shifting used */
|
||||
for( lag = 0; lag < order; lag++ ) {
|
||||
inner_prod = 0;
|
||||
for( i = 0; i < L; i++ ) {
|
||||
inner_prod = silk_ADD_RSHIFT32( inner_prod, silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
|
||||
}
|
||||
Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
|
||||
ptr1--; /* Go to next column of X */
|
||||
}
|
||||
} else {
|
||||
silk_assert( rshifts == 0 );
|
||||
for( lag = 0; lag < order; lag++ ) {
|
||||
Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L, arch ); /* X[:,lag]'*t */
|
||||
ptr1--; /* Go to next column of X */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates correlation matrix X'*X */
|
||||
void silk_corrMatrix_FIX(
|
||||
const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
|
||||
const opus_int L, /* I Length of vectors */
|
||||
const opus_int order, /* I Max lag for correlation */
|
||||
opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */
|
||||
opus_int32 *nrg, /* O Energy of x vector */
|
||||
opus_int *rshifts, /* O Right shifts of correlations and energy */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i, j, lag;
|
||||
opus_int32 energy;
|
||||
const opus_int16 *ptr1, *ptr2;
|
||||
|
||||
/* Calculate energy to find shift used to fit in 32 bits */
|
||||
silk_sum_sqr_shift( nrg, rshifts, x, L + order - 1 );
|
||||
energy = *nrg;
|
||||
|
||||
/* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */
|
||||
/* Remove contribution of first order - 1 samples */
|
||||
for( i = 0; i < order - 1; i++ ) {
|
||||
energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), *rshifts );
|
||||
}
|
||||
|
||||
/* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */
|
||||
/* Fill out the diagonal of the correlation matrix */
|
||||
matrix_ptr( XX, 0, 0, order ) = energy;
|
||||
silk_assert( energy >= 0 );
|
||||
ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */
|
||||
for( j = 1; j < order; j++ ) {
|
||||
energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), *rshifts ) );
|
||||
energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), *rshifts ) );
|
||||
matrix_ptr( XX, j, j, order ) = energy;
|
||||
silk_assert( energy >= 0 );
|
||||
}
|
||||
|
||||
ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */
|
||||
/* Calculate the remaining elements of the correlation matrix */
|
||||
if( *rshifts > 0 ) {
|
||||
/* Right shifting used */
|
||||
for( lag = 1; lag < order; lag++ ) {
|
||||
/* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
|
||||
energy = 0;
|
||||
for( i = 0; i < L; i++ ) {
|
||||
energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), *rshifts );
|
||||
}
|
||||
/* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
|
||||
matrix_ptr( XX, lag, 0, order ) = energy;
|
||||
matrix_ptr( XX, 0, lag, order ) = energy;
|
||||
for( j = 1; j < ( order - lag ); j++ ) {
|
||||
energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), *rshifts ) );
|
||||
energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), *rshifts ) );
|
||||
matrix_ptr( XX, lag + j, j, order ) = energy;
|
||||
matrix_ptr( XX, j, lag + j, order ) = energy;
|
||||
}
|
||||
ptr2--; /* Update pointer to first sample of next column (lag) in X */
|
||||
}
|
||||
} else {
|
||||
for( lag = 1; lag < order; lag++ ) {
|
||||
/* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
|
||||
energy = silk_inner_prod_aligned( ptr1, ptr2, L, arch );
|
||||
matrix_ptr( XX, lag, 0, order ) = energy;
|
||||
matrix_ptr( XX, 0, lag, order ) = energy;
|
||||
/* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
|
||||
for( j = 1; j < ( order - lag ); j++ ) {
|
||||
energy = silk_SUB32( energy, silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) );
|
||||
energy = silk_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] );
|
||||
matrix_ptr( XX, lag + j, j, order ) = energy;
|
||||
matrix_ptr( XX, j, lag + j, order ) = energy;
|
||||
}
|
||||
ptr2--;/* Update pointer to first sample of next column (lag) in X */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
448
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/encode_frame_FIX.c
vendored
Normal file
448
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/encode_frame_FIX.c
vendored
Normal file
|
@ -0,0 +1,448 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 <stdlib.h>
|
||||
#include "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */
|
||||
static OPUS_INLINE void silk_LBRR_encode_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
|
||||
const opus_int16 x16[], /* I Input signal */
|
||||
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
||||
);
|
||||
|
||||
void silk_encode_do_VAD_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
opus_int activity /* I Decision of Opus voice activity detector */
|
||||
)
|
||||
{
|
||||
const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
|
||||
|
||||
/****************************/
|
||||
/* Voice Activity Detection */
|
||||
/****************************/
|
||||
silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
|
||||
/* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */
|
||||
if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
|
||||
psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
/* Convert speech activity into VAD and DTX flags */
|
||||
/**************************************************/
|
||||
if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
|
||||
psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
|
||||
psEnc->sCmn.noSpeechCounter++;
|
||||
if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
|
||||
psEnc->sCmn.inDTX = 0;
|
||||
} else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
|
||||
psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
|
||||
psEnc->sCmn.inDTX = 0;
|
||||
}
|
||||
psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
|
||||
} else {
|
||||
psEnc->sCmn.noSpeechCounter = 0;
|
||||
psEnc->sCmn.inDTX = 0;
|
||||
psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
|
||||
psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/****************/
|
||||
/* Encode frame */
|
||||
/****************/
|
||||
opus_int silk_encode_frame_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */
|
||||
ec_enc *psRangeEnc, /* I/O compressor data structure */
|
||||
opus_int condCoding, /* I The type of conditional coding to use */
|
||||
opus_int maxBits, /* I If > 0: maximum number of output bits */
|
||||
opus_int useCBR /* I Flag to force constant-bitrate operation */
|
||||
)
|
||||
{
|
||||
silk_encoder_control_FIX sEncCtrl;
|
||||
opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
|
||||
opus_int16 *x_frame;
|
||||
ec_enc sRangeEnc_copy, sRangeEnc_copy2;
|
||||
silk_nsq_state sNSQ_copy, sNSQ_copy2;
|
||||
opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
|
||||
opus_int32 gainsID, gainsID_lower, gainsID_upper;
|
||||
opus_int16 gainMult_Q8;
|
||||
opus_int16 ec_prevLagIndex_copy;
|
||||
opus_int ec_prevSignalType_copy;
|
||||
opus_int8 LastGainIndex_copy2;
|
||||
opus_int gain_lock[ MAX_NB_SUBFR ] = {0};
|
||||
opus_int16 best_gain_mult[ MAX_NB_SUBFR ];
|
||||
opus_int best_sum[ MAX_NB_SUBFR ];
|
||||
SAVE_STACK;
|
||||
|
||||
/* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
|
||||
LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
|
||||
|
||||
psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
|
||||
|
||||
/**************************************************************/
|
||||
/* Set up Input Pointers, and insert frame in input buffer */
|
||||
/*************************************************************/
|
||||
/* start of frame to encode */
|
||||
x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;
|
||||
|
||||
/***************************************/
|
||||
/* Ensure smooth bandwidth transitions */
|
||||
/***************************************/
|
||||
silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
|
||||
|
||||
/*******************************************/
|
||||
/* Copy new frame to front of input buffer */
|
||||
/*******************************************/
|
||||
silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
|
||||
|
||||
if( !psEnc->sCmn.prefillFlag ) {
|
||||
VARDECL( opus_int16, res_pitch );
|
||||
VARDECL( opus_uint8, ec_buf_copy );
|
||||
opus_int16 *res_pitch_frame;
|
||||
|
||||
ALLOC( res_pitch,
|
||||
psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length
|
||||
+ psEnc->sCmn.ltp_mem_length, opus_int16 );
|
||||
/* start of pitch LPC residual frame */
|
||||
res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;
|
||||
|
||||
/*****************************************/
|
||||
/* Find pitch lags, initial LPC analysis */
|
||||
/*****************************************/
|
||||
silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch );
|
||||
|
||||
/************************/
|
||||
/* Noise shape analysis */
|
||||
/************************/
|
||||
silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch );
|
||||
|
||||
/***************************************************/
|
||||
/* Find linear prediction coefficients (LPC + LTP) */
|
||||
/***************************************************/
|
||||
silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
|
||||
|
||||
/****************************************/
|
||||
/* Process gains */
|
||||
/****************************************/
|
||||
silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
|
||||
|
||||
/****************************************/
|
||||
/* Low Bitrate Redundant Encoding */
|
||||
/****************************************/
|
||||
silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding );
|
||||
|
||||
/* Loop over quantizer and entropy coding to control bitrate */
|
||||
maxIter = 6;
|
||||
gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
|
||||
found_lower = 0;
|
||||
found_upper = 0;
|
||||
gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
|
||||
gainsID_lower = -1;
|
||||
gainsID_upper = -1;
|
||||
/* Copy part of the input state */
|
||||
silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
|
||||
silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
|
||||
seed_copy = psEnc->sCmn.indices.Seed;
|
||||
ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
|
||||
ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
|
||||
ALLOC( ec_buf_copy, 1275, opus_uint8 );
|
||||
for( iter = 0; ; iter++ ) {
|
||||
if( gainsID == gainsID_lower ) {
|
||||
nBits = nBits_lower;
|
||||
} else if( gainsID == gainsID_upper ) {
|
||||
nBits = nBits_upper;
|
||||
} else {
|
||||
/* Restore part of the input state */
|
||||
if( iter > 0 ) {
|
||||
silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
|
||||
silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
|
||||
psEnc->sCmn.indices.Seed = seed_copy;
|
||||
psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
|
||||
psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
|
||||
}
|
||||
|
||||
/*****************************************/
|
||||
/* Noise shaping quantization */
|
||||
/*****************************************/
|
||||
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
|
||||
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
|
||||
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
|
||||
psEnc->sCmn.arch );
|
||||
} else {
|
||||
silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
|
||||
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
|
||||
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
|
||||
psEnc->sCmn.arch);
|
||||
}
|
||||
|
||||
if ( iter == maxIter && !found_lower ) {
|
||||
silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
/* Encode Parameters */
|
||||
/****************************************/
|
||||
silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
|
||||
|
||||
/****************************************/
|
||||
/* Encode Excitation Signal */
|
||||
/****************************************/
|
||||
silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
|
||||
psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
|
||||
|
||||
nBits = ec_tell( psRangeEnc );
|
||||
|
||||
/* If we still bust after the last iteration, do some damage control. */
|
||||
if ( iter == maxIter && !found_lower && nBits > maxBits ) {
|
||||
silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
|
||||
|
||||
/* Keep gains the same as the last frame. */
|
||||
psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
|
||||
for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
psEnc->sCmn.indices.GainsIndices[ i ] = 4;
|
||||
}
|
||||
if (condCoding != CODE_CONDITIONALLY) {
|
||||
psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
|
||||
}
|
||||
psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
|
||||
psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
|
||||
/* Clear all pulses. */
|
||||
for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
|
||||
psEnc->sCmn.pulses[ i ] = 0;
|
||||
}
|
||||
|
||||
silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
|
||||
|
||||
silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
|
||||
psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
|
||||
|
||||
nBits = ec_tell( psRangeEnc );
|
||||
}
|
||||
|
||||
if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( iter == maxIter ) {
|
||||
if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
|
||||
/* Restore output state from earlier iteration that did meet the bitrate budget */
|
||||
silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
|
||||
celt_assert( sRangeEnc_copy2.offs <= 1275 );
|
||||
silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
|
||||
silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
|
||||
psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( nBits > maxBits ) {
|
||||
if( found_lower == 0 && iter >= 2 ) {
|
||||
/* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
|
||||
sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );
|
||||
found_upper = 0;
|
||||
gainsID_upper = -1;
|
||||
} else {
|
||||
found_upper = 1;
|
||||
nBits_upper = nBits;
|
||||
gainMult_upper = gainMult_Q8;
|
||||
gainsID_upper = gainsID;
|
||||
}
|
||||
} else if( nBits < maxBits - 5 ) {
|
||||
found_lower = 1;
|
||||
nBits_lower = nBits;
|
||||
gainMult_lower = gainMult_Q8;
|
||||
if( gainsID != gainsID_lower ) {
|
||||
gainsID_lower = gainsID;
|
||||
/* Copy part of the output state */
|
||||
silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
|
||||
celt_assert( psRangeEnc->offs <= 1275 );
|
||||
silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
|
||||
silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
|
||||
LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
|
||||
}
|
||||
} else {
|
||||
/* Within 5 bits of budget: close enough */
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !found_lower && nBits > maxBits ) {
|
||||
int j;
|
||||
for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
int sum=0;
|
||||
for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
|
||||
sum += abs( psEnc->sCmn.pulses[j] );
|
||||
}
|
||||
if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
|
||||
best_sum[i] = sum;
|
||||
best_gain_mult[i] = gainMult_Q8;
|
||||
} else {
|
||||
gain_lock[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ( found_lower & found_upper ) == 0 ) {
|
||||
/* Adjust gain according to high-rate rate/distortion curve */
|
||||
if( nBits > maxBits ) {
|
||||
if (gainMult_Q8 < 16384) {
|
||||
gainMult_Q8 *= 2;
|
||||
} else {
|
||||
gainMult_Q8 = 32767;
|
||||
}
|
||||
} else {
|
||||
opus_int32 gain_factor_Q16;
|
||||
gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
|
||||
gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Adjust gain by interpolating */
|
||||
gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
|
||||
/* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
|
||||
if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
|
||||
gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
|
||||
} else
|
||||
if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
|
||||
gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
opus_int16 tmp;
|
||||
if ( gain_lock[i] ) {
|
||||
tmp = best_gain_mult[i];
|
||||
} else {
|
||||
tmp = gainMult_Q8;
|
||||
}
|
||||
sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
|
||||
}
|
||||
|
||||
/* Quantize gains */
|
||||
psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
|
||||
silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
|
||||
&psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
|
||||
|
||||
/* Unique identifier of gains vector */
|
||||
gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
|
||||
}
|
||||
}
|
||||
|
||||
/* Update input buffer */
|
||||
silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
|
||||
( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
|
||||
|
||||
/* Exit without entropy coding */
|
||||
if( psEnc->sCmn.prefillFlag ) {
|
||||
/* No payload */
|
||||
*pnBytesOut = 0;
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Parameters needed for next frame */
|
||||
psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
|
||||
psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
|
||||
|
||||
/****************************************/
|
||||
/* Finalize payload */
|
||||
/****************************************/
|
||||
psEnc->sCmn.first_frame_after_reset = 0;
|
||||
/* Payload size */
|
||||
*pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
|
||||
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */
|
||||
static OPUS_INLINE void silk_LBRR_encode_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
|
||||
const opus_int16 x16[], /* I Input signal */
|
||||
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
||||
)
|
||||
{
|
||||
opus_int32 TempGains_Q16[ MAX_NB_SUBFR ];
|
||||
SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
|
||||
silk_nsq_state sNSQ_LBRR;
|
||||
|
||||
/*******************************************/
|
||||
/* Control use of inband LBRR */
|
||||
/*******************************************/
|
||||
if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
|
||||
psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
|
||||
|
||||
/* Copy noise shaping quantizer state and quantization indices from regular encoding */
|
||||
silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
|
||||
silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
|
||||
|
||||
/* Save original gains */
|
||||
silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
|
||||
|
||||
if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
|
||||
/* First frame in packet or previous frame not LBRR coded */
|
||||
psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
|
||||
|
||||
/* Increase Gains to get target LBRR rate */
|
||||
psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
|
||||
psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
|
||||
}
|
||||
|
||||
/* Decode to get gains in sync with decoder */
|
||||
/* Overwrite unquantized gains with quantized gains */
|
||||
silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
|
||||
&psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
|
||||
|
||||
/*****************************************/
|
||||
/* Noise shaping quantization */
|
||||
/*****************************************/
|
||||
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
|
||||
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
|
||||
psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
|
||||
psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
|
||||
} else {
|
||||
silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
|
||||
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
|
||||
psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
|
||||
psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
|
||||
}
|
||||
|
||||
/* Restore original gains */
|
||||
silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
|
||||
}
|
||||
}
|
151
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/find_LPC_FIX.c
vendored
Normal file
151
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/find_LPC_FIX.c
vendored
Normal file
|
@ -0,0 +1,151 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Finds LPC vector from correlations, and converts to NLSF */
|
||||
void silk_find_LPC_FIX(
|
||||
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||
opus_int16 NLSF_Q15[], /* O NLSFs */
|
||||
const opus_int16 x[], /* I Input signal */
|
||||
const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */
|
||||
)
|
||||
{
|
||||
opus_int k, subfr_length;
|
||||
opus_int32 a_Q16[ MAX_LPC_ORDER ];
|
||||
opus_int isInterpLower, shift;
|
||||
opus_int32 res_nrg0, res_nrg1;
|
||||
opus_int rshift0, rshift1;
|
||||
|
||||
/* Used only for LSF interpolation */
|
||||
opus_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg;
|
||||
opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;
|
||||
opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ];
|
||||
opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
|
||||
SAVE_STACK;
|
||||
|
||||
subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;
|
||||
|
||||
/* Default: no interpolation */
|
||||
psEncC->indices.NLSFInterpCoef_Q2 = 4;
|
||||
|
||||
/* Burg AR analysis for the full frame */
|
||||
silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
|
||||
VARDECL( opus_int16, LPC_res );
|
||||
|
||||
/* Optimal solution for last 10 ms */
|
||||
silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
/* subtract residual energy here, as that's easier than adding it to the */
|
||||
/* residual energy of the first 10 ms in each iteration of the search below */
|
||||
shift = res_tmp_nrg_Q - res_nrg_Q;
|
||||
if( shift >= 0 ) {
|
||||
if( shift < 32 ) {
|
||||
res_nrg = res_nrg - silk_RSHIFT( res_tmp_nrg, shift );
|
||||
}
|
||||
} else {
|
||||
silk_assert( shift > -32 );
|
||||
res_nrg = silk_RSHIFT( res_nrg, -shift ) - res_tmp_nrg;
|
||||
res_nrg_Q = res_tmp_nrg_Q;
|
||||
}
|
||||
|
||||
/* Convert to NLSFs */
|
||||
silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder );
|
||||
|
||||
ALLOC( LPC_res, 2 * subfr_length, opus_int16 );
|
||||
|
||||
/* Search over interpolation indices to find the one with lowest residual energy */
|
||||
for( k = 3; k >= 0; k-- ) {
|
||||
/* Interpolate NLSFs for first half */
|
||||
silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
|
||||
|
||||
/* Convert to LPC for residual energy evaluation */
|
||||
silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
/* Calculate residual energy with NLSF interpolation */
|
||||
silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder );
|
||||
silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder );
|
||||
|
||||
/* Add subframe energies from first half frame */
|
||||
shift = rshift0 - rshift1;
|
||||
if( shift >= 0 ) {
|
||||
res_nrg1 = silk_RSHIFT( res_nrg1, shift );
|
||||
res_nrg_interp_Q = -rshift0;
|
||||
} else {
|
||||
res_nrg0 = silk_RSHIFT( res_nrg0, -shift );
|
||||
res_nrg_interp_Q = -rshift1;
|
||||
}
|
||||
res_nrg_interp = silk_ADD32( res_nrg0, res_nrg1 );
|
||||
|
||||
/* Compare with first half energy without NLSF interpolation, or best interpolated value so far */
|
||||
shift = res_nrg_interp_Q - res_nrg_Q;
|
||||
if( shift >= 0 ) {
|
||||
if( silk_RSHIFT( res_nrg_interp, shift ) < res_nrg ) {
|
||||
isInterpLower = silk_TRUE;
|
||||
} else {
|
||||
isInterpLower = silk_FALSE;
|
||||
}
|
||||
} else {
|
||||
if( -shift < 32 ) {
|
||||
if( res_nrg_interp < silk_RSHIFT( res_nrg, -shift ) ) {
|
||||
isInterpLower = silk_TRUE;
|
||||
} else {
|
||||
isInterpLower = silk_FALSE;
|
||||
}
|
||||
} else {
|
||||
isInterpLower = silk_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine whether current interpolated NLSFs are best so far */
|
||||
if( isInterpLower == silk_TRUE ) {
|
||||
/* Interpolation has lower residual energy */
|
||||
res_nrg = res_nrg_interp;
|
||||
res_nrg_Q = res_nrg_interp_Q;
|
||||
psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
|
||||
/* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
|
||||
silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder );
|
||||
}
|
||||
|
||||
celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
|
||||
RESTORE_STACK;
|
||||
}
|
99
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/find_LTP_FIX.c
vendored
Normal file
99
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/find_LTP_FIX.c
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
void silk_find_LTP_FIX(
|
||||
opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */
|
||||
opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */
|
||||
const opus_int16 r_ptr[], /* I Residual signal after LPC */
|
||||
const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
|
||||
const opus_int subfr_length, /* I Subframe length */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i, k, extra_shifts;
|
||||
opus_int xx_shifts, xX_shifts, XX_shifts;
|
||||
const opus_int16 *lag_ptr;
|
||||
opus_int32 *XXLTP_Q17_ptr, *xXLTP_Q17_ptr;
|
||||
opus_int32 xx, nrg, temp;
|
||||
|
||||
xXLTP_Q17_ptr = xXLTP_Q17;
|
||||
XXLTP_Q17_ptr = XXLTP_Q17;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
|
||||
|
||||
silk_sum_sqr_shift( &xx, &xx_shifts, r_ptr, subfr_length + LTP_ORDER ); /* xx in Q( -xx_shifts ) */
|
||||
silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, XXLTP_Q17_ptr, &nrg, &XX_shifts, arch ); /* XXLTP_Q17_ptr and nrg in Q( -XX_shifts ) */
|
||||
extra_shifts = xx_shifts - XX_shifts;
|
||||
if( extra_shifts > 0 ) {
|
||||
/* Shift XX */
|
||||
xX_shifts = xx_shifts;
|
||||
for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
|
||||
XXLTP_Q17_ptr[ i ] = silk_RSHIFT32( XXLTP_Q17_ptr[ i ], extra_shifts ); /* Q( -xX_shifts ) */
|
||||
}
|
||||
nrg = silk_RSHIFT32( nrg, extra_shifts ); /* Q( -xX_shifts ) */
|
||||
} else if( extra_shifts < 0 ) {
|
||||
/* Shift xx */
|
||||
xX_shifts = XX_shifts;
|
||||
xx = silk_RSHIFT32( xx, -extra_shifts ); /* Q( -xX_shifts ) */
|
||||
} else {
|
||||
xX_shifts = xx_shifts;
|
||||
}
|
||||
silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xXLTP_Q17_ptr, xX_shifts, arch ); /* xXLTP_Q17_ptr in Q( -xX_shifts ) */
|
||||
|
||||
/* At this point all correlations are in Q(-xX_shifts) */
|
||||
temp = silk_SMLAWB( 1, nrg, SILK_FIX_CONST( LTP_CORR_INV_MAX, 16 ) );
|
||||
temp = silk_max( temp, xx );
|
||||
TIC(div)
|
||||
#if 0
|
||||
for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
|
||||
XXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( XXLTP_Q17_ptr[ i ], temp, 17 );
|
||||
}
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
xXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( xXLTP_Q17_ptr[ i ], temp, 17 );
|
||||
}
|
||||
#else
|
||||
for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
|
||||
XXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)XXLTP_Q17_ptr[ i ], 17 ) / temp );
|
||||
}
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
xXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)xXLTP_Q17_ptr[ i ], 17 ) / temp );
|
||||
}
|
||||
#endif
|
||||
TOC(div)
|
||||
r_ptr += subfr_length;
|
||||
XXLTP_Q17_ptr += LTP_ORDER * LTP_ORDER;
|
||||
xXLTP_Q17_ptr += LTP_ORDER;
|
||||
}
|
||||
}
|
143
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/find_pitch_lags_FIX.c
vendored
Normal file
143
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/find_pitch_lags_FIX.c
vendored
Normal file
|
@ -0,0 +1,143 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Find pitch lags */
|
||||
void silk_find_pitch_lags_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
opus_int16 res[], /* O residual */
|
||||
const opus_int16 x[], /* I Speech signal */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int buf_len, i, scale;
|
||||
opus_int32 thrhld_Q13, res_nrg;
|
||||
const opus_int16 *x_ptr;
|
||||
VARDECL( opus_int16, Wsig );
|
||||
opus_int16 *Wsig_ptr;
|
||||
opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
|
||||
opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||
opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||
opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||
SAVE_STACK;
|
||||
|
||||
/******************************************/
|
||||
/* Set up buffer lengths etc based on Fs */
|
||||
/******************************************/
|
||||
buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
|
||||
|
||||
/* Safety check */
|
||||
celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
|
||||
|
||||
/*************************************/
|
||||
/* Estimate LPC AR coefficients */
|
||||
/*************************************/
|
||||
|
||||
/* Calculate windowed signal */
|
||||
|
||||
ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 );
|
||||
|
||||
/* First LA_LTP samples */
|
||||
x_ptr = x + buf_len - psEnc->sCmn.pitch_LPC_win_length;
|
||||
Wsig_ptr = Wsig;
|
||||
silk_apply_sine_window( Wsig_ptr, x_ptr, 1, psEnc->sCmn.la_pitch );
|
||||
|
||||
/* Middle un - windowed samples */
|
||||
Wsig_ptr += psEnc->sCmn.la_pitch;
|
||||
x_ptr += psEnc->sCmn.la_pitch;
|
||||
silk_memcpy( Wsig_ptr, x_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );
|
||||
|
||||
/* Last LA_LTP samples */
|
||||
Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
|
||||
x_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
|
||||
silk_apply_sine_window( Wsig_ptr, x_ptr, 2, psEnc->sCmn.la_pitch );
|
||||
|
||||
/* Calculate autocorrelation sequence */
|
||||
silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch );
|
||||
|
||||
/* Add white noise, as fraction of energy */
|
||||
auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1;
|
||||
|
||||
/* Calculate the reflection coefficients using schur */
|
||||
res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );
|
||||
|
||||
/* Prediction gain */
|
||||
psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 );
|
||||
|
||||
/* Convert reflection coefficients to prediction coefficients */
|
||||
silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder );
|
||||
|
||||
/* Convert From 32 bit Q24 to 16 bit Q12 coefs */
|
||||
for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {
|
||||
A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) );
|
||||
}
|
||||
|
||||
/* Do BWE */
|
||||
silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) );
|
||||
|
||||
/*****************************************/
|
||||
/* LPC analysis filtering */
|
||||
/*****************************************/
|
||||
silk_LPC_analysis_filter( res, x, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch );
|
||||
|
||||
if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {
|
||||
/* Threshold for pitch estimator */
|
||||
thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 );
|
||||
thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder );
|
||||
thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 21 ), psEnc->sCmn.speech_activity_Q8 );
|
||||
thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15, 13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) );
|
||||
thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 14 ), psEnc->sCmn.input_tilt_Q15 );
|
||||
thrhld_Q13 = silk_SAT16( thrhld_Q13 );
|
||||
|
||||
/*****************************************/
|
||||
/* Call pitch estimator */
|
||||
/*****************************************/
|
||||
if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex,
|
||||
&psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16,
|
||||
(opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr,
|
||||
psEnc->sCmn.arch) == 0 )
|
||||
{
|
||||
psEnc->sCmn.indices.signalType = TYPE_VOICED;
|
||||
} else {
|
||||
psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
|
||||
}
|
||||
} else {
|
||||
silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) );
|
||||
psEnc->sCmn.indices.lagIndex = 0;
|
||||
psEnc->sCmn.indices.contourIndex = 0;
|
||||
psEnc->LTPCorr_Q15 = 0;
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
145
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/find_pred_coefs_FIX.c
vendored
Normal file
145
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/find_pred_coefs_FIX.c
vendored
Normal file
|
@ -0,0 +1,145 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
void silk_find_pred_coefs_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
const opus_int16 res_pitch[], /* I Residual from pitch analysis */
|
||||
const opus_int16 x[], /* I Speech signal */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ];
|
||||
opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
|
||||
const opus_int16 *x_ptr;
|
||||
opus_int16 *x_pre_ptr;
|
||||
VARDECL( opus_int16, LPC_in_pre );
|
||||
opus_int32 min_gain_Q16, minInvGain_Q30;
|
||||
SAVE_STACK;
|
||||
|
||||
/* weighting for weighted least squares */
|
||||
min_gain_Q16 = silk_int32_MAX >> 6;
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
min_gain_Q16 = silk_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] );
|
||||
}
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
/* Divide to Q16 */
|
||||
silk_assert( psEncCtrl->Gains_Q16[ i ] > 0 );
|
||||
/* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */
|
||||
invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 );
|
||||
|
||||
/* Limit inverse */
|
||||
invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 100 );
|
||||
|
||||
/* Square the inverted gains */
|
||||
silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) );
|
||||
|
||||
/* Invert the inverted and normalized gains */
|
||||
local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] );
|
||||
}
|
||||
|
||||
ALLOC( LPC_in_pre,
|
||||
psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder
|
||||
+ psEnc->sCmn.frame_length, opus_int16 );
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
VARDECL( opus_int32, xXLTP_Q17 );
|
||||
VARDECL( opus_int32, XXLTP_Q17 );
|
||||
|
||||
/**********/
|
||||
/* VOICED */
|
||||
/**********/
|
||||
celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
|
||||
|
||||
ALLOC( xXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER, opus_int32 );
|
||||
ALLOC( XXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );
|
||||
|
||||
/* LTP analysis */
|
||||
silk_find_LTP_FIX( XXLTP_Q17, xXLTP_Q17, res_pitch,
|
||||
psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
|
||||
|
||||
/* Quantize LTP gain parameters */
|
||||
silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
|
||||
&psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain_Q7, XXLTP_Q17, xXLTP_Q17, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
|
||||
|
||||
/* Control LTP scaling */
|
||||
silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding );
|
||||
|
||||
/* Create LTP residual */
|
||||
silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14,
|
||||
psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
|
||||
|
||||
} else {
|
||||
/************/
|
||||
/* UNVOICED */
|
||||
/************/
|
||||
/* Create signal with prepended subframes, scaled by inverse gains */
|
||||
x_ptr = x - psEnc->sCmn.predictLPCOrder;
|
||||
x_pre_ptr = LPC_in_pre;
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ],
|
||||
psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
|
||||
x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
|
||||
x_ptr += psEnc->sCmn.subfr_length;
|
||||
}
|
||||
|
||||
silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) );
|
||||
psEncCtrl->LTPredCodGain_Q7 = 0;
|
||||
psEnc->sCmn.sum_log_gain_Q7 = 0;
|
||||
}
|
||||
|
||||
/* Limit on total predictive coding gain */
|
||||
if( psEnc->sCmn.first_frame_after_reset ) {
|
||||
minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 );
|
||||
} else {
|
||||
minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */
|
||||
minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30,
|
||||
silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ),
|
||||
silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 );
|
||||
}
|
||||
|
||||
/* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
|
||||
silk_find_LPC_FIX( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain_Q30 );
|
||||
|
||||
/* Quantize LSFs */
|
||||
silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
|
||||
|
||||
/* Calculate residual energy using quantized LPC coefficients */
|
||||
silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains,
|
||||
psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder, psEnc->sCmn.arch );
|
||||
|
||||
/* Copy to prediction struct for use in next frame for interpolation */
|
||||
silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
|
||||
RESTORE_STACK;
|
||||
}
|
54
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/k2a_FIX.c
vendored
Normal file
54
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/k2a_FIX.c
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 rc, tmp1, tmp2;
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
rc = rc_Q15[ k ];
|
||||
for( n = 0; n < (k + 1) >> 1; n++ ) {
|
||||
tmp1 = A_Q24[ n ];
|
||||
tmp2 = A_Q24[ k - n - 1 ];
|
||||
A_Q24[ n ] = silk_SMLAWB( tmp1, silk_LSHIFT( tmp2, 1 ), rc );
|
||||
A_Q24[ k - n - 1 ] = silk_SMLAWB( tmp2, silk_LSHIFT( tmp1, 1 ), rc );
|
||||
}
|
||||
A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 );
|
||||
}
|
||||
}
|
54
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/k2a_Q16_FIX.c
vendored
Normal file
54
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/k2a_Q16_FIX.c
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 rc, tmp1, tmp2;
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
rc = rc_Q16[ k ];
|
||||
for( n = 0; n < (k + 1) >> 1; n++ ) {
|
||||
tmp1 = A_Q24[ n ];
|
||||
tmp2 = A_Q24[ k - n - 1 ];
|
||||
A_Q24[ n ] = silk_SMLAWW( tmp1, tmp2, rc );
|
||||
A_Q24[ k - n - 1 ] = silk_SMLAWW( tmp2, tmp1, rc );
|
||||
}
|
||||
A_Q24[ k ] = -silk_LSHIFT( rc, 8 );
|
||||
}
|
||||
}
|
244
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/main_FIX.h
vendored
Normal file
244
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/main_FIX.h
vendored
Normal file
|
@ -0,0 +1,244 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_MAIN_FIX_H
|
||||
#define SILK_MAIN_FIX_H
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "structs_FIX.h"
|
||||
#include "control.h"
|
||||
#include "main.h"
|
||||
#include "PLC.h"
|
||||
#include "debug.h"
|
||||
#include "entenc.h"
|
||||
|
||||
#if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \
|
||||
|| defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
|
||||
#include "fixed/arm/warped_autocorrelation_FIX_arm.h"
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_CPP_BUILD
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define silk_encoder_state_Fxx silk_encoder_state_FIX
|
||||
#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FIX
|
||||
#define silk_encode_frame_Fxx silk_encode_frame_FIX
|
||||
|
||||
#define QC 10
|
||||
#define QS 13
|
||||
|
||||
/*********************/
|
||||
/* Encoder Functions */
|
||||
/*********************/
|
||||
|
||||
/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
|
||||
void silk_HP_variable_cutoff(
|
||||
silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */
|
||||
);
|
||||
|
||||
/* Encoder main function */
|
||||
void silk_encode_do_VAD_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
opus_int activity /* I Decision of Opus voice activity detector */
|
||||
);
|
||||
|
||||
/* Encoder main function */
|
||||
opus_int silk_encode_frame_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */
|
||||
ec_enc *psRangeEnc, /* I/O compressor data structure */
|
||||
opus_int condCoding, /* I The type of conditional coding to use */
|
||||
opus_int maxBits, /* I If > 0: maximum number of output bits */
|
||||
opus_int useCBR /* I Flag to force constant-bitrate operation */
|
||||
);
|
||||
|
||||
/* Initializes the Silk encoder state */
|
||||
opus_int silk_init_encoder(
|
||||
silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Control the Silk encoder */
|
||||
opus_int silk_control_encoder(
|
||||
silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
|
||||
silk_EncControlStruct *encControl, /* I Control structure */
|
||||
const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
|
||||
const opus_int channelNb, /* I Channel number */
|
||||
const opus_int force_fs_kHz
|
||||
);
|
||||
|
||||
/**************************/
|
||||
/* Noise shaping analysis */
|
||||
/**************************/
|
||||
/* Compute noise shaping coefficients and initial gain values */
|
||||
void silk_noise_shape_analysis_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
|
||||
const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
|
||||
const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Autocorrelations for a warped frequency axis */
|
||||
void silk_warped_autocorrelation_FIX_c(
|
||||
opus_int32 *corr, /* O Result [order + 1] */
|
||||
opus_int *scale, /* O Scaling of the correlation vector */
|
||||
const opus_int16 *input, /* I Input data to correlate */
|
||||
const opus_int warping_Q16, /* I Warping coefficient */
|
||||
const opus_int length, /* I Length of input */
|
||||
const opus_int order /* I Correlation order (even) */
|
||||
);
|
||||
|
||||
#if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
|
||||
#define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
|
||||
((void)(arch), silk_warped_autocorrelation_FIX_c(corr, scale, input, warping_Q16, length, order))
|
||||
#endif
|
||||
|
||||
/* Calculation of LTP state scaling */
|
||||
void silk_LTP_scale_ctrl_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
);
|
||||
|
||||
/**********************************************/
|
||||
/* Prediction Analysis */
|
||||
/**********************************************/
|
||||
/* Find pitch lags */
|
||||
void silk_find_pitch_lags_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
opus_int16 res[], /* O residual */
|
||||
const opus_int16 x[], /* I Speech signal */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Find LPC and LTP coefficients */
|
||||
void silk_find_pred_coefs_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
const opus_int16 res_pitch[], /* I Residual from pitch analysis */
|
||||
const opus_int16 x[], /* I Speech signal */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
);
|
||||
|
||||
/* LPC analysis */
|
||||
void silk_find_LPC_FIX(
|
||||
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||
opus_int16 NLSF_Q15[], /* O NLSFs */
|
||||
const opus_int16 x[], /* I Input signal */
|
||||
const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */
|
||||
);
|
||||
|
||||
/* LTP analysis */
|
||||
void silk_find_LTP_FIX(
|
||||
opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */
|
||||
opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */
|
||||
const opus_int16 r_lpc[], /* I Residual signal after LPC */
|
||||
const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
|
||||
const opus_int subfr_length, /* I Subframe length */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
void silk_LTP_analysis_filter_FIX(
|
||||
opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */
|
||||
const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */
|
||||
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */
|
||||
const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */
|
||||
const opus_int subfr_length, /* I Length of each subframe */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */
|
||||
);
|
||||
|
||||
/* Calculates residual energies of input subframes where all subframes have LPC_order */
|
||||
/* of preceding samples */
|
||||
void silk_residual_energy_FIX(
|
||||
opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
|
||||
opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */
|
||||
const opus_int16 x[], /* I Input signal */
|
||||
opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
|
||||
const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */
|
||||
const opus_int subfr_length, /* I Subframe length */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
const opus_int LPC_order, /* I LPC order */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
|
||||
opus_int32 silk_residual_energy16_covar_FIX(
|
||||
const opus_int16 *c, /* I Prediction vector */
|
||||
const opus_int32 *wXX, /* I Correlation matrix */
|
||||
const opus_int32 *wXx, /* I Correlation vector */
|
||||
opus_int32 wxx, /* I Signal energy */
|
||||
opus_int D, /* I Dimension */
|
||||
opus_int cQ /* I Q value for c vector 0 - 15 */
|
||||
);
|
||||
|
||||
/* Processing of gains */
|
||||
void silk_process_gains_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
);
|
||||
|
||||
/******************/
|
||||
/* Linear Algebra */
|
||||
/******************/
|
||||
/* Calculates correlation matrix X'*X */
|
||||
void silk_corrMatrix_FIX(
|
||||
const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
|
||||
const opus_int L, /* I Length of vectors */
|
||||
const opus_int order, /* I Max lag for correlation */
|
||||
opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */
|
||||
opus_int32 *nrg, /* O Energy of x vector */
|
||||
opus_int *rshifts, /* O Right shifts of correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Calculates correlation vector X'*t */
|
||||
void silk_corrVector_FIX(
|
||||
const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
|
||||
const opus_int16 *t, /* I Target vector [L] */
|
||||
const opus_int L, /* I Length of vectors */
|
||||
const opus_int order, /* I Max lag for correlation */
|
||||
opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
|
||||
const opus_int rshifts, /* I Right shifts of correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
#ifndef FORCE_CPP_BUILD
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* FORCE_CPP_BUILD */
|
||||
#endif /* SILK_MAIN_FIX_H */
|
|
@ -0,0 +1,336 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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.
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/**************************************************************/
|
||||
/* Compute noise shaping coefficients and initial gain values */
|
||||
/**************************************************************/
|
||||
#define OVERRIDE_silk_noise_shape_analysis_FIX
|
||||
|
||||
void silk_noise_shape_analysis_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
|
||||
const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
|
||||
const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
|
||||
opus_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
|
||||
opus_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
|
||||
opus_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
|
||||
opus_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
|
||||
opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
|
||||
opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
|
||||
opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ];
|
||||
opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ];
|
||||
VARDECL( opus_int16, x_windowed );
|
||||
const opus_int16 *x_ptr, *pitch_res_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
/* Point to start of first LPC analysis block */
|
||||
x_ptr = x - psEnc->sCmn.la_shape;
|
||||
|
||||
/****************/
|
||||
/* GAIN CONTROL */
|
||||
/****************/
|
||||
SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
|
||||
|
||||
/* Input quality is the average of the quality in the lowest two VAD bands */
|
||||
psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
|
||||
+ psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
|
||||
|
||||
/* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
|
||||
psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
|
||||
SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
|
||||
|
||||
/* Reduce coding SNR during low speech activity */
|
||||
if( psEnc->sCmn.useCBR == 0 ) {
|
||||
b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
|
||||
b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
|
||||
silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/
|
||||
silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/
|
||||
}
|
||||
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Reduce gains for periodic signals */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
|
||||
} else {
|
||||
/* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
|
||||
silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
|
||||
SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* SPARSENESS PROCESSING */
|
||||
/*************************/
|
||||
/* Set quantizer offset */
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Initially set to 0; may be overruled in process_gains(..) */
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
psEncCtrl->sparseness_Q8 = 0;
|
||||
} else {
|
||||
/* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
|
||||
nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
|
||||
energy_variation_Q7 = 0;
|
||||
log_energy_prev_Q7 = 0;
|
||||
pitch_res_ptr = pitch_res;
|
||||
for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
|
||||
silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
|
||||
nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/
|
||||
|
||||
log_energy_Q7 = silk_lin2log( nrg );
|
||||
if( k > 0 ) {
|
||||
energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );
|
||||
}
|
||||
log_energy_prev_Q7 = log_energy_Q7;
|
||||
pitch_res_ptr += nSamples;
|
||||
}
|
||||
|
||||
psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 -
|
||||
SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );
|
||||
|
||||
/* Set quantization offset depending on sparseness measure */
|
||||
if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
} else {
|
||||
psEnc->sCmn.indices.quantOffsetType = 1;
|
||||
}
|
||||
|
||||
/* Increase coding SNR for sparse signals */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) );
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
/* Control bandwidth expansion */
|
||||
/*******************************/
|
||||
/* More BWE for signals with high prediction gain */
|
||||
strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
|
||||
BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
|
||||
silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
|
||||
delta_Q16 = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),
|
||||
SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );
|
||||
BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 );
|
||||
BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 );
|
||||
/* BWExp1 will be applied after BWExp2, so make it relative */
|
||||
BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) );
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
|
||||
warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
|
||||
} else {
|
||||
warping_Q16 = 0;
|
||||
}
|
||||
|
||||
/********************************************/
|
||||
/* Compute noise shaping AR coefs and gains */
|
||||
/********************************************/
|
||||
ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
/* Apply window: sine slope followed by flat part followed by cosine slope */
|
||||
opus_int shift, slope_part, flat_part;
|
||||
flat_part = psEnc->sCmn.fs_kHz * 3;
|
||||
slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
|
||||
|
||||
silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
|
||||
shift = slope_part;
|
||||
silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
|
||||
shift += flat_part;
|
||||
silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
|
||||
|
||||
/* Update pointer: next LPC analysis block */
|
||||
x_ptr += psEnc->sCmn.subfr_length;
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Calculate warped auto correlation */
|
||||
silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
|
||||
} else {
|
||||
/* Calculate regular auto correlation */
|
||||
silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
|
||||
}
|
||||
|
||||
/* Add white noise, as a fraction of energy */
|
||||
auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),
|
||||
SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
|
||||
|
||||
/* Calculate the reflection coefficients using schur */
|
||||
nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_assert( nrg >= 0 );
|
||||
|
||||
/* Convert reflection coefficients to prediction coefficients */
|
||||
silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
Qnrg = -scale; /* range: -12...30*/
|
||||
silk_assert( Qnrg >= -12 );
|
||||
silk_assert( Qnrg <= 30 );
|
||||
|
||||
/* Make sure that Qnrg is an even number */
|
||||
if( Qnrg & 1 ) {
|
||||
Qnrg -= 1;
|
||||
nrg >>= 1;
|
||||
}
|
||||
|
||||
tmp32 = silk_SQRT_APPROX( nrg );
|
||||
Qnrg >>= 1; /* range: -6...15*/
|
||||
|
||||
psEncCtrl->Gains_Q16[ k ] = (silk_LSHIFT32( silk_LIMIT( (tmp32), silk_RSHIFT32( silk_int32_MIN, (16 - Qnrg) ), \
|
||||
silk_RSHIFT32( silk_int32_MAX, (16 - Qnrg) ) ), (16 - Qnrg) ));
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Adjust gain for warping */
|
||||
gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
|
||||
if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
|
||||
} else {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Bandwidth expansion for synthesis filter shaping */
|
||||
silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );
|
||||
|
||||
/* Compute noise shaping filter coefficients */
|
||||
silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );
|
||||
|
||||
/* Bandwidth expansion for analysis filter shaping */
|
||||
silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );
|
||||
silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
|
||||
|
||||
/* Ratio of prediction gains, in energy domain */
|
||||
pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder, arch );
|
||||
nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder, arch );
|
||||
|
||||
/*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
|
||||
pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
|
||||
psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );
|
||||
|
||||
/* Convert to monic warped prediction coefficients and limit absolute values */
|
||||
limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
/* Convert from Q24 to Q13 and store in int16 */
|
||||
for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
|
||||
psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );
|
||||
psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************/
|
||||
/* Gain tweaking */
|
||||
/*****************/
|
||||
/* Increase gains during low speech activity and put lower limit on gains */
|
||||
gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
|
||||
gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) );
|
||||
silk_assert( gain_mult_Q16 > 0 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
|
||||
}
|
||||
|
||||
gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ),
|
||||
psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Control low-frequency shaping and noise tilt */
|
||||
/************************************************/
|
||||
/* Less low frequency shaping for noisy inputs */
|
||||
strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
|
||||
SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
|
||||
strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
|
||||
/*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
|
||||
opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );
|
||||
/* Pack two coefficients in one int32 */
|
||||
psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );
|
||||
psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
|
||||
}
|
||||
silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/
|
||||
Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
|
||||
silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
|
||||
silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
|
||||
} else {
|
||||
b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/
|
||||
/* Pack two coefficients in one int32 */
|
||||
psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
|
||||
silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
|
||||
psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
|
||||
for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
|
||||
}
|
||||
Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* HARMONIC SHAPING CONTROL */
|
||||
/****************************/
|
||||
/* Control boosting of harmonic frequencies */
|
||||
HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),
|
||||
psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );
|
||||
|
||||
/* More harmonic boost for noisy input signals */
|
||||
HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16,
|
||||
SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );
|
||||
|
||||
if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* More harmonic noise shaping for high bitrates or noisy input */
|
||||
HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
|
||||
SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
|
||||
psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
|
||||
|
||||
/* Less harmonic noise shaping for less periodic signals */
|
||||
HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),
|
||||
silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
|
||||
} else {
|
||||
HarmShapeGain_Q16 = 0;
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* Smooth over subframes */
|
||||
/*************************/
|
||||
for( k = 0; k < MAX_NB_SUBFR; k++ ) {
|
||||
psShapeSt->HarmBoost_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
psShapeSt->HarmShapeGain_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
psShapeSt->Tilt_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
|
||||
psEncCtrl->HarmBoost_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 );
|
||||
psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
|
||||
psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 );
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__
|
||||
#define __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "main_FIX.h"
|
||||
|
||||
#undef QC
|
||||
#define QC 10
|
||||
|
||||
#undef QS
|
||||
#define QS 14
|
||||
|
||||
/* Autocorrelations for a warped frequency axis */
|
||||
#define OVERRIDE_silk_warped_autocorrelation_FIX_c
|
||||
void silk_warped_autocorrelation_FIX_c(
|
||||
opus_int32 *corr, /* O Result [order + 1] */
|
||||
opus_int *scale, /* O Scaling of the correlation vector */
|
||||
const opus_int16 *input, /* I Input data to correlate */
|
||||
const opus_int warping_Q16, /* I Warping coefficient */
|
||||
const opus_int length, /* I Length of input */
|
||||
const opus_int order /* I Correlation order (even) */
|
||||
)
|
||||
{
|
||||
opus_int n, i, lsh;
|
||||
opus_int32 tmp1_QS=0, tmp2_QS=0, tmp3_QS=0, tmp4_QS=0, tmp5_QS=0, tmp6_QS=0, tmp7_QS=0, tmp8_QS=0, start_1=0, start_2=0, start_3=0;
|
||||
opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
||||
opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
||||
opus_int64 temp64;
|
||||
|
||||
opus_int32 val;
|
||||
val = 2 * QS - QC;
|
||||
|
||||
/* Order must be even */
|
||||
silk_assert( ( order & 1 ) == 0 );
|
||||
silk_assert( 2 * QS - QC >= 0 );
|
||||
|
||||
/* Loop over samples */
|
||||
for( n = 0; n < length; n=n+4 ) {
|
||||
|
||||
tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
|
||||
start_1 = tmp1_QS;
|
||||
tmp3_QS = silk_LSHIFT32( (opus_int32)input[ n+1], QS );
|
||||
start_2 = tmp3_QS;
|
||||
tmp5_QS = silk_LSHIFT32( (opus_int32)input[ n+2], QS );
|
||||
start_3 = tmp5_QS;
|
||||
tmp7_QS = silk_LSHIFT32( (opus_int32)input[ n+3], QS );
|
||||
|
||||
/* Loop over allpass sections */
|
||||
for( i = 0; i < order; i += 2 ) {
|
||||
/* Output of allpass section */
|
||||
tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
|
||||
corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, start_1);
|
||||
|
||||
tmp4_QS = silk_SMLAWB( tmp1_QS, tmp2_QS - tmp3_QS, warping_Q16 );
|
||||
corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp3_QS, start_2);
|
||||
|
||||
tmp6_QS = silk_SMLAWB( tmp3_QS, tmp4_QS - tmp5_QS, warping_Q16 );
|
||||
corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp5_QS, start_3);
|
||||
|
||||
tmp8_QS = silk_SMLAWB( tmp5_QS, tmp6_QS - tmp7_QS, warping_Q16 );
|
||||
state_QS[ i ] = tmp7_QS;
|
||||
corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp7_QS, state_QS[0]);
|
||||
|
||||
/* Output of allpass section */
|
||||
tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
|
||||
corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, start_1);
|
||||
|
||||
tmp3_QS = silk_SMLAWB( tmp2_QS, tmp1_QS - tmp4_QS, warping_Q16 );
|
||||
corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp4_QS, start_2);
|
||||
|
||||
tmp5_QS = silk_SMLAWB( tmp4_QS, tmp3_QS - tmp6_QS, warping_Q16 );
|
||||
corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp6_QS, start_3);
|
||||
|
||||
tmp7_QS = silk_SMLAWB( tmp6_QS, tmp5_QS - tmp8_QS, warping_Q16 );
|
||||
state_QS[ i + 1 ] = tmp8_QS;
|
||||
corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp8_QS, state_QS[ 0 ]);
|
||||
|
||||
}
|
||||
state_QS[ order ] = tmp7_QS;
|
||||
|
||||
corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, start_1);
|
||||
corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp3_QS, start_2);
|
||||
corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp5_QS, start_3);
|
||||
corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp7_QS, state_QS[ 0 ]);
|
||||
}
|
||||
|
||||
for(;n< length; n++ ) {
|
||||
|
||||
tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
|
||||
|
||||
/* Loop over allpass sections */
|
||||
for( i = 0; i < order; i += 2 ) {
|
||||
|
||||
/* Output of allpass section */
|
||||
tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
|
||||
state_QS[ i ] = tmp1_QS;
|
||||
corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, state_QS[ 0 ]);
|
||||
|
||||
/* Output of allpass section */
|
||||
tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
|
||||
state_QS[ i + 1 ] = tmp2_QS;
|
||||
corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, state_QS[ 0 ]);
|
||||
}
|
||||
state_QS[ order ] = tmp1_QS;
|
||||
corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, state_QS[ 0 ]);
|
||||
}
|
||||
|
||||
temp64 = corr_QC[ 0 ];
|
||||
temp64 = __builtin_mips_shilo(temp64, val);
|
||||
|
||||
lsh = silk_CLZ64( temp64 ) - 35;
|
||||
lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
|
||||
*scale = -( QC + lsh );
|
||||
silk_assert( *scale >= -30 && *scale <= 12 );
|
||||
if( lsh >= 0 ) {
|
||||
for( i = 0; i < order + 1; i++ ) {
|
||||
temp64 = corr_QC[ i ];
|
||||
//temp64 = __builtin_mips_shilo(temp64, val);
|
||||
temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val);
|
||||
corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) );
|
||||
}
|
||||
} else {
|
||||
for( i = 0; i < order + 1; i++ ) {
|
||||
temp64 = corr_QC[ i ];
|
||||
//temp64 = __builtin_mips_shilo(temp64, val);
|
||||
temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val);
|
||||
corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) );
|
||||
}
|
||||
}
|
||||
|
||||
corr_QC[ 0 ] = __builtin_mips_shilo(corr_QC[ 0 ], val);
|
||||
|
||||
silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
|
||||
}
|
||||
#endif /* __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ */
|
407
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/noise_shape_analysis_FIX.c
vendored
Normal file
407
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/noise_shape_analysis_FIX.c
vendored
Normal file
|
@ -0,0 +1,407 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */
|
||||
/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */
|
||||
/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */
|
||||
/* coefficient in an array of coefficients, for monic filters. */
|
||||
static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/
|
||||
const opus_int32 *coefs_Q24,
|
||||
opus_int lambda_Q16,
|
||||
opus_int order
|
||||
) {
|
||||
opus_int i;
|
||||
opus_int32 gain_Q24;
|
||||
|
||||
lambda_Q16 = -lambda_Q16;
|
||||
gain_Q24 = coefs_Q24[ order - 1 ];
|
||||
for( i = order - 2; i >= 0; i-- ) {
|
||||
gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 );
|
||||
}
|
||||
gain_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 );
|
||||
return silk_INVERSE32_varQ( gain_Q24, 40 );
|
||||
}
|
||||
|
||||
/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
|
||||
/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
|
||||
static OPUS_INLINE void limit_warped_coefs(
|
||||
opus_int32 *coefs_Q24,
|
||||
opus_int lambda_Q16,
|
||||
opus_int32 limit_Q24,
|
||||
opus_int order
|
||||
) {
|
||||
opus_int i, iter, ind = 0;
|
||||
opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_Q16;
|
||||
opus_int32 nom_Q16, den_Q24;
|
||||
opus_int32 limit_Q20, maxabs_Q20;
|
||||
|
||||
/* Convert to monic coefficients */
|
||||
lambda_Q16 = -lambda_Q16;
|
||||
for( i = order - 1; i > 0; i-- ) {
|
||||
coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
|
||||
}
|
||||
lambda_Q16 = -lambda_Q16;
|
||||
nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
|
||||
den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
|
||||
gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
|
||||
for( i = 0; i < order; i++ ) {
|
||||
coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
|
||||
}
|
||||
limit_Q20 = silk_RSHIFT(limit_Q24, 4);
|
||||
for( iter = 0; iter < 10; iter++ ) {
|
||||
/* Find maximum absolute value */
|
||||
maxabs_Q24 = -1;
|
||||
for( i = 0; i < order; i++ ) {
|
||||
tmp = silk_abs_int32( coefs_Q24[ i ] );
|
||||
if( tmp > maxabs_Q24 ) {
|
||||
maxabs_Q24 = tmp;
|
||||
ind = i;
|
||||
}
|
||||
}
|
||||
/* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */
|
||||
maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4);
|
||||
if( maxabs_Q20 <= limit_Q20 ) {
|
||||
/* Coefficients are within range - done */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert back to true warped coefficients */
|
||||
for( i = 1; i < order; i++ ) {
|
||||
coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
|
||||
}
|
||||
gain_Q16 = silk_INVERSE32_varQ( gain_Q16, 32 );
|
||||
for( i = 0; i < order; i++ ) {
|
||||
coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
|
||||
}
|
||||
|
||||
/* Apply bandwidth expansion */
|
||||
chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(
|
||||
silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
|
||||
silk_MUL( maxabs_Q20, ind + 1 ), 22 );
|
||||
silk_bwexpander_32( coefs_Q24, order, chirp_Q16 );
|
||||
|
||||
/* Convert to monic warped coefficients */
|
||||
lambda_Q16 = -lambda_Q16;
|
||||
for( i = order - 1; i > 0; i-- ) {
|
||||
coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
|
||||
}
|
||||
lambda_Q16 = -lambda_Q16;
|
||||
nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
|
||||
den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
|
||||
gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
|
||||
for( i = 0; i < order; i++ ) {
|
||||
coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
|
||||
}
|
||||
}
|
||||
silk_assert( 0 );
|
||||
}
|
||||
|
||||
/* Disable MIPS version until it's updated. */
|
||||
#if 0 && defined(MIPSr1_ASM)
|
||||
#include "mips/noise_shape_analysis_FIX_mipsr1.h"
|
||||
#endif
|
||||
|
||||
/**************************************************************/
|
||||
/* Compute noise shaping coefficients and initial gain values */
|
||||
/**************************************************************/
|
||||
#ifndef OVERRIDE_silk_noise_shape_analysis_FIX
|
||||
void silk_noise_shape_analysis_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
|
||||
const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
|
||||
const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
|
||||
opus_int k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0;
|
||||
opus_int32 SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32;
|
||||
opus_int32 nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
|
||||
opus_int32 BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
|
||||
opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
|
||||
opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
|
||||
opus_int32 AR_Q24[ MAX_SHAPE_LPC_ORDER ];
|
||||
VARDECL( opus_int16, x_windowed );
|
||||
const opus_int16 *x_ptr, *pitch_res_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
/* Point to start of first LPC analysis block */
|
||||
x_ptr = x - psEnc->sCmn.la_shape;
|
||||
|
||||
/****************/
|
||||
/* GAIN CONTROL */
|
||||
/****************/
|
||||
SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
|
||||
|
||||
/* Input quality is the average of the quality in the lowest two VAD bands */
|
||||
psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
|
||||
+ psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
|
||||
|
||||
/* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
|
||||
psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
|
||||
SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
|
||||
|
||||
/* Reduce coding SNR during low speech activity */
|
||||
if( psEnc->sCmn.useCBR == 0 ) {
|
||||
b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
|
||||
b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
|
||||
silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/
|
||||
silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/
|
||||
}
|
||||
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Reduce gains for periodic signals */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
|
||||
} else {
|
||||
/* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
|
||||
silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
|
||||
SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* SPARSENESS PROCESSING */
|
||||
/*************************/
|
||||
/* Set quantizer offset */
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Initially set to 0; may be overruled in process_gains(..) */
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
} else {
|
||||
/* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
|
||||
nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
|
||||
energy_variation_Q7 = 0;
|
||||
log_energy_prev_Q7 = 0;
|
||||
pitch_res_ptr = pitch_res;
|
||||
nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
|
||||
for( k = 0; k < nSegs; k++ ) {
|
||||
silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
|
||||
nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/
|
||||
|
||||
log_energy_Q7 = silk_lin2log( nrg );
|
||||
if( k > 0 ) {
|
||||
energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );
|
||||
}
|
||||
log_energy_prev_Q7 = log_energy_Q7;
|
||||
pitch_res_ptr += nSamples;
|
||||
}
|
||||
|
||||
/* Set quantization offset depending on sparseness measure */
|
||||
if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) {
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
} else {
|
||||
psEnc->sCmn.indices.quantOffsetType = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
/* Control bandwidth expansion */
|
||||
/*******************************/
|
||||
/* More BWE for signals with high prediction gain */
|
||||
strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
|
||||
BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
|
||||
silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
|
||||
warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
|
||||
} else {
|
||||
warping_Q16 = 0;
|
||||
}
|
||||
|
||||
/********************************************/
|
||||
/* Compute noise shaping AR coefs and gains */
|
||||
/********************************************/
|
||||
ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
/* Apply window: sine slope followed by flat part followed by cosine slope */
|
||||
opus_int shift, slope_part, flat_part;
|
||||
flat_part = psEnc->sCmn.fs_kHz * 3;
|
||||
slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
|
||||
|
||||
silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
|
||||
shift = slope_part;
|
||||
silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
|
||||
shift += flat_part;
|
||||
silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
|
||||
|
||||
/* Update pointer: next LPC analysis block */
|
||||
x_ptr += psEnc->sCmn.subfr_length;
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Calculate warped auto correlation */
|
||||
silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
|
||||
} else {
|
||||
/* Calculate regular auto correlation */
|
||||
silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
|
||||
}
|
||||
|
||||
/* Add white noise, as a fraction of energy */
|
||||
auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),
|
||||
SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
|
||||
|
||||
/* Calculate the reflection coefficients using schur */
|
||||
nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_assert( nrg >= 0 );
|
||||
|
||||
/* Convert reflection coefficients to prediction coefficients */
|
||||
silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
Qnrg = -scale; /* range: -12...30*/
|
||||
silk_assert( Qnrg >= -12 );
|
||||
silk_assert( Qnrg <= 30 );
|
||||
|
||||
/* Make sure that Qnrg is an even number */
|
||||
if( Qnrg & 1 ) {
|
||||
Qnrg -= 1;
|
||||
nrg >>= 1;
|
||||
}
|
||||
|
||||
tmp32 = silk_SQRT_APPROX( nrg );
|
||||
Qnrg >>= 1; /* range: -6...15*/
|
||||
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg );
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Adjust gain for warping */
|
||||
gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
|
||||
if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
|
||||
} else {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 );
|
||||
if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
|
||||
} else {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 );
|
||||
}
|
||||
}
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
|
||||
}
|
||||
|
||||
/* Bandwidth expansion */
|
||||
silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 );
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Convert to monic warped prediction coefficients and limit absolute values */
|
||||
limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
/* Convert from Q24 to Q13 and store in int16 */
|
||||
for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
|
||||
psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) );
|
||||
}
|
||||
} else {
|
||||
silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************/
|
||||
/* Gain tweaking */
|
||||
/*****************/
|
||||
/* Increase gains during low speech activity and put lower limit on gains */
|
||||
gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
|
||||
gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) );
|
||||
silk_assert( gain_mult_Q16 > 0 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
|
||||
}
|
||||
|
||||
|
||||
/************************************************/
|
||||
/* Control low-frequency shaping and noise tilt */
|
||||
/************************************************/
|
||||
/* Less low frequency shaping for noisy inputs */
|
||||
strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
|
||||
SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
|
||||
strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
|
||||
/*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
|
||||
opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );
|
||||
/* Pack two coefficients in one int32 */
|
||||
psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );
|
||||
psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
|
||||
}
|
||||
silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/
|
||||
Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
|
||||
silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
|
||||
silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
|
||||
} else {
|
||||
b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/
|
||||
/* Pack two coefficients in one int32 */
|
||||
psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
|
||||
silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
|
||||
psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
|
||||
for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
|
||||
}
|
||||
Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* HARMONIC SHAPING CONTROL */
|
||||
/****************************/
|
||||
if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* More harmonic noise shaping for high bitrates or noisy input */
|
||||
HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
|
||||
SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
|
||||
psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
|
||||
|
||||
/* Less harmonic noise shaping for less periodic signals */
|
||||
HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),
|
||||
silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
|
||||
} else {
|
||||
HarmShapeGain_Q16 = 0;
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* Smooth over subframes */
|
||||
/*************************/
|
||||
for( k = 0; k < MAX_NB_SUBFR; k++ ) {
|
||||
psShapeSt->HarmShapeGain_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
psShapeSt->Tilt_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
|
||||
psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
|
||||
psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 );
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
||||
#endif /* OVERRIDE_silk_noise_shape_analysis_FIX */
|
721
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/pitch_analysis_core_FIX.c
vendored
Normal file
721
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/pitch_analysis_core_FIX.c
vendored
Normal file
|
@ -0,0 +1,721 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "stack_alloc.h"
|
||||
#include "debug.h"
|
||||
#include "pitch.h"
|
||||
|
||||
#define SCRATCH_SIZE 22
|
||||
#define SF_LENGTH_4KHZ ( PE_SUBFR_LENGTH_MS * 4 )
|
||||
#define SF_LENGTH_8KHZ ( PE_SUBFR_LENGTH_MS * 8 )
|
||||
#define MIN_LAG_4KHZ ( PE_MIN_LAG_MS * 4 )
|
||||
#define MIN_LAG_8KHZ ( PE_MIN_LAG_MS * 8 )
|
||||
#define MAX_LAG_4KHZ ( PE_MAX_LAG_MS * 4 )
|
||||
#define MAX_LAG_8KHZ ( PE_MAX_LAG_MS * 8 - 1 )
|
||||
#define CSTRIDE_4KHZ ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ )
|
||||
#define CSTRIDE_8KHZ ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) )
|
||||
#define D_COMP_MIN ( MIN_LAG_8KHZ - 3 )
|
||||
#define D_COMP_MAX ( MAX_LAG_8KHZ + 4 )
|
||||
#define D_COMP_STRIDE ( D_COMP_MAX - D_COMP_MIN )
|
||||
|
||||
typedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ];
|
||||
|
||||
/************************************************************/
|
||||
/* Internally used functions */
|
||||
/************************************************************/
|
||||
static void silk_P_Ana_calc_corr_st3(
|
||||
silk_pe_stage3_vals cross_corr_st3[], /* 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 */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
static void silk_P_Ana_calc_energy_st3(
|
||||
silk_pe_stage3_vals energies_st3[], /* 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 */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/*************************************************************/
|
||||
/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */
|
||||
/*************************************************************/
|
||||
opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
|
||||
const opus_int16 *frame_unscaled, /* 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_Q13, /* 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 */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
VARDECL( opus_int16, frame_8kHz_buf );
|
||||
VARDECL( opus_int16, frame_4kHz );
|
||||
VARDECL( opus_int16, frame_scaled );
|
||||
opus_int32 filt_state[ 6 ];
|
||||
const opus_int16 *frame, *frame_8kHz;
|
||||
opus_int i, k, d, j;
|
||||
VARDECL( opus_int16, C );
|
||||
VARDECL( opus_int32, xcorr32 );
|
||||
const opus_int16 *target_ptr, *basis_ptr;
|
||||
opus_int32 cross_corr, normalizer, energy, energy_basis, energy_target;
|
||||
opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp, shift;
|
||||
VARDECL( opus_int16, d_comp );
|
||||
opus_int32 sum, threshold, 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;
|
||||
VARDECL( silk_pe_stage3_vals, energies_st3 );
|
||||
VARDECL( silk_pe_stage3_vals, cross_corr_st3 );
|
||||
opus_int frame_length, frame_length_8kHz, frame_length_4kHz;
|
||||
opus_int sf_length;
|
||||
opus_int min_lag;
|
||||
opus_int max_lag;
|
||||
opus_int32 contour_bias_Q15, diff;
|
||||
opus_int nb_cbk_search, cbk_size;
|
||||
opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13;
|
||||
const opus_int8 *Lag_CB_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
/* Check for valid sampling frequency */
|
||||
celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
|
||||
|
||||
/* Check for valid complexity setting */
|
||||
celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
|
||||
celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
|
||||
|
||||
silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
|
||||
silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) );
|
||||
|
||||
/* Set up 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;
|
||||
min_lag = PE_MIN_LAG_MS * Fs_kHz;
|
||||
max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
|
||||
|
||||
/* Downscale input if necessary */
|
||||
silk_sum_sqr_shift( &energy, &shift, frame_unscaled, frame_length );
|
||||
shift += 3 - silk_CLZ32( energy ); /* at least two bits headroom */
|
||||
ALLOC( frame_scaled, frame_length, opus_int16 );
|
||||
if( shift > 0 ) {
|
||||
shift = silk_RSHIFT( shift + 1, 1 );
|
||||
for( i = 0; i < frame_length; i++ ) {
|
||||
frame_scaled[ i ] = silk_RSHIFT( frame_unscaled[ i ], shift );
|
||||
}
|
||||
frame = frame_scaled;
|
||||
} else {
|
||||
frame = frame_unscaled;
|
||||
}
|
||||
|
||||
ALLOC( frame_8kHz_buf, ( Fs_kHz == 8 ) ? 1 : frame_length_8kHz, opus_int16 );
|
||||
/* 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_buf, frame, frame_length );
|
||||
frame_8kHz = frame_8kHz_buf;
|
||||
} else if( Fs_kHz == 12 ) {
|
||||
silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
|
||||
silk_resampler_down2_3( filt_state, frame_8kHz_buf, frame, frame_length );
|
||||
frame_8kHz = frame_8kHz_buf;
|
||||
} else {
|
||||
celt_assert( Fs_kHz == 8 );
|
||||
frame_8kHz = frame;
|
||||
}
|
||||
|
||||
/* Decimate again to 4 kHz */
|
||||
silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */
|
||||
ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 );
|
||||
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 ] );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* FIRST STAGE, operating in 4 khz
|
||||
******************************************************************************/
|
||||
ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 );
|
||||
ALLOC( xcorr32, MAX_LAG_4KHZ-MIN_LAG_4KHZ+1, opus_int32 );
|
||||
silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) );
|
||||
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 */
|
||||
celt_assert( target_ptr >= frame_4kHz );
|
||||
celt_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 */
|
||||
celt_assert( basis_ptr >= frame_4kHz );
|
||||
celt_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
|
||||
|
||||
celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch );
|
||||
|
||||
/* Calculate first vector products before loop */
|
||||
cross_corr = xcorr32[ MAX_LAG_4KHZ - MIN_LAG_4KHZ ];
|
||||
normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch );
|
||||
normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ) );
|
||||
normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) );
|
||||
|
||||
matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) =
|
||||
(opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */
|
||||
|
||||
/* 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 = xcorr32[ MAX_LAG_4KHZ - d ];
|
||||
|
||||
/* Add contribution of new sample and remove contribution from oldest sample */
|
||||
normalizer = silk_ADD32( normalizer,
|
||||
silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) -
|
||||
silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) );
|
||||
|
||||
matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) =
|
||||
(opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */
|
||||
}
|
||||
/* 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)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ )
|
||||
+ (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ); /* Q14 */
|
||||
sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */
|
||||
C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */
|
||||
}
|
||||
} else {
|
||||
/* Only short-lag bias */
|
||||
for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {
|
||||
sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 ); /* Q14 */
|
||||
sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */
|
||||
C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort */
|
||||
length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 );
|
||||
celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
|
||||
silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ,
|
||||
length_d_srch );
|
||||
|
||||
/* Escape if correlation is very low already here */
|
||||
Cmax = (opus_int)C[ 0 ]; /* Q14 */
|
||||
if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) {
|
||||
silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
|
||||
*LTPCorr_Q15 = 0;
|
||||
*lagIndex = 0;
|
||||
*contourIndex = 0;
|
||||
RESTORE_STACK;
|
||||
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[ i ] > threshold ) {
|
||||
d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 );
|
||||
} else {
|
||||
length_d_srch = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
celt_assert( length_d_srch > 0 );
|
||||
|
||||
ALLOC( d_comp, D_COMP_STRIDE, opus_int16 );
|
||||
for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) {
|
||||
d_comp[ i - D_COMP_MIN ] = 0;
|
||||
}
|
||||
for( i = 0; i < length_d_srch; i++ ) {
|
||||
d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1;
|
||||
}
|
||||
|
||||
/* Convolution */
|
||||
for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {
|
||||
d_comp[ i - D_COMP_MIN ] +=
|
||||
d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ];
|
||||
}
|
||||
|
||||
length_d_srch = 0;
|
||||
for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) {
|
||||
if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) {
|
||||
d_srch[ length_d_srch ] = i;
|
||||
length_d_srch++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convolution */
|
||||
for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {
|
||||
d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ]
|
||||
+ d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ];
|
||||
}
|
||||
|
||||
length_d_comp = 0;
|
||||
for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) {
|
||||
if( d_comp[ i - D_COMP_MIN ] > 0 ) {
|
||||
d_comp[ length_d_comp ] = i - 2;
|
||||
length_d_comp++;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************************
|
||||
** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
|
||||
*************************************************************************************/
|
||||
|
||||
/*********************************************************************************
|
||||
* Find energy of each subframe projected onto its history, for a range of delays
|
||||
*********************************************************************************/
|
||||
silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * 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 */
|
||||
celt_assert( target_ptr >= frame_8kHz );
|
||||
celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
|
||||
|
||||
energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ), 1 );
|
||||
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, arch );
|
||||
if( cross_corr > 0 ) {
|
||||
energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch );
|
||||
matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) =
|
||||
(opus_int16)silk_DIV32_varQ( cross_corr,
|
||||
silk_ADD32( energy_target,
|
||||
energy_basis ),
|
||||
13 + 1 ); /* Q13 */
|
||||
} else {
|
||||
matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 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_Q13 == silk_SAT16( search_thres2_Q13 ) );
|
||||
/* Set up 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;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
|
||||
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++ ) {
|
||||
opus_int d_subfr;
|
||||
/* Try all codebooks */
|
||||
d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size );
|
||||
CC[ j ] = CC[ j ]
|
||||
+ (opus_int32)matrix_ptr( C, i,
|
||||
d_subfr - ( MIN_LAG_8KHZ - 2 ),
|
||||
CSTRIDE_8KHZ );
|
||||
}
|
||||
}
|
||||
/* 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( d ); /* Q7 */
|
||||
silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) );
|
||||
silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) ) );
|
||||
CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ), lag_log2_Q7 ), 7 ); /* Q13 */
|
||||
|
||||
/* Bias towards previous lag */
|
||||
silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) ) );
|
||||
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_Q13 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ), *LTPCorr_Q15 ), 15 ); /* Q13 */
|
||||
prev_lag_bias_Q13 = silk_DIV32( silk_MUL( prev_lag_bias_Q13, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + SILK_FIX_CONST( 0.5, 7 ) );
|
||||
CCmax_new_b -= prev_lag_bias_Q13; /* Q13 */
|
||||
}
|
||||
|
||||
if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
|
||||
CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 ) && /* 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;
|
||||
RESTORE_STACK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Output normalized correlation */
|
||||
*LTPCorr_Q15 = (opus_int)silk_LSHIFT( silk_DIV32_16( CCmax, nb_subfr ), 2 );
|
||||
silk_assert( *LTPCorr_Q15 >= 0 );
|
||||
|
||||
if( Fs_kHz > 8 ) {
|
||||
/* 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 */
|
||||
|
||||
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 ];
|
||||
}
|
||||
|
||||
/* Set up codebook parameters according 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 ];
|
||||
}
|
||||
|
||||
/* Calculate the correlations and energies needed in stage 3 */
|
||||
ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
|
||||
ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
|
||||
silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
|
||||
silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
|
||||
|
||||
lag_counter = 0;
|
||||
silk_assert( lag == silk_SAT16( lag ) );
|
||||
contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag );
|
||||
|
||||
target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
|
||||
energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length, arch ), 1 );
|
||||
for( d = start_lag; d <= end_lag; d++ ) {
|
||||
for( j = 0; j < nb_cbk_search; j++ ) {
|
||||
cross_corr = 0;
|
||||
energy = energy_target;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
cross_corr = silk_ADD32( cross_corr,
|
||||
matrix_ptr( cross_corr_st3, k, j,
|
||||
nb_cbk_search )[ lag_counter ] );
|
||||
energy = silk_ADD32( energy,
|
||||
matrix_ptr( energies_st3, k, j,
|
||||
nb_cbk_search )[ lag_counter ] );
|
||||
silk_assert( energy >= 0 );
|
||||
}
|
||||
if( cross_corr > 0 ) {
|
||||
CCmax_new = silk_DIV32_varQ( cross_corr, energy, 13 + 1 ); /* Q13 */
|
||||
/* Reduce depending on flatness of contour */
|
||||
diff = silk_int16_MAX - silk_MUL( contour_bias_Q15, j ); /* Q15 */
|
||||
silk_assert( diff == silk_SAT16( diff ) );
|
||||
CCmax_new = silk_SMULWB( CCmax_new, diff ); /* Q14 */
|
||||
} 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 */
|
||||
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 * 8 );
|
||||
}
|
||||
*lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ );
|
||||
*contourIndex = (opus_int8)CBimax;
|
||||
}
|
||||
celt_assert( *lagIndex >= 0 );
|
||||
/* return as voiced */
|
||||
RESTORE_STACK;
|
||||
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),
|
||||
* the following correlations are needed in each sub frame:
|
||||
*
|
||||
* sf1: lag range [-8,...,7] total 16 correlations
|
||||
* sf2: lag range [-4,...,4] total 9 correlations
|
||||
* sf3: lag range [-3,....4] total 8 correltions
|
||||
* sf4: lag range [-6,....8] total 15 correlations
|
||||
*
|
||||
* In total 48 correlations. The direct implementation computed in worst
|
||||
* case 4*12*5 = 240 correlations, but more likely around 120.
|
||||
***********************************************************************/
|
||||
static void silk_P_Ana_calc_corr_st3(
|
||||
silk_pe_stage3_vals cross_corr_st3[], /* 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 */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
const opus_int16 *target_ptr;
|
||||
opus_int i, j, k, lag_counter, lag_low, lag_high;
|
||||
opus_int nb_cbk_search, delta, idx, cbk_size;
|
||||
VARDECL( opus_int32, scratch_mem );
|
||||
VARDECL( opus_int32, xcorr32 );
|
||||
const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
|
||||
celt_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 {
|
||||
celt_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;
|
||||
}
|
||||
ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );
|
||||
ALLOC( xcorr32, SCRATCH_SIZE, opus_int32 );
|
||||
|
||||
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 );
|
||||
celt_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
|
||||
celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch );
|
||||
for( j = lag_low; j <= lag_high; j++ ) {
|
||||
silk_assert( lag_counter < SCRATCH_SIZE );
|
||||
scratch_mem[ lag_counter ] = xcorr32[ lag_high - j ];
|
||||
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 );
|
||||
matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] =
|
||||
scratch_mem[ idx + j ];
|
||||
}
|
||||
}
|
||||
target_ptr += sf_length;
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* Calculate the energies for first two subframes. The energies are */
|
||||
/* calculated recursively. */
|
||||
/********************************************************************/
|
||||
static void silk_P_Ana_calc_energy_st3(
|
||||
silk_pe_stage3_vals energies_st3[], /* 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 */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
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;
|
||||
VARDECL( opus_int32, scratch_mem );
|
||||
const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
|
||||
celt_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 {
|
||||
celt_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;
|
||||
}
|
||||
ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );
|
||||
|
||||
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, arch );
|
||||
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 );
|
||||
matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] =
|
||||
scratch_mem[ idx + j ];
|
||||
silk_assert(
|
||||
matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 );
|
||||
}
|
||||
}
|
||||
target_ptr += sf_length;
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
117
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/process_gains_FIX.c
vendored
Normal file
117
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/process_gains_FIX.c
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Processing of gains */
|
||||
void silk_process_gains_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
)
|
||||
{
|
||||
silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
|
||||
opus_int k;
|
||||
opus_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10;
|
||||
|
||||
/* Gain reduction when LTP coding gain is high */
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/*s = -0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */
|
||||
s_Q16 = -silk_sigm_Q15( silk_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Limit the quantized signal */
|
||||
/* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */
|
||||
InvMaxSqrVal_Q16 = silk_DIV32_16( silk_log2lin(
|
||||
silk_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length );
|
||||
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
/* Soft limit on ratio residual energy and squared gains */
|
||||
ResNrg = psEncCtrl->ResNrg[ k ];
|
||||
ResNrgPart = silk_SMULWW( ResNrg, InvMaxSqrVal_Q16 );
|
||||
if( psEncCtrl->ResNrgQ[ k ] > 0 ) {
|
||||
ResNrgPart = silk_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] );
|
||||
} else {
|
||||
if( ResNrgPart >= silk_RSHIFT( silk_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) {
|
||||
ResNrgPart = silk_int32_MAX;
|
||||
} else {
|
||||
ResNrgPart = silk_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] );
|
||||
}
|
||||
}
|
||||
gain = psEncCtrl->Gains_Q16[ k ];
|
||||
gain_squared = silk_ADD_SAT32( ResNrgPart, silk_SMMUL( gain, gain ) );
|
||||
if( gain_squared < silk_int16_MAX ) {
|
||||
/* recalculate with higher precision */
|
||||
gain_squared = silk_SMLAWW( silk_LSHIFT( ResNrgPart, 16 ), gain, gain );
|
||||
silk_assert( gain_squared > 0 );
|
||||
gain = silk_SQRT_APPROX( gain_squared ); /* Q8 */
|
||||
gain = silk_min( gain, silk_int32_MAX >> 8 );
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 8 ); /* Q16 */
|
||||
} else {
|
||||
gain = silk_SQRT_APPROX( gain_squared ); /* Q0 */
|
||||
gain = silk_min( gain, silk_int32_MAX >> 16 );
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 16 ); /* Q16 */
|
||||
}
|
||||
}
|
||||
|
||||
/* Save unquantized gains and gain Index */
|
||||
silk_memcpy( psEncCtrl->GainsUnq_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
|
||||
psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex;
|
||||
|
||||
/* Quantize gains */
|
||||
silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16,
|
||||
&psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
|
||||
|
||||
/* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
if( psEncCtrl->LTPredCodGain_Q7 + silk_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) {
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
} else {
|
||||
psEnc->sCmn.indices.quantOffsetType = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Quantizer boundary adjustment */
|
||||
quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ];
|
||||
psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 )
|
||||
+ silk_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision )
|
||||
+ silk_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->sCmn.speech_activity_Q8 )
|
||||
+ silk_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 )
|
||||
+ silk_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 )
|
||||
+ silk_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 );
|
||||
|
||||
silk_assert( psEncCtrl->Lambda_Q10 > 0 );
|
||||
silk_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) );
|
||||
}
|
47
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/regularize_correlations_FIX.c
vendored
Normal file
47
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/regularize_correlations_FIX.c
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
|
||||
/* Add noise to matrix diagonal */
|
||||
void silk_regularize_correlations_FIX(
|
||||
opus_int32 *XX, /* I/O Correlation matrices */
|
||||
opus_int32 *xx, /* I/O Correlation values */
|
||||
opus_int32 noise, /* I Noise to add */
|
||||
opus_int D /* I Dimension of XX */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
for( i = 0; i < D; i++ ) {
|
||||
matrix_ptr( &XX[ 0 ], i, i, D ) = silk_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise );
|
||||
}
|
||||
xx[ 0 ] += noise;
|
||||
}
|
103
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/residual_energy16_FIX.c
vendored
Normal file
103
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/residual_energy16_FIX.c
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
|
||||
/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
|
||||
opus_int32 silk_residual_energy16_covar_FIX(
|
||||
const opus_int16 *c, /* I Prediction vector */
|
||||
const opus_int32 *wXX, /* I Correlation matrix */
|
||||
const opus_int32 *wXx, /* I Correlation vector */
|
||||
opus_int32 wxx, /* I Signal energy */
|
||||
opus_int D, /* I Dimension */
|
||||
opus_int cQ /* I Q value for c vector 0 - 15 */
|
||||
)
|
||||
{
|
||||
opus_int i, j, lshifts, Qxtra;
|
||||
opus_int32 c_max, w_max, tmp, tmp2, nrg;
|
||||
opus_int cn[ MAX_MATRIX_SIZE ];
|
||||
const opus_int32 *pRow;
|
||||
|
||||
/* Safety checks */
|
||||
celt_assert( D >= 0 );
|
||||
celt_assert( D <= 16 );
|
||||
celt_assert( cQ > 0 );
|
||||
celt_assert( cQ < 16 );
|
||||
|
||||
lshifts = 16 - cQ;
|
||||
Qxtra = lshifts;
|
||||
|
||||
c_max = 0;
|
||||
for( i = 0; i < D; i++ ) {
|
||||
c_max = silk_max_32( c_max, silk_abs( (opus_int32)c[ i ] ) );
|
||||
}
|
||||
Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 );
|
||||
|
||||
w_max = silk_max_32( wXX[ 0 ], wXX[ D * D - 1 ] );
|
||||
Qxtra = silk_min_int( Qxtra, silk_CLZ32( silk_MUL( D, silk_RSHIFT( silk_SMULWB( w_max, c_max ), 4 ) ) ) - 5 );
|
||||
Qxtra = silk_max_int( Qxtra, 0 );
|
||||
for( i = 0; i < D; i++ ) {
|
||||
cn[ i ] = silk_LSHIFT( ( opus_int )c[ i ], Qxtra );
|
||||
silk_assert( silk_abs(cn[i]) <= ( silk_int16_MAX + 1 ) ); /* Check that silk_SMLAWB can be used */
|
||||
}
|
||||
lshifts -= Qxtra;
|
||||
|
||||
/* Compute wxx - 2 * wXx * c */
|
||||
tmp = 0;
|
||||
for( i = 0; i < D; i++ ) {
|
||||
tmp = silk_SMLAWB( tmp, wXx[ i ], cn[ i ] );
|
||||
}
|
||||
nrg = silk_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */
|
||||
|
||||
/* Add c' * wXX * c, assuming wXX is symmetric */
|
||||
tmp2 = 0;
|
||||
for( i = 0; i < D; i++ ) {
|
||||
tmp = 0;
|
||||
pRow = &wXX[ i * D ];
|
||||
for( j = i + 1; j < D; j++ ) {
|
||||
tmp = silk_SMLAWB( tmp, pRow[ j ], cn[ j ] );
|
||||
}
|
||||
tmp = silk_SMLAWB( tmp, silk_RSHIFT( pRow[ i ], 1 ), cn[ i ] );
|
||||
tmp2 = silk_SMLAWB( tmp2, tmp, cn[ i ] );
|
||||
}
|
||||
nrg = silk_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */
|
||||
|
||||
/* Keep one bit free always, because we add them for LSF interpolation */
|
||||
if( nrg < 1 ) {
|
||||
nrg = 1;
|
||||
} else if( nrg > silk_RSHIFT( silk_int32_MAX, lshifts + 2 ) ) {
|
||||
nrg = silk_int32_MAX >> 1;
|
||||
} else {
|
||||
nrg = silk_LSHIFT( nrg, lshifts + 1 ); /* Q0 */
|
||||
}
|
||||
return nrg;
|
||||
|
||||
}
|
98
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/residual_energy_FIX.c
vendored
Normal file
98
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/residual_energy_FIX.c
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
/* Calculates residual energies of input subframes where all subframes have LPC_order */
|
||||
/* of preceding samples */
|
||||
void silk_residual_energy_FIX(
|
||||
opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
|
||||
opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */
|
||||
const opus_int16 x[], /* I Input signal */
|
||||
opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
|
||||
const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */
|
||||
const opus_int subfr_length, /* I Subframe length */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
const opus_int LPC_order, /* I LPC order */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int offset, i, j, rshift, lz1, lz2;
|
||||
opus_int16 *LPC_res_ptr;
|
||||
VARDECL( opus_int16, LPC_res );
|
||||
const opus_int16 *x_ptr;
|
||||
opus_int32 tmp32;
|
||||
SAVE_STACK;
|
||||
|
||||
x_ptr = x;
|
||||
offset = LPC_order + subfr_length;
|
||||
|
||||
/* Filter input to create the LPC residual for each frame half, and measure subframe energies */
|
||||
ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 );
|
||||
celt_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr );
|
||||
for( i = 0; i < nb_subfr >> 1; i++ ) {
|
||||
/* Calculate half frame LPC residual signal including preceding samples */
|
||||
silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order, arch );
|
||||
|
||||
/* Point to first subframe of the just calculated LPC residual signal */
|
||||
LPC_res_ptr = LPC_res + LPC_order;
|
||||
for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) {
|
||||
/* Measure subframe energy */
|
||||
silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length );
|
||||
|
||||
/* Set Q values for the measured energy */
|
||||
nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift;
|
||||
|
||||
/* Move to next subframe */
|
||||
LPC_res_ptr += offset;
|
||||
}
|
||||
/* Move to next frame half */
|
||||
x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset;
|
||||
}
|
||||
|
||||
/* Apply the squared subframe gains */
|
||||
for( i = 0; i < nb_subfr; i++ ) {
|
||||
/* Fully upscale gains and energies */
|
||||
lz1 = silk_CLZ32( nrgs[ i ] ) - 1;
|
||||
lz2 = silk_CLZ32( gains[ i ] ) - 1;
|
||||
|
||||
tmp32 = silk_LSHIFT32( gains[ i ], lz2 );
|
||||
|
||||
/* Find squared gains */
|
||||
tmp32 = silk_SMMUL( tmp32, tmp32 ); /* Q( 2 * lz2 - 32 )*/
|
||||
|
||||
/* Scale energies */
|
||||
nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/
|
||||
nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32;
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
93
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/schur64_FIX.c
vendored
Normal file
93
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/schur64_FIX.c
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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;
|
||||
|
||||
celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
|
||||
|
||||
/* Check for invalid input */
|
||||
if( c[ 0 ] <= 0 ) {
|
||||
silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
k = 0;
|
||||
do {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
|
||||
} while( ++k <= order );
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
/* Check that we won't be getting an unstable rc, otherwise stop here. */
|
||||
if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) {
|
||||
if ( C[ k + 1 ][ 0 ] > 0 ) {
|
||||
rc_Q16[ k ] = -SILK_FIX_CONST( .99f, 16 );
|
||||
} else {
|
||||
rc_Q16[ k ] = SILK_FIX_CONST( .99f, 16 );
|
||||
}
|
||||
k++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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 );
|
||||
}
|
||||
}
|
||||
|
||||
for(; k < order; k++ ) {
|
||||
rc_Q16[ k ] = 0;
|
||||
}
|
||||
|
||||
return silk_max_32( 1, C[ 0 ][ 1 ] );
|
||||
}
|
107
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/schur_FIX.c
vendored
Normal file
107
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/schur_FIX.c
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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;
|
||||
|
||||
celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
|
||||
|
||||
/* Get number of leading zeros */
|
||||
lz = silk_CLZ32( c[ 0 ] );
|
||||
|
||||
/* Copy correlations and adjust level to Q30 */
|
||||
k = 0;
|
||||
if( lz < 2 ) {
|
||||
/* lz must be 1, so shift one to the right */
|
||||
do {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 );
|
||||
} while( ++k <= order );
|
||||
} else if( lz > 2 ) {
|
||||
/* Shift to the left */
|
||||
lz -= 2;
|
||||
do {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz );
|
||||
} while( ++k <= order );
|
||||
} else {
|
||||
/* No need to shift */
|
||||
do {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
|
||||
} while( ++k <= order );
|
||||
}
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
/* Check that we won't be getting an unstable rc, otherwise stop here. */
|
||||
if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) {
|
||||
if ( C[ k + 1 ][ 0 ] > 0 ) {
|
||||
rc_Q15[ k ] = -SILK_FIX_CONST( .99f, 15 );
|
||||
} else {
|
||||
rc_Q15[ k ] = SILK_FIX_CONST( .99f, 15 );
|
||||
}
|
||||
k++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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 );
|
||||
}
|
||||
}
|
||||
|
||||
for(; k < order; k++ ) {
|
||||
rc_Q15[ k ] = 0;
|
||||
}
|
||||
|
||||
/* return residual energy */
|
||||
return silk_max_32( 1, C[ 0 ][ 1 ] );
|
||||
}
|
116
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/structs_FIX.h
vendored
Normal file
116
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/structs_FIX.h
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_STRUCTS_FIX_H
|
||||
#define SILK_STRUCTS_FIX_H
|
||||
|
||||
#include "typedef.h"
|
||||
#include "main.h"
|
||||
#include "structs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/********************************/
|
||||
/* Noise shaping analysis state */
|
||||
/********************************/
|
||||
typedef struct {
|
||||
opus_int8 LastGainIndex;
|
||||
opus_int32 HarmBoost_smth_Q16;
|
||||
opus_int32 HarmShapeGain_smth_Q16;
|
||||
opus_int32 Tilt_smth_Q16;
|
||||
} silk_shape_state_FIX;
|
||||
|
||||
/********************************/
|
||||
/* Encoder state FIX */
|
||||
/********************************/
|
||||
typedef struct {
|
||||
silk_encoder_state sCmn; /* Common struct, shared with floating-point code */
|
||||
silk_shape_state_FIX sShape; /* Shape state */
|
||||
|
||||
/* Buffer for find pitch and noise shape analysis */
|
||||
silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
|
||||
opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */
|
||||
opus_int32 resNrgSmth;
|
||||
} silk_encoder_state_FIX;
|
||||
|
||||
/************************/
|
||||
/* Encoder control FIX */
|
||||
/************************/
|
||||
typedef struct {
|
||||
/* Prediction and coding parameters */
|
||||
opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
|
||||
silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
|
||||
opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
|
||||
opus_int LTP_scale_Q14;
|
||||
opus_int pitchL[ MAX_NB_SUBFR ];
|
||||
|
||||
/* Noise shaping parameters */
|
||||
/* Testing */
|
||||
silk_DWORD_ALIGN opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
|
||||
opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */
|
||||
opus_int Tilt_Q14[ MAX_NB_SUBFR ];
|
||||
opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ];
|
||||
opus_int Lambda_Q10;
|
||||
opus_int input_quality_Q14;
|
||||
opus_int coding_quality_Q14;
|
||||
|
||||
/* measures */
|
||||
opus_int32 predGain_Q16;
|
||||
opus_int LTPredCodGain_Q7;
|
||||
opus_int32 ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */
|
||||
opus_int ResNrgQ[ MAX_NB_SUBFR ]; /* Q domain for the residual energy > 0 */
|
||||
|
||||
/* Parameters for CBR mode */
|
||||
opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ];
|
||||
opus_int8 lastGainIndexPrev;
|
||||
} silk_encoder_control_FIX;
|
||||
|
||||
/************************/
|
||||
/* Encoder Super Struct */
|
||||
/************************/
|
||||
typedef struct {
|
||||
silk_encoder_state_FIX state_Fxx[ ENCODER_NUM_CHANNELS ];
|
||||
stereo_enc_state sStereo;
|
||||
opus_int32 nBitsUsedLBRR;
|
||||
opus_int32 nBitsExceeded;
|
||||
opus_int nChannelsAPI;
|
||||
opus_int nChannelsInternal;
|
||||
opus_int nPrevChannelsInternal;
|
||||
opus_int timeSinceSwitchAllowed_ms;
|
||||
opus_int allowBandwidthSwitch;
|
||||
opus_int prev_decode_only_middle;
|
||||
} silk_encoder;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
102
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/vector_ops_FIX.c
vendored
Normal file
102
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/vector_ops_FIX.c
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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"
|
||||
#include "pitch.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. */
|
||||
/* * 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 */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
#ifdef FIXED_POINT
|
||||
return celt_inner_prod(inVec1, inVec2, len, arch);
|
||||
#else
|
||||
opus_int i;
|
||||
opus_int32 sum = 0;
|
||||
for( i = 0; i < len; i++ ) {
|
||||
sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
|
||||
}
|
||||
return sum;
|
||||
#endif
|
||||
}
|
||||
|
||||
opus_int64 silk_inner_prod16_aligned_64_c(
|
||||
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;
|
||||
}
|
92
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/warped_autocorrelation_FIX.c
vendored
Normal file
92
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/warped_autocorrelation_FIX.c
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific contributors, may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
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 "main_FIX.h"
|
||||
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "mips/warped_autocorrelation_FIX_mipsr1.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Autocorrelations for a warped frequency axis */
|
||||
#ifndef OVERRIDE_silk_warped_autocorrelation_FIX_c
|
||||
void silk_warped_autocorrelation_FIX_c(
|
||||
opus_int32 *corr, /* O Result [order + 1] */
|
||||
opus_int *scale, /* O Scaling of the correlation vector */
|
||||
const opus_int16 *input, /* I Input data to correlate */
|
||||
const opus_int warping_Q16, /* I Warping coefficient */
|
||||
const opus_int length, /* I Length of input */
|
||||
const opus_int order /* I Correlation order (even) */
|
||||
)
|
||||
{
|
||||
opus_int n, i, lsh;
|
||||
opus_int32 tmp1_QS, tmp2_QS;
|
||||
opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
||||
opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
||||
|
||||
/* Order must be even */
|
||||
celt_assert( ( order & 1 ) == 0 );
|
||||
silk_assert( 2 * QS - QC >= 0 );
|
||||
|
||||
/* Loop over samples */
|
||||
for( n = 0; n < length; n++ ) {
|
||||
tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
|
||||
/* Loop over allpass sections */
|
||||
for( i = 0; i < order; i += 2 ) {
|
||||
/* Output of allpass section */
|
||||
tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
|
||||
state_QS[ i ] = tmp1_QS;
|
||||
corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
|
||||
/* Output of allpass section */
|
||||
tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
|
||||
state_QS[ i + 1 ] = tmp2_QS;
|
||||
corr_QC[ i + 1 ] += silk_RSHIFT64( silk_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC );
|
||||
}
|
||||
state_QS[ order ] = tmp1_QS;
|
||||
corr_QC[ order ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
|
||||
}
|
||||
|
||||
lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35;
|
||||
lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
|
||||
*scale = -( QC + lsh );
|
||||
silk_assert( *scale >= -30 && *scale <= 12 );
|
||||
if( lsh >= 0 ) {
|
||||
for( i = 0; i < order + 1; i++ ) {
|
||||
corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) );
|
||||
}
|
||||
} else {
|
||||
for( i = 0; i < order + 1; i++ ) {
|
||||
corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) );
|
||||
}
|
||||
}
|
||||
silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
|
||||
}
|
||||
#endif /* OVERRIDE_silk_warped_autocorrelation_FIX_c */
|
377
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/x86/burg_modified_FIX_sse4_1.c
vendored
Normal file
377
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/x86/burg_modified_FIX_sse4_1.c
vendored
Normal file
|
@ -0,0 +1,377 @@
|
|||
/* Copyright (c) 2014, Cisco Systems, INC
|
||||
Written by XiangMingZhu WeiZhou MinPeng YanWang
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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.
|
||||
|
||||
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 <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <smmintrin.h>
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "define.h"
|
||||
#include "tuning_parameters.h"
|
||||
#include "pitch.h"
|
||||
#include "celt/x86/x86cpu.h"
|
||||
|
||||
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
|
||||
|
||||
#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_sse4_1(
|
||||
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_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
|
||||
const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
|
||||
const opus_int nb_subfr, /* I Number of subframes stacked in x */
|
||||
const opus_int D, /* I Order */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain;
|
||||
opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, 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 ];
|
||||
opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
|
||||
|
||||
__m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210;
|
||||
__m128i CONST1 = _mm_set1_epi32(1);
|
||||
|
||||
celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||
|
||||
/* 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;
|
||||
}
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||
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, arch ), rshifts );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
int i;
|
||||
opus_int32 d;
|
||||
x_ptr = x + s * subfr_length;
|
||||
celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch );
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ )
|
||||
d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] );
|
||||
xcorr[ n - 1 ] += d;
|
||||
}
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts );
|
||||
}
|
||||
}
|
||||
}
|
||||
silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
||||
|
||||
/* Initialize */
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||
|
||||
invGain_Q30 = (opus_int32)1 << 30;
|
||||
reached_max_gain = 0;
|
||||
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 */
|
||||
|
||||
X1_3210 = _mm_set1_epi32( x1 );
|
||||
X2_3210 = _mm_set1_epi32( x2 );
|
||||
TMP1_3210 = _mm_setzero_si128();
|
||||
TMP2_3210 = _mm_setzero_si128();
|
||||
for( k = 0; k < n - 3; k += 4 ) {
|
||||
PTR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 1 - 3 ] );
|
||||
SUBFR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k ] );
|
||||
FIRST_3210 = _mm_loadu_si128( (__m128i *)&C_first_row[ k ] );
|
||||
PTR_3210 = _mm_shuffle_epi32( PTR_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
LAST_3210 = _mm_loadu_si128( (__m128i *)&C_last_row[ k ] );
|
||||
ATMP_3210 = _mm_loadu_si128( (__m128i *)&Af_QA[ k ] );
|
||||
|
||||
T1_3210 = _mm_mullo_epi32( PTR_3210, X1_3210 );
|
||||
T2_3210 = _mm_mullo_epi32( SUBFR_3210, X2_3210 );
|
||||
|
||||
ATMP_3210 = _mm_srai_epi32( ATMP_3210, 7 );
|
||||
ATMP_3210 = _mm_add_epi32( ATMP_3210, CONST1 );
|
||||
ATMP_3210 = _mm_srai_epi32( ATMP_3210, 1 );
|
||||
|
||||
FIRST_3210 = _mm_add_epi32( FIRST_3210, T1_3210 );
|
||||
LAST_3210 = _mm_add_epi32( LAST_3210, T2_3210 );
|
||||
|
||||
PTR_3210 = _mm_mullo_epi32( ATMP_3210, PTR_3210 );
|
||||
SUBFR_3210 = _mm_mullo_epi32( ATMP_3210, SUBFR_3210 );
|
||||
|
||||
_mm_storeu_si128( (__m128i *)&C_first_row[ k ], FIRST_3210 );
|
||||
_mm_storeu_si128( (__m128i *)&C_last_row[ k ], LAST_3210 );
|
||||
|
||||
TMP1_3210 = _mm_add_epi32( TMP1_3210, PTR_3210 );
|
||||
TMP2_3210 = _mm_add_epi32( TMP2_3210, SUBFR_3210 );
|
||||
}
|
||||
|
||||
TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_unpackhi_epi64(TMP1_3210, TMP1_3210 ) );
|
||||
TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_unpackhi_epi64(TMP2_3210, TMP2_3210 ) );
|
||||
TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_shufflelo_epi16(TMP1_3210, 0x0E ) );
|
||||
TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_shufflelo_epi16(TMP2_3210, 0x0E ) );
|
||||
|
||||
tmp1 += _mm_cvtsi128_si32( TMP1_3210 );
|
||||
tmp2 += _mm_cvtsi128_si32( TMP2_3210 );
|
||||
|
||||
for( ; 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 */
|
||||
|
||||
{
|
||||
__m128i xmm_tmp1, xmm_tmp2;
|
||||
__m128i xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1;
|
||||
__m128i xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1;
|
||||
|
||||
xmm_tmp1 = _mm_set1_epi32( tmp1 );
|
||||
xmm_tmp2 = _mm_set1_epi32( tmp2 );
|
||||
|
||||
for( k = 0; k <= n - 3; k += 4 ) {
|
||||
xmm_x_ptr_n_k_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 3 ] );
|
||||
xmm_x_ptr_sub_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k - 1 ] );
|
||||
|
||||
xmm_x_ptr_n_k_x2x0 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
|
||||
xmm_x_ptr_n_k_x2x0 = _mm_slli_epi32( xmm_x_ptr_n_k_x2x0, -rshifts - 1 );
|
||||
xmm_x_ptr_sub_x2x0 = _mm_slli_epi32( xmm_x_ptr_sub_x2x0, -rshifts - 1 );
|
||||
|
||||
/* equal shift right 4 bytes, xmm_x_ptr_n_k_x3x1 = _mm_srli_si128(xmm_x_ptr_n_k_x2x0, 4)*/
|
||||
xmm_x_ptr_n_k_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
|
||||
xmm_x_ptr_sub_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_sub_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
|
||||
|
||||
xmm_x_ptr_n_k_x2x0 = _mm_mul_epi32( xmm_x_ptr_n_k_x2x0, xmm_tmp1 );
|
||||
xmm_x_ptr_n_k_x3x1 = _mm_mul_epi32( xmm_x_ptr_n_k_x3x1, xmm_tmp1 );
|
||||
xmm_x_ptr_sub_x2x0 = _mm_mul_epi32( xmm_x_ptr_sub_x2x0, xmm_tmp2 );
|
||||
xmm_x_ptr_sub_x3x1 = _mm_mul_epi32( xmm_x_ptr_sub_x3x1, xmm_tmp2 );
|
||||
|
||||
xmm_x_ptr_n_k_x2x0 = _mm_srli_epi64( xmm_x_ptr_n_k_x2x0, 16 );
|
||||
xmm_x_ptr_n_k_x3x1 = _mm_slli_epi64( xmm_x_ptr_n_k_x3x1, 16 );
|
||||
xmm_x_ptr_sub_x2x0 = _mm_srli_epi64( xmm_x_ptr_sub_x2x0, 16 );
|
||||
xmm_x_ptr_sub_x3x1 = _mm_slli_epi64( xmm_x_ptr_sub_x3x1, 16 );
|
||||
|
||||
xmm_x_ptr_n_k_x2x0 = _mm_blend_epi16( xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1, 0xCC );
|
||||
xmm_x_ptr_sub_x2x0 = _mm_blend_epi16( xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1, 0xCC );
|
||||
|
||||
X1_3210 = _mm_loadu_si128( (__m128i *)&CAf[ k ] );
|
||||
PTR_3210 = _mm_loadu_si128( (__m128i *)&CAb[ k ] );
|
||||
|
||||
X1_3210 = _mm_add_epi32( X1_3210, xmm_x_ptr_n_k_x2x0 );
|
||||
PTR_3210 = _mm_add_epi32( PTR_3210, xmm_x_ptr_sub_x2x0 );
|
||||
|
||||
_mm_storeu_si128( (__m128i *)&CAf[ k ], X1_3210 );
|
||||
_mm_storeu_si128( (__m128i *)&CAb[ k ], PTR_3210 );
|
||||
}
|
||||
|
||||
for( ; 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 {
|
||||
rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;
|
||||
}
|
||||
|
||||
/* Update inverse prediction gain */
|
||||
tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
|
||||
tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );
|
||||
if( tmp1 <= minInvGain_Q30 ) {
|
||||
/* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
|
||||
tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
|
||||
rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
|
||||
if( rc_Q31 > 0 ) {
|
||||
/* Newton-Raphson iteration */
|
||||
rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
|
||||
rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
|
||||
if( num < 0 ) {
|
||||
/* Ensure adjusted reflection coefficients has the original sign */
|
||||
rc_Q31 = -rc_Q31;
|
||||
}
|
||||
}
|
||||
invGain_Q30 = minInvGain_Q30;
|
||||
reached_max_gain = 1;
|
||||
} else {
|
||||
invGain_Q30 = tmp1;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
||||
if( reached_max_gain ) {
|
||||
/* Reached max prediction gain; set remaining coefficients to zero and exit loop */
|
||||
for( k = n + 1; k < D; k++ ) {
|
||||
Af_QA[ k ] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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 ) */
|
||||
}
|
||||
}
|
||||
|
||||
if( reached_max_gain ) {
|
||||
for( k = 0; k < D; k++ ) {
|
||||
/* Scale coefficients */
|
||||
A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
|
||||
}
|
||||
/* Subtract energy of preceding samples from C0 */
|
||||
if( rshifts > 0 ) {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch ), -rshifts );
|
||||
}
|
||||
}
|
||||
/* Approximate residual energy */
|
||||
*res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );
|
||||
*res_nrg_Q = -rshifts;
|
||||
} else {
|
||||
/* Return residual energy */
|
||||
nrg = CAf[ 0 ]; /* Q( -rshifts ) */
|
||||
tmp1 = (opus_int32)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( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
|
||||
*res_nrg_Q = -rshifts;
|
||||
}
|
||||
}
|
88
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/x86/vector_ops_FIX_sse4_1.c
vendored
Normal file
88
Src/external_dependencies/openmpt-trunk/include/opus/silk/fixed/x86/vector_ops_FIX_sse4_1.c
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* Copyright (c) 2014, Cisco Systems, INC
|
||||
Written by XiangMingZhu WeiZhou MinPeng YanWang
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, 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.
|
||||
|
||||
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 <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <smmintrin.h>
|
||||
#include "main.h"
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "pitch.h"
|
||||
|
||||
opus_int64 silk_inner_prod16_aligned_64_sse4_1(
|
||||
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, dataSize8;
|
||||
opus_int64 sum;
|
||||
|
||||
__m128i xmm_tempa;
|
||||
__m128i inVec1_76543210, acc1;
|
||||
__m128i inVec2_76543210, acc2;
|
||||
|
||||
sum = 0;
|
||||
dataSize8 = len & ~7;
|
||||
|
||||
acc1 = _mm_setzero_si128();
|
||||
acc2 = _mm_setzero_si128();
|
||||
|
||||
for( i = 0; i < dataSize8; i += 8 ) {
|
||||
inVec1_76543210 = _mm_loadu_si128( (__m128i *)(&inVec1[i + 0] ) );
|
||||
inVec2_76543210 = _mm_loadu_si128( (__m128i *)(&inVec2[i + 0] ) );
|
||||
|
||||
/* only when all 4 operands are -32768 (0x8000), this results in wrap around */
|
||||
inVec1_76543210 = _mm_madd_epi16( inVec1_76543210, inVec2_76543210 );
|
||||
|
||||
xmm_tempa = _mm_cvtepi32_epi64( inVec1_76543210 );
|
||||
/* equal shift right 8 bytes */
|
||||
inVec1_76543210 = _mm_shuffle_epi32( inVec1_76543210, _MM_SHUFFLE( 0, 0, 3, 2 ) );
|
||||
inVec1_76543210 = _mm_cvtepi32_epi64( inVec1_76543210 );
|
||||
|
||||
acc1 = _mm_add_epi64( acc1, xmm_tempa );
|
||||
acc2 = _mm_add_epi64( acc2, inVec1_76543210 );
|
||||
}
|
||||
|
||||
acc1 = _mm_add_epi64( acc1, acc2 );
|
||||
|
||||
/* equal shift right 8 bytes */
|
||||
acc2 = _mm_shuffle_epi32( acc1, _MM_SHUFFLE( 0, 0, 3, 2 ) );
|
||||
acc1 = _mm_add_epi64( acc1, acc2 );
|
||||
|
||||
_mm_storel_epi64( (__m128i *)&sum, acc1 );
|
||||
|
||||
for( ; i < len; i++ ) {
|
||||
sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue