summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/silk/fixed
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libopus/silk/fixed')
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c90
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c53
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c101
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h68
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c260
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c48
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c280
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c150
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c448
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c151
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c99
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c143
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c145
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c54
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c54
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h244
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h336
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h184
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h166
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c407
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c721
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c117
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c47
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c103
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c98
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c93
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c107
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h116
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c102
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c90
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c377
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c160
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c88
33 files changed, 5700 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c
new file mode 100644
index 0000000000..5574e7069f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c
@@ -0,0 +1,90 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33
34void silk_LTP_analysis_filter_FIX(
35 opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */
36 const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */
37 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */
38 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */
39 const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */
40 const opus_int subfr_length, /* I Length of each subframe */
41 const opus_int nb_subfr, /* I Number of subframes */
42 const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */
43)
44{
45 const opus_int16 *x_ptr, *x_lag_ptr;
46 opus_int16 Btmp_Q14[ LTP_ORDER ];
47 opus_int16 *LTP_res_ptr;
48 opus_int k, i;
49 opus_int32 LTP_est;
50
51 x_ptr = x;
52 LTP_res_ptr = LTP_res;
53 for( k = 0; k < nb_subfr; k++ ) {
54
55 x_lag_ptr = x_ptr - pitchL[ k ];
56
57 Btmp_Q14[ 0 ] = LTPCoef_Q14[ k * LTP_ORDER ];
58 Btmp_Q14[ 1 ] = LTPCoef_Q14[ k * LTP_ORDER + 1 ];
59 Btmp_Q14[ 2 ] = LTPCoef_Q14[ k * LTP_ORDER + 2 ];
60 Btmp_Q14[ 3 ] = LTPCoef_Q14[ k * LTP_ORDER + 3 ];
61 Btmp_Q14[ 4 ] = LTPCoef_Q14[ k * LTP_ORDER + 4 ];
62
63 /* LTP analysis FIR filter */
64 for( i = 0; i < subfr_length + pre_length; i++ ) {
65 LTP_res_ptr[ i ] = x_ptr[ i ];
66
67 /* Long-term prediction */
68 LTP_est = silk_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );
69 LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 1 ], Btmp_Q14[ 1 ] );
70 LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 0 ], Btmp_Q14[ 2 ] );
71 LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -1 ], Btmp_Q14[ 3 ] );
72 LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -2 ], Btmp_Q14[ 4 ] );
73
74 LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/
75
76 /* Subtract long-term prediction */
77 LTP_res_ptr[ i ] = (opus_int16)silk_SAT16( (opus_int32)x_ptr[ i ] - LTP_est );
78
79 /* Scale residual */
80 LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );
81
82 x_lag_ptr++;
83 }
84
85 /* Update pointers */
86 LTP_res_ptr += subfr_length + pre_length;
87 x_ptr += subfr_length;
88 }
89}
90
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c
new file mode 100644
index 0000000000..3dcedef891
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c
@@ -0,0 +1,53 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33
34/* Calculation of LTP state scaling */
35void silk_LTP_scale_ctrl_FIX(
36 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
37 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
38 opus_int condCoding /* I The type of conditional coding to use */
39)
40{
41 opus_int round_loss;
42
43 if( condCoding == CODE_INDEPENDENTLY ) {
44 /* Only scale if first frame in packet */
45 round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
46 psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT(
47 silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 );
48 } else {
49 /* Default is minimum scaling */
50 psEnc->sCmn.indices.LTP_scaleIndex = 0;
51 }
52 psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ];
53}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c
new file mode 100644
index 0000000000..03e088a6de
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c
@@ -0,0 +1,101 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Apply sine window to signal vector. */
35/* Window types: */
36/* 1 -> sine window from 0 to pi/2 */
37/* 2 -> sine window from pi/2 to pi */
38/* Every other sample is linearly interpolated, for speed. */
39/* Window length must be between 16 and 120 (incl) and a multiple of 4. */
40
41/* Matlab code for table:
42 for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end
43*/
44static const opus_int16 freq_table_Q16[ 27 ] = {
45 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202,
46 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422,
47 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702,
48};
49
50void silk_apply_sine_window(
51 opus_int16 px_win[], /* O Pointer to windowed signal */
52 const opus_int16 px[], /* I Pointer to input signal */
53 const opus_int win_type, /* I Selects a window type */
54 const opus_int length /* I Window length, multiple of 4 */
55)
56{
57 opus_int k, f_Q16, c_Q16;
58 opus_int32 S0_Q16, S1_Q16;
59
60 celt_assert( win_type == 1 || win_type == 2 );
61
62 /* Length must be in a range from 16 to 120 and a multiple of 4 */
63 celt_assert( length >= 16 && length <= 120 );
64 celt_assert( ( length & 3 ) == 0 );
65
66 /* Frequency */
67 k = ( length >> 2 ) - 4;
68 celt_assert( k >= 0 && k <= 26 );
69 f_Q16 = (opus_int)freq_table_Q16[ k ];
70
71 /* Factor used for cosine approximation */
72 c_Q16 = silk_SMULWB( (opus_int32)f_Q16, -f_Q16 );
73 silk_assert( c_Q16 >= -32768 );
74
75 /* initialize state */
76 if( win_type == 1 ) {
77 /* start from 0 */
78 S0_Q16 = 0;
79 /* approximation of sin(f) */
80 S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 );
81 } else {
82 /* start from 1 */
83 S0_Q16 = ( (opus_int32)1 << 16 );
84 /* approximation of cos(f) */
85 S1_Q16 = ( (opus_int32)1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 );
86 }
87
88 /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
89 /* 4 samples at a time */
90 for( k = 0; k < length; k += 4 ) {
91 px_win[ k ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] );
92 px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] );
93 S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;
94 S0_Q16 = silk_min( S0_Q16, ( (opus_int32)1 << 16 ) );
95
96 px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] );
97 px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] );
98 S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16;
99 S1_Q16 = silk_min( S1_Q16, ( (opus_int32)1 << 16 ) );
100 }
101}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h
new file mode 100644
index 0000000000..1992e43288
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h
@@ -0,0 +1,68 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_WARPED_AUTOCORRELATION_FIX_ARM_H
29# define SILK_WARPED_AUTOCORRELATION_FIX_ARM_H
30
31# include "celt/arm/armcpu.h"
32
33# if defined(FIXED_POINT)
34
35# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
36void silk_warped_autocorrelation_FIX_neon(
37 opus_int32 *corr, /* O Result [order + 1] */
38 opus_int *scale, /* O Scaling of the correlation vector */
39 const opus_int16 *input, /* I Input data to correlate */
40 const opus_int warping_Q16, /* I Warping coefficient */
41 const opus_int length, /* I Length of input */
42 const opus_int order /* I Correlation order (even) */
43);
44
45# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
46# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
47# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
48 ((void)(arch), PRESUME_NEON(silk_warped_autocorrelation_FIX)(corr, scale, input, warping_Q16, length, order))
49# endif
50# endif
51
52# if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
53/*Is run-time CPU detection enabled on this platform?*/
54# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
55extern 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);
56# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
57# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
58 ((*SILK_WARPED_AUTOCORRELATION_FIX_IMPL[(arch)&OPUS_ARCHMASK])(corr, scale, input, warping_Q16, length, order))
59# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
60# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
61# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
62 ((void)(arch), silk_warped_autocorrelation_FIX_neon(corr, scale, input, warping_Q16, length, order))
63# endif
64# endif
65
66# endif /* end FIXED_POINT */
67
68#endif /* end SILK_WARPED_AUTOCORRELATION_FIX_ARM_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c
new file mode 100644
index 0000000000..00a70cb51f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c
@@ -0,0 +1,260 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc., Jean-Marc Valin
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <arm_neon.h>
33#ifdef OPUS_CHECK_ASM
34# include <string.h>
35#endif
36#include "stack_alloc.h"
37#include "main_FIX.h"
38
39static 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 )
40{
41 int64x2_t corr_QC_s64x2[ 2 ], t_s64x2[ 2 ];
42 const int32x4_t input_QS_s32x4 = vld1q_s32( input_QS + offset );
43 corr_QC_s64x2[ 0 ] = vld1q_s64( corr_QC + offset + 0 );
44 corr_QC_s64x2[ 1 ] = vld1q_s64( corr_QC + offset + 2 );
45 t_s64x2[ 0 ] = vmull_s32( vget_low_s32( state_QS_s32x4 ), vget_low_s32( input_QS_s32x4 ) );
46 t_s64x2[ 1 ] = vmull_s32( vget_high_s32( state_QS_s32x4 ), vget_high_s32( input_QS_s32x4 ) );
47 corr_QC_s64x2[ 0 ] = vsraq_n_s64( corr_QC_s64x2[ 0 ], t_s64x2[ 0 ], 2 * QS - QC );
48 corr_QC_s64x2[ 1 ] = vsraq_n_s64( corr_QC_s64x2[ 1 ], t_s64x2[ 1 ], 2 * QS - QC );
49 vst1q_s64( corr_QC + offset + 0, corr_QC_s64x2[ 0 ] );
50 vst1q_s64( corr_QC + offset + 2, corr_QC_s64x2[ 1 ] );
51}
52
53static 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 )
54{
55 int32x4_t t_s32x4 = vsubq_s32( state_QS0_s32x4, state_QS0_1_s32x4 );
56 t_s32x4 = vqdmulhq_s32( t_s32x4, warping_Q16_s32x4 );
57 return vaddq_s32( state_QS1_1_s32x4, t_s32x4 );
58}
59
60void silk_warped_autocorrelation_FIX_neon(
61 opus_int32 *corr, /* O Result [order + 1] */
62 opus_int *scale, /* O Scaling of the correlation vector */
63 const opus_int16 *input, /* I Input data to correlate */
64 const opus_int warping_Q16, /* I Warping coefficient */
65 const opus_int length, /* I Length of input */
66 const opus_int order /* I Correlation order (even) */
67)
68{
69 if( ( MAX_SHAPE_LPC_ORDER > 24 ) || ( order < 6 ) ) {
70 silk_warped_autocorrelation_FIX_c( corr, scale, input, warping_Q16, length, order );
71 } else {
72 opus_int n, i, lsh;
73 opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* In reverse order */
74 opus_int64 corr_QC_orderT;
75 int64x2_t lsh_s64x2;
76 const opus_int orderT = ( order + 3 ) & ~3;
77 opus_int64 *corr_QCT;
78 opus_int32 *input_QS;
79 VARDECL( opus_int32, input_QST );
80 VARDECL( opus_int32, state );
81 SAVE_STACK;
82
83 /* Order must be even */
84 silk_assert( ( order & 1 ) == 0 );
85 silk_assert( 2 * QS - QC >= 0 );
86
87 ALLOC( input_QST, length + 2 * MAX_SHAPE_LPC_ORDER, opus_int32 );
88
89 input_QS = input_QST;
90 /* input_QS has zero paddings in the beginning and end. */
91 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
92 input_QS += 4;
93 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
94 input_QS += 4;
95 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
96 input_QS += 4;
97 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
98 input_QS += 4;
99 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
100 input_QS += 4;
101 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
102 input_QS += 4;
103
104 /* Loop over samples */
105 for( n = 0; n < length - 7; n += 8, input_QS += 8 ) {
106 const int16x8_t t0_s16x4 = vld1q_s16( input + n );
107 vst1q_s32( input_QS + 0, vshll_n_s16( vget_low_s16( t0_s16x4 ), QS ) );
108 vst1q_s32( input_QS + 4, vshll_n_s16( vget_high_s16( t0_s16x4 ), QS ) );
109 }
110 for( ; n < length; n++, input_QS++ ) {
111 input_QS[ 0 ] = silk_LSHIFT32( (opus_int32)input[ n ], QS );
112 }
113 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
114 input_QS += 4;
115 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
116 input_QS += 4;
117 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
118 input_QS += 4;
119 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
120 input_QS += 4;
121 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
122 input_QS += 4;
123 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
124 input_QS = input_QST + MAX_SHAPE_LPC_ORDER - orderT;
125
126 /* The following loop runs ( length + order ) times, with ( order ) extra epilogues. */
127 /* The zero paddings in input_QS guarantee corr_QC's correctness even with the extra epilogues. */
128 /* The values of state_QS will be polluted by the extra epilogues, however they are temporary values. */
129
130 /* Keep the C code here to help understand the intrinsics optimization. */
131 /*
132 {
133 opus_int32 state_QS[ 2 ][ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
134 opus_int32 *state_QST[ 3 ];
135 state_QST[ 0 ] = state_QS[ 0 ];
136 state_QST[ 1 ] = state_QS[ 1 ];
137 for( n = 0; n < length + order; n++, input_QS++ ) {
138 state_QST[ 0 ][ orderT ] = input_QS[ orderT ];
139 for( i = 0; i < orderT; i++ ) {
140 corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( state_QST[ 0 ][ i ], input_QS[ i ] ), 2 * QS - QC );
141 state_QST[ 1 ][ i ] = silk_SMLAWB( state_QST[ 1 ][ i + 1 ], state_QST[ 0 ][ i ] - state_QST[ 0 ][ i + 1 ], warping_Q16 );
142 }
143 state_QST[ 2 ] = state_QST[ 0 ];
144 state_QST[ 0 ] = state_QST[ 1 ];
145 state_QST[ 1 ] = state_QST[ 2 ];
146 }
147 }
148 */
149
150 {
151 const int32x4_t warping_Q16_s32x4 = vdupq_n_s32( warping_Q16 << 15 );
152 const opus_int32 *in = input_QS + orderT;
153 opus_int o = orderT;
154 int32x4_t state_QS_s32x4[ 3 ][ 2 ];
155
156 ALLOC( state, length + orderT, opus_int32 );
157 state_QS_s32x4[ 2 ][ 1 ] = vdupq_n_s32( 0 );
158
159 /* Calculate 8 taps of all inputs in each loop. */
160 do {
161 state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 0 ][ 1 ] =
162 state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 1 ][ 1 ] = vdupq_n_s32( 0 );
163 n = 0;
164 do {
165 calc_corr( input_QS + n, corr_QC, o - 8, state_QS_s32x4[ 0 ][ 0 ] );
166 calc_corr( input_QS + n, corr_QC, o - 4, state_QS_s32x4[ 0 ][ 1 ] );
167 state_QS_s32x4[ 2 ][ 1 ] = vld1q_s32( in + n );
168 vst1q_lane_s32( state + n, state_QS_s32x4[ 0 ][ 0 ], 0 );
169 state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 0 ][ 1 ], 1 );
170 state_QS_s32x4[ 2 ][ 1 ] = vextq_s32( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], 1 );
171 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 );
172 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 );
173 state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ];
174 state_QS_s32x4[ 1 ][ 1 ] = state_QS_s32x4[ 2 ][ 1 ];
175 } while( ++n < ( length + order ) );
176 in = state;
177 o -= 8;
178 } while( o > 4 );
179
180 if( o ) {
181 /* Calculate the last 4 taps of all inputs. */
182 opus_int32 *stateT = state;
183 silk_assert( o == 4 );
184 state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 1 ][ 0 ] = vdupq_n_s32( 0 );
185 n = length + order;
186 do {
187 calc_corr( input_QS, corr_QC, 0, state_QS_s32x4[ 0 ][ 0 ] );
188 state_QS_s32x4[ 2 ][ 0 ] = vld1q_s32( stateT );
189 vst1q_lane_s32( stateT, state_QS_s32x4[ 0 ][ 0 ], 0 );
190 state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], 1 );
191 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 );
192 state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ];
193 input_QS++;
194 stateT++;
195 } while( --n );
196 }
197 }
198
199 {
200 const opus_int16 *inputT = input;
201 int32x4_t t_s32x4;
202 int64x1_t t_s64x1;
203 int64x2_t t_s64x2 = vdupq_n_s64( 0 );
204 for( n = 0; n <= length - 8; n += 8 ) {
205 int16x8_t input_s16x8 = vld1q_s16( inputT );
206 t_s32x4 = vmull_s16( vget_low_s16( input_s16x8 ), vget_low_s16( input_s16x8 ) );
207 t_s32x4 = vmlal_s16( t_s32x4, vget_high_s16( input_s16x8 ), vget_high_s16( input_s16x8 ) );
208 t_s64x2 = vaddw_s32( t_s64x2, vget_low_s32( t_s32x4 ) );
209 t_s64x2 = vaddw_s32( t_s64x2, vget_high_s32( t_s32x4 ) );
210 inputT += 8;
211 }
212 t_s64x1 = vadd_s64( vget_low_s64( t_s64x2 ), vget_high_s64( t_s64x2 ) );
213 corr_QC_orderT = vget_lane_s64( t_s64x1, 0 );
214 for( ; n < length; n++ ) {
215 corr_QC_orderT += silk_SMULL( input[ n ], input[ n ] );
216 }
217 corr_QC_orderT = silk_LSHIFT64( corr_QC_orderT, QC );
218 corr_QC[ orderT ] = corr_QC_orderT;
219 }
220
221 corr_QCT = corr_QC + orderT - order;
222 lsh = silk_CLZ64( corr_QC_orderT ) - 35;
223 lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
224 *scale = -( QC + lsh );
225 silk_assert( *scale >= -30 && *scale <= 12 );
226 lsh_s64x2 = vdupq_n_s64( lsh );
227 for( i = 0; i <= order - 3; i += 4 ) {
228 int32x4_t corr_s32x4;
229 int64x2_t corr_QC0_s64x2, corr_QC1_s64x2;
230 corr_QC0_s64x2 = vld1q_s64( corr_QCT + i );
231 corr_QC1_s64x2 = vld1q_s64( corr_QCT + i + 2 );
232 corr_QC0_s64x2 = vshlq_s64( corr_QC0_s64x2, lsh_s64x2 );
233 corr_QC1_s64x2 = vshlq_s64( corr_QC1_s64x2, lsh_s64x2 );
234 corr_s32x4 = vcombine_s32( vmovn_s64( corr_QC1_s64x2 ), vmovn_s64( corr_QC0_s64x2 ) );
235 corr_s32x4 = vrev64q_s32( corr_s32x4 );
236 vst1q_s32( corr + order - i - 3, corr_s32x4 );
237 }
238 if( lsh >= 0 ) {
239 for( ; i < order + 1; i++ ) {
240 corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QCT[ i ], lsh ) );
241 }
242 } else {
243 for( ; i < order + 1; i++ ) {
244 corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QCT[ i ], -lsh ) );
245 }
246 }
247 silk_assert( corr_QCT[ order ] >= 0 ); /* If breaking, decrease QC*/
248 RESTORE_STACK;
249 }
250
251#ifdef OPUS_CHECK_ASM
252 {
253 opus_int32 corr_c[ MAX_SHAPE_LPC_ORDER + 1 ];
254 opus_int scale_c;
255 silk_warped_autocorrelation_FIX_c( corr_c, &scale_c, input, warping_Q16, length, order );
256 silk_assert( !memcmp( corr_c, corr, sizeof( corr_c[ 0 ] ) * ( order + 1 ) ) );
257 silk_assert( scale_c == *scale );
258 }
259#endif
260}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c
new file mode 100644
index 0000000000..de95c98693
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c
@@ -0,0 +1,48 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33#include "celt_lpc.h"
34
35/* Compute autocorrelation */
36void silk_autocorr(
37 opus_int32 *results, /* O Result (length correlationCount) */
38 opus_int *scale, /* O Scaling of the correlation vector */
39 const opus_int16 *inputData, /* I Input data to correlate */
40 const opus_int inputDataSize, /* I Length of input */
41 const opus_int correlationCount, /* I Number of correlation taps to compute */
42 int arch /* I Run-time architecture */
43)
44{
45 opus_int corrCount;
46 corrCount = silk_min_int( inputDataSize, correlationCount );
47 *scale = _celt_autocorr(inputData, results, NULL, 0, corrCount-1, inputDataSize, arch);
48}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c
new file mode 100644
index 0000000000..274d4b28e1
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c
@@ -0,0 +1,280 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33#include "define.h"
34#include "tuning_parameters.h"
35#include "pitch.h"
36
37#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
38
39#define QA 25
40#define N_BITS_HEAD_ROOM 3
41#define MIN_RSHIFTS -16
42#define MAX_RSHIFTS (32 - QA)
43
44/* Compute reflection coefficients from input signal */
45void silk_burg_modified_c(
46 opus_int32 *res_nrg, /* O Residual energy */
47 opus_int *res_nrg_Q, /* O Residual energy Q value */
48 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
49 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
50 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
51 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
52 const opus_int nb_subfr, /* I Number of subframes stacked in x */
53 const opus_int D, /* I Order */
54 int arch /* I Run-time architecture */
55)
56{
57 opus_int k, n, s, lz, rshifts, reached_max_gain;
58 opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
59 const opus_int16 *x_ptr;
60 opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
61 opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
62 opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
63 opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
64 opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
65 opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
66 opus_int64 C0_64;
67
68 celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
69
70 /* Compute autocorrelations, added over subframes */
71 C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch );
72 lz = silk_CLZ64(C0_64);
73 rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz;
74 if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS;
75 if (rshifts < MIN_RSHIFTS) rshifts = MIN_RSHIFTS;
76
77 if (rshifts > 0) {
78 C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts );
79 } else {
80 C0 = silk_LSHIFT32((opus_int32)C0_64, -rshifts );
81 }
82
83 CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
84 silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
85 if( rshifts > 0 ) {
86 for( s = 0; s < nb_subfr; s++ ) {
87 x_ptr = x + s * subfr_length;
88 for( n = 1; n < D + 1; n++ ) {
89 C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(
90 silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );
91 }
92 }
93 } else {
94 for( s = 0; s < nb_subfr; s++ ) {
95 int i;
96 opus_int32 d;
97 x_ptr = x + s * subfr_length;
98 celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch );
99 for( n = 1; n < D + 1; n++ ) {
100 for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ )
101 d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] );
102 xcorr[ n - 1 ] += d;
103 }
104 for( n = 1; n < D + 1; n++ ) {
105 C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts );
106 }
107 }
108 }
109 silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
110
111 /* Initialize */
112 CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
113
114 invGain_Q30 = (opus_int32)1 << 30;
115 reached_max_gain = 0;
116 for( n = 0; n < D; n++ ) {
117 /* Update first row of correlation matrix (without first element) */
118 /* Update last row of correlation matrix (without last element, stored in reversed order) */
119 /* Update C * Af */
120 /* Update C * flipud(Af) (stored in reversed order) */
121 if( rshifts > -2 ) {
122 for( s = 0; s < nb_subfr; s++ ) {
123 x_ptr = x + s * subfr_length;
124 x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */
125 x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */
126 tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */
127 tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */
128 for( k = 0; k < n; k++ ) {
129 C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
130 C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
131 Atmp_QA = Af_QA[ k ];
132 tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */
133 tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */
134 }
135 tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */
136 tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */
137 for( k = 0; k <= n; k++ ) {
138 CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */
139 CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */
140 }
141 }
142 } else {
143 for( s = 0; s < nb_subfr; s++ ) {
144 x_ptr = x + s * subfr_length;
145 x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */
146 x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */
147 tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */
148 tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */
149 for( k = 0; k < n; k++ ) {
150 C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
151 C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
152 Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */
153 /* We sometimes have get overflows in the multiplications (even beyond +/- 2^32),
154 but they cancel each other and the real result seems to always fit in a 32-bit
155 signed integer. This was determined experimentally, not theoretically (unfortunately). */
156 tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
157 tmp2 = silk_MLA_ovflw( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
158 }
159 tmp1 = -tmp1; /* Q17 */
160 tmp2 = -tmp2; /* Q17 */
161 for( k = 0; k <= n; k++ ) {
162 CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,
163 silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */
164 CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,
165 silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */
166 }
167 }
168 }
169
170 /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
171 tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */
172 tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */
173 num = 0; /* Q( -rshifts ) */
174 nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */
175 for( k = 0; k < n; k++ ) {
176 Atmp_QA = Af_QA[ k ];
177 lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;
178 lz = silk_min( 32 - QA, lz );
179 Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */
180
181 tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
182 tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
183 num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
184 nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
185 Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */
186 }
187 CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */
188 CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */
189 num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */
190 num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */
191
192 /* Calculate the next order reflection (parcor) coefficient */
193 if( silk_abs( num ) < nrg ) {
194 rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );
195 } else {
196 rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;
197 }
198
199 /* Update inverse prediction gain */
200 tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
201 tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );
202 if( tmp1 <= minInvGain_Q30 ) {
203 /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
204 tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
205 rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
206 if( rc_Q31 > 0 ) {
207 /* Newton-Raphson iteration */
208 rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
209 rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
210 if( num < 0 ) {
211 /* Ensure adjusted reflection coefficients has the original sign */
212 rc_Q31 = -rc_Q31;
213 }
214 }
215 invGain_Q30 = minInvGain_Q30;
216 reached_max_gain = 1;
217 } else {
218 invGain_Q30 = tmp1;
219 }
220
221 /* Update the AR coefficients */
222 for( k = 0; k < (n + 1) >> 1; k++ ) {
223 tmp1 = Af_QA[ k ]; /* QA */
224 tmp2 = Af_QA[ n - k - 1 ]; /* QA */
225 Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */
226 Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */
227 }
228 Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */
229
230 if( reached_max_gain ) {
231 /* Reached max prediction gain; set remaining coefficients to zero and exit loop */
232 for( k = n + 1; k < D; k++ ) {
233 Af_QA[ k ] = 0;
234 }
235 break;
236 }
237
238 /* Update C * Af and C * Ab */
239 for( k = 0; k <= n + 1; k++ ) {
240 tmp1 = CAf[ k ]; /* Q( -rshifts ) */
241 tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */
242 CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */
243 CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */
244 }
245 }
246
247 if( reached_max_gain ) {
248 for( k = 0; k < D; k++ ) {
249 /* Scale coefficients */
250 A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
251 }
252 /* Subtract energy of preceding samples from C0 */
253 if( rshifts > 0 ) {
254 for( s = 0; s < nb_subfr; s++ ) {
255 x_ptr = x + s * subfr_length;
256 C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );
257 }
258 } else {
259 for( s = 0; s < nb_subfr; s++ ) {
260 x_ptr = x + s * subfr_length;
261 C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch), -rshifts);
262 }
263 }
264 /* Approximate residual energy */
265 *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );
266 *res_nrg_Q = -rshifts;
267 } else {
268 /* Return residual energy */
269 nrg = CAf[ 0 ]; /* Q( -rshifts ) */
270 tmp1 = (opus_int32)1 << 16; /* Q16 */
271 for( k = 0; k < D; k++ ) {
272 Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */
273 nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */
274 tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */
275 A_Q16[ k ] = -Atmp1;
276 }
277 *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
278 *res_nrg_Q = -rshifts;
279 }
280}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c
new file mode 100644
index 0000000000..1b4a29c232
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c
@@ -0,0 +1,150 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32/**********************************************************************
33 * Correlation Matrix Computations for LS estimate.
34 **********************************************************************/
35
36#include "main_FIX.h"
37
38/* Calculates correlation vector X'*t */
39void silk_corrVector_FIX(
40 const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
41 const opus_int16 *t, /* I Target vector [L] */
42 const opus_int L, /* I Length of vectors */
43 const opus_int order, /* I Max lag for correlation */
44 opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
45 const opus_int rshifts, /* I Right shifts of correlations */
46 int arch /* I Run-time architecture */
47)
48{
49 opus_int lag, i;
50 const opus_int16 *ptr1, *ptr2;
51 opus_int32 inner_prod;
52
53 ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
54 ptr2 = t;
55 /* Calculate X'*t */
56 if( rshifts > 0 ) {
57 /* Right shifting used */
58 for( lag = 0; lag < order; lag++ ) {
59 inner_prod = 0;
60 for( i = 0; i < L; i++ ) {
61 inner_prod = silk_ADD_RSHIFT32( inner_prod, silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
62 }
63 Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
64 ptr1--; /* Go to next column of X */
65 }
66 } else {
67 silk_assert( rshifts == 0 );
68 for( lag = 0; lag < order; lag++ ) {
69 Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L, arch ); /* X[:,lag]'*t */
70 ptr1--; /* Go to next column of X */
71 }
72 }
73}
74
75/* Calculates correlation matrix X'*X */
76void silk_corrMatrix_FIX(
77 const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
78 const opus_int L, /* I Length of vectors */
79 const opus_int order, /* I Max lag for correlation */
80 opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */
81 opus_int32 *nrg, /* O Energy of x vector */
82 opus_int *rshifts, /* O Right shifts of correlations and energy */
83 int arch /* I Run-time architecture */
84)
85{
86 opus_int i, j, lag;
87 opus_int32 energy;
88 const opus_int16 *ptr1, *ptr2;
89
90 /* Calculate energy to find shift used to fit in 32 bits */
91 silk_sum_sqr_shift( nrg, rshifts, x, L + order - 1 );
92 energy = *nrg;
93
94 /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */
95 /* Remove contribution of first order - 1 samples */
96 for( i = 0; i < order - 1; i++ ) {
97 energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), *rshifts );
98 }
99
100 /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */
101 /* Fill out the diagonal of the correlation matrix */
102 matrix_ptr( XX, 0, 0, order ) = energy;
103 silk_assert( energy >= 0 );
104 ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */
105 for( j = 1; j < order; j++ ) {
106 energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), *rshifts ) );
107 energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), *rshifts ) );
108 matrix_ptr( XX, j, j, order ) = energy;
109 silk_assert( energy >= 0 );
110 }
111
112 ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */
113 /* Calculate the remaining elements of the correlation matrix */
114 if( *rshifts > 0 ) {
115 /* Right shifting used */
116 for( lag = 1; lag < order; lag++ ) {
117 /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
118 energy = 0;
119 for( i = 0; i < L; i++ ) {
120 energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), *rshifts );
121 }
122 /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
123 matrix_ptr( XX, lag, 0, order ) = energy;
124 matrix_ptr( XX, 0, lag, order ) = energy;
125 for( j = 1; j < ( order - lag ); j++ ) {
126 energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), *rshifts ) );
127 energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), *rshifts ) );
128 matrix_ptr( XX, lag + j, j, order ) = energy;
129 matrix_ptr( XX, j, lag + j, order ) = energy;
130 }
131 ptr2--; /* Update pointer to first sample of next column (lag) in X */
132 }
133 } else {
134 for( lag = 1; lag < order; lag++ ) {
135 /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
136 energy = silk_inner_prod_aligned( ptr1, ptr2, L, arch );
137 matrix_ptr( XX, lag, 0, order ) = energy;
138 matrix_ptr( XX, 0, lag, order ) = energy;
139 /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
140 for( j = 1; j < ( order - lag ); j++ ) {
141 energy = silk_SUB32( energy, silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) );
142 energy = silk_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] );
143 matrix_ptr( XX, lag + j, j, order ) = energy;
144 matrix_ptr( XX, j, lag + j, order ) = energy;
145 }
146 ptr2--;/* Update pointer to first sample of next column (lag) in X */
147 }
148 }
149}
150
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c
new file mode 100644
index 0000000000..a02bf87dbb
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c
@@ -0,0 +1,448 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <stdlib.h>
33#include "main_FIX.h"
34#include "stack_alloc.h"
35#include "tuning_parameters.h"
36
37/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */
38static OPUS_INLINE void silk_LBRR_encode_FIX(
39 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
40 silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
41 const opus_int16 x16[], /* I Input signal */
42 opus_int condCoding /* I The type of conditional coding used so far for this frame */
43);
44
45void silk_encode_do_VAD_FIX(
46 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
47 opus_int activity /* I Decision of Opus voice activity detector */
48)
49{
50 const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
51
52 /****************************/
53 /* Voice Activity Detection */
54 /****************************/
55 silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
56 /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */
57 if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
58 psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
59 }
60
61 /**************************************************/
62 /* Convert speech activity into VAD and DTX flags */
63 /**************************************************/
64 if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
65 psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
66 psEnc->sCmn.noSpeechCounter++;
67 if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
68 psEnc->sCmn.inDTX = 0;
69 } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
70 psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
71 psEnc->sCmn.inDTX = 0;
72 }
73 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
74 } else {
75 psEnc->sCmn.noSpeechCounter = 0;
76 psEnc->sCmn.inDTX = 0;
77 psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
78 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
79 }
80}
81
82/****************/
83/* Encode frame */
84/****************/
85opus_int silk_encode_frame_FIX(
86 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
87 opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */
88 ec_enc *psRangeEnc, /* I/O compressor data structure */
89 opus_int condCoding, /* I The type of conditional coding to use */
90 opus_int maxBits, /* I If > 0: maximum number of output bits */
91 opus_int useCBR /* I Flag to force constant-bitrate operation */
92)
93{
94 silk_encoder_control_FIX sEncCtrl;
95 opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
96 opus_int16 *x_frame;
97 ec_enc sRangeEnc_copy, sRangeEnc_copy2;
98 silk_nsq_state sNSQ_copy, sNSQ_copy2;
99 opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
100 opus_int32 gainsID, gainsID_lower, gainsID_upper;
101 opus_int16 gainMult_Q8;
102 opus_int16 ec_prevLagIndex_copy;
103 opus_int ec_prevSignalType_copy;
104 opus_int8 LastGainIndex_copy2;
105 opus_int gain_lock[ MAX_NB_SUBFR ] = {0};
106 opus_int16 best_gain_mult[ MAX_NB_SUBFR ];
107 opus_int best_sum[ MAX_NB_SUBFR ];
108 SAVE_STACK;
109
110 /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
111 LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
112
113 psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
114
115 /**************************************************************/
116 /* Set up Input Pointers, and insert frame in input buffer */
117 /*************************************************************/
118 /* start of frame to encode */
119 x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;
120
121 /***************************************/
122 /* Ensure smooth bandwidth transitions */
123 /***************************************/
124 silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
125
126 /*******************************************/
127 /* Copy new frame to front of input buffer */
128 /*******************************************/
129 silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
130
131 if( !psEnc->sCmn.prefillFlag ) {
132 VARDECL( opus_int16, res_pitch );
133 VARDECL( opus_uint8, ec_buf_copy );
134 opus_int16 *res_pitch_frame;
135
136 ALLOC( res_pitch,
137 psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length
138 + psEnc->sCmn.ltp_mem_length, opus_int16 );
139 /* start of pitch LPC residual frame */
140 res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;
141
142 /*****************************************/
143 /* Find pitch lags, initial LPC analysis */
144 /*****************************************/
145 silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch );
146
147 /************************/
148 /* Noise shape analysis */
149 /************************/
150 silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch );
151
152 /***************************************************/
153 /* Find linear prediction coefficients (LPC + LTP) */
154 /***************************************************/
155 silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
156
157 /****************************************/
158 /* Process gains */
159 /****************************************/
160 silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
161
162 /****************************************/
163 /* Low Bitrate Redundant Encoding */
164 /****************************************/
165 silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding );
166
167 /* Loop over quantizer and entropy coding to control bitrate */
168 maxIter = 6;
169 gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
170 found_lower = 0;
171 found_upper = 0;
172 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
173 gainsID_lower = -1;
174 gainsID_upper = -1;
175 /* Copy part of the input state */
176 silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
177 silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
178 seed_copy = psEnc->sCmn.indices.Seed;
179 ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
180 ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
181 ALLOC( ec_buf_copy, 1275, opus_uint8 );
182 for( iter = 0; ; iter++ ) {
183 if( gainsID == gainsID_lower ) {
184 nBits = nBits_lower;
185 } else if( gainsID == gainsID_upper ) {
186 nBits = nBits_upper;
187 } else {
188 /* Restore part of the input state */
189 if( iter > 0 ) {
190 silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
191 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
192 psEnc->sCmn.indices.Seed = seed_copy;
193 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
194 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
195 }
196
197 /*****************************************/
198 /* Noise shaping quantization */
199 /*****************************************/
200 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
201 silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
202 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
203 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
204 psEnc->sCmn.arch );
205 } else {
206 silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
207 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
208 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
209 psEnc->sCmn.arch);
210 }
211
212 if ( iter == maxIter && !found_lower ) {
213 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
214 }
215
216 /****************************************/
217 /* Encode Parameters */
218 /****************************************/
219 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
220
221 /****************************************/
222 /* Encode Excitation Signal */
223 /****************************************/
224 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
225 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
226
227 nBits = ec_tell( psRangeEnc );
228
229 /* If we still bust after the last iteration, do some damage control. */
230 if ( iter == maxIter && !found_lower && nBits > maxBits ) {
231 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
232
233 /* Keep gains the same as the last frame. */
234 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
235 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
236 psEnc->sCmn.indices.GainsIndices[ i ] = 4;
237 }
238 if (condCoding != CODE_CONDITIONALLY) {
239 psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
240 }
241 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
242 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
243 /* Clear all pulses. */
244 for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
245 psEnc->sCmn.pulses[ i ] = 0;
246 }
247
248 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
249
250 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
251 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
252
253 nBits = ec_tell( psRangeEnc );
254 }
255
256 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
257 break;
258 }
259 }
260
261 if( iter == maxIter ) {
262 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
263 /* Restore output state from earlier iteration that did meet the bitrate budget */
264 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
265 celt_assert( sRangeEnc_copy2.offs <= 1275 );
266 silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
267 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
268 psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
269 }
270 break;
271 }
272
273 if( nBits > maxBits ) {
274 if( found_lower == 0 && iter >= 2 ) {
275 /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
276 sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );
277 found_upper = 0;
278 gainsID_upper = -1;
279 } else {
280 found_upper = 1;
281 nBits_upper = nBits;
282 gainMult_upper = gainMult_Q8;
283 gainsID_upper = gainsID;
284 }
285 } else if( nBits < maxBits - 5 ) {
286 found_lower = 1;
287 nBits_lower = nBits;
288 gainMult_lower = gainMult_Q8;
289 if( gainsID != gainsID_lower ) {
290 gainsID_lower = gainsID;
291 /* Copy part of the output state */
292 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
293 celt_assert( psRangeEnc->offs <= 1275 );
294 silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
295 silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
296 LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
297 }
298 } else {
299 /* Within 5 bits of budget: close enough */
300 break;
301 }
302
303 if ( !found_lower && nBits > maxBits ) {
304 int j;
305 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
306 int sum=0;
307 for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
308 sum += abs( psEnc->sCmn.pulses[j] );
309 }
310 if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
311 best_sum[i] = sum;
312 best_gain_mult[i] = gainMult_Q8;
313 } else {
314 gain_lock[i] = 1;
315 }
316 }
317 }
318 if( ( found_lower & found_upper ) == 0 ) {
319 /* Adjust gain according to high-rate rate/distortion curve */
320 if( nBits > maxBits ) {
321 if (gainMult_Q8 < 16384) {
322 gainMult_Q8 *= 2;
323 } else {
324 gainMult_Q8 = 32767;
325 }
326 } else {
327 opus_int32 gain_factor_Q16;
328 gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
329 gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
330 }
331
332 } else {
333 /* Adjust gain by interpolating */
334 gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
335 /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
336 if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
337 gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
338 } else
339 if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
340 gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
341 }
342 }
343
344 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
345 opus_int16 tmp;
346 if ( gain_lock[i] ) {
347 tmp = best_gain_mult[i];
348 } else {
349 tmp = gainMult_Q8;
350 }
351 sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
352 }
353
354 /* Quantize gains */
355 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
356 silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
357 &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
358
359 /* Unique identifier of gains vector */
360 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
361 }
362 }
363
364 /* Update input buffer */
365 silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
366 ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
367
368 /* Exit without entropy coding */
369 if( psEnc->sCmn.prefillFlag ) {
370 /* No payload */
371 *pnBytesOut = 0;
372 RESTORE_STACK;
373 return ret;
374 }
375
376 /* Parameters needed for next frame */
377 psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
378 psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
379
380 /****************************************/
381 /* Finalize payload */
382 /****************************************/
383 psEnc->sCmn.first_frame_after_reset = 0;
384 /* Payload size */
385 *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
386
387 RESTORE_STACK;
388 return ret;
389}
390
391/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */
392static OPUS_INLINE void silk_LBRR_encode_FIX(
393 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
394 silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
395 const opus_int16 x16[], /* I Input signal */
396 opus_int condCoding /* I The type of conditional coding used so far for this frame */
397)
398{
399 opus_int32 TempGains_Q16[ MAX_NB_SUBFR ];
400 SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
401 silk_nsq_state sNSQ_LBRR;
402
403 /*******************************************/
404 /* Control use of inband LBRR */
405 /*******************************************/
406 if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
407 psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
408
409 /* Copy noise shaping quantizer state and quantization indices from regular encoding */
410 silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
411 silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
412
413 /* Save original gains */
414 silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
415
416 if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
417 /* First frame in packet or previous frame not LBRR coded */
418 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
419
420 /* Increase Gains to get target LBRR rate */
421 psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
422 psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
423 }
424
425 /* Decode to get gains in sync with decoder */
426 /* Overwrite unquantized gains with quantized gains */
427 silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
428 &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
429
430 /*****************************************/
431 /* Noise shaping quantization */
432 /*****************************************/
433 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
434 silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
435 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
436 psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
437 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
438 } else {
439 silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
440 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
441 psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
442 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
443 }
444
445 /* Restore original gains */
446 silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
447 }
448}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c
new file mode 100644
index 0000000000..c762a0f2a2
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c
@@ -0,0 +1,151 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "stack_alloc.h"
34#include "tuning_parameters.h"
35
36/* Finds LPC vector from correlations, and converts to NLSF */
37void silk_find_LPC_FIX(
38 silk_encoder_state *psEncC, /* I/O Encoder state */
39 opus_int16 NLSF_Q15[], /* O NLSFs */
40 const opus_int16 x[], /* I Input signal */
41 const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */
42)
43{
44 opus_int k, subfr_length;
45 opus_int32 a_Q16[ MAX_LPC_ORDER ];
46 opus_int isInterpLower, shift;
47 opus_int32 res_nrg0, res_nrg1;
48 opus_int rshift0, rshift1;
49
50 /* Used only for LSF interpolation */
51 opus_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg;
52 opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;
53 opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ];
54 opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
55 SAVE_STACK;
56
57 subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;
58
59 /* Default: no interpolation */
60 psEncC->indices.NLSFInterpCoef_Q2 = 4;
61
62 /* Burg AR analysis for the full frame */
63 silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder, psEncC->arch );
64
65 if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
66 VARDECL( opus_int16, LPC_res );
67
68 /* Optimal solution for last 10 ms */
69 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 );
70
71 /* subtract residual energy here, as that's easier than adding it to the */
72 /* residual energy of the first 10 ms in each iteration of the search below */
73 shift = res_tmp_nrg_Q - res_nrg_Q;
74 if( shift >= 0 ) {
75 if( shift < 32 ) {
76 res_nrg = res_nrg - silk_RSHIFT( res_tmp_nrg, shift );
77 }
78 } else {
79 silk_assert( shift > -32 );
80 res_nrg = silk_RSHIFT( res_nrg, -shift ) - res_tmp_nrg;
81 res_nrg_Q = res_tmp_nrg_Q;
82 }
83
84 /* Convert to NLSFs */
85 silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder );
86
87 ALLOC( LPC_res, 2 * subfr_length, opus_int16 );
88
89 /* Search over interpolation indices to find the one with lowest residual energy */
90 for( k = 3; k >= 0; k-- ) {
91 /* Interpolate NLSFs for first half */
92 silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
93
94 /* Convert to LPC for residual energy evaluation */
95 silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
96
97 /* Calculate residual energy with NLSF interpolation */
98 silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder, psEncC->arch );
99
100 silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder );
101 silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder );
102
103 /* Add subframe energies from first half frame */
104 shift = rshift0 - rshift1;
105 if( shift >= 0 ) {
106 res_nrg1 = silk_RSHIFT( res_nrg1, shift );
107 res_nrg_interp_Q = -rshift0;
108 } else {
109 res_nrg0 = silk_RSHIFT( res_nrg0, -shift );
110 res_nrg_interp_Q = -rshift1;
111 }
112 res_nrg_interp = silk_ADD32( res_nrg0, res_nrg1 );
113
114 /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */
115 shift = res_nrg_interp_Q - res_nrg_Q;
116 if( shift >= 0 ) {
117 if( silk_RSHIFT( res_nrg_interp, shift ) < res_nrg ) {
118 isInterpLower = silk_TRUE;
119 } else {
120 isInterpLower = silk_FALSE;
121 }
122 } else {
123 if( -shift < 32 ) {
124 if( res_nrg_interp < silk_RSHIFT( res_nrg, -shift ) ) {
125 isInterpLower = silk_TRUE;
126 } else {
127 isInterpLower = silk_FALSE;
128 }
129 } else {
130 isInterpLower = silk_FALSE;
131 }
132 }
133
134 /* Determine whether current interpolated NLSFs are best so far */
135 if( isInterpLower == silk_TRUE ) {
136 /* Interpolation has lower residual energy */
137 res_nrg = res_nrg_interp;
138 res_nrg_Q = res_nrg_interp_Q;
139 psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
140 }
141 }
142 }
143
144 if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
145 /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
146 silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder );
147 }
148
149 celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
150 RESTORE_STACK;
151}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c
new file mode 100644
index 0000000000..62d4afb250
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c
@@ -0,0 +1,99 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "tuning_parameters.h"
34
35void silk_find_LTP_FIX(
36 opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */
37 opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */
38 const opus_int16 r_ptr[], /* I Residual signal after LPC */
39 const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
40 const opus_int subfr_length, /* I Subframe length */
41 const opus_int nb_subfr, /* I Number of subframes */
42 int arch /* I Run-time architecture */
43)
44{
45 opus_int i, k, extra_shifts;
46 opus_int xx_shifts, xX_shifts, XX_shifts;
47 const opus_int16 *lag_ptr;
48 opus_int32 *XXLTP_Q17_ptr, *xXLTP_Q17_ptr;
49 opus_int32 xx, nrg, temp;
50
51 xXLTP_Q17_ptr = xXLTP_Q17;
52 XXLTP_Q17_ptr = XXLTP_Q17;
53 for( k = 0; k < nb_subfr; k++ ) {
54 lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
55
56 silk_sum_sqr_shift( &xx, &xx_shifts, r_ptr, subfr_length + LTP_ORDER ); /* xx in Q( -xx_shifts ) */
57 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 ) */
58 extra_shifts = xx_shifts - XX_shifts;
59 if( extra_shifts > 0 ) {
60 /* Shift XX */
61 xX_shifts = xx_shifts;
62 for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
63 XXLTP_Q17_ptr[ i ] = silk_RSHIFT32( XXLTP_Q17_ptr[ i ], extra_shifts ); /* Q( -xX_shifts ) */
64 }
65 nrg = silk_RSHIFT32( nrg, extra_shifts ); /* Q( -xX_shifts ) */
66 } else if( extra_shifts < 0 ) {
67 /* Shift xx */
68 xX_shifts = XX_shifts;
69 xx = silk_RSHIFT32( xx, -extra_shifts ); /* Q( -xX_shifts ) */
70 } else {
71 xX_shifts = xx_shifts;
72 }
73 silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xXLTP_Q17_ptr, xX_shifts, arch ); /* xXLTP_Q17_ptr in Q( -xX_shifts ) */
74
75 /* At this point all correlations are in Q(-xX_shifts) */
76 temp = silk_SMLAWB( 1, nrg, SILK_FIX_CONST( LTP_CORR_INV_MAX, 16 ) );
77 temp = silk_max( temp, xx );
78TIC(div)
79#if 0
80 for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
81 XXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( XXLTP_Q17_ptr[ i ], temp, 17 );
82 }
83 for( i = 0; i < LTP_ORDER; i++ ) {
84 xXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( xXLTP_Q17_ptr[ i ], temp, 17 );
85 }
86#else
87 for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
88 XXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)XXLTP_Q17_ptr[ i ], 17 ) / temp );
89 }
90 for( i = 0; i < LTP_ORDER; i++ ) {
91 xXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)xXLTP_Q17_ptr[ i ], 17 ) / temp );
92 }
93#endif
94TOC(div)
95 r_ptr += subfr_length;
96 XXLTP_Q17_ptr += LTP_ORDER * LTP_ORDER;
97 xXLTP_Q17_ptr += LTP_ORDER;
98 }
99}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c
new file mode 100644
index 0000000000..6c3379f2bb
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c
@@ -0,0 +1,143 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "stack_alloc.h"
34#include "tuning_parameters.h"
35
36/* Find pitch lags */
37void silk_find_pitch_lags_FIX(
38 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
39 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
40 opus_int16 res[], /* O residual */
41 const opus_int16 x[], /* I Speech signal */
42 int arch /* I Run-time architecture */
43)
44{
45 opus_int buf_len, i, scale;
46 opus_int32 thrhld_Q13, res_nrg;
47 const opus_int16 *x_ptr;
48 VARDECL( opus_int16, Wsig );
49 opus_int16 *Wsig_ptr;
50 opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
51 opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ];
52 opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ];
53 opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ];
54 SAVE_STACK;
55
56 /******************************************/
57 /* Set up buffer lengths etc based on Fs */
58 /******************************************/
59 buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
60
61 /* Safety check */
62 celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
63
64 /*************************************/
65 /* Estimate LPC AR coefficients */
66 /*************************************/
67
68 /* Calculate windowed signal */
69
70 ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 );
71
72 /* First LA_LTP samples */
73 x_ptr = x + buf_len - psEnc->sCmn.pitch_LPC_win_length;
74 Wsig_ptr = Wsig;
75 silk_apply_sine_window( Wsig_ptr, x_ptr, 1, psEnc->sCmn.la_pitch );
76
77 /* Middle un - windowed samples */
78 Wsig_ptr += psEnc->sCmn.la_pitch;
79 x_ptr += psEnc->sCmn.la_pitch;
80 silk_memcpy( Wsig_ptr, x_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );
81
82 /* Last LA_LTP samples */
83 Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
84 x_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
85 silk_apply_sine_window( Wsig_ptr, x_ptr, 2, psEnc->sCmn.la_pitch );
86
87 /* Calculate autocorrelation sequence */
88 silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch );
89
90 /* Add white noise, as fraction of energy */
91 auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1;
92
93 /* Calculate the reflection coefficients using schur */
94 res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );
95
96 /* Prediction gain */
97 psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 );
98
99 /* Convert reflection coefficients to prediction coefficients */
100 silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder );
101
102 /* Convert From 32 bit Q24 to 16 bit Q12 coefs */
103 for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {
104 A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) );
105 }
106
107 /* Do BWE */
108 silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) );
109
110 /*****************************************/
111 /* LPC analysis filtering */
112 /*****************************************/
113 silk_LPC_analysis_filter( res, x, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch );
114
115 if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {
116 /* Threshold for pitch estimator */
117 thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 );
118 thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder );
119 thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 21 ), psEnc->sCmn.speech_activity_Q8 );
120 thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15, 13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) );
121 thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 14 ), psEnc->sCmn.input_tilt_Q15 );
122 thrhld_Q13 = silk_SAT16( thrhld_Q13 );
123
124 /*****************************************/
125 /* Call pitch estimator */
126 /*****************************************/
127 if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex,
128 &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16,
129 (opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr,
130 psEnc->sCmn.arch) == 0 )
131 {
132 psEnc->sCmn.indices.signalType = TYPE_VOICED;
133 } else {
134 psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
135 }
136 } else {
137 silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) );
138 psEnc->sCmn.indices.lagIndex = 0;
139 psEnc->sCmn.indices.contourIndex = 0;
140 psEnc->LTPCorr_Q15 = 0;
141 }
142 RESTORE_STACK;
143}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c
new file mode 100644
index 0000000000..606d863347
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c
@@ -0,0 +1,145 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "stack_alloc.h"
34
35void silk_find_pred_coefs_FIX(
36 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
37 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
38 const opus_int16 res_pitch[], /* I Residual from pitch analysis */
39 const opus_int16 x[], /* I Speech signal */
40 opus_int condCoding /* I The type of conditional coding to use */
41)
42{
43 opus_int i;
44 opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ];
45 opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
46 const opus_int16 *x_ptr;
47 opus_int16 *x_pre_ptr;
48 VARDECL( opus_int16, LPC_in_pre );
49 opus_int32 min_gain_Q16, minInvGain_Q30;
50 SAVE_STACK;
51
52 /* weighting for weighted least squares */
53 min_gain_Q16 = silk_int32_MAX >> 6;
54 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
55 min_gain_Q16 = silk_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] );
56 }
57 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
58 /* Divide to Q16 */
59 silk_assert( psEncCtrl->Gains_Q16[ i ] > 0 );
60 /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */
61 invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 );
62
63 /* Limit inverse */
64 invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 100 );
65
66 /* Square the inverted gains */
67 silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) );
68
69 /* Invert the inverted and normalized gains */
70 local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] );
71 }
72
73 ALLOC( LPC_in_pre,
74 psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder
75 + psEnc->sCmn.frame_length, opus_int16 );
76 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
77 VARDECL( opus_int32, xXLTP_Q17 );
78 VARDECL( opus_int32, XXLTP_Q17 );
79
80 /**********/
81 /* VOICED */
82 /**********/
83 celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
84
85 ALLOC( xXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER, opus_int32 );
86 ALLOC( XXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );
87
88 /* LTP analysis */
89 silk_find_LTP_FIX( XXLTP_Q17, xXLTP_Q17, res_pitch,
90 psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
91
92 /* Quantize LTP gain parameters */
93 silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
94 &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain_Q7, XXLTP_Q17, xXLTP_Q17, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
95
96 /* Control LTP scaling */
97 silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding );
98
99 /* Create LTP residual */
100 silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14,
101 psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
102
103 } else {
104 /************/
105 /* UNVOICED */
106 /************/
107 /* Create signal with prepended subframes, scaled by inverse gains */
108 x_ptr = x - psEnc->sCmn.predictLPCOrder;
109 x_pre_ptr = LPC_in_pre;
110 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
111 silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ],
112 psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
113 x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
114 x_ptr += psEnc->sCmn.subfr_length;
115 }
116
117 silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) );
118 psEncCtrl->LTPredCodGain_Q7 = 0;
119 psEnc->sCmn.sum_log_gain_Q7 = 0;
120 }
121
122 /* Limit on total predictive coding gain */
123 if( psEnc->sCmn.first_frame_after_reset ) {
124 minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 );
125 } else {
126 minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */
127 minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30,
128 silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ),
129 silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 );
130 }
131
132 /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
133 silk_find_LPC_FIX( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain_Q30 );
134
135 /* Quantize LSFs */
136 silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
137
138 /* Calculate residual energy using quantized LPC coefficients */
139 silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains,
140 psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder, psEnc->sCmn.arch );
141
142 /* Copy to prediction struct for use in next frame for interpolation */
143 silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
144 RESTORE_STACK;
145}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c
new file mode 100644
index 0000000000..549f6eadaa
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c
@@ -0,0 +1,54 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Step up function, converts reflection coefficients to prediction coefficients */
35void silk_k2a(
36 opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */
37 const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */
38 const opus_int32 order /* I Prediction order */
39)
40{
41 opus_int k, n;
42 opus_int32 rc, tmp1, tmp2;
43
44 for( k = 0; k < order; k++ ) {
45 rc = rc_Q15[ k ];
46 for( n = 0; n < (k + 1) >> 1; n++ ) {
47 tmp1 = A_Q24[ n ];
48 tmp2 = A_Q24[ k - n - 1 ];
49 A_Q24[ n ] = silk_SMLAWB( tmp1, silk_LSHIFT( tmp2, 1 ), rc );
50 A_Q24[ k - n - 1 ] = silk_SMLAWB( tmp2, silk_LSHIFT( tmp1, 1 ), rc );
51 }
52 A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 );
53 }
54}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c
new file mode 100644
index 0000000000..1595aa6212
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c
@@ -0,0 +1,54 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Step up function, converts reflection coefficients to prediction coefficients */
35void silk_k2a_Q16(
36 opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */
37 const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */
38 const opus_int32 order /* I Prediction order */
39)
40{
41 opus_int k, n;
42 opus_int32 rc, tmp1, tmp2;
43
44 for( k = 0; k < order; k++ ) {
45 rc = rc_Q16[ k ];
46 for( n = 0; n < (k + 1) >> 1; n++ ) {
47 tmp1 = A_Q24[ n ];
48 tmp2 = A_Q24[ k - n - 1 ];
49 A_Q24[ n ] = silk_SMLAWW( tmp1, tmp2, rc );
50 A_Q24[ k - n - 1 ] = silk_SMLAWW( tmp2, tmp1, rc );
51 }
52 A_Q24[ k ] = -silk_LSHIFT( rc, 8 );
53 }
54}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h b/lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h
new file mode 100644
index 0000000000..6d2112e511
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h
@@ -0,0 +1,244 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_MAIN_FIX_H
29#define SILK_MAIN_FIX_H
30
31#include "SigProc_FIX.h"
32#include "structs_FIX.h"
33#include "control.h"
34#include "main.h"
35#include "PLC.h"
36#include "debug.h"
37#include "entenc.h"
38
39#if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \
40 || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
41#include "fixed/arm/warped_autocorrelation_FIX_arm.h"
42#endif
43
44#ifndef FORCE_CPP_BUILD
45#ifdef __cplusplus
46extern "C"
47{
48#endif
49#endif
50
51#define silk_encoder_state_Fxx silk_encoder_state_FIX
52#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FIX
53#define silk_encode_frame_Fxx silk_encode_frame_FIX
54
55#define QC 10
56#define QS 13
57
58/*********************/
59/* Encoder Functions */
60/*********************/
61
62/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
63void silk_HP_variable_cutoff(
64 silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */
65);
66
67/* Encoder main function */
68void silk_encode_do_VAD_FIX(
69 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
70 opus_int activity /* I Decision of Opus voice activity detector */
71);
72
73/* Encoder main function */
74opus_int silk_encode_frame_FIX(
75 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
76 opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */
77 ec_enc *psRangeEnc, /* I/O compressor data structure */
78 opus_int condCoding, /* I The type of conditional coding to use */
79 opus_int maxBits, /* I If > 0: maximum number of output bits */
80 opus_int useCBR /* I Flag to force constant-bitrate operation */
81);
82
83/* Initializes the Silk encoder state */
84opus_int silk_init_encoder(
85 silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */
86 int arch /* I Run-time architecture */
87);
88
89/* Control the Silk encoder */
90opus_int silk_control_encoder(
91 silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
92 silk_EncControlStruct *encControl, /* I Control structure */
93 const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
94 const opus_int channelNb, /* I Channel number */
95 const opus_int force_fs_kHz
96);
97
98/**************************/
99/* Noise shaping analysis */
100/**************************/
101/* Compute noise shaping coefficients and initial gain values */
102void silk_noise_shape_analysis_FIX(
103 silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
104 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
105 const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
106 const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
107 int arch /* I Run-time architecture */
108);
109
110/* Autocorrelations for a warped frequency axis */
111void silk_warped_autocorrelation_FIX_c(
112 opus_int32 *corr, /* O Result [order + 1] */
113 opus_int *scale, /* O Scaling of the correlation vector */
114 const opus_int16 *input, /* I Input data to correlate */
115 const opus_int warping_Q16, /* I Warping coefficient */
116 const opus_int length, /* I Length of input */
117 const opus_int order /* I Correlation order (even) */
118);
119
120#if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
121#define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
122 ((void)(arch), silk_warped_autocorrelation_FIX_c(corr, scale, input, warping_Q16, length, order))
123#endif
124
125/* Calculation of LTP state scaling */
126void silk_LTP_scale_ctrl_FIX(
127 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
128 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
129 opus_int condCoding /* I The type of conditional coding to use */
130);
131
132/**********************************************/
133/* Prediction Analysis */
134/**********************************************/
135/* Find pitch lags */
136void silk_find_pitch_lags_FIX(
137 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
138 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
139 opus_int16 res[], /* O residual */
140 const opus_int16 x[], /* I Speech signal */
141 int arch /* I Run-time architecture */
142);
143
144/* Find LPC and LTP coefficients */
145void silk_find_pred_coefs_FIX(
146 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
147 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
148 const opus_int16 res_pitch[], /* I Residual from pitch analysis */
149 const opus_int16 x[], /* I Speech signal */
150 opus_int condCoding /* I The type of conditional coding to use */
151);
152
153/* LPC analysis */
154void silk_find_LPC_FIX(
155 silk_encoder_state *psEncC, /* I/O Encoder state */
156 opus_int16 NLSF_Q15[], /* O NLSFs */
157 const opus_int16 x[], /* I Input signal */
158 const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */
159);
160
161/* LTP analysis */
162void silk_find_LTP_FIX(
163 opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */
164 opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */
165 const opus_int16 r_lpc[], /* I Residual signal after LPC */
166 const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
167 const opus_int subfr_length, /* I Subframe length */
168 const opus_int nb_subfr, /* I Number of subframes */
169 int arch /* I Run-time architecture */
170);
171
172void silk_LTP_analysis_filter_FIX(
173 opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */
174 const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */
175 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */
176 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */
177 const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */
178 const opus_int subfr_length, /* I Length of each subframe */
179 const opus_int nb_subfr, /* I Number of subframes */
180 const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */
181);
182
183/* Calculates residual energies of input subframes where all subframes have LPC_order */
184/* of preceding samples */
185void silk_residual_energy_FIX(
186 opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
187 opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */
188 const opus_int16 x[], /* I Input signal */
189 opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
190 const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */
191 const opus_int subfr_length, /* I Subframe length */
192 const opus_int nb_subfr, /* I Number of subframes */
193 const opus_int LPC_order, /* I LPC order */
194 int arch /* I Run-time architecture */
195);
196
197/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
198opus_int32 silk_residual_energy16_covar_FIX(
199 const opus_int16 *c, /* I Prediction vector */
200 const opus_int32 *wXX, /* I Correlation matrix */
201 const opus_int32 *wXx, /* I Correlation vector */
202 opus_int32 wxx, /* I Signal energy */
203 opus_int D, /* I Dimension */
204 opus_int cQ /* I Q value for c vector 0 - 15 */
205);
206
207/* Processing of gains */
208void silk_process_gains_FIX(
209 silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
210 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */
211 opus_int condCoding /* I The type of conditional coding to use */
212);
213
214/******************/
215/* Linear Algebra */
216/******************/
217/* Calculates correlation matrix X'*X */
218void silk_corrMatrix_FIX(
219 const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
220 const opus_int L, /* I Length of vectors */
221 const opus_int order, /* I Max lag for correlation */
222 opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */
223 opus_int32 *nrg, /* O Energy of x vector */
224 opus_int *rshifts, /* O Right shifts of correlations */
225 int arch /* I Run-time architecture */
226);
227
228/* Calculates correlation vector X'*t */
229void silk_corrVector_FIX(
230 const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
231 const opus_int16 *t, /* I Target vector [L] */
232 const opus_int L, /* I Length of vectors */
233 const opus_int order, /* I Max lag for correlation */
234 opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
235 const opus_int rshifts, /* I Right shifts of correlations */
236 int arch /* I Run-time architecture */
237);
238
239#ifndef FORCE_CPP_BUILD
240#ifdef __cplusplus
241}
242#endif /* __cplusplus */
243#endif /* FORCE_CPP_BUILD */
244#endif /* SILK_MAIN_FIX_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
new file mode 100644
index 0000000000..3999b5bd09
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
@@ -0,0 +1,336 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28
29/**************************************************************/
30/* Compute noise shaping coefficients and initial gain values */
31/**************************************************************/
32#define OVERRIDE_silk_noise_shape_analysis_FIX
33
34void silk_noise_shape_analysis_FIX(
35 silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
36 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
37 const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
38 const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
39 int arch /* I Run-time architecture */
40)
41{
42 silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
43 opus_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
44 opus_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
45 opus_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
46 opus_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
47 opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
48 opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
49 opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ];
50 opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ];
51 VARDECL( opus_int16, x_windowed );
52 const opus_int16 *x_ptr, *pitch_res_ptr;
53 SAVE_STACK;
54
55 /* Point to start of first LPC analysis block */
56 x_ptr = x - psEnc->sCmn.la_shape;
57
58 /****************/
59 /* GAIN CONTROL */
60 /****************/
61 SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
62
63 /* Input quality is the average of the quality in the lowest two VAD bands */
64 psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
65 + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
66
67 /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
68 psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
69 SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
70
71 /* Reduce coding SNR during low speech activity */
72 if( psEnc->sCmn.useCBR == 0 ) {
73 b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
74 b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );
75 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
76 silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/
77 silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/
78 }
79
80 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
81 /* Reduce gains for periodic signals */
82 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
83 } else {
84 /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
85 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
86 silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
87 SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
88 }
89
90 /*************************/
91 /* SPARSENESS PROCESSING */
92 /*************************/
93 /* Set quantizer offset */
94 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
95 /* Initially set to 0; may be overruled in process_gains(..) */
96 psEnc->sCmn.indices.quantOffsetType = 0;
97 psEncCtrl->sparseness_Q8 = 0;
98 } else {
99 /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
100 nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
101 energy_variation_Q7 = 0;
102 log_energy_prev_Q7 = 0;
103 pitch_res_ptr = pitch_res;
104 for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
105 silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
106 nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/
107
108 log_energy_Q7 = silk_lin2log( nrg );
109 if( k > 0 ) {
110 energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );
111 }
112 log_energy_prev_Q7 = log_energy_Q7;
113 pitch_res_ptr += nSamples;
114 }
115
116 psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 -
117 SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );
118
119 /* Set quantization offset depending on sparseness measure */
120 if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {
121 psEnc->sCmn.indices.quantOffsetType = 0;
122 } else {
123 psEnc->sCmn.indices.quantOffsetType = 1;
124 }
125
126 /* Increase coding SNR for sparse signals */
127 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 ) );
128 }
129
130 /*******************************/
131 /* Control bandwidth expansion */
132 /*******************************/
133 /* More BWE for signals with high prediction gain */
134 strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
135 BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
136 silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
137 delta_Q16 = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),
138 SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );
139 BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 );
140 BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 );
141 /* BWExp1 will be applied after BWExp2, so make it relative */
142 BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) );
143
144 if( psEnc->sCmn.warping_Q16 > 0 ) {
145 /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
146 warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
147 } else {
148 warping_Q16 = 0;
149 }
150
151 /********************************************/
152 /* Compute noise shaping AR coefs and gains */
153 /********************************************/
154 ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
155 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
156 /* Apply window: sine slope followed by flat part followed by cosine slope */
157 opus_int shift, slope_part, flat_part;
158 flat_part = psEnc->sCmn.fs_kHz * 3;
159 slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
160
161 silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
162 shift = slope_part;
163 silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
164 shift += flat_part;
165 silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
166
167 /* Update pointer: next LPC analysis block */
168 x_ptr += psEnc->sCmn.subfr_length;
169
170 if( psEnc->sCmn.warping_Q16 > 0 ) {
171 /* Calculate warped auto correlation */
172 silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
173 } else {
174 /* Calculate regular auto correlation */
175 silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
176 }
177
178 /* Add white noise, as a fraction of energy */
179 auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),
180 SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
181
182 /* Calculate the reflection coefficients using schur */
183 nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
184 silk_assert( nrg >= 0 );
185
186 /* Convert reflection coefficients to prediction coefficients */
187 silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
188
189 Qnrg = -scale; /* range: -12...30*/
190 silk_assert( Qnrg >= -12 );
191 silk_assert( Qnrg <= 30 );
192
193 /* Make sure that Qnrg is an even number */
194 if( Qnrg & 1 ) {
195 Qnrg -= 1;
196 nrg >>= 1;
197 }
198
199 tmp32 = silk_SQRT_APPROX( nrg );
200 Qnrg >>= 1; /* range: -6...15*/
201
202 psEncCtrl->Gains_Q16[ k ] = (silk_LSHIFT32( silk_LIMIT( (tmp32), silk_RSHIFT32( silk_int32_MIN, (16 - Qnrg) ), \
203 silk_RSHIFT32( silk_int32_MAX, (16 - Qnrg) ) ), (16 - Qnrg) ));
204
205 if( psEnc->sCmn.warping_Q16 > 0 ) {
206 /* Adjust gain for warping */
207 gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
208 silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
209 if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) {
210 psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
211 } else {
212 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
213 }
214 }
215
216 /* Bandwidth expansion for synthesis filter shaping */
217 silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );
218
219 /* Compute noise shaping filter coefficients */
220 silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );
221
222 /* Bandwidth expansion for analysis filter shaping */
223 silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );
224 silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
225
226 /* Ratio of prediction gains, in energy domain */
227 pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder, arch );
228 nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder, arch );
229
230 /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
231 pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
232 psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );
233
234 /* Convert to monic warped prediction coefficients and limit absolute values */
235 limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
236
237 /* Convert from Q24 to Q13 and store in int16 */
238 for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
239 psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );
240 psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );
241 }
242 }
243
244 /*****************/
245 /* Gain tweaking */
246 /*****************/
247 /* Increase gains during low speech activity and put lower limit on gains */
248 gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
249 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 ) ) );
250 silk_assert( gain_mult_Q16 > 0 );
251 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
252 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
253 silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
254 psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
255 }
256
257 gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ),
258 psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );
259 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
260 psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );
261 }
262
263 /************************************************/
264 /* Control low-frequency shaping and noise tilt */
265 /************************************************/
266 /* Less low frequency shaping for noisy inputs */
267 strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
268 SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
269 strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
270 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
271 /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
272 /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
273 opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
274 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
275 b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );
276 /* Pack two coefficients in one int32 */
277 psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );
278 psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
279 }
280 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*/
281 Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
282 silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
283 silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
284 } else {
285 b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/
286 /* Pack two coefficients in one int32 */
287 psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
288 silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
289 psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
290 for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
291 psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
292 }
293 Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
294 }
295
296 /****************************/
297 /* HARMONIC SHAPING CONTROL */
298 /****************************/
299 /* Control boosting of harmonic frequencies */
300 HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),
301 psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );
302
303 /* More harmonic boost for noisy input signals */
304 HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16,
305 SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );
306
307 if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
308 /* More harmonic noise shaping for high bitrates or noisy input */
309 HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
310 SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
311 psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
312
313 /* Less harmonic noise shaping for less periodic signals */
314 HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),
315 silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
316 } else {
317 HarmShapeGain_Q16 = 0;
318 }
319
320 /*************************/
321 /* Smooth over subframes */
322 /*************************/
323 for( k = 0; k < MAX_NB_SUBFR; k++ ) {
324 psShapeSt->HarmBoost_smth_Q16 =
325 silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
326 psShapeSt->HarmShapeGain_smth_Q16 =
327 silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
328 psShapeSt->Tilt_smth_Q16 =
329 silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
330
331 psEncCtrl->HarmBoost_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 );
332 psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
333 psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 );
334 }
335 RESTORE_STACK;
336}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h
new file mode 100644
index 0000000000..21b256885f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h
@@ -0,0 +1,184 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27#ifndef __PREFILTER_FIX_MIPSR1_H__
28#define __PREFILTER_FIX_MIPSR1_H__
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include "main_FIX.h"
35#include "stack_alloc.h"
36#include "tuning_parameters.h"
37
38#define OVERRIDE_silk_warped_LPC_analysis_filter_FIX
39void silk_warped_LPC_analysis_filter_FIX(
40 opus_int32 state[], /* I/O State [order + 1] */
41 opus_int32 res_Q2[], /* O Residual signal [length] */
42 const opus_int16 coef_Q13[], /* I Coefficients [order] */
43 const opus_int16 input[], /* I Input signal [length] */
44 const opus_int16 lambda_Q16, /* I Warping factor */
45 const opus_int length, /* I Length of input signal */
46 const opus_int order, /* I Filter order (even) */
47 int arch
48)
49{
50 opus_int n, i;
51 opus_int32 acc_Q11, acc_Q22, tmp1, tmp2, tmp3, tmp4;
52 opus_int32 state_cur, state_next;
53
54 (void)arch;
55
56 /* Order must be even */
57 /* Length must be even */
58
59 silk_assert( ( order & 1 ) == 0 );
60 silk_assert( ( length & 1 ) == 0 );
61
62 for( n = 0; n < length; n+=2 ) {
63 /* Output of lowpass section */
64 tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
65 state_cur = silk_LSHIFT( input[ n ], 14 );
66 /* Output of allpass section */
67 tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
68 state_next = tmp2;
69 acc_Q11 = silk_RSHIFT( order, 1 );
70 acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
71
72
73 /* Output of lowpass section */
74 tmp4 = silk_SMLAWB( state_cur, state_next, lambda_Q16 );
75 state[ 0 ] = silk_LSHIFT( input[ n+1 ], 14 );
76 /* Output of allpass section */
77 tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 );
78 state[ 1 ] = tmp4;
79 acc_Q22 = silk_RSHIFT( order, 1 );
80 acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ 0 ] );
81
82 /* Loop over allpass sections */
83 for( i = 2; i < order; i += 2 ) {
84 /* Output of allpass section */
85 tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
86 state_cur = tmp1;
87 acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
88 /* Output of allpass section */
89 tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
90 state_next = tmp2;
91 acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
92
93
94 /* Output of allpass section */
95 tmp4 = silk_SMLAWB( state_cur, state_next - tmp3, lambda_Q16 );
96 state[ i ] = tmp3;
97 acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ i - 1 ] );
98 /* Output of allpass section */
99 tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 );
100 state[ i + 1 ] = tmp4;
101 acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ i ] );
102 }
103 acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
104 res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
105
106 state[ order ] = tmp3;
107 acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ order - 1 ] );
108 res_Q2[ n+1 ] = silk_LSHIFT( (opus_int32)input[ n+1 ], 2 ) - silk_RSHIFT_ROUND( acc_Q22, 9 );
109 }
110}
111
112
113
114/* Prefilter for finding Quantizer input signal */
115#define OVERRIDE_silk_prefilt_FIX
116static inline void silk_prefilt_FIX(
117 silk_prefilter_state_FIX *P, /* I/O state */
118 opus_int32 st_res_Q12[], /* I short term residual signal */
119 opus_int32 xw_Q3[], /* O prefiltered signal */
120 opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
121 opus_int Tilt_Q14, /* I Tilt shaping coeficient */
122 opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
123 opus_int lag, /* I Lag for harmonic shaping */
124 opus_int length /* I Length of signals */
125)
126{
127 opus_int i, idx, LTP_shp_buf_idx;
128 opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
129 opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
130 opus_int16 *LTP_shp_buf;
131
132 /* To speed up use temp variables instead of using the struct */
133 LTP_shp_buf = P->sLTP_shp;
134 LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
135 sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12;
136 sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12;
137
138 if( lag > 0 ) {
139 for( i = 0; i < length; i++ ) {
140 /* unrolled loop */
141 silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
142 idx = lag + LTP_shp_buf_idx;
143 n_LTP_Q12 = silk_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
144 n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
145 n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
146
147 n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
148 n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
149
150 sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
151 sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
152
153 LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
154 LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
155
156 xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 );
157 }
158 }
159 else
160 {
161 for( i = 0; i < length; i++ ) {
162
163 n_LTP_Q12 = 0;
164
165 n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
166 n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
167
168 sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
169 sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
170
171 LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
172 LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
173
174 xw_Q3[i] = silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 9 );
175 }
176 }
177
178 /* Copy temp variable back to state */
179 P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12;
180 P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12;
181 P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
182}
183
184#endif /* __PREFILTER_FIX_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
new file mode 100644
index 0000000000..fcbd96c88d
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
@@ -0,0 +1,166 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__
29#define __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include "main_FIX.h"
36
37#undef QC
38#define QC 10
39
40#undef QS
41#define QS 14
42
43/* Autocorrelations for a warped frequency axis */
44#define OVERRIDE_silk_warped_autocorrelation_FIX
45void silk_warped_autocorrelation_FIX(
46 opus_int32 *corr, /* O Result [order + 1] */
47 opus_int *scale, /* O Scaling of the correlation vector */
48 const opus_int16 *input, /* I Input data to correlate */
49 const opus_int warping_Q16, /* I Warping coefficient */
50 const opus_int length, /* I Length of input */
51 const opus_int order, /* I Correlation order (even) */
52 int arch /* I Run-time architecture */
53)
54{
55 opus_int n, i, lsh;
56 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;
57 opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
58 opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
59 opus_int64 temp64;
60
61 opus_int32 val;
62 val = 2 * QS - QC;
63
64 /* Order must be even */
65 silk_assert( ( order & 1 ) == 0 );
66 silk_assert( 2 * QS - QC >= 0 );
67
68 /* Loop over samples */
69 for( n = 0; n < length; n=n+4 ) {
70
71 tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
72 start_1 = tmp1_QS;
73 tmp3_QS = silk_LSHIFT32( (opus_int32)input[ n+1], QS );
74 start_2 = tmp3_QS;
75 tmp5_QS = silk_LSHIFT32( (opus_int32)input[ n+2], QS );
76 start_3 = tmp5_QS;
77 tmp7_QS = silk_LSHIFT32( (opus_int32)input[ n+3], QS );
78
79 /* Loop over allpass sections */
80 for( i = 0; i < order; i += 2 ) {
81 /* Output of allpass section */
82 tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
83 corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, start_1);
84
85 tmp4_QS = silk_SMLAWB( tmp1_QS, tmp2_QS - tmp3_QS, warping_Q16 );
86 corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp3_QS, start_2);
87
88 tmp6_QS = silk_SMLAWB( tmp3_QS, tmp4_QS - tmp5_QS, warping_Q16 );
89 corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp5_QS, start_3);
90
91 tmp8_QS = silk_SMLAWB( tmp5_QS, tmp6_QS - tmp7_QS, warping_Q16 );
92 state_QS[ i ] = tmp7_QS;
93 corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp7_QS, state_QS[0]);
94
95 /* Output of allpass section */
96 tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
97 corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, start_1);
98
99 tmp3_QS = silk_SMLAWB( tmp2_QS, tmp1_QS - tmp4_QS, warping_Q16 );
100 corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp4_QS, start_2);
101
102 tmp5_QS = silk_SMLAWB( tmp4_QS, tmp3_QS - tmp6_QS, warping_Q16 );
103 corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp6_QS, start_3);
104
105 tmp7_QS = silk_SMLAWB( tmp6_QS, tmp5_QS - tmp8_QS, warping_Q16 );
106 state_QS[ i + 1 ] = tmp8_QS;
107 corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp8_QS, state_QS[ 0 ]);
108
109 }
110 state_QS[ order ] = tmp7_QS;
111
112 corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, start_1);
113 corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp3_QS, start_2);
114 corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp5_QS, start_3);
115 corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp7_QS, state_QS[ 0 ]);
116 }
117
118 for(;n< length; n++ ) {
119
120 tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
121
122 /* Loop over allpass sections */
123 for( i = 0; i < order; i += 2 ) {
124
125 /* Output of allpass section */
126 tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
127 state_QS[ i ] = tmp1_QS;
128 corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, state_QS[ 0 ]);
129
130 /* Output of allpass section */
131 tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
132 state_QS[ i + 1 ] = tmp2_QS;
133 corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, state_QS[ 0 ]);
134 }
135 state_QS[ order ] = tmp1_QS;
136 corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, state_QS[ 0 ]);
137 }
138
139 temp64 = corr_QC[ 0 ];
140 temp64 = __builtin_mips_shilo(temp64, val);
141
142 lsh = silk_CLZ64( temp64 ) - 35;
143 lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
144 *scale = -( QC + lsh );
145 silk_assert( *scale >= -30 && *scale <= 12 );
146 if( lsh >= 0 ) {
147 for( i = 0; i < order + 1; i++ ) {
148 temp64 = corr_QC[ i ];
149 //temp64 = __builtin_mips_shilo(temp64, val);
150 temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val);
151 corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) );
152 }
153 } else {
154 for( i = 0; i < order + 1; i++ ) {
155 temp64 = corr_QC[ i ];
156 //temp64 = __builtin_mips_shilo(temp64, val);
157 temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val);
158 corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) );
159 }
160 }
161
162 corr_QC[ 0 ] = __builtin_mips_shilo(corr_QC[ 0 ], val);
163
164 silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
165}
166#endif /* __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c
new file mode 100644
index 0000000000..85fea0bf09
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c
@@ -0,0 +1,407 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "stack_alloc.h"
34#include "tuning_parameters.h"
35
36/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */
37/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */
38/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */
39/* coefficient in an array of coefficients, for monic filters. */
40static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/
41 const opus_int32 *coefs_Q24,
42 opus_int lambda_Q16,
43 opus_int order
44) {
45 opus_int i;
46 opus_int32 gain_Q24;
47
48 lambda_Q16 = -lambda_Q16;
49 gain_Q24 = coefs_Q24[ order - 1 ];
50 for( i = order - 2; i >= 0; i-- ) {
51 gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 );
52 }
53 gain_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 );
54 return silk_INVERSE32_varQ( gain_Q24, 40 );
55}
56
57/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
58/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
59static OPUS_INLINE void limit_warped_coefs(
60 opus_int32 *coefs_Q24,
61 opus_int lambda_Q16,
62 opus_int32 limit_Q24,
63 opus_int order
64) {
65 opus_int i, iter, ind = 0;
66 opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_Q16;
67 opus_int32 nom_Q16, den_Q24;
68 opus_int32 limit_Q20, maxabs_Q20;
69
70 /* Convert to monic coefficients */
71 lambda_Q16 = -lambda_Q16;
72 for( i = order - 1; i > 0; i-- ) {
73 coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
74 }
75 lambda_Q16 = -lambda_Q16;
76 nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
77 den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
78 gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
79 for( i = 0; i < order; i++ ) {
80 coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
81 }
82 limit_Q20 = silk_RSHIFT(limit_Q24, 4);
83 for( iter = 0; iter < 10; iter++ ) {
84 /* Find maximum absolute value */
85 maxabs_Q24 = -1;
86 for( i = 0; i < order; i++ ) {
87 tmp = silk_abs_int32( coefs_Q24[ i ] );
88 if( tmp > maxabs_Q24 ) {
89 maxabs_Q24 = tmp;
90 ind = i;
91 }
92 }
93 /* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */
94 maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4);
95 if( maxabs_Q20 <= limit_Q20 ) {
96 /* Coefficients are within range - done */
97 return;
98 }
99
100 /* Convert back to true warped coefficients */
101 for( i = 1; i < order; i++ ) {
102 coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
103 }
104 gain_Q16 = silk_INVERSE32_varQ( gain_Q16, 32 );
105 for( i = 0; i < order; i++ ) {
106 coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
107 }
108
109 /* Apply bandwidth expansion */
110 chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(
111 silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
112 silk_MUL( maxabs_Q20, ind + 1 ), 22 );
113 silk_bwexpander_32( coefs_Q24, order, chirp_Q16 );
114
115 /* Convert to monic warped coefficients */
116 lambda_Q16 = -lambda_Q16;
117 for( i = order - 1; i > 0; i-- ) {
118 coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
119 }
120 lambda_Q16 = -lambda_Q16;
121 nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
122 den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
123 gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
124 for( i = 0; i < order; i++ ) {
125 coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
126 }
127 }
128 silk_assert( 0 );
129}
130
131/* Disable MIPS version until it's updated. */
132#if 0 && defined(MIPSr1_ASM)
133#include "mips/noise_shape_analysis_FIX_mipsr1.h"
134#endif
135
136/**************************************************************/
137/* Compute noise shaping coefficients and initial gain values */
138/**************************************************************/
139#ifndef OVERRIDE_silk_noise_shape_analysis_FIX
140void silk_noise_shape_analysis_FIX(
141 silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
142 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
143 const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
144 const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
145 int arch /* I Run-time architecture */
146)
147{
148 silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
149 opus_int k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0;
150 opus_int32 SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32;
151 opus_int32 nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
152 opus_int32 BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
153 opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
154 opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
155 opus_int32 AR_Q24[ MAX_SHAPE_LPC_ORDER ];
156 VARDECL( opus_int16, x_windowed );
157 const opus_int16 *x_ptr, *pitch_res_ptr;
158 SAVE_STACK;
159
160 /* Point to start of first LPC analysis block */
161 x_ptr = x - psEnc->sCmn.la_shape;
162
163 /****************/
164 /* GAIN CONTROL */
165 /****************/
166 SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
167
168 /* Input quality is the average of the quality in the lowest two VAD bands */
169 psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
170 + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
171
172 /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
173 psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
174 SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
175
176 /* Reduce coding SNR during low speech activity */
177 if( psEnc->sCmn.useCBR == 0 ) {
178 b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
179 b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );
180 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
181 silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/
182 silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/
183 }
184
185 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
186 /* Reduce gains for periodic signals */
187 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
188 } else {
189 /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
190 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
191 silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
192 SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
193 }
194
195 /*************************/
196 /* SPARSENESS PROCESSING */
197 /*************************/
198 /* Set quantizer offset */
199 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
200 /* Initially set to 0; may be overruled in process_gains(..) */
201 psEnc->sCmn.indices.quantOffsetType = 0;
202 } else {
203 /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
204 nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
205 energy_variation_Q7 = 0;
206 log_energy_prev_Q7 = 0;
207 pitch_res_ptr = pitch_res;
208 nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
209 for( k = 0; k < nSegs; k++ ) {
210 silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
211 nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/
212
213 log_energy_Q7 = silk_lin2log( nrg );
214 if( k > 0 ) {
215 energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );
216 }
217 log_energy_prev_Q7 = log_energy_Q7;
218 pitch_res_ptr += nSamples;
219 }
220
221 /* Set quantization offset depending on sparseness measure */
222 if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) {
223 psEnc->sCmn.indices.quantOffsetType = 0;
224 } else {
225 psEnc->sCmn.indices.quantOffsetType = 1;
226 }
227 }
228
229 /*******************************/
230 /* Control bandwidth expansion */
231 /*******************************/
232 /* More BWE for signals with high prediction gain */
233 strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
234 BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
235 silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
236
237 if( psEnc->sCmn.warping_Q16 > 0 ) {
238 /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
239 warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
240 } else {
241 warping_Q16 = 0;
242 }
243
244 /********************************************/
245 /* Compute noise shaping AR coefs and gains */
246 /********************************************/
247 ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
248 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
249 /* Apply window: sine slope followed by flat part followed by cosine slope */
250 opus_int shift, slope_part, flat_part;
251 flat_part = psEnc->sCmn.fs_kHz * 3;
252 slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
253
254 silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
255 shift = slope_part;
256 silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
257 shift += flat_part;
258 silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
259
260 /* Update pointer: next LPC analysis block */
261 x_ptr += psEnc->sCmn.subfr_length;
262
263 if( psEnc->sCmn.warping_Q16 > 0 ) {
264 /* Calculate warped auto correlation */
265 silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
266 } else {
267 /* Calculate regular auto correlation */
268 silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
269 }
270
271 /* Add white noise, as a fraction of energy */
272 auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),
273 SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
274
275 /* Calculate the reflection coefficients using schur */
276 nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
277 silk_assert( nrg >= 0 );
278
279 /* Convert reflection coefficients to prediction coefficients */
280 silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
281
282 Qnrg = -scale; /* range: -12...30*/
283 silk_assert( Qnrg >= -12 );
284 silk_assert( Qnrg <= 30 );
285
286 /* Make sure that Qnrg is an even number */
287 if( Qnrg & 1 ) {
288 Qnrg -= 1;
289 nrg >>= 1;
290 }
291
292 tmp32 = silk_SQRT_APPROX( nrg );
293 Qnrg >>= 1; /* range: -6...15*/
294
295 psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg );
296
297 if( psEnc->sCmn.warping_Q16 > 0 ) {
298 /* Adjust gain for warping */
299 gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
300 silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
301 if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) {
302 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
303 } else {
304 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 );
305 if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) {
306 psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
307 } else {
308 psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 );
309 }
310 }
311 silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
312 }
313
314 /* Bandwidth expansion */
315 silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 );
316
317 if( psEnc->sCmn.warping_Q16 > 0 ) {
318 /* Convert to monic warped prediction coefficients and limit absolute values */
319 limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
320
321 /* Convert from Q24 to Q13 and store in int16 */
322 for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
323 psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) );
324 }
325 } else {
326 silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder );
327 }
328 }
329
330 /*****************/
331 /* Gain tweaking */
332 /*****************/
333 /* Increase gains during low speech activity and put lower limit on gains */
334 gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
335 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 ) ) );
336 silk_assert( gain_mult_Q16 > 0 );
337 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
338 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
339 silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
340 psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
341 }
342
343
344 /************************************************/
345 /* Control low-frequency shaping and noise tilt */
346 /************************************************/
347 /* Less low frequency shaping for noisy inputs */
348 strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
349 SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
350 strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
351 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
352 /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
353 /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
354 opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
355 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
356 b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );
357 /* Pack two coefficients in one int32 */
358 psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );
359 psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
360 }
361 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*/
362 Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
363 silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
364 silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
365 } else {
366 b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/
367 /* Pack two coefficients in one int32 */
368 psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
369 silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
370 psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
371 for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
372 psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
373 }
374 Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
375 }
376
377 /****************************/
378 /* HARMONIC SHAPING CONTROL */
379 /****************************/
380 if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
381 /* More harmonic noise shaping for high bitrates or noisy input */
382 HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
383 SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
384 psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
385
386 /* Less harmonic noise shaping for less periodic signals */
387 HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),
388 silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
389 } else {
390 HarmShapeGain_Q16 = 0;
391 }
392
393 /*************************/
394 /* Smooth over subframes */
395 /*************************/
396 for( k = 0; k < MAX_NB_SUBFR; k++ ) {
397 psShapeSt->HarmShapeGain_smth_Q16 =
398 silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
399 psShapeSt->Tilt_smth_Q16 =
400 silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
401
402 psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
403 psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 );
404 }
405 RESTORE_STACK;
406}
407#endif /* OVERRIDE_silk_noise_shape_analysis_FIX */
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c
new file mode 100644
index 0000000000..14729046d2
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c
@@ -0,0 +1,721 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32/***********************************************************
33* Pitch analyser function
34********************************************************** */
35#include "SigProc_FIX.h"
36#include "pitch_est_defines.h"
37#include "stack_alloc.h"
38#include "debug.h"
39#include "pitch.h"
40
41#define SCRATCH_SIZE 22
42#define SF_LENGTH_4KHZ ( PE_SUBFR_LENGTH_MS * 4 )
43#define SF_LENGTH_8KHZ ( PE_SUBFR_LENGTH_MS * 8 )
44#define MIN_LAG_4KHZ ( PE_MIN_LAG_MS * 4 )
45#define MIN_LAG_8KHZ ( PE_MIN_LAG_MS * 8 )
46#define MAX_LAG_4KHZ ( PE_MAX_LAG_MS * 4 )
47#define MAX_LAG_8KHZ ( PE_MAX_LAG_MS * 8 - 1 )
48#define CSTRIDE_4KHZ ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ )
49#define CSTRIDE_8KHZ ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) )
50#define D_COMP_MIN ( MIN_LAG_8KHZ - 3 )
51#define D_COMP_MAX ( MAX_LAG_8KHZ + 4 )
52#define D_COMP_STRIDE ( D_COMP_MAX - D_COMP_MIN )
53
54typedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ];
55
56/************************************************************/
57/* Internally used functions */
58/************************************************************/
59static void silk_P_Ana_calc_corr_st3(
60 silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */
61 const opus_int16 frame[], /* I vector to correlate */
62 opus_int start_lag, /* I lag offset to search around */
63 opus_int sf_length, /* I length of a 5 ms subframe */
64 opus_int nb_subfr, /* I number of subframes */
65 opus_int complexity, /* I Complexity setting */
66 int arch /* I Run-time architecture */
67);
68
69static void silk_P_Ana_calc_energy_st3(
70 silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */
71 const opus_int16 frame[], /* I vector to calc energy in */
72 opus_int start_lag, /* I lag offset to search around */
73 opus_int sf_length, /* I length of one 5 ms subframe */
74 opus_int nb_subfr, /* I number of subframes */
75 opus_int complexity, /* I Complexity setting */
76 int arch /* I Run-time architecture */
77);
78
79/*************************************************************/
80/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */
81/*************************************************************/
82opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
83 const opus_int16 *frame_unscaled, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
84 opus_int *pitch_out, /* O 4 pitch lag values */
85 opus_int16 *lagIndex, /* O Lag Index */
86 opus_int8 *contourIndex, /* O Pitch contour Index */
87 opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */
88 opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
89 const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */
90 const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */
91 const opus_int Fs_kHz, /* I Sample frequency (kHz) */
92 const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
93 const opus_int nb_subfr, /* I number of 5 ms subframes */
94 int arch /* I Run-time architecture */
95)
96{
97 VARDECL( opus_int16, frame_8kHz_buf );
98 VARDECL( opus_int16, frame_4kHz );
99 VARDECL( opus_int16, frame_scaled );
100 opus_int32 filt_state[ 6 ];
101 const opus_int16 *frame, *frame_8kHz;
102 opus_int i, k, d, j;
103 VARDECL( opus_int16, C );
104 VARDECL( opus_int32, xcorr32 );
105 const opus_int16 *target_ptr, *basis_ptr;
106 opus_int32 cross_corr, normalizer, energy, energy_basis, energy_target;
107 opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp, shift;
108 VARDECL( opus_int16, d_comp );
109 opus_int32 sum, threshold, lag_counter;
110 opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new;
111 opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new;
112 VARDECL( silk_pe_stage3_vals, energies_st3 );
113 VARDECL( silk_pe_stage3_vals, cross_corr_st3 );
114 opus_int frame_length, frame_length_8kHz, frame_length_4kHz;
115 opus_int sf_length;
116 opus_int min_lag;
117 opus_int max_lag;
118 opus_int32 contour_bias_Q15, diff;
119 opus_int nb_cbk_search, cbk_size;
120 opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13;
121 const opus_int8 *Lag_CB_ptr;
122 SAVE_STACK;
123
124 /* Check for valid sampling frequency */
125 celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
126
127 /* Check for valid complexity setting */
128 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
129 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
130
131 silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
132 silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) );
133
134 /* Set up frame lengths max / min lag for the sampling frequency */
135 frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
136 frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
137 frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
138 sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz;
139 min_lag = PE_MIN_LAG_MS * Fs_kHz;
140 max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
141
142 /* Downscale input if necessary */
143 silk_sum_sqr_shift( &energy, &shift, frame_unscaled, frame_length );
144 shift += 3 - silk_CLZ32( energy ); /* at least two bits headroom */
145 ALLOC( frame_scaled, frame_length, opus_int16 );
146 if( shift > 0 ) {
147 shift = silk_RSHIFT( shift + 1, 1 );
148 for( i = 0; i < frame_length; i++ ) {
149 frame_scaled[ i ] = silk_RSHIFT( frame_unscaled[ i ], shift );
150 }
151 frame = frame_scaled;
152 } else {
153 frame = frame_unscaled;
154 }
155
156 ALLOC( frame_8kHz_buf, ( Fs_kHz == 8 ) ? 1 : frame_length_8kHz, opus_int16 );
157 /* Resample from input sampled at Fs_kHz to 8 kHz */
158 if( Fs_kHz == 16 ) {
159 silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
160 silk_resampler_down2( filt_state, frame_8kHz_buf, frame, frame_length );
161 frame_8kHz = frame_8kHz_buf;
162 } else if( Fs_kHz == 12 ) {
163 silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
164 silk_resampler_down2_3( filt_state, frame_8kHz_buf, frame, frame_length );
165 frame_8kHz = frame_8kHz_buf;
166 } else {
167 celt_assert( Fs_kHz == 8 );
168 frame_8kHz = frame;
169 }
170
171 /* Decimate again to 4 kHz */
172 silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */
173 ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 );
174 silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz );
175
176 /* Low-pass filter */
177 for( i = frame_length_4kHz - 1; i > 0; i-- ) {
178 frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
179 }
180
181
182 /******************************************************************************
183 * FIRST STAGE, operating in 4 khz
184 ******************************************************************************/
185 ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 );
186 ALLOC( xcorr32, MAX_LAG_4KHZ-MIN_LAG_4KHZ+1, opus_int32 );
187 silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) );
188 target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ];
189 for( k = 0; k < nb_subfr >> 1; k++ ) {
190 /* Check that we are within range of the array */
191 celt_assert( target_ptr >= frame_4kHz );
192 celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
193
194 basis_ptr = target_ptr - MIN_LAG_4KHZ;
195
196 /* Check that we are within range of the array */
197 celt_assert( basis_ptr >= frame_4kHz );
198 celt_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
199
200 celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch );
201
202 /* Calculate first vector products before loop */
203 cross_corr = xcorr32[ MAX_LAG_4KHZ - MIN_LAG_4KHZ ];
204 normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch );
205 normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ) );
206 normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) );
207
208 matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) =
209 (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */
210
211 /* From now on normalizer is computed recursively */
212 for( d = MIN_LAG_4KHZ + 1; d <= MAX_LAG_4KHZ; d++ ) {
213 basis_ptr--;
214
215 /* Check that we are within range of the array */
216 silk_assert( basis_ptr >= frame_4kHz );
217 silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
218
219 cross_corr = xcorr32[ MAX_LAG_4KHZ - d ];
220
221 /* Add contribution of new sample and remove contribution from oldest sample */
222 normalizer = silk_ADD32( normalizer,
223 silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) -
224 silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) );
225
226 matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) =
227 (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */
228 }
229 /* Update target pointer */
230 target_ptr += SF_LENGTH_8KHZ;
231 }
232
233 /* Combine two subframes into single correlation measure and apply short-lag bias */
234 if( nb_subfr == PE_MAX_NB_SUBFR ) {
235 for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {
236 sum = (opus_int32)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ )
237 + (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ); /* Q14 */
238 sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */
239 C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */
240 }
241 } else {
242 /* Only short-lag bias */
243 for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {
244 sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 ); /* Q14 */
245 sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */
246 C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */
247 }
248 }
249
250 /* Sort */
251 length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 );
252 celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
253 silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ,
254 length_d_srch );
255
256 /* Escape if correlation is very low already here */
257 Cmax = (opus_int)C[ 0 ]; /* Q14 */
258 if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) {
259 silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
260 *LTPCorr_Q15 = 0;
261 *lagIndex = 0;
262 *contourIndex = 0;
263 RESTORE_STACK;
264 return 1;
265 }
266
267 threshold = silk_SMULWB( search_thres1_Q16, Cmax );
268 for( i = 0; i < length_d_srch; i++ ) {
269 /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
270 if( C[ i ] > threshold ) {
271 d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 );
272 } else {
273 length_d_srch = i;
274 break;
275 }
276 }
277 celt_assert( length_d_srch > 0 );
278
279 ALLOC( d_comp, D_COMP_STRIDE, opus_int16 );
280 for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) {
281 d_comp[ i - D_COMP_MIN ] = 0;
282 }
283 for( i = 0; i < length_d_srch; i++ ) {
284 d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1;
285 }
286
287 /* Convolution */
288 for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {
289 d_comp[ i - D_COMP_MIN ] +=
290 d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ];
291 }
292
293 length_d_srch = 0;
294 for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) {
295 if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) {
296 d_srch[ length_d_srch ] = i;
297 length_d_srch++;
298 }
299 }
300
301 /* Convolution */
302 for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {
303 d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ]
304 + d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ];
305 }
306
307 length_d_comp = 0;
308 for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) {
309 if( d_comp[ i - D_COMP_MIN ] > 0 ) {
310 d_comp[ length_d_comp ] = i - 2;
311 length_d_comp++;
312 }
313 }
314
315 /**********************************************************************************
316 ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
317 *************************************************************************************/
318
319 /*********************************************************************************
320 * Find energy of each subframe projected onto its history, for a range of delays
321 *********************************************************************************/
322 silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * sizeof( opus_int16 ) );
323
324 target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];
325 for( k = 0; k < nb_subfr; k++ ) {
326
327 /* Check that we are within range of the array */
328 celt_assert( target_ptr >= frame_8kHz );
329 celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
330
331 energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ), 1 );
332 for( j = 0; j < length_d_comp; j++ ) {
333 d = d_comp[ j ];
334 basis_ptr = target_ptr - d;
335
336 /* Check that we are within range of the array */
337 silk_assert( basis_ptr >= frame_8kHz );
338 silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
339
340 cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ, arch );
341 if( cross_corr > 0 ) {
342 energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch );
343 matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) =
344 (opus_int16)silk_DIV32_varQ( cross_corr,
345 silk_ADD32( energy_target,
346 energy_basis ),
347 13 + 1 ); /* Q13 */
348 } else {
349 matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 0;
350 }
351 }
352 target_ptr += SF_LENGTH_8KHZ;
353 }
354
355 /* search over lag range and lags codebook */
356 /* scale factor for lag codebook, as a function of center lag */
357
358 CCmax = silk_int32_MIN;
359 CCmax_b = silk_int32_MIN;
360
361 CBimax = 0; /* To avoid returning undefined lag values */
362 lag = -1; /* To check if lag with strong enough correlation has been found */
363
364 if( prevLag > 0 ) {
365 if( Fs_kHz == 12 ) {
366 prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 );
367 } else if( Fs_kHz == 16 ) {
368 prevLag = silk_RSHIFT( prevLag, 1 );
369 }
370 prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag );
371 } else {
372 prevLag_log2_Q7 = 0;
373 }
374 silk_assert( search_thres2_Q13 == silk_SAT16( search_thres2_Q13 ) );
375 /* Set up stage 2 codebook based on number of subframes */
376 if( nb_subfr == PE_MAX_NB_SUBFR ) {
377 cbk_size = PE_NB_CBKS_STAGE2_EXT;
378 Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
379 if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {
380 /* If input is 8 khz use a larger codebook here because it is last stage */
381 nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;
382 } else {
383 nb_cbk_search = PE_NB_CBKS_STAGE2;
384 }
385 } else {
386 cbk_size = PE_NB_CBKS_STAGE2_10MS;
387 Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
388 nb_cbk_search = PE_NB_CBKS_STAGE2_10MS;
389 }
390
391 for( k = 0; k < length_d_srch; k++ ) {
392 d = d_srch[ k ];
393 for( j = 0; j < nb_cbk_search; j++ ) {
394 CC[ j ] = 0;
395 for( i = 0; i < nb_subfr; i++ ) {
396 opus_int d_subfr;
397 /* Try all codebooks */
398 d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size );
399 CC[ j ] = CC[ j ]
400 + (opus_int32)matrix_ptr( C, i,
401 d_subfr - ( MIN_LAG_8KHZ - 2 ),
402 CSTRIDE_8KHZ );
403 }
404 }
405 /* Find best codebook */
406 CCmax_new = silk_int32_MIN;
407 CBimax_new = 0;
408 for( i = 0; i < nb_cbk_search; i++ ) {
409 if( CC[ i ] > CCmax_new ) {
410 CCmax_new = CC[ i ];
411 CBimax_new = i;
412 }
413 }
414
415 /* Bias towards shorter lags */
416 lag_log2_Q7 = silk_lin2log( d ); /* Q7 */
417 silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) );
418 silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) ) );
419 CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ), lag_log2_Q7 ), 7 ); /* Q13 */
420
421 /* Bias towards previous lag */
422 silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) ) );
423 if( prevLag > 0 ) {
424 delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7;
425 silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) );
426 delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 );
427 prev_lag_bias_Q13 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ), *LTPCorr_Q15 ), 15 ); /* Q13 */
428 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 ) );
429 CCmax_new_b -= prev_lag_bias_Q13; /* Q13 */
430 }
431
432 if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
433 CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 ) && /* Correlation needs to be high enough to be voiced */
434 silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= MIN_LAG_8KHZ /* Lag must be in range */
435 ) {
436 CCmax_b = CCmax_new_b;
437 CCmax = CCmax_new;
438 lag = d;
439 CBimax = CBimax_new;
440 }
441 }
442
443 if( lag == -1 ) {
444 /* No suitable candidate found */
445 silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
446 *LTPCorr_Q15 = 0;
447 *lagIndex = 0;
448 *contourIndex = 0;
449 RESTORE_STACK;
450 return 1;
451 }
452
453 /* Output normalized correlation */
454 *LTPCorr_Q15 = (opus_int)silk_LSHIFT( silk_DIV32_16( CCmax, nb_subfr ), 2 );
455 silk_assert( *LTPCorr_Q15 >= 0 );
456
457 if( Fs_kHz > 8 ) {
458 /* Search in original signal */
459
460 CBimax_old = CBimax;
461 /* Compensate for decimation */
462 silk_assert( lag == silk_SAT16( lag ) );
463 if( Fs_kHz == 12 ) {
464 lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 );
465 } else if( Fs_kHz == 16 ) {
466 lag = silk_LSHIFT( lag, 1 );
467 } else {
468 lag = silk_SMULBB( lag, 3 );
469 }
470
471 lag = silk_LIMIT_int( lag, min_lag, max_lag );
472 start_lag = silk_max_int( lag - 2, min_lag );
473 end_lag = silk_min_int( lag + 2, max_lag );
474 lag_new = lag; /* to avoid undefined lag */
475 CBimax = 0; /* to avoid undefined lag */
476
477 CCmax = silk_int32_MIN;
478 /* pitch lags according to second stage */
479 for( k = 0; k < nb_subfr; k++ ) {
480 pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ];
481 }
482
483 /* Set up codebook parameters according to complexity setting and frame length */
484 if( nb_subfr == PE_MAX_NB_SUBFR ) {
485 nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
486 cbk_size = PE_NB_CBKS_STAGE3_MAX;
487 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
488 } else {
489 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
490 cbk_size = PE_NB_CBKS_STAGE3_10MS;
491 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
492 }
493
494 /* Calculate the correlations and energies needed in stage 3 */
495 ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
496 ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
497 silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
498 silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
499
500 lag_counter = 0;
501 silk_assert( lag == silk_SAT16( lag ) );
502 contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag );
503
504 target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
505 energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length, arch ), 1 );
506 for( d = start_lag; d <= end_lag; d++ ) {
507 for( j = 0; j < nb_cbk_search; j++ ) {
508 cross_corr = 0;
509 energy = energy_target;
510 for( k = 0; k < nb_subfr; k++ ) {
511 cross_corr = silk_ADD32( cross_corr,
512 matrix_ptr( cross_corr_st3, k, j,
513 nb_cbk_search )[ lag_counter ] );
514 energy = silk_ADD32( energy,
515 matrix_ptr( energies_st3, k, j,
516 nb_cbk_search )[ lag_counter ] );
517 silk_assert( energy >= 0 );
518 }
519 if( cross_corr > 0 ) {
520 CCmax_new = silk_DIV32_varQ( cross_corr, energy, 13 + 1 ); /* Q13 */
521 /* Reduce depending on flatness of contour */
522 diff = silk_int16_MAX - silk_MUL( contour_bias_Q15, j ); /* Q15 */
523 silk_assert( diff == silk_SAT16( diff ) );
524 CCmax_new = silk_SMULWB( CCmax_new, diff ); /* Q14 */
525 } else {
526 CCmax_new = 0;
527 }
528
529 if( CCmax_new > CCmax && ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) {
530 CCmax = CCmax_new;
531 lag_new = d;
532 CBimax = j;
533 }
534 }
535 lag_counter++;
536 }
537
538 for( k = 0; k < nb_subfr; k++ ) {
539 pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
540 pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );
541 }
542 *lagIndex = (opus_int16)( lag_new - min_lag);
543 *contourIndex = (opus_int8)CBimax;
544 } else { /* Fs_kHz == 8 */
545 /* Save Lags */
546 for( k = 0; k < nb_subfr; k++ ) {
547 pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
548 pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], MIN_LAG_8KHZ, PE_MAX_LAG_MS * 8 );
549 }
550 *lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ );
551 *contourIndex = (opus_int8)CBimax;
552 }
553 celt_assert( *lagIndex >= 0 );
554 /* return as voiced */
555 RESTORE_STACK;
556 return 0;
557}
558
559/***********************************************************************
560 * Calculates the correlations used in stage 3 search. In order to cover
561 * the whole lag codebook for all the searched offset lags (lag +- 2),
562 * the following correlations are needed in each sub frame:
563 *
564 * sf1: lag range [-8,...,7] total 16 correlations
565 * sf2: lag range [-4,...,4] total 9 correlations
566 * sf3: lag range [-3,....4] total 8 correltions
567 * sf4: lag range [-6,....8] total 15 correlations
568 *
569 * In total 48 correlations. The direct implementation computed in worst
570 * case 4*12*5 = 240 correlations, but more likely around 120.
571 ***********************************************************************/
572static void silk_P_Ana_calc_corr_st3(
573 silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */
574 const opus_int16 frame[], /* I vector to correlate */
575 opus_int start_lag, /* I lag offset to search around */
576 opus_int sf_length, /* I length of a 5 ms subframe */
577 opus_int nb_subfr, /* I number of subframes */
578 opus_int complexity, /* I Complexity setting */
579 int arch /* I Run-time architecture */
580)
581{
582 const opus_int16 *target_ptr;
583 opus_int i, j, k, lag_counter, lag_low, lag_high;
584 opus_int nb_cbk_search, delta, idx, cbk_size;
585 VARDECL( opus_int32, scratch_mem );
586 VARDECL( opus_int32, xcorr32 );
587 const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
588 SAVE_STACK;
589
590 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
591 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
592
593 if( nb_subfr == PE_MAX_NB_SUBFR ) {
594 Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
595 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
596 nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
597 cbk_size = PE_NB_CBKS_STAGE3_MAX;
598 } else {
599 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
600 Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
601 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
602 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
603 cbk_size = PE_NB_CBKS_STAGE3_10MS;
604 }
605 ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );
606 ALLOC( xcorr32, SCRATCH_SIZE, opus_int32 );
607
608 target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
609 for( k = 0; k < nb_subfr; k++ ) {
610 lag_counter = 0;
611
612 /* Calculate the correlations for each subframe */
613 lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 );
614 lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
615 celt_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
616 celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch );
617 for( j = lag_low; j <= lag_high; j++ ) {
618 silk_assert( lag_counter < SCRATCH_SIZE );
619 scratch_mem[ lag_counter ] = xcorr32[ lag_high - j ];
620 lag_counter++;
621 }
622
623 delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
624 for( i = 0; i < nb_cbk_search; i++ ) {
625 /* Fill out the 3 dim array that stores the correlations for */
626 /* each code_book vector for each start lag */
627 idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
628 for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
629 silk_assert( idx + j < SCRATCH_SIZE );
630 silk_assert( idx + j < lag_counter );
631 matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] =
632 scratch_mem[ idx + j ];
633 }
634 }
635 target_ptr += sf_length;
636 }
637 RESTORE_STACK;
638}
639
640/********************************************************************/
641/* Calculate the energies for first two subframes. The energies are */
642/* calculated recursively. */
643/********************************************************************/
644static void silk_P_Ana_calc_energy_st3(
645 silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */
646 const opus_int16 frame[], /* I vector to calc energy in */
647 opus_int start_lag, /* I lag offset to search around */
648 opus_int sf_length, /* I length of one 5 ms subframe */
649 opus_int nb_subfr, /* I number of subframes */
650 opus_int complexity, /* I Complexity setting */
651 int arch /* I Run-time architecture */
652)
653{
654 const opus_int16 *target_ptr, *basis_ptr;
655 opus_int32 energy;
656 opus_int k, i, j, lag_counter;
657 opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff;
658 VARDECL( opus_int32, scratch_mem );
659 const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
660 SAVE_STACK;
661
662 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
663 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
664
665 if( nb_subfr == PE_MAX_NB_SUBFR ) {
666 Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
667 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
668 nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
669 cbk_size = PE_NB_CBKS_STAGE3_MAX;
670 } else {
671 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
672 Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
673 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
674 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
675 cbk_size = PE_NB_CBKS_STAGE3_10MS;
676 }
677 ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );
678
679 target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];
680 for( k = 0; k < nb_subfr; k++ ) {
681 lag_counter = 0;
682
683 /* Calculate the energy for first lag */
684 basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );
685 energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length, arch );
686 silk_assert( energy >= 0 );
687 scratch_mem[ lag_counter ] = energy;
688 lag_counter++;
689
690 lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );
691 for( i = 1; i < lag_diff; i++ ) {
692 /* remove part outside new window */
693 energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] );
694 silk_assert( energy >= 0 );
695
696 /* add part that comes into window */
697 energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) );
698 silk_assert( energy >= 0 );
699 silk_assert( lag_counter < SCRATCH_SIZE );
700 scratch_mem[ lag_counter ] = energy;
701 lag_counter++;
702 }
703
704 delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
705 for( i = 0; i < nb_cbk_search; i++ ) {
706 /* Fill out the 3 dim array that stores the correlations for */
707 /* each code_book vector for each start lag */
708 idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
709 for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
710 silk_assert( idx + j < SCRATCH_SIZE );
711 silk_assert( idx + j < lag_counter );
712 matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] =
713 scratch_mem[ idx + j ];
714 silk_assert(
715 matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 );
716 }
717 }
718 target_ptr += sf_length;
719 }
720 RESTORE_STACK;
721}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c
new file mode 100644
index 0000000000..05aba31788
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c
@@ -0,0 +1,117 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "tuning_parameters.h"
34
35/* Processing of gains */
36void silk_process_gains_FIX(
37 silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
38 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */
39 opus_int condCoding /* I The type of conditional coding to use */
40)
41{
42 silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
43 opus_int k;
44 opus_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10;
45
46 /* Gain reduction when LTP coding gain is high */
47 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
48 /*s = -0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */
49 s_Q16 = -silk_sigm_Q15( silk_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) );
50 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
51 psEncCtrl->Gains_Q16[ k ] = silk_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 );
52 }
53 }
54
55 /* Limit the quantized signal */
56 /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */
57 InvMaxSqrVal_Q16 = silk_DIV32_16( silk_log2lin(
58 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 );
59
60 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
61 /* Soft limit on ratio residual energy and squared gains */
62 ResNrg = psEncCtrl->ResNrg[ k ];
63 ResNrgPart = silk_SMULWW( ResNrg, InvMaxSqrVal_Q16 );
64 if( psEncCtrl->ResNrgQ[ k ] > 0 ) {
65 ResNrgPart = silk_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] );
66 } else {
67 if( ResNrgPart >= silk_RSHIFT( silk_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) {
68 ResNrgPart = silk_int32_MAX;
69 } else {
70 ResNrgPart = silk_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] );
71 }
72 }
73 gain = psEncCtrl->Gains_Q16[ k ];
74 gain_squared = silk_ADD_SAT32( ResNrgPart, silk_SMMUL( gain, gain ) );
75 if( gain_squared < silk_int16_MAX ) {
76 /* recalculate with higher precision */
77 gain_squared = silk_SMLAWW( silk_LSHIFT( ResNrgPart, 16 ), gain, gain );
78 silk_assert( gain_squared > 0 );
79 gain = silk_SQRT_APPROX( gain_squared ); /* Q8 */
80 gain = silk_min( gain, silk_int32_MAX >> 8 );
81 psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 8 ); /* Q16 */
82 } else {
83 gain = silk_SQRT_APPROX( gain_squared ); /* Q0 */
84 gain = silk_min( gain, silk_int32_MAX >> 16 );
85 psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 16 ); /* Q16 */
86 }
87 }
88
89 /* Save unquantized gains and gain Index */
90 silk_memcpy( psEncCtrl->GainsUnq_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
91 psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex;
92
93 /* Quantize gains */
94 silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16,
95 &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
96
97 /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */
98 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
99 if( psEncCtrl->LTPredCodGain_Q7 + silk_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) {
100 psEnc->sCmn.indices.quantOffsetType = 0;
101 } else {
102 psEnc->sCmn.indices.quantOffsetType = 1;
103 }
104 }
105
106 /* Quantizer boundary adjustment */
107 quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ];
108 psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 )
109 + silk_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision )
110 + silk_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->sCmn.speech_activity_Q8 )
111 + silk_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 )
112 + silk_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 )
113 + silk_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 );
114
115 silk_assert( psEncCtrl->Lambda_Q10 > 0 );
116 silk_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) );
117}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c
new file mode 100644
index 0000000000..a2836b05f4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c
@@ -0,0 +1,47 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33
34/* Add noise to matrix diagonal */
35void silk_regularize_correlations_FIX(
36 opus_int32 *XX, /* I/O Correlation matrices */
37 opus_int32 *xx, /* I/O Correlation values */
38 opus_int32 noise, /* I Noise to add */
39 opus_int D /* I Dimension of XX */
40)
41{
42 opus_int i;
43 for( i = 0; i < D; i++ ) {
44 matrix_ptr( &XX[ 0 ], i, i, D ) = silk_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise );
45 }
46 xx[ 0 ] += noise;
47}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c
new file mode 100644
index 0000000000..7f130f3d3d
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c
@@ -0,0 +1,103 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33
34/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
35opus_int32 silk_residual_energy16_covar_FIX(
36 const opus_int16 *c, /* I Prediction vector */
37 const opus_int32 *wXX, /* I Correlation matrix */
38 const opus_int32 *wXx, /* I Correlation vector */
39 opus_int32 wxx, /* I Signal energy */
40 opus_int D, /* I Dimension */
41 opus_int cQ /* I Q value for c vector 0 - 15 */
42)
43{
44 opus_int i, j, lshifts, Qxtra;
45 opus_int32 c_max, w_max, tmp, tmp2, nrg;
46 opus_int cn[ MAX_MATRIX_SIZE ];
47 const opus_int32 *pRow;
48
49 /* Safety checks */
50 celt_assert( D >= 0 );
51 celt_assert( D <= 16 );
52 celt_assert( cQ > 0 );
53 celt_assert( cQ < 16 );
54
55 lshifts = 16 - cQ;
56 Qxtra = lshifts;
57
58 c_max = 0;
59 for( i = 0; i < D; i++ ) {
60 c_max = silk_max_32( c_max, silk_abs( (opus_int32)c[ i ] ) );
61 }
62 Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 );
63
64 w_max = silk_max_32( wXX[ 0 ], wXX[ D * D - 1 ] );
65 Qxtra = silk_min_int( Qxtra, silk_CLZ32( silk_MUL( D, silk_RSHIFT( silk_SMULWB( w_max, c_max ), 4 ) ) ) - 5 );
66 Qxtra = silk_max_int( Qxtra, 0 );
67 for( i = 0; i < D; i++ ) {
68 cn[ i ] = silk_LSHIFT( ( opus_int )c[ i ], Qxtra );
69 silk_assert( silk_abs(cn[i]) <= ( silk_int16_MAX + 1 ) ); /* Check that silk_SMLAWB can be used */
70 }
71 lshifts -= Qxtra;
72
73 /* Compute wxx - 2 * wXx * c */
74 tmp = 0;
75 for( i = 0; i < D; i++ ) {
76 tmp = silk_SMLAWB( tmp, wXx[ i ], cn[ i ] );
77 }
78 nrg = silk_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */
79
80 /* Add c' * wXX * c, assuming wXX is symmetric */
81 tmp2 = 0;
82 for( i = 0; i < D; i++ ) {
83 tmp = 0;
84 pRow = &wXX[ i * D ];
85 for( j = i + 1; j < D; j++ ) {
86 tmp = silk_SMLAWB( tmp, pRow[ j ], cn[ j ] );
87 }
88 tmp = silk_SMLAWB( tmp, silk_RSHIFT( pRow[ i ], 1 ), cn[ i ] );
89 tmp2 = silk_SMLAWB( tmp2, tmp, cn[ i ] );
90 }
91 nrg = silk_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */
92
93 /* Keep one bit free always, because we add them for LSF interpolation */
94 if( nrg < 1 ) {
95 nrg = 1;
96 } else if( nrg > silk_RSHIFT( silk_int32_MAX, lshifts + 2 ) ) {
97 nrg = silk_int32_MAX >> 1;
98 } else {
99 nrg = silk_LSHIFT( nrg, lshifts + 1 ); /* Q0 */
100 }
101 return nrg;
102
103}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c
new file mode 100644
index 0000000000..6c7cade9a0
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c
@@ -0,0 +1,98 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "stack_alloc.h"
34
35/* Calculates residual energies of input subframes where all subframes have LPC_order */
36/* of preceding samples */
37void silk_residual_energy_FIX(
38 opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
39 opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */
40 const opus_int16 x[], /* I Input signal */
41 opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
42 const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */
43 const opus_int subfr_length, /* I Subframe length */
44 const opus_int nb_subfr, /* I Number of subframes */
45 const opus_int LPC_order, /* I LPC order */
46 int arch /* I Run-time architecture */
47)
48{
49 opus_int offset, i, j, rshift, lz1, lz2;
50 opus_int16 *LPC_res_ptr;
51 VARDECL( opus_int16, LPC_res );
52 const opus_int16 *x_ptr;
53 opus_int32 tmp32;
54 SAVE_STACK;
55
56 x_ptr = x;
57 offset = LPC_order + subfr_length;
58
59 /* Filter input to create the LPC residual for each frame half, and measure subframe energies */
60 ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 );
61 celt_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr );
62 for( i = 0; i < nb_subfr >> 1; i++ ) {
63 /* Calculate half frame LPC residual signal including preceding samples */
64 silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order, arch );
65
66 /* Point to first subframe of the just calculated LPC residual signal */
67 LPC_res_ptr = LPC_res + LPC_order;
68 for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) {
69 /* Measure subframe energy */
70 silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length );
71
72 /* Set Q values for the measured energy */
73 nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift;
74
75 /* Move to next subframe */
76 LPC_res_ptr += offset;
77 }
78 /* Move to next frame half */
79 x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset;
80 }
81
82 /* Apply the squared subframe gains */
83 for( i = 0; i < nb_subfr; i++ ) {
84 /* Fully upscale gains and energies */
85 lz1 = silk_CLZ32( nrgs[ i ] ) - 1;
86 lz2 = silk_CLZ32( gains[ i ] ) - 1;
87
88 tmp32 = silk_LSHIFT32( gains[ i ], lz2 );
89
90 /* Find squared gains */
91 tmp32 = silk_SMMUL( tmp32, tmp32 ); /* Q( 2 * lz2 - 32 )*/
92
93 /* Scale energies */
94 nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/
95 nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32;
96 }
97 RESTORE_STACK;
98}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c
new file mode 100644
index 0000000000..4b7e19ea59
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c
@@ -0,0 +1,93 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Slower than schur(), but more accurate. */
35/* Uses SMULL(), available on armv4 */
36opus_int32 silk_schur64( /* O returns residual energy */
37 opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */
38 const opus_int32 c[], /* I Correlations [order+1] */
39 opus_int32 order /* I Prediction order */
40)
41{
42 opus_int k, n;
43 opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
44 opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31;
45
46 celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
47
48 /* Check for invalid input */
49 if( c[ 0 ] <= 0 ) {
50 silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) );
51 return 0;
52 }
53
54 k = 0;
55 do {
56 C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
57 } while( ++k <= order );
58
59 for( k = 0; k < order; k++ ) {
60 /* Check that we won't be getting an unstable rc, otherwise stop here. */
61 if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) {
62 if ( C[ k + 1 ][ 0 ] > 0 ) {
63 rc_Q16[ k ] = -SILK_FIX_CONST( .99f, 16 );
64 } else {
65 rc_Q16[ k ] = SILK_FIX_CONST( .99f, 16 );
66 }
67 k++;
68 break;
69 }
70
71 /* Get reflection coefficient: divide two Q30 values and get result in Q31 */
72 rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 );
73
74 /* Save the output */
75 rc_Q16[ k ] = silk_RSHIFT_ROUND( rc_tmp_Q31, 15 );
76
77 /* Update correlations */
78 for( n = 0; n < order - k; n++ ) {
79 Ctmp1_Q30 = C[ n + k + 1 ][ 0 ];
80 Ctmp2_Q30 = C[ n ][ 1 ];
81
82 /* Multiply and add the highest int32 */
83 C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 );
84 C[ n ][ 1 ] = Ctmp2_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 );
85 }
86 }
87
88 for(; k < order; k++ ) {
89 rc_Q16[ k ] = 0;
90 }
91
92 return silk_max_32( 1, C[ 0 ][ 1 ] );
93}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c
new file mode 100644
index 0000000000..2840f6b1aa
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c
@@ -0,0 +1,107 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Faster than schur64(), but much less accurate. */
35/* uses SMLAWB(), requiring armv5E and higher. */
36opus_int32 silk_schur( /* O Returns residual energy */
37 opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */
38 const opus_int32 *c, /* I correlations [order+1] */
39 const opus_int32 order /* I prediction order */
40)
41{
42 opus_int k, n, lz;
43 opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
44 opus_int32 Ctmp1, Ctmp2, rc_tmp_Q15;
45
46 celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
47
48 /* Get number of leading zeros */
49 lz = silk_CLZ32( c[ 0 ] );
50
51 /* Copy correlations and adjust level to Q30 */
52 k = 0;
53 if( lz < 2 ) {
54 /* lz must be 1, so shift one to the right */
55 do {
56 C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 );
57 } while( ++k <= order );
58 } else if( lz > 2 ) {
59 /* Shift to the left */
60 lz -= 2;
61 do {
62 C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz );
63 } while( ++k <= order );
64 } else {
65 /* No need to shift */
66 do {
67 C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
68 } while( ++k <= order );
69 }
70
71 for( k = 0; k < order; k++ ) {
72 /* Check that we won't be getting an unstable rc, otherwise stop here. */
73 if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) {
74 if ( C[ k + 1 ][ 0 ] > 0 ) {
75 rc_Q15[ k ] = -SILK_FIX_CONST( .99f, 15 );
76 } else {
77 rc_Q15[ k ] = SILK_FIX_CONST( .99f, 15 );
78 }
79 k++;
80 break;
81 }
82
83 /* Get reflection coefficient */
84 rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) );
85
86 /* Clip (shouldn't happen for properly conditioned inputs) */
87 rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 );
88
89 /* Store */
90 rc_Q15[ k ] = (opus_int16)rc_tmp_Q15;
91
92 /* Update correlations */
93 for( n = 0; n < order - k; n++ ) {
94 Ctmp1 = C[ n + k + 1 ][ 0 ];
95 Ctmp2 = C[ n ][ 1 ];
96 C[ n + k + 1 ][ 0 ] = silk_SMLAWB( Ctmp1, silk_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 );
97 C[ n ][ 1 ] = silk_SMLAWB( Ctmp2, silk_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 );
98 }
99 }
100
101 for(; k < order; k++ ) {
102 rc_Q15[ k ] = 0;
103 }
104
105 /* return residual energy */
106 return silk_max_32( 1, C[ 0 ][ 1 ] );
107}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h b/lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h
new file mode 100644
index 0000000000..2774a97b24
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h
@@ -0,0 +1,116 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_STRUCTS_FIX_H
29#define SILK_STRUCTS_FIX_H
30
31#include "typedef.h"
32#include "main.h"
33#include "structs.h"
34
35#ifdef __cplusplus
36extern "C"
37{
38#endif
39
40/********************************/
41/* Noise shaping analysis state */
42/********************************/
43typedef struct {
44 opus_int8 LastGainIndex;
45 opus_int32 HarmBoost_smth_Q16;
46 opus_int32 HarmShapeGain_smth_Q16;
47 opus_int32 Tilt_smth_Q16;
48} silk_shape_state_FIX;
49
50/********************************/
51/* Encoder state FIX */
52/********************************/
53typedef struct {
54 silk_encoder_state sCmn; /* Common struct, shared with floating-point code */
55 silk_shape_state_FIX sShape; /* Shape state */
56
57 /* Buffer for find pitch and noise shape analysis */
58 silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
59 opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */
60 opus_int32 resNrgSmth;
61} silk_encoder_state_FIX;
62
63/************************/
64/* Encoder control FIX */
65/************************/
66typedef struct {
67 /* Prediction and coding parameters */
68 opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
69 silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
70 opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
71 opus_int LTP_scale_Q14;
72 opus_int pitchL[ MAX_NB_SUBFR ];
73
74 /* Noise shaping parameters */
75 /* Testing */
76 silk_DWORD_ALIGN opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
77 opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */
78 opus_int Tilt_Q14[ MAX_NB_SUBFR ];
79 opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ];
80 opus_int Lambda_Q10;
81 opus_int input_quality_Q14;
82 opus_int coding_quality_Q14;
83
84 /* measures */
85 opus_int32 predGain_Q16;
86 opus_int LTPredCodGain_Q7;
87 opus_int32 ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */
88 opus_int ResNrgQ[ MAX_NB_SUBFR ]; /* Q domain for the residual energy > 0 */
89
90 /* Parameters for CBR mode */
91 opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ];
92 opus_int8 lastGainIndexPrev;
93} silk_encoder_control_FIX;
94
95/************************/
96/* Encoder Super Struct */
97/************************/
98typedef struct {
99 silk_encoder_state_FIX state_Fxx[ ENCODER_NUM_CHANNELS ];
100 stereo_enc_state sStereo;
101 opus_int32 nBitsUsedLBRR;
102 opus_int32 nBitsExceeded;
103 opus_int nChannelsAPI;
104 opus_int nChannelsInternal;
105 opus_int nPrevChannelsInternal;
106 opus_int timeSinceSwitchAllowed_ms;
107 opus_int allowBandwidthSwitch;
108 opus_int prev_decode_only_middle;
109} silk_encoder;
110
111
112#ifdef __cplusplus
113}
114#endif
115
116#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c
new file mode 100644
index 0000000000..d94980014f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c
@@ -0,0 +1,102 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33#include "pitch.h"
34
35/* Copy and multiply a vector by a constant */
36void silk_scale_copy_vector16(
37 opus_int16 *data_out,
38 const opus_int16 *data_in,
39 opus_int32 gain_Q16, /* I Gain in Q16 */
40 const opus_int dataSize /* I Length */
41)
42{
43 opus_int i;
44 opus_int32 tmp32;
45
46 for( i = 0; i < dataSize; i++ ) {
47 tmp32 = silk_SMULWB( gain_Q16, data_in[ i ] );
48 data_out[ i ] = (opus_int16)silk_CHECK_FIT16( tmp32 );
49 }
50}
51
52/* Multiply a vector by a constant */
53void silk_scale_vector32_Q26_lshift_18(
54 opus_int32 *data1, /* I/O Q0/Q18 */
55 opus_int32 gain_Q26, /* I Q26 */
56 opus_int dataSize /* I length */
57)
58{
59 opus_int i;
60
61 for( i = 0; i < dataSize; i++ ) {
62 data1[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_SMULL( data1[ i ], gain_Q26 ), 8 ) ); /* OUTPUT: Q18 */
63 }
64}
65
66/* sum = for(i=0;i<len;i++)inVec1[i]*inVec2[i]; --- inner product */
67/* Note for ARM asm: */
68/* * inVec1 and inVec2 should be at least 2 byte aligned. */
69/* * len should be positive 16bit integer. */
70/* * only when len>6, memory access can be reduced by half. */
71opus_int32 silk_inner_prod_aligned(
72 const opus_int16 *const inVec1, /* I input vector 1 */
73 const opus_int16 *const inVec2, /* I input vector 2 */
74 const opus_int len, /* I vector lengths */
75 int arch /* I Run-time architecture */
76)
77{
78#ifdef FIXED_POINT
79 return celt_inner_prod(inVec1, inVec2, len, arch);
80#else
81 opus_int i;
82 opus_int32 sum = 0;
83 for( i = 0; i < len; i++ ) {
84 sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
85 }
86 return sum;
87#endif
88}
89
90opus_int64 silk_inner_prod16_aligned_64_c(
91 const opus_int16 *inVec1, /* I input vector 1 */
92 const opus_int16 *inVec2, /* I input vector 2 */
93 const opus_int len /* I vector lengths */
94)
95{
96 opus_int i;
97 opus_int64 sum = 0;
98 for( i = 0; i < len; i++ ) {
99 sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] );
100 }
101 return sum;
102}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c
new file mode 100644
index 0000000000..52002a1118
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c
@@ -0,0 +1,90 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33
34#if defined(MIPSr1_ASM)
35#include "mips/warped_autocorrelation_FIX_mipsr1.h"
36#endif
37
38
39/* Autocorrelations for a warped frequency axis */
40void silk_warped_autocorrelation_FIX_c(
41 opus_int32 *corr, /* O Result [order + 1] */
42 opus_int *scale, /* O Scaling of the correlation vector */
43 const opus_int16 *input, /* I Input data to correlate */
44 const opus_int warping_Q16, /* I Warping coefficient */
45 const opus_int length, /* I Length of input */
46 const opus_int order /* I Correlation order (even) */
47)
48{
49 opus_int n, i, lsh;
50 opus_int32 tmp1_QS, tmp2_QS;
51 opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
52 opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
53
54 /* Order must be even */
55 celt_assert( ( order & 1 ) == 0 );
56 silk_assert( 2 * QS - QC >= 0 );
57
58 /* Loop over samples */
59 for( n = 0; n < length; n++ ) {
60 tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
61 /* Loop over allpass sections */
62 for( i = 0; i < order; i += 2 ) {
63 /* Output of allpass section */
64 tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
65 state_QS[ i ] = tmp1_QS;
66 corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
67 /* Output of allpass section */
68 tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
69 state_QS[ i + 1 ] = tmp2_QS;
70 corr_QC[ i + 1 ] += silk_RSHIFT64( silk_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC );
71 }
72 state_QS[ order ] = tmp1_QS;
73 corr_QC[ order ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
74 }
75
76 lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35;
77 lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
78 *scale = -( QC + lsh );
79 silk_assert( *scale >= -30 && *scale <= 12 );
80 if( lsh >= 0 ) {
81 for( i = 0; i < order + 1; i++ ) {
82 corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) );
83 }
84 } else {
85 for( i = 0; i < order + 1; i++ ) {
86 corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) );
87 }
88 }
89 silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
90}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c
new file mode 100644
index 0000000000..bbb1ce0fcc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c
@@ -0,0 +1,377 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35
36#include "SigProc_FIX.h"
37#include "define.h"
38#include "tuning_parameters.h"
39#include "pitch.h"
40#include "celt/x86/x86cpu.h"
41
42#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
43
44#define QA 25
45#define N_BITS_HEAD_ROOM 2
46#define MIN_RSHIFTS -16
47#define MAX_RSHIFTS (32 - QA)
48
49/* Compute reflection coefficients from input signal */
50void silk_burg_modified_sse4_1(
51 opus_int32 *res_nrg, /* O Residual energy */
52 opus_int *res_nrg_Q, /* O Residual energy Q value */
53 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
54 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
55 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
56 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
57 const opus_int nb_subfr, /* I Number of subframes stacked in x */
58 const opus_int D, /* I Order */
59 int arch /* I Run-time architecture */
60)
61{
62 opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain;
63 opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
64 const opus_int16 *x_ptr;
65 opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
66 opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
67 opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
68 opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
69 opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
70 opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
71
72 __m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210;
73 __m128i CONST1 = _mm_set1_epi32(1);
74
75 celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
76
77 /* Compute autocorrelations, added over subframes */
78 silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
79 if( rshifts > MAX_RSHIFTS ) {
80 C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS );
81 silk_assert( C0 > 0 );
82 rshifts = MAX_RSHIFTS;
83 } else {
84 lz = silk_CLZ32( C0 ) - 1;
85 rshifts_extra = N_BITS_HEAD_ROOM - lz;
86 if( rshifts_extra > 0 ) {
87 rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts );
88 C0 = silk_RSHIFT32( C0, rshifts_extra );
89 } else {
90 rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts );
91 C0 = silk_LSHIFT32( C0, -rshifts_extra );
92 }
93 rshifts += rshifts_extra;
94 }
95 CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
96 silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
97 if( rshifts > 0 ) {
98 for( s = 0; s < nb_subfr; s++ ) {
99 x_ptr = x + s * subfr_length;
100 for( n = 1; n < D + 1; n++ ) {
101 C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(
102 silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );
103 }
104 }
105 } else {
106 for( s = 0; s < nb_subfr; s++ ) {
107 int i;
108 opus_int32 d;
109 x_ptr = x + s * subfr_length;
110 celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch );
111 for( n = 1; n < D + 1; n++ ) {
112 for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ )
113 d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] );
114 xcorr[ n - 1 ] += d;
115 }
116 for( n = 1; n < D + 1; n++ ) {
117 C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts );
118 }
119 }
120 }
121 silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
122
123 /* Initialize */
124 CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
125
126 invGain_Q30 = (opus_int32)1 << 30;
127 reached_max_gain = 0;
128 for( n = 0; n < D; n++ ) {
129 /* Update first row of correlation matrix (without first element) */
130 /* Update last row of correlation matrix (without last element, stored in reversed order) */
131 /* Update C * Af */
132 /* Update C * flipud(Af) (stored in reversed order) */
133 if( rshifts > -2 ) {
134 for( s = 0; s < nb_subfr; s++ ) {
135 x_ptr = x + s * subfr_length;
136 x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */
137 x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */
138 tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */
139 tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */
140 for( k = 0; k < n; k++ ) {
141 C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
142 C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
143 Atmp_QA = Af_QA[ k ];
144 tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */
145 tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */
146 }
147 tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */
148 tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */
149 for( k = 0; k <= n; k++ ) {
150 CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */
151 CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */
152 }
153 }
154 } else {
155 for( s = 0; s < nb_subfr; s++ ) {
156 x_ptr = x + s * subfr_length;
157 x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */
158 x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */
159 tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */
160 tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */
161
162 X1_3210 = _mm_set1_epi32( x1 );
163 X2_3210 = _mm_set1_epi32( x2 );
164 TMP1_3210 = _mm_setzero_si128();
165 TMP2_3210 = _mm_setzero_si128();
166 for( k = 0; k < n - 3; k += 4 ) {
167 PTR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 1 - 3 ] );
168 SUBFR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k ] );
169 FIRST_3210 = _mm_loadu_si128( (__m128i *)&C_first_row[ k ] );
170 PTR_3210 = _mm_shuffle_epi32( PTR_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) );
171 LAST_3210 = _mm_loadu_si128( (__m128i *)&C_last_row[ k ] );
172 ATMP_3210 = _mm_loadu_si128( (__m128i *)&Af_QA[ k ] );
173
174 T1_3210 = _mm_mullo_epi32( PTR_3210, X1_3210 );
175 T2_3210 = _mm_mullo_epi32( SUBFR_3210, X2_3210 );
176
177 ATMP_3210 = _mm_srai_epi32( ATMP_3210, 7 );
178 ATMP_3210 = _mm_add_epi32( ATMP_3210, CONST1 );
179 ATMP_3210 = _mm_srai_epi32( ATMP_3210, 1 );
180
181 FIRST_3210 = _mm_add_epi32( FIRST_3210, T1_3210 );
182 LAST_3210 = _mm_add_epi32( LAST_3210, T2_3210 );
183
184 PTR_3210 = _mm_mullo_epi32( ATMP_3210, PTR_3210 );
185 SUBFR_3210 = _mm_mullo_epi32( ATMP_3210, SUBFR_3210 );
186
187 _mm_storeu_si128( (__m128i *)&C_first_row[ k ], FIRST_3210 );
188 _mm_storeu_si128( (__m128i *)&C_last_row[ k ], LAST_3210 );
189
190 TMP1_3210 = _mm_add_epi32( TMP1_3210, PTR_3210 );
191 TMP2_3210 = _mm_add_epi32( TMP2_3210, SUBFR_3210 );
192 }
193
194 TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_unpackhi_epi64(TMP1_3210, TMP1_3210 ) );
195 TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_unpackhi_epi64(TMP2_3210, TMP2_3210 ) );
196 TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_shufflelo_epi16(TMP1_3210, 0x0E ) );
197 TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_shufflelo_epi16(TMP2_3210, 0x0E ) );
198
199 tmp1 += _mm_cvtsi128_si32( TMP1_3210 );
200 tmp2 += _mm_cvtsi128_si32( TMP2_3210 );
201
202 for( ; k < n; k++ ) {
203 C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
204 C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
205 Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */
206 tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
207 tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
208 }
209
210 tmp1 = -tmp1; /* Q17 */
211 tmp2 = -tmp2; /* Q17 */
212
213 {
214 __m128i xmm_tmp1, xmm_tmp2;
215 __m128i xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1;
216 __m128i xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1;
217
218 xmm_tmp1 = _mm_set1_epi32( tmp1 );
219 xmm_tmp2 = _mm_set1_epi32( tmp2 );
220
221 for( k = 0; k <= n - 3; k += 4 ) {
222 xmm_x_ptr_n_k_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 3 ] );
223 xmm_x_ptr_sub_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k - 1 ] );
224
225 xmm_x_ptr_n_k_x2x0 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 1, 2, 3 ) );
226
227 xmm_x_ptr_n_k_x2x0 = _mm_slli_epi32( xmm_x_ptr_n_k_x2x0, -rshifts - 1 );
228 xmm_x_ptr_sub_x2x0 = _mm_slli_epi32( xmm_x_ptr_sub_x2x0, -rshifts - 1 );
229
230 /* equal shift right 4 bytes, xmm_x_ptr_n_k_x3x1 = _mm_srli_si128(xmm_x_ptr_n_k_x2x0, 4)*/
231 xmm_x_ptr_n_k_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
232 xmm_x_ptr_sub_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_sub_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
233
234 xmm_x_ptr_n_k_x2x0 = _mm_mul_epi32( xmm_x_ptr_n_k_x2x0, xmm_tmp1 );
235 xmm_x_ptr_n_k_x3x1 = _mm_mul_epi32( xmm_x_ptr_n_k_x3x1, xmm_tmp1 );
236 xmm_x_ptr_sub_x2x0 = _mm_mul_epi32( xmm_x_ptr_sub_x2x0, xmm_tmp2 );
237 xmm_x_ptr_sub_x3x1 = _mm_mul_epi32( xmm_x_ptr_sub_x3x1, xmm_tmp2 );
238
239 xmm_x_ptr_n_k_x2x0 = _mm_srli_epi64( xmm_x_ptr_n_k_x2x0, 16 );
240 xmm_x_ptr_n_k_x3x1 = _mm_slli_epi64( xmm_x_ptr_n_k_x3x1, 16 );
241 xmm_x_ptr_sub_x2x0 = _mm_srli_epi64( xmm_x_ptr_sub_x2x0, 16 );
242 xmm_x_ptr_sub_x3x1 = _mm_slli_epi64( xmm_x_ptr_sub_x3x1, 16 );
243
244 xmm_x_ptr_n_k_x2x0 = _mm_blend_epi16( xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1, 0xCC );
245 xmm_x_ptr_sub_x2x0 = _mm_blend_epi16( xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1, 0xCC );
246
247 X1_3210 = _mm_loadu_si128( (__m128i *)&CAf[ k ] );
248 PTR_3210 = _mm_loadu_si128( (__m128i *)&CAb[ k ] );
249
250 X1_3210 = _mm_add_epi32( X1_3210, xmm_x_ptr_n_k_x2x0 );
251 PTR_3210 = _mm_add_epi32( PTR_3210, xmm_x_ptr_sub_x2x0 );
252
253 _mm_storeu_si128( (__m128i *)&CAf[ k ], X1_3210 );
254 _mm_storeu_si128( (__m128i *)&CAb[ k ], PTR_3210 );
255 }
256
257 for( ; k <= n; k++ ) {
258 CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,
259 silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */
260 CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,
261 silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */
262 }
263 }
264 }
265 }
266
267 /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
268 tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */
269 tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */
270 num = 0; /* Q( -rshifts ) */
271 nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */
272 for( k = 0; k < n; k++ ) {
273 Atmp_QA = Af_QA[ k ];
274 lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;
275 lz = silk_min( 32 - QA, lz );
276 Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */
277
278 tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
279 tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
280 num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
281 nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
282 Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */
283 }
284 CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */
285 CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */
286 num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */
287 num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */
288
289 /* Calculate the next order reflection (parcor) coefficient */
290 if( silk_abs( num ) < nrg ) {
291 rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );
292 } else {
293 rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;
294 }
295
296 /* Update inverse prediction gain */
297 tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
298 tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );
299 if( tmp1 <= minInvGain_Q30 ) {
300 /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
301 tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
302 rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
303 if( rc_Q31 > 0 ) {
304 /* Newton-Raphson iteration */
305 rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
306 rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
307 if( num < 0 ) {
308 /* Ensure adjusted reflection coefficients has the original sign */
309 rc_Q31 = -rc_Q31;
310 }
311 }
312 invGain_Q30 = minInvGain_Q30;
313 reached_max_gain = 1;
314 } else {
315 invGain_Q30 = tmp1;
316 }
317
318 /* Update the AR coefficients */
319 for( k = 0; k < (n + 1) >> 1; k++ ) {
320 tmp1 = Af_QA[ k ]; /* QA */
321 tmp2 = Af_QA[ n - k - 1 ]; /* QA */
322 Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */
323 Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */
324 }
325 Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */
326
327 if( reached_max_gain ) {
328 /* Reached max prediction gain; set remaining coefficients to zero and exit loop */
329 for( k = n + 1; k < D; k++ ) {
330 Af_QA[ k ] = 0;
331 }
332 break;
333 }
334
335 /* Update C * Af and C * Ab */
336 for( k = 0; k <= n + 1; k++ ) {
337 tmp1 = CAf[ k ]; /* Q( -rshifts ) */
338 tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */
339 CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */
340 CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */
341 }
342 }
343
344 if( reached_max_gain ) {
345 for( k = 0; k < D; k++ ) {
346 /* Scale coefficients */
347 A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
348 }
349 /* Subtract energy of preceding samples from C0 */
350 if( rshifts > 0 ) {
351 for( s = 0; s < nb_subfr; s++ ) {
352 x_ptr = x + s * subfr_length;
353 C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );
354 }
355 } else {
356 for( s = 0; s < nb_subfr; s++ ) {
357 x_ptr = x + s * subfr_length;
358 C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch ), -rshifts );
359 }
360 }
361 /* Approximate residual energy */
362 *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );
363 *res_nrg_Q = -rshifts;
364 } else {
365 /* Return residual energy */
366 nrg = CAf[ 0 ]; /* Q( -rshifts ) */
367 tmp1 = (opus_int32)1 << 16; /* Q16 */
368 for( k = 0; k < D; k++ ) {
369 Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */
370 nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */
371 tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */
372 A_Q16[ k ] = -Atmp1;
373 }
374 *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
375 *res_nrg_Q = -rshifts;
376 }
377}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c b/lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c
new file mode 100644
index 0000000000..555432cd96
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c
@@ -0,0 +1,160 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35#include "main.h"
36#include "celt/x86/x86cpu.h"
37
38void silk_warped_LPC_analysis_filter_FIX_sse4_1(
39 opus_int32 state[], /* I/O State [order + 1] */
40 opus_int32 res_Q2[], /* O Residual signal [length] */
41 const opus_int16 coef_Q13[], /* I Coefficients [order] */
42 const opus_int16 input[], /* I Input signal [length] */
43 const opus_int16 lambda_Q16, /* I Warping factor */
44 const opus_int length, /* I Length of input signal */
45 const opus_int order /* I Filter order (even) */
46)
47{
48 opus_int n, i;
49 opus_int32 acc_Q11, tmp1, tmp2;
50
51 /* Order must be even */
52 celt_assert( ( order & 1 ) == 0 );
53
54 if (order == 10)
55 {
56 if (0 == lambda_Q16)
57 {
58 __m128i coef_Q13_3210, coef_Q13_7654;
59 __m128i coef_Q13_0123, coef_Q13_4567;
60 __m128i state_0123, state_4567;
61 __m128i xmm_product1, xmm_product2;
62 __m128i xmm_tempa, xmm_tempb;
63
64 register opus_int32 sum;
65 register opus_int32 state_8, state_9, state_a;
66 register opus_int64 coef_Q13_8, coef_Q13_9;
67
68 celt_assert( length > 0 );
69
70 coef_Q13_3210 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 0 ] );
71 coef_Q13_7654 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 4 ] );
72
73 coef_Q13_0123 = _mm_shuffle_epi32( coef_Q13_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) );
74 coef_Q13_4567 = _mm_shuffle_epi32( coef_Q13_7654, _MM_SHUFFLE( 0, 1, 2, 3 ) );
75
76 coef_Q13_8 = (opus_int64) coef_Q13[ 8 ];
77 coef_Q13_9 = (opus_int64) coef_Q13[ 9 ];
78
79 state_0123 = _mm_loadu_si128( (__m128i *)(&state[ 0 ] ) );
80 state_4567 = _mm_loadu_si128( (__m128i *)(&state[ 4 ] ) );
81
82 state_0123 = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );
83 state_4567 = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );
84
85 state_8 = state[ 8 ];
86 state_9 = state[ 9 ];
87 state_a = 0;
88
89 for( n = 0; n < length; n++ )
90 {
91 xmm_product1 = _mm_mul_epi32( coef_Q13_0123, state_0123 ); /* 64-bit multiply, only 2 pairs */
92 xmm_product2 = _mm_mul_epi32( coef_Q13_4567, state_4567 );
93
94 xmm_tempa = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );
95 xmm_tempb = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );
96
97 xmm_product1 = _mm_srli_epi64( xmm_product1, 16 ); /* >> 16, zero extending works */
98 xmm_product2 = _mm_srli_epi64( xmm_product2, 16 );
99
100 xmm_tempa = _mm_mul_epi32( coef_Q13_3210, xmm_tempa );
101 xmm_tempb = _mm_mul_epi32( coef_Q13_7654, xmm_tempb );
102
103 xmm_tempa = _mm_srli_epi64( xmm_tempa, 16 );
104 xmm_tempb = _mm_srli_epi64( xmm_tempb, 16 );
105
106 xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_product1 );
107 xmm_tempb = _mm_add_epi32( xmm_tempb, xmm_product2 );
108 xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_tempb );
109
110 sum = (opus_int32)((coef_Q13_8 * state_8) >> 16);
111 sum += (opus_int32)((coef_Q13_9 * state_9) >> 16);
112
113 xmm_tempa = _mm_add_epi32( xmm_tempa, _mm_shuffle_epi32( xmm_tempa, _MM_SHUFFLE( 0, 0, 0, 2 ) ) );
114 sum += _mm_cvtsi128_si32( xmm_tempa);
115 res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( ( 5 + sum ), 9);
116
117 /* move right */
118 state_a = state_9;
119 state_9 = state_8;
120 state_8 = _mm_cvtsi128_si32( state_4567 );
121 state_4567 = _mm_alignr_epi8( state_0123, state_4567, 4 );
122
123 state_0123 = _mm_alignr_epi8( _mm_cvtsi32_si128( silk_LSHIFT( input[ n ], 14 ) ), state_0123, 4 );
124 }
125
126 _mm_storeu_si128( (__m128i *)( &state[ 0 ] ), _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );
127 _mm_storeu_si128( (__m128i *)( &state[ 4 ] ), _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );
128 state[ 8 ] = state_8;
129 state[ 9 ] = state_9;
130 state[ 10 ] = state_a;
131
132 return;
133 }
134 }
135
136 for( n = 0; n < length; n++ ) {
137 /* Output of lowpass section */
138 tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
139 state[ 0 ] = silk_LSHIFT( input[ n ], 14 );
140 /* Output of allpass section */
141 tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
142 state[ 1 ] = tmp2;
143 acc_Q11 = silk_RSHIFT( order, 1 );
144 acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
145 /* Loop over allpass sections */
146 for( i = 2; i < order; i += 2 ) {
147 /* Output of allpass section */
148 tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
149 state[ i ] = tmp1;
150 acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
151 /* Output of allpass section */
152 tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
153 state[ i + 1 ] = tmp2;
154 acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
155 }
156 state[ order ] = tmp1;
157 acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
158 res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
159 }
160}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c
new file mode 100644
index 0000000000..c1e90564d0
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c
@@ -0,0 +1,88 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35#include "main.h"
36
37#include "SigProc_FIX.h"
38#include "pitch.h"
39
40opus_int64 silk_inner_prod16_aligned_64_sse4_1(
41 const opus_int16 *inVec1, /* I input vector 1 */
42 const opus_int16 *inVec2, /* I input vector 2 */
43 const opus_int len /* I vector lengths */
44)
45{
46 opus_int i, dataSize8;
47 opus_int64 sum;
48
49 __m128i xmm_tempa;
50 __m128i inVec1_76543210, acc1;
51 __m128i inVec2_76543210, acc2;
52
53 sum = 0;
54 dataSize8 = len & ~7;
55
56 acc1 = _mm_setzero_si128();
57 acc2 = _mm_setzero_si128();
58
59 for( i = 0; i < dataSize8; i += 8 ) {
60 inVec1_76543210 = _mm_loadu_si128( (__m128i *)(&inVec1[i + 0] ) );
61 inVec2_76543210 = _mm_loadu_si128( (__m128i *)(&inVec2[i + 0] ) );
62
63 /* only when all 4 operands are -32768 (0x8000), this results in wrap around */
64 inVec1_76543210 = _mm_madd_epi16( inVec1_76543210, inVec2_76543210 );
65
66 xmm_tempa = _mm_cvtepi32_epi64( inVec1_76543210 );
67 /* equal shift right 8 bytes */
68 inVec1_76543210 = _mm_shuffle_epi32( inVec1_76543210, _MM_SHUFFLE( 0, 0, 3, 2 ) );
69 inVec1_76543210 = _mm_cvtepi32_epi64( inVec1_76543210 );
70
71 acc1 = _mm_add_epi64( acc1, xmm_tempa );
72 acc2 = _mm_add_epi64( acc2, inVec1_76543210 );
73 }
74
75 acc1 = _mm_add_epi64( acc1, acc2 );
76
77 /* equal shift right 8 bytes */
78 acc2 = _mm_shuffle_epi32( acc1, _MM_SHUFFLE( 0, 0, 3, 2 ) );
79 acc1 = _mm_add_epi64( acc1, acc2 );
80
81 _mm_storel_epi64( (__m128i *)&sum, acc1 );
82
83 for( ; i < len; i++ ) {
84 sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
85 }
86
87 return sum;
88}