summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/silk
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libopus/silk')
-rw-r--r--lib/rbcodec/codecs/libopus/silk/A2NLSF.c267
-rw-r--r--lib/rbcodec/codecs/libopus/silk/API.h6
-rw-r--r--lib/rbcodec/codecs/libopus/silk/CNG.c83
-rw-r--r--lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c77
-rw-r--r--lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c29
-rw-r--r--lib/rbcodec/codecs/libopus/silk/LPC_fit.c81
-rw-r--r--lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c99
-rw-r--r--lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c135
-rw-r--r--lib/rbcodec/codecs/libopus/silk/MacroCount.h10
-rw-r--r--lib/rbcodec/codecs/libopus/silk/MacroDebug.h3
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF2A.c59
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c76
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c4
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_decode.c22
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c215
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_encode.c124
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c2
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NSQ.c437
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NSQ.h101
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c733
-rw-r--r--lib/rbcodec/codecs/libopus/silk/PLC.c28
-rw-r--r--lib/rbcodec/codecs/libopus/silk/PLC.h3
-rw-r--r--lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h80
-rw-r--r--lib/rbcodec/codecs/libopus/silk/VAD.c360
-rw-r--r--lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c131
-rw-r--r--lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c74
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h57
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c280
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h100
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c1124
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c112
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h114
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c123
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_arm.h68
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c156
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h39
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h13
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h9
-rw-r--r--lib/rbcodec/codecs/libopus/silk/biquad_alt.c121
-rw-r--r--lib/rbcodec/codecs/libopus/silk/bwexpander.c2
-rw-r--r--lib/rbcodec/codecs/libopus/silk/check_control_input.c106
-rw-r--r--lib/rbcodec/codecs/libopus/silk/code_signs.c2
-rw-r--r--lib/rbcodec/codecs/libopus/silk/control.h8
-rw-r--r--lib/rbcodec/codecs/libopus/silk/control_SNR.c113
-rw-r--r--lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c132
-rw-r--r--lib/rbcodec/codecs/libopus/silk/control_codec.c423
-rw-r--r--lib/rbcodec/codecs/libopus/silk/debug.c170
-rw-r--r--lib/rbcodec/codecs/libopus/silk/debug.h266
-rw-r--r--lib/rbcodec/codecs/libopus/silk/dec_API.c11
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_core.c13
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_frame.c16
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_indices.c2
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_parameters.c4
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_pitch.c4
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_pulses.c6
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c8
-rw-r--r--lib/rbcodec/codecs/libopus/silk/define.h19
-rw-r--r--lib/rbcodec/codecs/libopus/silk/enc_API.c576
-rw-r--r--lib/rbcodec/codecs/libopus/silk/encode_indices.c181
-rw-r--r--lib/rbcodec/codecs/libopus/silk/encode_pulses.c206
-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
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c249
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c73
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c75
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c52
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h197
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c81
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c52
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c186
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c49
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.c93
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c435
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c59
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c104
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c64
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c132
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c116
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c59
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.c54
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/main_FLP.h286
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c350
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c630
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.c103
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.c48
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.c117
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c57
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c56
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c70
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c83
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h112
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c73
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c207
-rw-r--r--lib/rbcodec/codecs/libopus/silk/gain_quant.c5
-rw-r--r--lib/rbcodec/codecs/libopus/silk/init_decoder.c1
-rw-r--r--lib/rbcodec/codecs/libopus/silk/init_encoder.c64
-rw-r--r--lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.c47
-rw-r--r--lib/rbcodec/codecs/libopus/silk/interpolate.c51
-rw-r--r--lib/rbcodec/codecs/libopus/silk/lin2log.c46
-rw-r--r--lib/rbcodec/codecs/libopus/silk/log2lin.c6
-rw-r--r--lib/rbcodec/codecs/libopus/silk/macros.h29
-rw-r--r--lib/rbcodec/codecs/libopus/silk/main.h108
-rw-r--r--lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h410
-rw-r--r--lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h92
-rw-r--r--lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h60
-rw-r--r--lib/rbcodec/codecs/libopus/silk/process_NLSFs.c107
-rw-r--r--lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c132
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler.c10
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_down2.c74
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_down2_3.c103
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c2
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_rom.c54
-rw-r--r--lib/rbcodec/codecs/libopus/silk/shell_coder.c4
-rw-r--r--lib/rbcodec/codecs/libopus/silk/sigm_Q15.c76
-rw-r--r--lib/rbcodec/codecs/libopus/silk/sort.c18
-rw-r--r--lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c229
-rw-r--r--lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c62
-rw-r--r--lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c79
-rw-r--r--lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c73
-rw-r--r--lib/rbcodec/codecs/libopus/silk/structs.h8
-rw-r--r--lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c51
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables.h14
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_LTP.c8
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c36
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c36
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_other.c14
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c129
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tuning_parameters.h155
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c859
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c719
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h94
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c277
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c142
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/main_sse.h248
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c164
166 files changed, 22320 insertions, 421 deletions
diff --git a/lib/rbcodec/codecs/libopus/silk/A2NLSF.c b/lib/rbcodec/codecs/libopus/silk/A2NLSF.c
new file mode 100644
index 0000000000..b487686ff9
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/A2NLSF.c
@@ -0,0 +1,267 @@
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/* Conversion between prediction filter coefficients and NLSFs */
29/* Requires the order to be an even number */
30/* A piecewise linear approximation maps LSF <-> cos(LSF) */
31/* Therefore the result is not accurate NLSFs, but the two */
32/* functions are accurate inverses of each other */
33
34#ifdef HAVE_CONFIG_H
35#include "config.h"
36#endif
37
38#include "SigProc_FIX.h"
39#include "tables.h"
40
41/* Number of binary divisions, when not in low complexity mode */
42#define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
43#define MAX_ITERATIONS_A2NLSF_FIX 16
44
45/* Helper function for A2NLSF(..) */
46/* Transforms polynomials from cos(n*f) to cos(f)^n */
47static OPUS_INLINE void silk_A2NLSF_trans_poly(
48 opus_int32 *p, /* I/O Polynomial */
49 const opus_int dd /* I Polynomial order (= filter order / 2 ) */
50)
51{
52 opus_int k, n;
53
54 for( k = 2; k <= dd; k++ ) {
55 for( n = dd; n > k; n-- ) {
56 p[ n - 2 ] -= p[ n ];
57 }
58 p[ k - 2 ] -= silk_LSHIFT( p[ k ], 1 );
59 }
60}
61/* Helper function for A2NLSF(..) */
62/* Polynomial evaluation */
63static OPUS_INLINE opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16 */
64 opus_int32 *p, /* I Polynomial, Q16 */
65 const opus_int32 x, /* I Evaluation point, Q12 */
66 const opus_int dd /* I Order */
67)
68{
69 opus_int n;
70 opus_int32 x_Q16, y32;
71
72 y32 = p[ dd ]; /* Q16 */
73 x_Q16 = silk_LSHIFT( x, 4 );
74
75 if ( opus_likely( 8 == dd ) )
76 {
77 y32 = silk_SMLAWW( p[ 7 ], y32, x_Q16 );
78 y32 = silk_SMLAWW( p[ 6 ], y32, x_Q16 );
79 y32 = silk_SMLAWW( p[ 5 ], y32, x_Q16 );
80 y32 = silk_SMLAWW( p[ 4 ], y32, x_Q16 );
81 y32 = silk_SMLAWW( p[ 3 ], y32, x_Q16 );
82 y32 = silk_SMLAWW( p[ 2 ], y32, x_Q16 );
83 y32 = silk_SMLAWW( p[ 1 ], y32, x_Q16 );
84 y32 = silk_SMLAWW( p[ 0 ], y32, x_Q16 );
85 }
86 else
87 {
88 for( n = dd - 1; n >= 0; n-- ) {
89 y32 = silk_SMLAWW( p[ n ], y32, x_Q16 ); /* Q16 */
90 }
91 }
92 return y32;
93}
94
95static OPUS_INLINE void silk_A2NLSF_init(
96 const opus_int32 *a_Q16,
97 opus_int32 *P,
98 opus_int32 *Q,
99 const opus_int dd
100)
101{
102 opus_int k;
103
104 /* Convert filter coefs to even and odd polynomials */
105 P[dd] = silk_LSHIFT( 1, 16 );
106 Q[dd] = silk_LSHIFT( 1, 16 );
107 for( k = 0; k < dd; k++ ) {
108 P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; /* Q16 */
109 Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; /* Q16 */
110 }
111
112 /* Divide out zeros as we have that for even filter orders, */
113 /* z = 1 is always a root in Q, and */
114 /* z = -1 is always a root in P */
115 for( k = dd; k > 0; k-- ) {
116 P[ k - 1 ] -= P[ k ];
117 Q[ k - 1 ] += Q[ k ];
118 }
119
120 /* Transform polynomials from cos(n*f) to cos(f)^n */
121 silk_A2NLSF_trans_poly( P, dd );
122 silk_A2NLSF_trans_poly( Q, dd );
123}
124
125/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
126/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
127void silk_A2NLSF(
128 opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */
129 opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */
130 const opus_int d /* I Filter order (must be even) */
131)
132{
133 opus_int i, k, m, dd, root_ix, ffrac;
134 opus_int32 xlo, xhi, xmid;
135 opus_int32 ylo, yhi, ymid, thr;
136 opus_int32 nom, den;
137 opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ];
138 opus_int32 Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
139 opus_int32 *PQ[ 2 ];
140 opus_int32 *p;
141
142 /* Store pointers to array */
143 PQ[ 0 ] = P;
144 PQ[ 1 ] = Q;
145
146 dd = silk_RSHIFT( d, 1 );
147
148 silk_A2NLSF_init( a_Q16, P, Q, dd );
149
150 /* Find roots, alternating between P and Q */
151 p = P; /* Pointer to polynomial */
152
153 xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/
154 ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
155
156 if( ylo < 0 ) {
157 /* Set the first NLSF to zero and move on to the next */
158 NLSF[ 0 ] = 0;
159 p = Q; /* Pointer to polynomial */
160 ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
161 root_ix = 1; /* Index of current root */
162 } else {
163 root_ix = 0; /* Index of current root */
164 }
165 k = 1; /* Loop counter */
166 i = 0; /* Counter for bandwidth expansions applied */
167 thr = 0;
168 while( 1 ) {
169 /* Evaluate polynomial */
170 xhi = silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */
171 yhi = silk_A2NLSF_eval_poly( p, xhi, dd );
172
173 /* Detect zero crossing */
174 if( ( ylo <= 0 && yhi >= thr ) || ( ylo >= 0 && yhi <= -thr ) ) {
175 if( yhi == 0 ) {
176 /* If the root lies exactly at the end of the current */
177 /* interval, look for the next root in the next interval */
178 thr = 1;
179 } else {
180 thr = 0;
181 }
182 /* Binary division */
183 ffrac = -256;
184 for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) {
185 /* Evaluate polynomial */
186 xmid = silk_RSHIFT_ROUND( xlo + xhi, 1 );
187 ymid = silk_A2NLSF_eval_poly( p, xmid, dd );
188
189 /* Detect zero crossing */
190 if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) {
191 /* Reduce frequency */
192 xhi = xmid;
193 yhi = ymid;
194 } else {
195 /* Increase frequency */
196 xlo = xmid;
197 ylo = ymid;
198 ffrac = silk_ADD_RSHIFT( ffrac, 128, m );
199 }
200 }
201
202 /* Interpolate */
203 if( silk_abs( ylo ) < 65536 ) {
204 /* Avoid dividing by zero */
205 den = ylo - yhi;
206 nom = silk_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + silk_RSHIFT( den, 1 );
207 if( den != 0 ) {
208 ffrac += silk_DIV32( nom, den );
209 }
210 } else {
211 /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */
212 ffrac += silk_DIV32( ylo, silk_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) );
213 }
214 NLSF[ root_ix ] = (opus_int16)silk_min_32( silk_LSHIFT( (opus_int32)k, 8 ) + ffrac, silk_int16_MAX );
215
216 silk_assert( NLSF[ root_ix ] >= 0 );
217
218 root_ix++; /* Next root */
219 if( root_ix >= d ) {
220 /* Found all roots */
221 break;
222 }
223 /* Alternate pointer to polynomial */
224 p = PQ[ root_ix & 1 ];
225
226 /* Evaluate polynomial */
227 xlo = silk_LSFCosTab_FIX_Q12[ k - 1 ]; /* Q12*/
228 ylo = silk_LSHIFT( 1 - ( root_ix & 2 ), 12 );
229 } else {
230 /* Increment loop counter */
231 k++;
232 xlo = xhi;
233 ylo = yhi;
234 thr = 0;
235
236 if( k > LSF_COS_TAB_SZ_FIX ) {
237 i++;
238 if( i > MAX_ITERATIONS_A2NLSF_FIX ) {
239 /* Set NLSFs to white spectrum and exit */
240 NLSF[ 0 ] = (opus_int16)silk_DIV32_16( 1 << 15, d + 1 );
241 for( k = 1; k < d; k++ ) {
242 NLSF[ k ] = (opus_int16)silk_ADD16( NLSF[ k-1 ], NLSF[ 0 ] );
243 }
244 return;
245 }
246
247 /* Error: Apply progressively more bandwidth expansion and run again */
248 silk_bwexpander_32( a_Q16, d, 65536 - silk_LSHIFT( 1, i ) );
249
250 silk_A2NLSF_init( a_Q16, P, Q, dd );
251 p = P; /* Pointer to polynomial */
252 xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/
253 ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
254 if( ylo < 0 ) {
255 /* Set the first NLSF to zero and move on to the next */
256 NLSF[ 0 ] = 0;
257 p = Q; /* Pointer to polynomial */
258 ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
259 root_ix = 1; /* Index of current root */
260 } else {
261 root_ix = 0; /* Index of current root */
262 }
263 k = 1; /* Reset loop counter */
264 }
265 }
266 }
267}
diff --git a/lib/rbcodec/codecs/libopus/silk/API.h b/lib/rbcodec/codecs/libopus/silk/API.h
index f0601bcf6b..4d90ff9aa3 100644
--- a/lib/rbcodec/codecs/libopus/silk/API.h
+++ b/lib/rbcodec/codecs/libopus/silk/API.h
@@ -80,7 +80,8 @@ opus_int silk_Encode( /* O Returns error co
80 opus_int nSamplesIn, /* I Number of samples in input vector */ 80 opus_int nSamplesIn, /* I Number of samples in input vector */
81 ec_enc *psRangeEnc, /* I/O Compressor data structure */ 81 ec_enc *psRangeEnc, /* I/O Compressor data structure */
82 opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ 82 opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
83 const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */ 83 const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */
84 int activity /* I Decision of Opus voice activity detector */
84); 85);
85 86
86/****************************************/ 87/****************************************/
@@ -111,7 +112,8 @@ opus_int silk_Decode( /* O Returns error co
111 opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ 112 opus_int newPacketFlag, /* I Indicates first decoder call for this packet */
112 ec_dec *psRangeDec, /* I/O Compressor data structure */ 113 ec_dec *psRangeDec, /* I/O Compressor data structure */
113 opus_int16 *samplesOut, /* O Decoded output speech vector */ 114 opus_int16 *samplesOut, /* O Decoded output speech vector */
114 opus_int32 *nSamplesOut /* O Number of samples decoded */ 115 opus_int32 *nSamplesOut, /* O Number of samples decoded */
116 int arch /* I Run-time architecture */
115); 117);
116 118
117#if 0 119#if 0
diff --git a/lib/rbcodec/codecs/libopus/silk/CNG.c b/lib/rbcodec/codecs/libopus/silk/CNG.c
index bb30a7ccf2..ef8e38df9f 100644
--- a/lib/rbcodec/codecs/libopus/silk/CNG.c
+++ b/lib/rbcodec/codecs/libopus/silk/CNG.c
@@ -34,9 +34,8 @@ POSSIBILITY OF SUCH DAMAGE.
34 34
35/* Generates excitation for CNG LPC synthesis */ 35/* Generates excitation for CNG LPC synthesis */
36static OPUS_INLINE void silk_CNG_exc( 36static OPUS_INLINE void silk_CNG_exc(
37 opus_int32 exc_Q10[], /* O CNG excitation signal Q10 */ 37 opus_int32 exc_Q14[], /* O CNG excitation signal Q10 */
38 opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */ 38 opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */
39 opus_int32 Gain_Q16, /* I Gain to apply */
40 opus_int length, /* I Length */ 39 opus_int length, /* I Length */
41 opus_int32 *rand_seed /* I/O Seed to random index generator */ 40 opus_int32 *rand_seed /* I/O Seed to random index generator */
42) 41)
@@ -55,7 +54,7 @@ static OPUS_INLINE void silk_CNG_exc(
55 idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask ); 54 idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask );
56 silk_assert( idx >= 0 ); 55 silk_assert( idx >= 0 );
57 silk_assert( idx <= CNG_BUF_MASK_MAX ); 56 silk_assert( idx <= CNG_BUF_MASK_MAX );
58 exc_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) ); 57 exc_Q14[ i ] = exc_buf_Q14[ idx ];
59 } 58 }
60 *rand_seed = seed; 59 *rand_seed = seed;
61} 60}
@@ -85,7 +84,7 @@ void silk_CNG(
85) 84)
86{ 85{
87 opus_int i, subfr; 86 opus_int i, subfr;
88 opus_int32 sum_Q6, max_Gain_Q16, gain_Q16; 87 opus_int32 LPC_pred_Q10, max_Gain_Q16, gain_Q16, gain_Q10;
89 opus_int16 A_Q12[ MAX_LPC_ORDER ]; 88 opus_int16 A_Q12[ MAX_LPC_ORDER ];
90 silk_CNG_struct *psCNG = &psDec->sCNG; 89 silk_CNG_struct *psCNG = &psDec->sCNG;
91 SAVE_STACK; 90 SAVE_STACK;
@@ -124,56 +123,60 @@ void silk_CNG(
124 123
125 /* Add CNG when packet is lost or during DTX */ 124 /* Add CNG when packet is lost or during DTX */
126 if( psDec->lossCnt ) { 125 if( psDec->lossCnt ) {
127 VARDECL( opus_int32, CNG_sig_Q10 ); 126 VARDECL( opus_int32, CNG_sig_Q14 );
128 ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 ); 127 ALLOC( CNG_sig_Q14, length + MAX_LPC_ORDER, opus_int32 );
129 128
130 /* Generate CNG excitation */ 129 /* Generate CNG excitation */
131 gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] ); 130 gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] );
132 if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) { 131 if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) {
133 gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 ); 132 gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 );
134 gain_Q16 = silk_SUB_LSHIFT32(silk_SMULTT( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 ); 133 gain_Q16 = silk_SUB_LSHIFT32(silk_SMULTT( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
135 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 ); 134 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 );
136 } else { 135 } else {
137 gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 ); 136 gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 );
138 gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 ); 137 gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
139 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 ); 138 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );
140 } 139 }
141 silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, gain_Q16, length, &psCNG->rand_seed ); 140 gain_Q10 = silk_RSHIFT( gain_Q16, 6 );
141
142 silk_CNG_exc( CNG_sig_Q14 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, length, &psCNG->rand_seed );
142 143
143 /* Convert CNG NLSF to filter representation */ 144 /* Convert CNG NLSF to filter representation */
144 silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order ); 145 silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order, psDec->arch );
145 146
146 /* Generate CNG signal, by synthesis filtering */ 147 /* Generate CNG signal, by synthesis filtering */
147 silk_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) ); 148 silk_memcpy( CNG_sig_Q14, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
149 celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
148 for( i = 0; i < length; i++ ) { 150 for( i = 0; i < length; i++ ) {
149 silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
150 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 151 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
151 sum_Q6 = silk_RSHIFT( psDec->LPC_order, 1 ); 152 LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
152 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] ); 153 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
153 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] ); 154 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] );
154 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] ); 155 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] );
155 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] ); 156 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] );
156 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] ); 157 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] );
157 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] ); 158 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] );
158 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] ); 159 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] );
159 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] ); 160 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] );
160 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] ); 161 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] );
161 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] ); 162 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );
162 if( psDec->LPC_order == 16 ) { 163 if( psDec->LPC_order == 16 ) {
163 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] ); 164 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] );
164 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] ); 165 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] );
165 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] ); 166 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] );
166 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] ); 167 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] );
167 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] ); 168 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] );
168 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] ); 169 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] );
169 } 170 }
170 171
171 /* Update states */ 172 /* Update states */
172 CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 ); 173 CNG_sig_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( CNG_sig_Q14[ MAX_LPC_ORDER + i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) );
174
175 /* Scale with Gain and add to input signal */
176 frame[ i ] = (opus_int16)silk_ADD_SAT16( frame[ i ], silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( CNG_sig_Q14[ MAX_LPC_ORDER + i ], gain_Q10 ), 8 ) ) );
173 177
174 frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( CNG_sig_Q10[ MAX_LPC_ORDER + i ], 10 ) );
175 } 178 }
176 silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); 179 silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q14[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
177 } else { 180 } else {
178 silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) ); 181 silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) );
179 } 182 }
diff --git a/lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c b/lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c
new file mode 100644
index 0000000000..bbe10f04ce
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c
@@ -0,0 +1,77 @@
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#ifdef FIXED_POINT
32#include "main_FIX.h"
33#else
34#include "main_FLP.h"
35#endif
36#include "tuning_parameters.h"
37
38/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
39void silk_HP_variable_cutoff(
40 silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */
41)
42{
43 opus_int quality_Q15;
44 opus_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7;
45 silk_encoder_state *psEncC1 = &state_Fxx[ 0 ].sCmn;
46
47 /* Adaptive cutoff frequency: estimate low end of pitch frequency range */
48 if( psEncC1->prevSignalType == TYPE_VOICED ) {
49 /* difference, in log domain */
50 pitch_freq_Hz_Q16 = silk_DIV32_16( silk_LSHIFT( silk_MUL( psEncC1->fs_kHz, 1000 ), 16 ), psEncC1->prevLag );
51 pitch_freq_log_Q7 = silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 );
52
53 /* adjustment based on quality */
54 quality_Q15 = psEncC1->input_quality_bands_Q15[ 0 ];
55 pitch_freq_log_Q7 = silk_SMLAWB( pitch_freq_log_Q7, silk_SMULWB( silk_LSHIFT( -quality_Q15, 2 ), quality_Q15 ),
56 pitch_freq_log_Q7 - ( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ) ) );
57
58 /* delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; */
59 delta_freq_Q7 = pitch_freq_log_Q7 - silk_RSHIFT( psEncC1->variable_HP_smth1_Q15, 8 );
60 if( delta_freq_Q7 < 0 ) {
61 /* less smoothing for decreasing pitch frequency, to track something close to the minimum */
62 delta_freq_Q7 = silk_MUL( delta_freq_Q7, 3 );
63 }
64
65 /* limit delta, to reduce impact of outliers in pitch estimation */
66 delta_freq_Q7 = silk_LIMIT_32( delta_freq_Q7, -SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) );
67
68 /* update smoother */
69 psEncC1->variable_HP_smth1_Q15 = silk_SMLAWB( psEncC1->variable_HP_smth1_Q15,
70 silk_SMULBB( psEncC1->speech_activity_Q8, delta_freq_Q7 ), SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) );
71
72 /* limit frequency range */
73 psEncC1->variable_HP_smth1_Q15 = silk_LIMIT_32( psEncC1->variable_HP_smth1_Q15,
74 silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ),
75 silk_LSHIFT( silk_lin2log( VARIABLE_HP_MAX_CUTOFF_HZ ), 8 ) );
76 }
77}
diff --git a/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c b/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c
index 9d1f16cb7d..d34b5eb709 100644
--- a/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c
+++ b/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c
@@ -39,17 +39,24 @@ POSSIBILITY OF SUCH DAMAGE.
39/* first d output samples are set to zero */ 39/* first d output samples are set to zero */
40/*******************************************/ 40/*******************************************/
41 41
42/* OPT: Using celt_fir() for this function should be faster, but it may cause
43 integer overflows in intermediate values (not final results), which the
44 current implementation silences by casting to unsigned. Enabling
45 this should be safe in pretty much all cases, even though it is not technically
46 C89-compliant. */
47#define USE_CELT_FIR 0
48
42void silk_LPC_analysis_filter( 49void silk_LPC_analysis_filter(
43 opus_int16 *out, /* O Output signal */ 50 opus_int16 *out, /* O Output signal */
44 const opus_int16 *in, /* I Input signal */ 51 const opus_int16 *in, /* I Input signal */
45 const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ 52 const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */
46 const opus_int32 len, /* I Signal length */ 53 const opus_int32 len, /* I Signal length */
47 const opus_int32 d /* I Filter order */ 54 const opus_int32 d, /* I Filter order */
55 int arch /* I Run-time architecture */
48) 56)
49{ 57{
50 opus_int j; 58 opus_int j;
51#ifdef FIXED_POINT 59#if defined(FIXED_POINT) && USE_CELT_FIR
52 opus_int16 mem[SILK_MAX_ORDER_LPC];
53 opus_int16 num[SILK_MAX_ORDER_LPC]; 60 opus_int16 num[SILK_MAX_ORDER_LPC];
54#else 61#else
55 int ix; 62 int ix;
@@ -57,23 +64,21 @@ void silk_LPC_analysis_filter(
57 const opus_int16 *in_ptr; 64 const opus_int16 *in_ptr;
58#endif 65#endif
59 66
60 silk_assert( d >= 6 ); 67 celt_assert( d >= 6 );
61 silk_assert( (d & 1) == 0 ); 68 celt_assert( (d & 1) == 0 );
62 silk_assert( d <= len ); 69 celt_assert( d <= len );
63 70
64#ifdef FIXED_POINT 71#if defined(FIXED_POINT) && USE_CELT_FIR
65 silk_assert( d <= SILK_MAX_ORDER_LPC ); 72 celt_assert( d <= SILK_MAX_ORDER_LPC );
66 for ( j = 0; j < d; j++ ) { 73 for ( j = 0; j < d; j++ ) {
67 num[ j ] = -B[ j ]; 74 num[ j ] = -B[ j ];
68 } 75 }
69 for (j=0;j<d;j++) { 76 celt_fir( in + d, num, out + d, len - d, d, arch );
70 mem[ j ] = in[ d - j - 1 ];
71 }
72 celt_fir( in + d, num, out + d, len - d, d, mem );
73 for ( j = 0; j < d; j++ ) { 77 for ( j = 0; j < d; j++ ) {
74 out[ j ] = 0; 78 out[ j ] = 0;
75 } 79 }
76#else 80#else
81 (void)arch;
77 for( ix = d; ix < len; ix++ ) { 82 for( ix = d; ix < len; ix++ ) {
78 in_ptr = &in[ ix - 1 ]; 83 in_ptr = &in[ ix - 1 ];
79 84
diff --git a/lib/rbcodec/codecs/libopus/silk/LPC_fit.c b/lib/rbcodec/codecs/libopus/silk/LPC_fit.c
new file mode 100644
index 0000000000..cdea4f3abc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/LPC_fit.c
@@ -0,0 +1,81 @@
1/***********************************************************************
2Copyright (c) 2013, Koen Vos. 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/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */
35void silk_LPC_fit(
36 opus_int16 *a_QOUT, /* O Output signal */
37 opus_int32 *a_QIN, /* I/O Input signal */
38 const opus_int QOUT, /* I Input Q domain */
39 const opus_int QIN, /* I Input Q domain */
40 const opus_int d /* I Filter order */
41)
42{
43 opus_int i, k, idx = 0;
44 opus_int32 maxabs, absval, chirp_Q16;
45
46 /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */
47 for( i = 0; i < 10; i++ ) {
48 /* Find maximum absolute value and its index */
49 maxabs = 0;
50 for( k = 0; k < d; k++ ) {
51 absval = silk_abs( a_QIN[k] );
52 if( absval > maxabs ) {
53 maxabs = absval;
54 idx = k;
55 }
56 }
57 maxabs = silk_RSHIFT_ROUND( maxabs, QIN - QOUT );
58
59 if( maxabs > silk_int16_MAX ) {
60 /* Reduce magnitude of prediction coefficients */
61 maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */
62 chirp_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ),
63 silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) );
64 silk_bwexpander_32( a_QIN, d, chirp_Q16 );
65 } else {
66 break;
67 }
68 }
69
70 if( i == 10 ) {
71 /* Reached the last iteration, clip the coefficients */
72 for( k = 0; k < d; k++ ) {
73 a_QOUT[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT ) );
74 a_QIN[ k ] = silk_LSHIFT( (opus_int32)a_QOUT[ k ], QIN - QOUT );
75 }
76 } else {
77 for( k = 0; k < d; k++ ) {
78 a_QOUT[ k ] = (opus_int16)silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT );
79 }
80 }
81}
diff --git a/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c b/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c
index dd14d4bca6..a3746a6ef9 100644
--- a/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c
+++ b/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
30#endif 30#endif
31 31
32#include "SigProc_FIX.h" 32#include "SigProc_FIX.h"
33#include "define.h"
33 34
34#define QA 24 35#define QA 24
35#define A_LIMIT SILK_FIX_CONST( 0.99975, QA ) 36#define A_LIMIT SILK_FIX_CONST( 0.99975, QA )
@@ -38,119 +39,103 @@ POSSIBILITY OF SUCH DAMAGE.
38 39
39/* Compute inverse of LPC prediction gain, and */ 40/* Compute inverse of LPC prediction gain, and */
40/* test if LPC coefficients are stable (all poles within unit circle) */ 41/* test if LPC coefficients are stable (all poles within unit circle) */
41static opus_int32 LPC_inverse_pred_gain_QA( /* O Returns inverse prediction gain in energy domain, Q30 */ 42static opus_int32 LPC_inverse_pred_gain_QA_c( /* O Returns inverse prediction gain in energy domain, Q30 */
42 opus_int32 A_QA[ 2 ][ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */ 43 opus_int32 A_QA[ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */
43 const opus_int order /* I Prediction order */ 44 const opus_int order /* I Prediction order */
44) 45)
45{ 46{
46 opus_int k, n, mult2Q; 47 opus_int k, n, mult2Q;
47 opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA; 48 opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2;
48 opus_int32 *Aold_QA, *Anew_QA;
49 49
50 Anew_QA = A_QA[ order & 1 ]; 50 invGain_Q30 = SILK_FIX_CONST( 1, 30 );
51
52 invGain_Q30 = (opus_int32)1 << 30;
53 for( k = order - 1; k > 0; k-- ) { 51 for( k = order - 1; k > 0; k-- ) {
54 /* Check for stability */ 52 /* Check for stability */
55 if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) { 53 if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
56 return 0; 54 return 0;
57 } 55 }
58 56
59 /* Set RC equal to negated AR coef */ 57 /* Set RC equal to negated AR coef */
60 rc_Q31 = -silk_LSHIFT( Anew_QA[ k ], 31 - QA ); 58 rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA );
61 59
62 /* rc_mult1_Q30 range: [ 1 : 2^30 ] */ 60 /* rc_mult1_Q30 range: [ 1 : 2^30 ] */
63 rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); 61 rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
64 silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ 62 silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */
65 silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) ); 63 silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );
66 64
67 /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
68 mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
69 rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
70
71 /* Update inverse gain */ 65 /* Update inverse gain */
72 /* invGain_Q30 range: [ 0 : 2^30 ] */ 66 /* invGain_Q30 range: [ 0 : 2^30 ] */
73 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); 67 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
74 silk_assert( invGain_Q30 >= 0 ); 68 silk_assert( invGain_Q30 >= 0 );
75 silk_assert( invGain_Q30 <= ( 1 << 30 ) ); 69 silk_assert( invGain_Q30 <= ( 1 << 30 ) );
70 if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
71 return 0;
72 }
76 73
77 /* Swap pointers */ 74 /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
78 Aold_QA = Anew_QA; 75 mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
79 Anew_QA = A_QA[ k & 1 ]; 76 rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
80 77
81 /* Update AR coefficient */ 78 /* Update AR coefficient */
82 for( n = 0; n < k; n++ ) { 79 for( n = 0; n < (k + 1) >> 1; n++ ) {
83 tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 ); 80 opus_int64 tmp64;
84 Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q ); 81 tmp1 = A_QA[ n ];
82 tmp2 = A_QA[ k - n - 1 ];
83 tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1,
84 MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q);
85 if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
86 return 0;
87 }
88 A_QA[ n ] = ( opus_int32 )tmp64;
89 tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2,
90 MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q);
91 if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
92 return 0;
93 }
94 A_QA[ k - n - 1 ] = ( opus_int32 )tmp64;
85 } 95 }
86 } 96 }
87 97
88 /* Check for stability */ 98 /* Check for stability */
89 if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) { 99 if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
90 return 0; 100 return 0;
91 } 101 }
92 102
93 /* Set RC equal to negated AR coef */ 103 /* Set RC equal to negated AR coef */
94 rc_Q31 = -silk_LSHIFT( Anew_QA[ 0 ], 31 - QA ); 104 rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA );
95 105
96 /* Range: [ 1 : 2^30 ] */ 106 /* Range: [ 1 : 2^30 ] */
97 rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); 107 rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
98 108
99 /* Update inverse gain */ 109 /* Update inverse gain */
100 /* Range: [ 0 : 2^30 ] */ 110 /* Range: [ 0 : 2^30 ] */
101 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); 111 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
102 silk_assert( invGain_Q30 >= 0 ); 112 silk_assert( invGain_Q30 >= 0 );
103 silk_assert( invGain_Q30 <= 1<<30 ); 113 silk_assert( invGain_Q30 <= ( 1 << 30 ) );
114 if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
115 return 0;
116 }
104 117
105 return invGain_Q30; 118 return invGain_Q30;
106} 119}
107 120
108/* For input in Q12 domain */ 121/* For input in Q12 domain */
109opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ 122opus_int32 silk_LPC_inverse_pred_gain_c( /* O Returns inverse prediction gain in energy domain, Q30 */
110 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ 123 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
111 const opus_int order /* I Prediction order */ 124 const opus_int order /* I Prediction order */
112) 125)
113{ 126{
114 opus_int k; 127 opus_int k;
115 opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ]; 128 opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ];
116 opus_int32 *Anew_QA;
117 opus_int32 DC_resp = 0; 129 opus_int32 DC_resp = 0;
118 130
119 Anew_QA = Atmp_QA[ order & 1 ];
120
121 /* Increase Q domain of the AR coefficients */ 131 /* Increase Q domain of the AR coefficients */
122 for( k = 0; k < order; k++ ) { 132 for( k = 0; k < order; k++ ) {
123 DC_resp += (opus_int32)A_Q12[ k ]; 133 DC_resp += (opus_int32)A_Q12[ k ];
124 Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 ); 134 Atmp_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 );
125 } 135 }
126 /* If the DC is unstable, we don't even need to do the full calculations */ 136 /* If the DC is unstable, we don't even need to do the full calculations */
127 if( DC_resp >= 4096 ) { 137 if( DC_resp >= 4096 ) {
128 return 0; 138 return 0;
129 } 139 }
130 return LPC_inverse_pred_gain_QA( Atmp_QA, order ); 140 return LPC_inverse_pred_gain_QA_c( Atmp_QA, order );
131} 141}
132
133#ifdef FIXED_POINT
134
135#if 0
136/* For input in Q24 domain */
137opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */
138 const opus_int32 *A_Q24, /* I Prediction coefficients [order] */
139 const opus_int order /* I Prediction order */
140)
141{
142 opus_int k;
143 opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
144 opus_int32 *Anew_QA;
145
146 Anew_QA = Atmp_QA[ order & 1 ];
147
148 /* Increase Q domain of the AR coefficients */
149 for( k = 0; k < order; k++ ) {
150 Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA );
151 }
152
153 return LPC_inverse_pred_gain_QA( Atmp_QA, order );
154}
155#endif
156#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c b/lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c
new file mode 100644
index 0000000000..79112ad354
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c
@@ -0,0 +1,135 @@
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 Elliptic/Cauer filters designed with 0.1 dB passband ripple,
34 80 dB minimum stopband attenuation, and
35 [0.95 : 0.15 : 0.35] normalized cut off frequencies.
36*/
37
38#include "main.h"
39
40/* Helper function, interpolates the filter taps */
41static OPUS_INLINE void silk_LP_interpolate_filter_taps(
42 opus_int32 B_Q28[ TRANSITION_NB ],
43 opus_int32 A_Q28[ TRANSITION_NA ],
44 const opus_int ind,
45 const opus_int32 fac_Q16
46)
47{
48 opus_int nb, na;
49
50 if( ind < TRANSITION_INT_NUM - 1 ) {
51 if( fac_Q16 > 0 ) {
52 if( fac_Q16 < 32768 ) { /* fac_Q16 is in range of a 16-bit int */
53 /* Piece-wise linear interpolation of B and A */
54 for( nb = 0; nb < TRANSITION_NB; nb++ ) {
55 B_Q28[ nb ] = silk_SMLAWB(
56 silk_Transition_LP_B_Q28[ ind ][ nb ],
57 silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
58 silk_Transition_LP_B_Q28[ ind ][ nb ],
59 fac_Q16 );
60 }
61 for( na = 0; na < TRANSITION_NA; na++ ) {
62 A_Q28[ na ] = silk_SMLAWB(
63 silk_Transition_LP_A_Q28[ ind ][ na ],
64 silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
65 silk_Transition_LP_A_Q28[ ind ][ na ],
66 fac_Q16 );
67 }
68 } else { /* ( fac_Q16 - ( 1 << 16 ) ) is in range of a 16-bit int */
69 silk_assert( fac_Q16 - ( 1 << 16 ) == silk_SAT16( fac_Q16 - ( 1 << 16 ) ) );
70 /* Piece-wise linear interpolation of B and A */
71 for( nb = 0; nb < TRANSITION_NB; nb++ ) {
72 B_Q28[ nb ] = silk_SMLAWB(
73 silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
74 silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
75 silk_Transition_LP_B_Q28[ ind ][ nb ],
76 fac_Q16 - ( (opus_int32)1 << 16 ) );
77 }
78 for( na = 0; na < TRANSITION_NA; na++ ) {
79 A_Q28[ na ] = silk_SMLAWB(
80 silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
81 silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
82 silk_Transition_LP_A_Q28[ ind ][ na ],
83 fac_Q16 - ( (opus_int32)1 << 16 ) );
84 }
85 }
86 } else {
87 silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( opus_int32 ) );
88 silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( opus_int32 ) );
89 }
90 } else {
91 silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( opus_int32 ) );
92 silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( opus_int32 ) );
93 }
94}
95
96/* Low-pass filter with variable cutoff frequency based on */
97/* piece-wise linear interpolation between elliptic filters */
98/* Start by setting psEncC->mode <> 0; */
99/* Deactivate by setting psEncC->mode = 0; */
100void silk_LP_variable_cutoff(
101 silk_LP_state *psLP, /* I/O LP filter state */
102 opus_int16 *frame, /* I/O Low-pass filtered output signal */
103 const opus_int frame_length /* I Frame length */
104)
105{
106 opus_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0;
107 opus_int ind = 0;
108
109 silk_assert( psLP->transition_frame_no >= 0 && psLP->transition_frame_no <= TRANSITION_FRAMES );
110
111 /* Run filter if needed */
112 if( psLP->mode != 0 ) {
113 /* Calculate index and interpolation factor for interpolation */
114#if( TRANSITION_INT_STEPS == 64 )
115 fac_Q16 = silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 - 6 );
116#else
117 fac_Q16 = silk_DIV32_16( silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 ), TRANSITION_FRAMES );
118#endif
119 ind = silk_RSHIFT( fac_Q16, 16 );
120 fac_Q16 -= silk_LSHIFT( ind, 16 );
121
122 silk_assert( ind >= 0 );
123 silk_assert( ind < TRANSITION_INT_NUM );
124
125 /* Interpolate filter coefficients */
126 silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );
127
128 /* Update transition frame number for next frame */
129 psLP->transition_frame_no = silk_LIMIT( psLP->transition_frame_no + psLP->mode, 0, TRANSITION_FRAMES );
130
131 /* ARMA low-pass filtering */
132 silk_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );
133 silk_biquad_alt_stride1( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length);
134 }
135}
diff --git a/lib/rbcodec/codecs/libopus/silk/MacroCount.h b/lib/rbcodec/codecs/libopus/silk/MacroCount.h
index 834817d058..78100ffede 100644
--- a/lib/rbcodec/codecs/libopus/silk/MacroCount.h
+++ b/lib/rbcodec/codecs/libopus/silk/MacroCount.h
@@ -319,14 +319,6 @@ static OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){
319 return(tmp); 319 return(tmp);
320} 320}
321 321
322#undef silk_ADD_POS_SAT64
323static OPUS_INLINE opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){
324 opus_int64 tmp;
325 ops_count += 1;
326 tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)));
327 return(tmp);
328}
329
330#undef silk_LSHIFT8 322#undef silk_LSHIFT8
331static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){ 323static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){
332 opus_int8 ret; 324 opus_int8 ret;
@@ -699,7 +691,7 @@ return(ret);
699 691
700 692
701#undef silk_LIMIT_32 693#undef silk_LIMIT_32
702static OPUS_INLINE opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2) 694static OPUS_INLINE opus_int32 silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2)
703{ 695{
704 opus_int32 ret; 696 opus_int32 ret;
705 ops_count += 6; 697 ops_count += 6;
diff --git a/lib/rbcodec/codecs/libopus/silk/MacroDebug.h b/lib/rbcodec/codecs/libopus/silk/MacroDebug.h
index 35aedc5c5f..8dd4ce2ee2 100644
--- a/lib/rbcodec/codecs/libopus/silk/MacroDebug.h
+++ b/lib/rbcodec/codecs/libopus/silk/MacroDebug.h
@@ -539,8 +539,7 @@ static OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, cha
539 no checking needed for silk_POS_SAT32 539 no checking needed for silk_POS_SAT32
540 no checking needed for silk_ADD_POS_SAT8 540 no checking needed for silk_ADD_POS_SAT8
541 no checking needed for silk_ADD_POS_SAT16 541 no checking needed for silk_ADD_POS_SAT16
542 no checking needed for silk_ADD_POS_SAT32 542 no checking needed for silk_ADD_POS_SAT32 */
543 no checking needed for silk_ADD_POS_SAT64 */
544 543
545#undef silk_LSHIFT8 544#undef silk_LSHIFT8
546#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__) 545#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__)
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF2A.c b/lib/rbcodec/codecs/libopus/silk/NLSF2A.c
index b1c559ea68..d5b7730638 100644
--- a/lib/rbcodec/codecs/libopus/silk/NLSF2A.c
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF2A.c
@@ -66,7 +66,8 @@ static OPUS_INLINE void silk_NLSF2A_find_poly(
66void silk_NLSF2A( 66void silk_NLSF2A(
67 opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ 67 opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */
68 const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ 68 const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */
69 const opus_int d /* I filter order (should be even) */ 69 const opus_int d, /* I filter order (should be even) */
70 int arch /* I Run-time architecture */
70) 71)
71{ 72{
72 /* This ordering was found to maximize quality. It improves numerical accuracy of 73 /* This ordering was found to maximize quality. It improves numerical accuracy of
@@ -83,15 +84,14 @@ void silk_NLSF2A(
83 opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; 84 opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
84 opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta; 85 opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;
85 opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ]; 86 opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];
86 opus_int32 maxabs, absval, idx=0, sc_Q16;
87 87
88 silk_assert( LSF_COS_TAB_SZ_FIX == 128 ); 88 silk_assert( LSF_COS_TAB_SZ_FIX == 128 );
89 silk_assert( d==10||d==16 ); 89 celt_assert( d==10 || d==16 );
90 90
91 /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */ 91 /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */
92 ordering = d == 16 ? ordering16 : ordering10; 92 ordering = d == 16 ? ordering16 : ordering10;
93 for( k = 0; k < d; k++ ) { 93 for( k = 0; k < d; k++ ) {
94 silk_assert(NLSF[k] >= 0 ); 94 silk_assert( NLSF[k] >= 0 );
95 95
96 /* f_int on a scale 0-127 (rounded down) */ 96 /* f_int on a scale 0-127 (rounded down) */
97 f_int = silk_RSHIFT( NLSF[k], 15 - 7 ); 97 f_int = silk_RSHIFT( NLSF[k], 15 - 7 );
@@ -126,52 +126,15 @@ void silk_NLSF2A(
126 a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */ 126 a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */
127 } 127 }
128 128
129 /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */ 129 /* Convert int32 coefficients to Q12 int16 coefs */
130 for( i = 0; i < 10; i++ ) { 130 silk_LPC_fit( a_Q12, a32_QA1, 12, QA + 1, d );
131 /* Find maximum absolute value and its index */
132 maxabs = 0;
133 for( k = 0; k < d; k++ ) {
134 absval = silk_abs( a32_QA1[k] );
135 if( absval > maxabs ) {
136 maxabs = absval;
137 idx = k;
138 }
139 }
140 maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 ); /* QA+1 -> Q12 */
141
142 if( maxabs > silk_int16_MAX ) {
143 /* Reduce magnitude of prediction coefficients */
144 maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */
145 sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ),
146 silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) );
147 silk_bwexpander_32( a32_QA1, d, sc_Q16 );
148 } else {
149 break;
150 }
151 }
152 131
153 if( i == 10 ) { 132 for( i = 0; silk_LPC_inverse_pred_gain( a_Q12, d, arch ) == 0 && i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
154 /* Reached the last iteration, clip the coefficients */ 133 /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */
134 /* on the unscaled coefficients, convert to Q12 and measure again */
135 silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );
155 for( k = 0; k < d; k++ ) { 136 for( k = 0; k < d; k++ ) {
156 a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */ 137 a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
157 a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 );
158 }
159 } else {
160 for( k = 0; k < d; k++ ) {
161 a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
162 }
163 }
164
165 for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
166 if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
167 /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */
168 /* on the unscaled coefficients, convert to Q12 and measure again */
169 silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );
170 for( k = 0; k < d; k++ ) {
171 a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
172 }
173 } else {
174 break;
175 } 138 }
176 } 139 }
177} 140}
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c
new file mode 100644
index 0000000000..b83182a79c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c
@@ -0,0 +1,76 @@
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.h"
33
34/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */
35void silk_NLSF_VQ(
36 opus_int32 err_Q24[], /* O Quantization errors [K] */
37 const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */
38 const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */
39 const opus_int16 pWght_Q9[], /* I Codebook weights [K*LPC_order] */
40 const opus_int K, /* I Number of codebook vectors */
41 const opus_int LPC_order /* I Number of LPCs */
42)
43{
44 opus_int i, m;
45 opus_int32 diff_Q15, diffw_Q24, sum_error_Q24, pred_Q24;
46 const opus_int16 *w_Q9_ptr;
47 const opus_uint8 *cb_Q8_ptr;
48
49 celt_assert( ( LPC_order & 1 ) == 0 );
50
51 /* Loop over codebook */
52 cb_Q8_ptr = pCB_Q8;
53 w_Q9_ptr = pWght_Q9;
54 for( i = 0; i < K; i++ ) {
55 sum_error_Q24 = 0;
56 pred_Q24 = 0;
57 for( m = LPC_order-2; m >= 0; m -= 2 ) {
58 /* Compute weighted absolute predictive quantization error for index m + 1 */
59 diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m + 1 ], (opus_int32)cb_Q8_ptr[ m + 1 ], 7 ); /* range: [ -32767 : 32767 ]*/
60 diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m + 1 ] );
61 sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) );
62 pred_Q24 = diffw_Q24;
63
64 /* Compute weighted absolute predictive quantization error for index m */
65 diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)cb_Q8_ptr[ m ], 7 ); /* range: [ -32767 : 32767 ]*/
66 diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m ] );
67 sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) );
68 pred_Q24 = diffw_Q24;
69
70 silk_assert( sum_error_Q24 >= 0 );
71 }
72 err_Q24[ i ] = sum_error_Q24;
73 cb_Q8_ptr += LPC_order;
74 w_Q9_ptr += LPC_order;
75 }
76}
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c
index 04894c59ab..9873bcde10 100644
--- a/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c
@@ -48,8 +48,8 @@ void silk_NLSF_VQ_weights_laroia(
48 opus_int k; 48 opus_int k;
49 opus_int32 tmp1_int, tmp2_int; 49 opus_int32 tmp1_int, tmp2_int;
50 50
51 silk_assert( D > 0 ); 51 celt_assert( D > 0 );
52 silk_assert( ( D & 1 ) == 0 ); 52 celt_assert( ( D & 1 ) == 0 );
53 53
54 /* First value */ 54 /* First value */
55 tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 ); 55 tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 );
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c b/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c
index 9f715060b8..eeb0ba8c92 100644
--- a/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c
@@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
32#include "main.h" 32#include "main.h"
33 33
34/* Predictive dequantizer for NLSF residuals */ 34/* Predictive dequantizer for NLSF residuals */
35static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */ 35static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */
36 opus_int16 x_Q10[], /* O Output [ order ] */ 36 opus_int16 x_Q10[], /* O Output [ order ] */
37 const opus_int8 indices[], /* I Quantization indices [ order ] */ 37 const opus_int8 indices[], /* I Quantization indices [ order ] */
38 const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ 38 const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */
@@ -70,15 +70,9 @@ void silk_NLSF_decode(
70 opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; 70 opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
71 opus_int16 ec_ix[ MAX_LPC_ORDER ]; 71 opus_int16 ec_ix[ MAX_LPC_ORDER ];
72 opus_int16 res_Q10[ MAX_LPC_ORDER ]; 72 opus_int16 res_Q10[ MAX_LPC_ORDER ];
73 opus_int16 W_tmp_QW[ MAX_LPC_ORDER ]; 73 opus_int32 NLSF_Q15_tmp;
74 opus_int32 W_tmp_Q9, NLSF_Q15_tmp;
75 const opus_uint8 *pCB_element; 74 const opus_uint8 *pCB_element;
76 75 const opus_int16 *pCB_Wght_Q9;
77 /* Decode first stage */
78 pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
79 for( i = 0; i < psNLSF_CB->order; i++ ) {
80 pNLSF_Q15[ i ] = silk_LSHIFT( (opus_int16)pCB_element[ i ], 7 );
81 }
82 76
83 /* Unpack entropy table indices and predictor for current CB1 index */ 77 /* Unpack entropy table indices and predictor for current CB1 index */
84 silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] ); 78 silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] );
@@ -86,13 +80,11 @@ void silk_NLSF_decode(
86 /* Predictive residual dequantizer */ 80 /* Predictive residual dequantizer */
87 silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order ); 81 silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order );
88 82
89 /* Weights from codebook vector */ 83 /* Apply inverse square-rooted weights to first stage and add to output */
90 silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order ); 84 pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
91 85 pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
92 /* Apply inverse square-rooted weights and add to output */
93 for( i = 0; i < psNLSF_CB->order; i++ ) { 86 for( i = 0; i < psNLSF_CB->order; i++ ) {
94 W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) ); 87 NLSF_Q15_tmp = silk_ADD_LSHIFT32( silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), pCB_Wght_Q9[ i ] ), (opus_int16)pCB_element[ i ], 7 );
95 NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), W_tmp_Q9 ) );
96 pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 ); 88 pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 );
97 } 89 }
98 90
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c b/lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c
new file mode 100644
index 0000000000..44a16acd0b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c
@@ -0,0 +1,215 @@
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.h"
33
34/* Delayed-decision quantizer for NLSF residuals */
35opus_int32 silk_NLSF_del_dec_quant( /* O Returns RD value in Q25 */
36 opus_int8 indices[], /* O Quantization indices [ order ] */
37 const opus_int16 x_Q10[], /* I Input [ order ] */
38 const opus_int16 w_Q5[], /* I Weights [ order ] */
39 const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */
40 const opus_int16 ec_ix[], /* I Indices to entropy coding tables [ order ] */
41 const opus_uint8 ec_rates_Q5[], /* I Rates [] */
42 const opus_int quant_step_size_Q16, /* I Quantization step size */
43 const opus_int16 inv_quant_step_size_Q6, /* I Inverse quantization step size */
44 const opus_int32 mu_Q20, /* I R/D tradeoff */
45 const opus_int16 order /* I Number of input values */
46)
47{
48 opus_int i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10;
49 opus_int pred_Q10, diff_Q10, rate0_Q5, rate1_Q5;
50 opus_int16 out0_Q10, out1_Q10;
51 opus_int32 RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25;
52 opus_int ind_sort[ NLSF_QUANT_DEL_DEC_STATES ];
53 opus_int8 ind[ NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ];
54 opus_int16 prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
55 opus_int32 RD_Q25[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
56 opus_int32 RD_min_Q25[ NLSF_QUANT_DEL_DEC_STATES ];
57 opus_int32 RD_max_Q25[ NLSF_QUANT_DEL_DEC_STATES ];
58 const opus_uint8 *rates_Q5;
59
60 opus_int out0_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
61 opus_int out1_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
62
63 for (i = -NLSF_QUANT_MAX_AMPLITUDE_EXT; i <= NLSF_QUANT_MAX_AMPLITUDE_EXT-1; i++)
64 {
65 out0_Q10 = silk_LSHIFT( i, 10 );
66 out1_Q10 = silk_ADD16( out0_Q10, 1024 );
67 if( i > 0 ) {
68 out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
69 out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
70 } else if( i == 0 ) {
71 out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
72 } else if( i == -1 ) {
73 out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
74 } else {
75 out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
76 out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
77 }
78 out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out0_Q10, quant_step_size_Q16 ), 16 );
79 out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out1_Q10, quant_step_size_Q16 ), 16 );
80 }
81
82 silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 ); /* must be power of two */
83
84 nStates = 1;
85 RD_Q25[ 0 ] = 0;
86 prev_out_Q10[ 0 ] = 0;
87 for( i = order - 1; i >= 0; i-- ) {
88 rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];
89 in_Q10 = x_Q10[ i ];
90 for( j = 0; j < nStates; j++ ) {
91 pred_Q10 = silk_RSHIFT( silk_SMULBB( (opus_int16)pred_coef_Q8[ i ], prev_out_Q10[ j ] ), 8 );
92 res_Q10 = silk_SUB16( in_Q10, pred_Q10 );
93 ind_tmp = silk_RSHIFT( silk_SMULBB( inv_quant_step_size_Q6, res_Q10 ), 16 );
94 ind_tmp = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 );
95 ind[ j ][ i ] = (opus_int8)ind_tmp;
96
97 /* compute outputs for ind_tmp and ind_tmp + 1 */
98 out0_Q10 = out0_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
99 out1_Q10 = out1_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
100
101 out0_Q10 = silk_ADD16( out0_Q10, pred_Q10 );
102 out1_Q10 = silk_ADD16( out1_Q10, pred_Q10 );
103 prev_out_Q10[ j ] = out0_Q10;
104 prev_out_Q10[ j + nStates ] = out1_Q10;
105
106 /* compute RD for ind_tmp and ind_tmp + 1 */
107 if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) {
108 if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) {
109 rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
110 rate1_Q5 = 280;
111 } else {
112 rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp );
113 rate1_Q5 = silk_ADD16( rate0_Q5, 43 );
114 }
115 } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) {
116 if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) {
117 rate0_Q5 = 280;
118 rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
119 } else {
120 rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp );
121 rate1_Q5 = silk_SUB16( rate0_Q5, 43 );
122 }
123 } else {
124 rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
125 rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
126 }
127 RD_tmp_Q25 = RD_Q25[ j ];
128 diff_Q10 = silk_SUB16( in_Q10, out0_Q10 );
129 RD_Q25[ j ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 );
130 diff_Q10 = silk_SUB16( in_Q10, out1_Q10 );
131 RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );
132 }
133
134 if( nStates <= NLSF_QUANT_DEL_DEC_STATES/2 ) {
135 /* double number of states and copy */
136 for( j = 0; j < nStates; j++ ) {
137 ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
138 }
139 nStates = silk_LSHIFT( nStates, 1 );
140 for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
141 ind[ j ][ i ] = ind[ j - nStates ][ i ];
142 }
143 } else {
144 /* sort lower and upper half of RD_Q25, pairwise */
145 for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
146 if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) {
147 RD_max_Q25[ j ] = RD_Q25[ j ];
148 RD_min_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
149 RD_Q25[ j ] = RD_min_Q25[ j ];
150 RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ];
151 /* swap prev_out values */
152 out0_Q10 = prev_out_Q10[ j ];
153 prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ];
154 prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10;
155 ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES;
156 } else {
157 RD_min_Q25[ j ] = RD_Q25[ j ];
158 RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
159 ind_sort[ j ] = j;
160 }
161 }
162 /* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */
163 /* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */
164 while( 1 ) {
165 min_max_Q25 = silk_int32_MAX;
166 max_min_Q25 = 0;
167 ind_min_max = 0;
168 ind_max_min = 0;
169 for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
170 if( min_max_Q25 > RD_max_Q25[ j ] ) {
171 min_max_Q25 = RD_max_Q25[ j ];
172 ind_min_max = j;
173 }
174 if( max_min_Q25 < RD_min_Q25[ j ] ) {
175 max_min_Q25 = RD_min_Q25[ j ];
176 ind_max_min = j;
177 }
178 }
179 if( min_max_Q25 >= max_min_Q25 ) {
180 break;
181 }
182 /* copy ind_min_max to ind_max_min */
183 ind_sort[ ind_max_min ] = ind_sort[ ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES;
184 RD_Q25[ ind_max_min ] = RD_Q25[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
185 prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
186 RD_min_Q25[ ind_max_min ] = 0;
187 RD_max_Q25[ ind_min_max ] = silk_int32_MAX;
188 silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) );
189 }
190 /* increment index if it comes from the upper half */
191 for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
192 ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 );
193 }
194 }
195 }
196
197 /* last sample: find winner, copy indices and return RD value */
198 ind_tmp = 0;
199 min_Q25 = silk_int32_MAX;
200 for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) {
201 if( min_Q25 > RD_Q25[ j ] ) {
202 min_Q25 = RD_Q25[ j ];
203 ind_tmp = j;
204 }
205 }
206 for( j = 0; j < order; j++ ) {
207 indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ];
208 silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT );
209 silk_assert( indices[ j ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
210 }
211 indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 );
212 silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
213 silk_assert( min_Q25 >= 0 );
214 return min_Q25;
215}
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_encode.c b/lib/rbcodec/codecs/libopus/silk/NLSF_encode.c
new file mode 100644
index 0000000000..01ac7db78c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_encode.c
@@ -0,0 +1,124 @@
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.h"
33#include "stack_alloc.h"
34
35/***********************/
36/* NLSF vector encoder */
37/***********************/
38opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */
39 opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */
40 opus_int16 *pNLSF_Q15, /* I/O (Un)quantized NLSF vector [ LPC_ORDER ] */
41 const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
42 const opus_int16 *pW_Q2, /* I NLSF weight vector [ LPC_ORDER ] */
43 const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */
44 const opus_int nSurvivors, /* I Max survivors after first stage */
45 const opus_int signalType /* I Signal type: 0/1/2 */
46)
47{
48 opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7;
49 opus_int32 W_tmp_Q9, ret;
50 VARDECL( opus_int32, err_Q24 );
51 VARDECL( opus_int32, RD_Q25 );
52 VARDECL( opus_int, tempIndices1 );
53 VARDECL( opus_int8, tempIndices2 );
54 opus_int16 res_Q10[ MAX_LPC_ORDER ];
55 opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ];
56 opus_int16 W_adj_Q5[ MAX_LPC_ORDER ];
57 opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
58 opus_int16 ec_ix[ MAX_LPC_ORDER ];
59 const opus_uint8 *pCB_element, *iCDF_ptr;
60 const opus_int16 *pCB_Wght_Q9;
61 SAVE_STACK;
62
63 celt_assert( signalType >= 0 && signalType <= 2 );
64 silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 );
65
66 /* NLSF stabilization */
67 silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
68
69 /* First stage: VQ */
70 ALLOC( err_Q24, psNLSF_CB->nVectors, opus_int32 );
71 silk_NLSF_VQ( err_Q24, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->CB1_Wght_Q9, psNLSF_CB->nVectors, psNLSF_CB->order );
72
73 /* Sort the quantization errors */
74 ALLOC( tempIndices1, nSurvivors, opus_int );
75 silk_insertion_sort_increasing( err_Q24, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
76
77 ALLOC( RD_Q25, nSurvivors, opus_int32 );
78 ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 );
79
80 /* Loop over survivors */
81 for( s = 0; s < nSurvivors; s++ ) {
82 ind1 = tempIndices1[ s ];
83
84 /* Residual after first stage */
85 pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ];
86 pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ ind1 * psNLSF_CB->order ];
87 for( i = 0; i < psNLSF_CB->order; i++ ) {
88 NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 );
89 W_tmp_Q9 = pCB_Wght_Q9[ i ];
90 res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ], W_tmp_Q9 ), 14 );
91 W_adj_Q5[ i ] = silk_DIV32_varQ( (opus_int32)pW_Q2[ i ], silk_SMULBB( W_tmp_Q9, W_tmp_Q9 ), 21 );
92 }
93
94 /* Unpack entropy table indices and predictor for current CB1 index */
95 silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, ind1 );
96
97 /* Trellis quantizer */
98 RD_Q25[ s ] = silk_NLSF_del_dec_quant( &tempIndices2[ s * MAX_LPC_ORDER ], res_Q10, W_adj_Q5, pred_Q8, ec_ix,
99 psNLSF_CB->ec_Rates_Q5, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->invQuantStepSize_Q6, NLSF_mu_Q20, psNLSF_CB->order );
100
101 /* Add rate for first stage */
102 iCDF_ptr = &psNLSF_CB->CB1_iCDF[ ( signalType >> 1 ) * psNLSF_CB->nVectors ];
103 if( ind1 == 0 ) {
104 prob_Q8 = 256 - iCDF_ptr[ ind1 ];
105 } else {
106 prob_Q8 = iCDF_ptr[ ind1 - 1 ] - iCDF_ptr[ ind1 ];
107 }
108 bits_q7 = ( 8 << 7 ) - silk_lin2log( prob_Q8 );
109 RD_Q25[ s ] = silk_SMLABB( RD_Q25[ s ], bits_q7, silk_RSHIFT( NLSF_mu_Q20, 2 ) );
110 }
111
112 /* Find the lowest rate-distortion error */
113 silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 );
114
115 NLSFIndices[ 0 ] = (opus_int8)tempIndices1[ bestIndex ];
116 silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) );
117
118 /* Decode */
119 silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB );
120
121 ret = RD_Q25[ 0 ];
122 RESTORE_STACK;
123 return ret;
124}
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c b/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c
index 1fa1ea379b..8f3426b91e 100644
--- a/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c
@@ -130,7 +130,7 @@ void silk_NLSF_stabilize(
130 130
131 /* Keep delta_min distance between the NLSFs */ 131 /* Keep delta_min distance between the NLSFs */
132 for( i = 1; i < L; i++ ) 132 for( i = 1; i < L; i++ )
133 NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); 133 NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) );
134 134
135 /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ 135 /* Last NLSF should be no higher than 1 - NDeltaMin[L] */
136 NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] ); 136 NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );
diff --git a/lib/rbcodec/codecs/libopus/silk/NSQ.c b/lib/rbcodec/codecs/libopus/silk/NSQ.c
new file mode 100644
index 0000000000..1d64d8e257
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NSQ.c
@@ -0,0 +1,437 @@
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.h"
33#include "stack_alloc.h"
34#include "NSQ.h"
35
36
37static OPUS_INLINE void silk_nsq_scale_states(
38 const silk_encoder_state *psEncC, /* I Encoder State */
39 silk_nsq_state *NSQ, /* I/O NSQ state */
40 const opus_int16 x16[], /* I input */
41 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
42 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
43 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
44 opus_int subfr, /* I subframe number */
45 const opus_int LTP_scale_Q14, /* I */
46 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
47 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
48 const opus_int signal_type /* I Signal type */
49);
50
51#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
52static OPUS_INLINE void silk_noise_shape_quantizer(
53 silk_nsq_state *NSQ, /* I/O NSQ state */
54 opus_int signalType, /* I Signal type */
55 const opus_int32 x_sc_Q10[], /* I */
56 opus_int8 pulses[], /* O */
57 opus_int16 xq[], /* O */
58 opus_int32 sLTP_Q15[], /* I/O LTP state */
59 const opus_int16 a_Q12[], /* I Short term prediction coefs */
60 const opus_int16 b_Q14[], /* I Long term prediction coefs */
61 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
62 opus_int lag, /* I Pitch lag */
63 opus_int32 HarmShapeFIRPacked_Q14, /* I */
64 opus_int Tilt_Q14, /* I Spectral tilt */
65 opus_int32 LF_shp_Q14, /* I */
66 opus_int32 Gain_Q16, /* I */
67 opus_int Lambda_Q10, /* I */
68 opus_int offset_Q10, /* I */
69 opus_int length, /* I Input length */
70 opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
71 opus_int predictLPCOrder, /* I Prediction filter order */
72 int arch /* I Architecture */
73);
74#endif
75
76void silk_NSQ_c
77(
78 const silk_encoder_state *psEncC, /* I Encoder State */
79 silk_nsq_state *NSQ, /* I/O NSQ state */
80 SideInfoIndices *psIndices, /* I/O Quantization Indices */
81 const opus_int16 x16[], /* I Input */
82 opus_int8 pulses[], /* O Quantized pulse signal */
83 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
84 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
85 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
86 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
87 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
88 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
89 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
90 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
91 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
92 const opus_int LTP_scale_Q14 /* I LTP state scaling */
93)
94{
95 opus_int k, lag, start_idx, LSF_interpolation_flag;
96 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
97 opus_int16 *pxq;
98 VARDECL( opus_int32, sLTP_Q15 );
99 VARDECL( opus_int16, sLTP );
100 opus_int32 HarmShapeFIRPacked_Q14;
101 opus_int offset_Q10;
102 VARDECL( opus_int32, x_sc_Q10 );
103 SAVE_STACK;
104
105 NSQ->rand_seed = psIndices->Seed;
106
107 /* Set unvoiced lag to the previous one, overwrite later for voiced */
108 lag = NSQ->lagPrev;
109
110 silk_assert( NSQ->prev_gain_Q16 != 0 );
111
112 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
113
114 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
115 LSF_interpolation_flag = 0;
116 } else {
117 LSF_interpolation_flag = 1;
118 }
119
120 ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
121 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
122 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
123 /* Set up pointers to start of sub frame */
124 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
125 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
126 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
127 for( k = 0; k < psEncC->nb_subfr; k++ ) {
128 A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
129 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
130 AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
131
132 /* Noise shape parameters */
133 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
134 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
135 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
136
137 NSQ->rewhite_flag = 0;
138 if( psIndices->signalType == TYPE_VOICED ) {
139 /* Voiced */
140 lag = pitchL[ k ];
141
142 /* Re-whitening */
143 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
144 /* Rewhiten with new A coefs */
145 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
146 celt_assert( start_idx > 0 );
147
148 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
149 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
150
151 NSQ->rewhite_flag = 1;
152 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
153 }
154 }
155
156 silk_nsq_scale_states( psEncC, NSQ, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
157
158 silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
159 AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
160 offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch );
161
162 x16 += psEncC->subfr_length;
163 pulses += psEncC->subfr_length;
164 pxq += psEncC->subfr_length;
165 }
166
167 /* Update lagPrev for next frame */
168 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
169
170 /* Save quantized speech and noise shaping signals */
171 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
172 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
173 RESTORE_STACK;
174}
175
176/***********************************/
177/* silk_noise_shape_quantizer */
178/***********************************/
179
180#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
181static OPUS_INLINE
182#endif
183void silk_noise_shape_quantizer(
184 silk_nsq_state *NSQ, /* I/O NSQ state */
185 opus_int signalType, /* I Signal type */
186 const opus_int32 x_sc_Q10[], /* I */
187 opus_int8 pulses[], /* O */
188 opus_int16 xq[], /* O */
189 opus_int32 sLTP_Q15[], /* I/O LTP state */
190 const opus_int16 a_Q12[], /* I Short term prediction coefs */
191 const opus_int16 b_Q14[], /* I Long term prediction coefs */
192 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
193 opus_int lag, /* I Pitch lag */
194 opus_int32 HarmShapeFIRPacked_Q14, /* I */
195 opus_int Tilt_Q14, /* I Spectral tilt */
196 opus_int32 LF_shp_Q14, /* I */
197 opus_int32 Gain_Q16, /* I */
198 opus_int Lambda_Q10, /* I */
199 opus_int offset_Q10, /* I */
200 opus_int length, /* I Input length */
201 opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
202 opus_int predictLPCOrder, /* I Prediction filter order */
203 int arch /* I Architecture */
204)
205{
206 opus_int i;
207 opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;
208 opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;
209 opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
210 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
211 opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
212#ifdef silk_short_prediction_create_arch_coef
213 opus_int32 a_Q12_arch[MAX_LPC_ORDER];
214#endif
215
216 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
217 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
218 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
219
220 /* Set up short term AR state */
221 psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
222
223#ifdef silk_short_prediction_create_arch_coef
224 silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
225#endif
226
227 for( i = 0; i < length; i++ ) {
228 /* Generate dither */
229 NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
230
231 /* Short-term prediction */
232 LPC_pred_Q10 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch);
233
234 /* Long-term prediction */
235 if( signalType == TYPE_VOICED ) {
236 /* Unrolled loop */
237 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
238 LTP_pred_Q13 = 2;
239 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
240 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
241 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
242 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
243 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
244 pred_lag_ptr++;
245 } else {
246 LTP_pred_Q13 = 0;
247 }
248
249 /* Noise shape feedback */
250 celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
251 n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(&NSQ->sDiff_shp_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch);
252
253 n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 );
254
255 n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
256 n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 );
257
258 celt_assert( lag > 0 || signalType != TYPE_VOICED );
259
260 /* Combine prediction and noise shaping signals */
261 tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */
262 tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */
263 if( lag > 0 ) {
264 /* Symmetric, packed FIR coefficients */
265 n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
266 n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
267 n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 );
268 shp_lag_ptr++;
269
270 tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */
271 tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */
272 tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */
273 } else {
274 tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */
275 }
276
277 r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */
278
279 /* Flip sign depending on dither */
280 if( NSQ->rand_seed < 0 ) {
281 r_Q10 = -r_Q10;
282 }
283 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
284
285 /* Find two quantization level candidates and measure their rate-distortion */
286 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
287 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
288 if (Lambda_Q10 > 2048) {
289 /* For aggressive RDO, the bias becomes more than one pulse. */
290 int rdo_offset = Lambda_Q10/2 - 512;
291 if (q1_Q10 > rdo_offset) {
292 q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
293 } else if (q1_Q10 < -rdo_offset) {
294 q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
295 } else if (q1_Q10 < 0) {
296 q1_Q0 = -1;
297 } else {
298 q1_Q0 = 0;
299 }
300 }
301 if( q1_Q0 > 0 ) {
302 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
303 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
304 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
305 rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
306 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
307 } else if( q1_Q0 == 0 ) {
308 q1_Q10 = offset_Q10;
309 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
310 rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
311 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
312 } else if( q1_Q0 == -1 ) {
313 q2_Q10 = offset_Q10;
314 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
315 rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
316 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
317 } else { /* Q1_Q0 < -1 */
318 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
319 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
320 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
321 rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
322 rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
323 }
324 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
325 rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 );
326 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
327 rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 );
328
329 if( rd2_Q20 < rd1_Q20 ) {
330 q1_Q10 = q2_Q10;
331 }
332
333 pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );
334
335 /* Excitation */
336 exc_Q14 = silk_LSHIFT( q1_Q10, 4 );
337 if ( NSQ->rand_seed < 0 ) {
338 exc_Q14 = -exc_Q14;
339 }
340
341 /* Add predictions */
342 LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );
343 xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 );
344
345 /* Scale XQ back to normal level before saving */
346 xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) );
347
348 /* Update states */
349 psLPC_Q14++;
350 *psLPC_Q14 = xq_Q14;
351 NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 );
352 sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 );
353 NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;
354
355 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );
356 sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 );
357 NSQ->sLTP_shp_buf_idx++;
358 NSQ->sLTP_buf_idx++;
359
360 /* Make dither dependent on quantized signal */
361 NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] );
362 }
363
364 /* Update LPC synth buffer */
365 silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
366}
367
368static OPUS_INLINE void silk_nsq_scale_states(
369 const silk_encoder_state *psEncC, /* I Encoder State */
370 silk_nsq_state *NSQ, /* I/O NSQ state */
371 const opus_int16 x16[], /* I input */
372 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
373 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
374 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
375 opus_int subfr, /* I subframe number */
376 const opus_int LTP_scale_Q14, /* I */
377 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
378 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
379 const opus_int signal_type /* I Signal type */
380)
381{
382 opus_int i, lag;
383 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
384
385 lag = pitchL[ subfr ];
386 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
387 silk_assert( inv_gain_Q31 != 0 );
388
389 /* Scale input */
390 inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
391 for( i = 0; i < psEncC->subfr_length; i++ ) {
392 x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
393 }
394
395 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
396 if( NSQ->rewhite_flag ) {
397 if( subfr == 0 ) {
398 /* Do LTP downscaling */
399 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
400 }
401 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
402 silk_assert( i < MAX_FRAME_LENGTH );
403 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
404 }
405 }
406
407 /* Adjust for changing gain */
408 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
409 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
410
411 /* Scale long-term shaping state */
412 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
413 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
414 }
415
416 /* Scale long-term prediction state */
417 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
418 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
419 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
420 }
421 }
422
423 NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );
424 NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 );
425
426 /* Scale short-term prediction and shaping states */
427 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
428 NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
429 }
430 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
431 NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
432 }
433
434 /* Save inverse gain */
435 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
436 }
437}
diff --git a/lib/rbcodec/codecs/libopus/silk/NSQ.h b/lib/rbcodec/codecs/libopus/silk/NSQ.h
new file mode 100644
index 0000000000..971832f660
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NSQ.h
@@ -0,0 +1,101 @@
1/***********************************************************************
2Copyright (c) 2014 Vidyo.
3Copyright (c) 2006-2011, Skype Limited. All rights reserved.
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions
6are met:
7- Redistributions of source code must retain the above copyright notice,
8this list of conditions and the following disclaimer.
9- Redistributions in binary form must reproduce the above copyright
10notice, this list of conditions and the following disclaimer in the
11documentation and/or other materials provided with the distribution.
12- Neither the name of Internet Society, IETF or IETF Trust, nor the
13names of specific contributors, may be used to endorse or promote
14products derived from this software without specific prior written
15permission.
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26POSSIBILITY OF SUCH DAMAGE.
27***********************************************************************/
28#ifndef SILK_NSQ_H
29#define SILK_NSQ_H
30
31#include "SigProc_FIX.h"
32
33#undef silk_short_prediction_create_arch_coef
34
35static OPUS_INLINE opus_int32 silk_noise_shape_quantizer_short_prediction_c(const opus_int32 *buf32, const opus_int16 *coef16, opus_int order)
36{
37 opus_int32 out;
38 silk_assert( order == 10 || order == 16 );
39
40 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
41 out = silk_RSHIFT( order, 1 );
42 out = silk_SMLAWB( out, buf32[ 0 ], coef16[ 0 ] );
43 out = silk_SMLAWB( out, buf32[ -1 ], coef16[ 1 ] );
44 out = silk_SMLAWB( out, buf32[ -2 ], coef16[ 2 ] );
45 out = silk_SMLAWB( out, buf32[ -3 ], coef16[ 3 ] );
46 out = silk_SMLAWB( out, buf32[ -4 ], coef16[ 4 ] );
47 out = silk_SMLAWB( out, buf32[ -5 ], coef16[ 5 ] );
48 out = silk_SMLAWB( out, buf32[ -6 ], coef16[ 6 ] );
49 out = silk_SMLAWB( out, buf32[ -7 ], coef16[ 7 ] );
50 out = silk_SMLAWB( out, buf32[ -8 ], coef16[ 8 ] );
51 out = silk_SMLAWB( out, buf32[ -9 ], coef16[ 9 ] );
52
53 if( order == 16 )
54 {
55 out = silk_SMLAWB( out, buf32[ -10 ], coef16[ 10 ] );
56 out = silk_SMLAWB( out, buf32[ -11 ], coef16[ 11 ] );
57 out = silk_SMLAWB( out, buf32[ -12 ], coef16[ 12 ] );
58 out = silk_SMLAWB( out, buf32[ -13 ], coef16[ 13 ] );
59 out = silk_SMLAWB( out, buf32[ -14 ], coef16[ 14 ] );
60 out = silk_SMLAWB( out, buf32[ -15 ], coef16[ 15 ] );
61 }
62 return out;
63}
64
65#define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) ((void)arch,silk_noise_shape_quantizer_short_prediction_c(in, coef, order))
66
67static OPUS_INLINE opus_int32 silk_NSQ_noise_shape_feedback_loop_c(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order)
68{
69 opus_int32 out;
70 opus_int32 tmp1, tmp2;
71 opus_int j;
72
73 tmp2 = data0[0];
74 tmp1 = data1[0];
75 data1[0] = tmp2;
76
77 out = silk_RSHIFT(order, 1);
78 out = silk_SMLAWB(out, tmp2, coef[0]);
79
80 for (j = 2; j < order; j += 2) {
81 tmp2 = data1[j - 1];
82 data1[j - 1] = tmp1;
83 out = silk_SMLAWB(out, tmp1, coef[j - 1]);
84 tmp1 = data1[j + 0];
85 data1[j + 0] = tmp2;
86 out = silk_SMLAWB(out, tmp2, coef[j]);
87 }
88 data1[order - 1] = tmp1;
89 out = silk_SMLAWB(out, tmp1, coef[order - 1]);
90 /* Q11 -> Q12 */
91 out = silk_LSHIFT32( out, 1 );
92 return out;
93}
94
95#define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) ((void)arch,silk_NSQ_noise_shape_feedback_loop_c(data0, data1, coef, order))
96
97#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
98#include "arm/NSQ_neon.h"
99#endif
100
101#endif /* SILK_NSQ_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c b/lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c
new file mode 100644
index 0000000000..3fd9fa0d5b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c
@@ -0,0 +1,733 @@
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.h"
33#include "stack_alloc.h"
34#include "NSQ.h"
35
36
37typedef struct {
38 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
39 opus_int32 RandState[ DECISION_DELAY ];
40 opus_int32 Q_Q10[ DECISION_DELAY ];
41 opus_int32 Xq_Q14[ DECISION_DELAY ];
42 opus_int32 Pred_Q15[ DECISION_DELAY ];
43 opus_int32 Shape_Q14[ DECISION_DELAY ];
44 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
45 opus_int32 LF_AR_Q14;
46 opus_int32 Diff_Q14;
47 opus_int32 Seed;
48 opus_int32 SeedInit;
49 opus_int32 RD_Q10;
50} NSQ_del_dec_struct;
51
52typedef struct {
53 opus_int32 Q_Q10;
54 opus_int32 RD_Q10;
55 opus_int32 xq_Q14;
56 opus_int32 LF_AR_Q14;
57 opus_int32 Diff_Q14;
58 opus_int32 sLTP_shp_Q14;
59 opus_int32 LPC_exc_Q14;
60} NSQ_sample_struct;
61
62typedef NSQ_sample_struct NSQ_sample_pair[ 2 ];
63
64#if defined(MIPSr1_ASM)
65#include "mips/NSQ_del_dec_mipsr1.h"
66#endif
67static OPUS_INLINE void silk_nsq_del_dec_scale_states(
68 const silk_encoder_state *psEncC, /* I Encoder State */
69 silk_nsq_state *NSQ, /* I/O NSQ state */
70 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
71 const opus_int16 x16[], /* I Input */
72 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
73 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
74 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
75 opus_int subfr, /* I Subframe number */
76 opus_int nStatesDelayedDecision, /* I Number of del dec states */
77 const opus_int LTP_scale_Q14, /* I LTP state scaling */
78 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
79 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
80 const opus_int signal_type, /* I Signal type */
81 const opus_int decisionDelay /* I Decision delay */
82);
83
84/******************************************/
85/* Noise shape quantizer for one subframe */
86/******************************************/
87static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
88 silk_nsq_state *NSQ, /* I/O NSQ state */
89 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
90 opus_int signalType, /* I Signal type */
91 const opus_int32 x_Q10[], /* I */
92 opus_int8 pulses[], /* O */
93 opus_int16 xq[], /* O */
94 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
95 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
96 const opus_int16 a_Q12[], /* I Short term prediction coefs */
97 const opus_int16 b_Q14[], /* I Long term prediction coefs */
98 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
99 opus_int lag, /* I Pitch lag */
100 opus_int32 HarmShapeFIRPacked_Q14, /* I */
101 opus_int Tilt_Q14, /* I Spectral tilt */
102 opus_int32 LF_shp_Q14, /* I */
103 opus_int32 Gain_Q16, /* I */
104 opus_int Lambda_Q10, /* I */
105 opus_int offset_Q10, /* I */
106 opus_int length, /* I Input length */
107 opus_int subfr, /* I Subframe number */
108 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
109 opus_int predictLPCOrder, /* I Prediction filter order */
110 opus_int warping_Q16, /* I */
111 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
112 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
113 opus_int decisionDelay, /* I */
114 int arch /* I */
115);
116
117void silk_NSQ_del_dec_c(
118 const silk_encoder_state *psEncC, /* I Encoder State */
119 silk_nsq_state *NSQ, /* I/O NSQ state */
120 SideInfoIndices *psIndices, /* I/O Quantization Indices */
121 const opus_int16 x16[], /* I Input */
122 opus_int8 pulses[], /* O Quantized pulse signal */
123 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
124 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
125 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
126 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
127 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
128 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
129 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
130 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
131 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
132 const opus_int LTP_scale_Q14 /* I LTP state scaling */
133)
134{
135 opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
136 opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
137 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
138 opus_int16 *pxq;
139 VARDECL( opus_int32, sLTP_Q15 );
140 VARDECL( opus_int16, sLTP );
141 opus_int32 HarmShapeFIRPacked_Q14;
142 opus_int offset_Q10;
143 opus_int32 RDmin_Q10, Gain_Q10;
144 VARDECL( opus_int32, x_sc_Q10 );
145 VARDECL( opus_int32, delayedGain_Q10 );
146 VARDECL( NSQ_del_dec_struct, psDelDec );
147 NSQ_del_dec_struct *psDD;
148 SAVE_STACK;
149
150 /* Set unvoiced lag to the previous one, overwrite later for voiced */
151 lag = NSQ->lagPrev;
152
153 silk_assert( NSQ->prev_gain_Q16 != 0 );
154
155 /* Initialize delayed decision states */
156 ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );
157 silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
158 for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
159 psDD = &psDelDec[ k ];
160 psDD->Seed = ( k + psIndices->Seed ) & 3;
161 psDD->SeedInit = psDD->Seed;
162 psDD->RD_Q10 = 0;
163 psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14;
164 psDD->Diff_Q14 = NSQ->sDiff_shp_Q14;
165 psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];
166 silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
167 silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
168 }
169
170 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
171 smpl_buf_idx = 0; /* index of oldest samples */
172
173 decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
174
175 /* For voiced frames limit the decision delay to lower than the pitch lag */
176 if( psIndices->signalType == TYPE_VOICED ) {
177 for( k = 0; k < psEncC->nb_subfr; k++ ) {
178 decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 );
179 }
180 } else {
181 if( lag > 0 ) {
182 decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
183 }
184 }
185
186 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
187 LSF_interpolation_flag = 0;
188 } else {
189 LSF_interpolation_flag = 1;
190 }
191
192 ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
193 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
194 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
195 ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
196 /* Set up pointers to start of sub frame */
197 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
198 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
199 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
200 subfr = 0;
201 for( k = 0; k < psEncC->nb_subfr; k++ ) {
202 A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
203 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
204 AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
205
206 /* Noise shape parameters */
207 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
208 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
209 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
210
211 NSQ->rewhite_flag = 0;
212 if( psIndices->signalType == TYPE_VOICED ) {
213 /* Voiced */
214 lag = pitchL[ k ];
215
216 /* Re-whitening */
217 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
218 if( k == 2 ) {
219 /* RESET DELAYED DECISIONS */
220 /* Find winner */
221 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
222 Winner_ind = 0;
223 for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
224 if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
225 RDmin_Q10 = psDelDec[ i ].RD_Q10;
226 Winner_ind = i;
227 }
228 }
229 for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
230 if( i != Winner_ind ) {
231 psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 );
232 silk_assert( psDelDec[ i ].RD_Q10 >= 0 );
233 }
234 }
235
236 /* Copy final part of signals from winner state to output and long-term filter states */
237 psDD = &psDelDec[ Winner_ind ];
238 last_smple_idx = smpl_buf_idx + decisionDelay;
239 for( i = 0; i < decisionDelay; i++ ) {
240 last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
241 if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
242 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
243 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
244 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
245 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
246 }
247
248 subfr = 0;
249 }
250
251 /* Rewhiten with new A coefs */
252 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
253 celt_assert( start_idx > 0 );
254
255 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
256 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
257
258 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
259 NSQ->rewhite_flag = 1;
260 }
261 }
262
263 silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k,
264 psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
265
266 silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
267 delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
268 Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
269 psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay, psEncC->arch );
270
271 x16 += psEncC->subfr_length;
272 pulses += psEncC->subfr_length;
273 pxq += psEncC->subfr_length;
274 }
275
276 /* Find winner */
277 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
278 Winner_ind = 0;
279 for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
280 if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
281 RDmin_Q10 = psDelDec[ k ].RD_Q10;
282 Winner_ind = k;
283 }
284 }
285
286 /* Copy final part of signals from winner state to output and long-term filter states */
287 psDD = &psDelDec[ Winner_ind ];
288 psIndices->Seed = psDD->SeedInit;
289 last_smple_idx = smpl_buf_idx + decisionDelay;
290 Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
291 for( i = 0; i < decisionDelay; i++ ) {
292 last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
293 if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
294
295 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
296 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
297 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
298 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
299 }
300 silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
301 silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
302
303 /* Update states */
304 NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;
305 NSQ->sDiff_shp_Q14 = psDD->Diff_Q14;
306 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
307
308 /* Save quantized speech signal */
309 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
310 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
311 RESTORE_STACK;
312}
313
314/******************************************/
315/* Noise shape quantizer for one subframe */
316/******************************************/
317#ifndef OVERRIDE_silk_noise_shape_quantizer_del_dec
318static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
319 silk_nsq_state *NSQ, /* I/O NSQ state */
320 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
321 opus_int signalType, /* I Signal type */
322 const opus_int32 x_Q10[], /* I */
323 opus_int8 pulses[], /* O */
324 opus_int16 xq[], /* O */
325 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
326 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
327 const opus_int16 a_Q12[], /* I Short term prediction coefs */
328 const opus_int16 b_Q14[], /* I Long term prediction coefs */
329 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
330 opus_int lag, /* I Pitch lag */
331 opus_int32 HarmShapeFIRPacked_Q14, /* I */
332 opus_int Tilt_Q14, /* I Spectral tilt */
333 opus_int32 LF_shp_Q14, /* I */
334 opus_int32 Gain_Q16, /* I */
335 opus_int Lambda_Q10, /* I */
336 opus_int offset_Q10, /* I */
337 opus_int length, /* I Input length */
338 opus_int subfr, /* I Subframe number */
339 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
340 opus_int predictLPCOrder, /* I Prediction filter order */
341 opus_int warping_Q16, /* I */
342 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
343 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
344 opus_int decisionDelay, /* I */
345 int arch /* I */
346)
347{
348 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
349 opus_int32 Winner_rand_state;
350 opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
351 opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
352 opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
353 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
354 opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
355#ifdef silk_short_prediction_create_arch_coef
356 opus_int32 a_Q12_arch[MAX_LPC_ORDER];
357#endif
358
359 VARDECL( NSQ_sample_pair, psSampleState );
360 NSQ_del_dec_struct *psDD;
361 NSQ_sample_struct *psSS;
362 SAVE_STACK;
363
364 celt_assert( nStatesDelayedDecision > 0 );
365 ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
366
367 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
368 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
369 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
370
371#ifdef silk_short_prediction_create_arch_coef
372 silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
373#endif
374
375 for( i = 0; i < length; i++ ) {
376 /* Perform common calculations used in all states */
377
378 /* Long-term prediction */
379 if( signalType == TYPE_VOICED ) {
380 /* Unrolled loop */
381 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
382 LTP_pred_Q14 = 2;
383 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
384 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
385 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
386 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
387 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
388 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
389 pred_lag_ptr++;
390 } else {
391 LTP_pred_Q14 = 0;
392 }
393
394 /* Long-term shaping */
395 if( lag > 0 ) {
396 /* Symmetric, packed FIR coefficients */
397 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
398 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
399 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
400 shp_lag_ptr++;
401 } else {
402 n_LTP_Q14 = 0;
403 }
404
405 for( k = 0; k < nStatesDelayedDecision; k++ ) {
406 /* Delayed decision state */
407 psDD = &psDelDec[ k ];
408
409 /* Sample state */
410 psSS = psSampleState[ k ];
411
412 /* Generate dither */
413 psDD->Seed = silk_RAND( psDD->Seed );
414
415 /* Pointer used in short term prediction and shaping */
416 psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
417 /* Short-term prediction */
418 LPC_pred_Q14 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch);
419 LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
420
421 /* Noise shape feedback */
422 celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
423 /* Output of lowpass section */
424 tmp2 = silk_SMLAWB( psDD->Diff_Q14, psDD->sAR2_Q14[ 0 ], warping_Q16 );
425 /* Output of allpass section */
426 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
427 psDD->sAR2_Q14[ 0 ] = tmp2;
428 n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 );
429 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] );
430 /* Loop over allpass sections */
431 for( j = 2; j < shapingLPCOrder; j += 2 ) {
432 /* Output of allpass section */
433 tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
434 psDD->sAR2_Q14[ j - 1 ] = tmp1;
435 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] );
436 /* Output of allpass section */
437 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
438 psDD->sAR2_Q14[ j + 0 ] = tmp2;
439 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] );
440 }
441 psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
442 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
443
444 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */
445 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */
446 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */
447
448 n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */
449 n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */
450 n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */
451
452 /* Input minus prediction plus noise feedback */
453 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
454 tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
455 tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
456 tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
457 tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
458
459 r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
460
461 /* Flip sign depending on dither */
462 if ( psDD->Seed < 0 ) {
463 r_Q10 = -r_Q10;
464 }
465 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
466
467 /* Find two quantization level candidates and measure their rate-distortion */
468 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
469 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
470 if (Lambda_Q10 > 2048) {
471 /* For aggressive RDO, the bias becomes more than one pulse. */
472 int rdo_offset = Lambda_Q10/2 - 512;
473 if (q1_Q10 > rdo_offset) {
474 q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
475 } else if (q1_Q10 < -rdo_offset) {
476 q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
477 } else if (q1_Q10 < 0) {
478 q1_Q0 = -1;
479 } else {
480 q1_Q0 = 0;
481 }
482 }
483 if( q1_Q0 > 0 ) {
484 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
485 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
486 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
487 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
488 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
489 } else if( q1_Q0 == 0 ) {
490 q1_Q10 = offset_Q10;
491 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
492 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
493 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
494 } else if( q1_Q0 == -1 ) {
495 q2_Q10 = offset_Q10;
496 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
497 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
498 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
499 } else { /* q1_Q0 < -1 */
500 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
501 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
502 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
503 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
504 rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
505 }
506 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
507 rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
508 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
509 rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
510
511 if( rd1_Q10 < rd2_Q10 ) {
512 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
513 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
514 psSS[ 0 ].Q_Q10 = q1_Q10;
515 psSS[ 1 ].Q_Q10 = q2_Q10;
516 } else {
517 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
518 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
519 psSS[ 0 ].Q_Q10 = q2_Q10;
520 psSS[ 1 ].Q_Q10 = q1_Q10;
521 }
522
523 /* Update states for best quantization */
524
525 /* Quantized excitation */
526 exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
527 if ( psDD->Seed < 0 ) {
528 exc_Q14 = -exc_Q14;
529 }
530
531 /* Add predictions */
532 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
533 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
534
535 /* Update states */
536 psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
537 sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 );
538 psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
539 psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
540 psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
541 psSS[ 0 ].xq_Q14 = xq_Q14;
542
543 /* Update states for second best quantization */
544
545 /* Quantized excitation */
546 exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
547 if ( psDD->Seed < 0 ) {
548 exc_Q14 = -exc_Q14;
549 }
550
551 /* Add predictions */
552 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
553 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
554
555 /* Update states */
556 psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
557 sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 );
558 psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
559 psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
560 psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
561 psSS[ 1 ].xq_Q14 = xq_Q14;
562 }
563
564 *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
565 if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
566 last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
567
568 /* Find winner */
569 RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
570 Winner_ind = 0;
571 for( k = 1; k < nStatesDelayedDecision; k++ ) {
572 if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
573 RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
574 Winner_ind = k;
575 }
576 }
577
578 /* Increase RD values of expired states */
579 Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
580 for( k = 0; k < nStatesDelayedDecision; k++ ) {
581 if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
582 psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
583 psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
584 silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
585 }
586 }
587
588 /* Find worst in first set and best in second set */
589 RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
590 RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
591 RDmax_ind = 0;
592 RDmin_ind = 0;
593 for( k = 1; k < nStatesDelayedDecision; k++ ) {
594 /* find worst in first set */
595 if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
596 RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
597 RDmax_ind = k;
598 }
599 /* find best in second set */
600 if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
601 RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
602 RDmin_ind = k;
603 }
604 }
605
606 /* Replace a state if best from second set outperforms worst in first set */
607 if( RDmin_Q10 < RDmax_Q10 ) {
608 silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
609 ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
610 silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
611 }
612
613 /* Write samples from winner to output and long-term filter states */
614 psDD = &psDelDec[ Winner_ind ];
615 if( subfr > 0 || i >= decisionDelay ) {
616 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
617 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
618 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
619 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
620 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ];
621 }
622 NSQ->sLTP_shp_buf_idx++;
623 NSQ->sLTP_buf_idx++;
624
625 /* Update states */
626 for( k = 0; k < nStatesDelayedDecision; k++ ) {
627 psDD = &psDelDec[ k ];
628 psSS = &psSampleState[ k ][ 0 ];
629 psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
630 psDD->Diff_Q14 = psSS->Diff_Q14;
631 psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
632 psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
633 psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
634 psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
635 psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14;
636 psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
637 psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
638 psDD->RD_Q10 = psSS->RD_Q10;
639 }
640 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
641 }
642 /* Update LPC states */
643 for( k = 0; k < nStatesDelayedDecision; k++ ) {
644 psDD = &psDelDec[ k ];
645 silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
646 }
647 RESTORE_STACK;
648}
649#endif /* OVERRIDE_silk_noise_shape_quantizer_del_dec */
650
651static OPUS_INLINE void silk_nsq_del_dec_scale_states(
652 const silk_encoder_state *psEncC, /* I Encoder State */
653 silk_nsq_state *NSQ, /* I/O NSQ state */
654 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
655 const opus_int16 x16[], /* I Input */
656 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
657 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
658 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
659 opus_int subfr, /* I Subframe number */
660 opus_int nStatesDelayedDecision, /* I Number of del dec states */
661 const opus_int LTP_scale_Q14, /* I LTP state scaling */
662 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
663 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
664 const opus_int signal_type, /* I Signal type */
665 const opus_int decisionDelay /* I Decision delay */
666)
667{
668 opus_int i, k, lag;
669 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
670 NSQ_del_dec_struct *psDD;
671
672 lag = pitchL[ subfr ];
673 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
674 silk_assert( inv_gain_Q31 != 0 );
675
676 /* Scale input */
677 inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
678 for( i = 0; i < psEncC->subfr_length; i++ ) {
679 x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
680 }
681
682 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
683 if( NSQ->rewhite_flag ) {
684 if( subfr == 0 ) {
685 /* Do LTP downscaling */
686 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
687 }
688 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
689 silk_assert( i < MAX_FRAME_LENGTH );
690 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
691 }
692 }
693
694 /* Adjust for changing gain */
695 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
696 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
697
698 /* Scale long-term shaping state */
699 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
700 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
701 }
702
703 /* Scale long-term prediction state */
704 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
705 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
706 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
707 }
708 }
709
710 for( k = 0; k < nStatesDelayedDecision; k++ ) {
711 psDD = &psDelDec[ k ];
712
713 /* Scale scalar states */
714 psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );
715 psDD->Diff_Q14 = silk_SMULWW( gain_adj_Q16, psDD->Diff_Q14 );
716
717 /* Scale short-term prediction and shaping states */
718 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
719 psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
720 }
721 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
722 psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
723 }
724 for( i = 0; i < DECISION_DELAY; i++ ) {
725 psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] );
726 psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );
727 }
728 }
729
730 /* Save inverse gain */
731 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
732 }
733}
diff --git a/lib/rbcodec/codecs/libopus/silk/PLC.c b/lib/rbcodec/codecs/libopus/silk/PLC.c
index 8b0a8fe57d..f89391651c 100644
--- a/lib/rbcodec/codecs/libopus/silk/PLC.c
+++ b/lib/rbcodec/codecs/libopus/silk/PLC.c
@@ -46,7 +46,8 @@ static OPUS_INLINE void silk_PLC_update(
46static OPUS_INLINE void silk_PLC_conceal( 46static OPUS_INLINE void silk_PLC_conceal(
47 silk_decoder_state *psDec, /* I/O Decoder state */ 47 silk_decoder_state *psDec, /* I/O Decoder state */
48 silk_decoder_control *psDecCtrl, /* I/O Decoder control */ 48 silk_decoder_control *psDecCtrl, /* I/O Decoder control */
49 opus_int16 frame[] /* O LPC residual signal */ 49 opus_int16 frame[], /* O LPC residual signal */
50 int arch /* I Run-time architecture */
50); 51);
51 52
52 53
@@ -65,7 +66,8 @@ void silk_PLC(
65 silk_decoder_state *psDec, /* I/O Decoder state */ 66 silk_decoder_state *psDec, /* I/O Decoder state */
66 silk_decoder_control *psDecCtrl, /* I/O Decoder control */ 67 silk_decoder_control *psDecCtrl, /* I/O Decoder control */
67 opus_int16 frame[], /* I/O signal */ 68 opus_int16 frame[], /* I/O signal */
68 opus_int lost /* I Loss flag */ 69 opus_int lost, /* I Loss flag */
70 int arch /* I Run-time architecture */
69) 71)
70{ 72{
71 /* PLC control function */ 73 /* PLC control function */
@@ -78,7 +80,7 @@ void silk_PLC(
78 /****************************/ 80 /****************************/
79 /* Generate Signal */ 81 /* Generate Signal */
80 /****************************/ 82 /****************************/
81 silk_PLC_conceal( psDec, psDecCtrl, frame ); 83 silk_PLC_conceal( psDec, psDecCtrl, frame, arch );
82 84
83 psDec->lossCnt++; 85 psDec->lossCnt++;
84 } else { 86 } else {
@@ -192,7 +194,8 @@ static OPUS_INLINE void silk_PLC_energy(opus_int32 *energy1, opus_int *shift1, o
192static OPUS_INLINE void silk_PLC_conceal( 194static OPUS_INLINE void silk_PLC_conceal(
193 silk_decoder_state *psDec, /* I/O Decoder state */ 195 silk_decoder_state *psDec, /* I/O Decoder state */
194 silk_decoder_control *psDecCtrl, /* I/O Decoder control */ 196 silk_decoder_control *psDecCtrl, /* I/O Decoder control */
195 opus_int16 frame[] /* O LPC residual signal */ 197 opus_int16 frame[], /* O LPC residual signal */
198 int arch /* I Run-time architecture */
196) 199)
197{ 200{
198 opus_int i, j, k; 201 opus_int i, j, k;
@@ -272,7 +275,7 @@ static OPUS_INLINE void silk_PLC_conceal(
272 /* Reduce random noise for unvoiced frames with high LPC gain */ 275 /* Reduce random noise for unvoiced frames with high LPC gain */
273 opus_int32 invGain_Q30, down_scale_Q30; 276 opus_int32 invGain_Q30, down_scale_Q30;
274 277
275 invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order ); 278 invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order, arch );
276 279
277 down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); 280 down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
278 down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); 281 down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
@@ -288,8 +291,8 @@ static OPUS_INLINE void silk_PLC_conceal(
288 291
289 /* Rewhiten LTP state */ 292 /* Rewhiten LTP state */
290 idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; 293 idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
291 silk_assert( idx > 0 ); 294 celt_assert( idx > 0 );
292 silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order ); 295 silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order, arch );
293 /* Scale LTP state */ 296 /* Scale LTP state */
294 inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 ); 297 inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 );
295 inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 ); 298 inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 );
@@ -325,8 +328,10 @@ static OPUS_INLINE void silk_PLC_conceal(
325 for( j = 0; j < LTP_ORDER; j++ ) { 328 for( j = 0; j < LTP_ORDER; j++ ) {
326 B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 ); 329 B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );
327 } 330 }
328 /* Gradually reduce excitation gain */ 331 if ( psDec->indices.signalType != TYPE_NO_VOICE_ACTIVITY ) {
329 rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); 332 /* Gradually reduce excitation gain */
333 rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
334 }
330 335
331 /* Slowly increase pitch lag */ 336 /* Slowly increase pitch lag */
332 psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); 337 psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );
@@ -342,7 +347,7 @@ static OPUS_INLINE void silk_PLC_conceal(
342 /* Copy LPC state */ 347 /* Copy LPC state */
343 silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); 348 silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) );
344 349
345 silk_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */ 350 celt_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
346 for( i = 0; i < psDec->frame_length; i++ ) { 351 for( i = 0; i < psDec->frame_length; i++ ) {
347 /* partly unrolled */ 352 /* partly unrolled */
348 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 353 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
@@ -362,7 +367,8 @@ static OPUS_INLINE void silk_PLC_conceal(
362 } 367 }
363 368
364 /* Add prediction to LPC excitation */ 369 /* Add prediction to LPC excitation */
365 sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 ); 370 sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ],
371 silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ));
366 372
367 /* Scale with Gain */ 373 /* Scale with Gain */
368 frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) ); 374 frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) );
diff --git a/lib/rbcodec/codecs/libopus/silk/PLC.h b/lib/rbcodec/codecs/libopus/silk/PLC.h
index f1e2eccc69..6438f51633 100644
--- a/lib/rbcodec/codecs/libopus/silk/PLC.h
+++ b/lib/rbcodec/codecs/libopus/silk/PLC.h
@@ -48,7 +48,8 @@ void silk_PLC(
48 silk_decoder_state *psDec, /* I/O Decoder state */ 48 silk_decoder_state *psDec, /* I/O Decoder state */
49 silk_decoder_control *psDecCtrl, /* I/O Decoder control */ 49 silk_decoder_control *psDecCtrl, /* I/O Decoder control */
50 opus_int16 frame[], /* I/O signal */ 50 opus_int16 frame[], /* I/O signal */
51 opus_int lost /* I Loss flag */ 51 opus_int lost, /* I Loss flag */
52 int arch /* I Run-time architecture */
52); 53);
53 54
54void silk_PLC_glue_frames( 55void silk_PLC_glue_frames(
diff --git a/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h b/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h
index 4be0985435..f9ae326326 100644
--- a/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h
+++ b/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h
@@ -35,13 +35,22 @@ extern "C"
35 35
36/*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */ 36/*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */
37 37
38#define SILK_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */ 38#define SILK_MAX_ORDER_LPC 24 /* max order of the LPC analysis in schur() and k2a() */
39 39
40#include <string.h> /* for memset(), memcpy(), memmove() */ 40#include <string.h> /* for memset(), memcpy(), memmove() */
41#include "typedef.h" 41#include "typedef.h"
42#include "resampler_structs.h" 42#include "resampler_structs.h"
43#include "macros.h" 43#include "macros.h"
44#include "cpu_support.h"
44 45
46#if defined(OPUS_X86_MAY_HAVE_SSE4_1)
47#include "x86/SigProc_FIX_sse.h"
48#endif
49
50#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
51#include "arm/biquad_alt_arm.h"
52#include "arm/LPC_inv_pred_gain_arm.h"
53#endif
45 54
46/********************************************************************/ 55/********************************************************************/
47/* SIGNAL PROCESSING FUNCTIONS */ 56/* SIGNAL PROCESSING FUNCTIONS */
@@ -92,14 +101,22 @@ void silk_resampler_down2_3(
92 * slower than biquad() but uses more precise coefficients 101 * slower than biquad() but uses more precise coefficients
93 * can handle (slowly) varying coefficients 102 * can handle (slowly) varying coefficients
94 */ 103 */
95void silk_biquad_alt( 104void silk_biquad_alt_stride1(
96 const opus_int16 *in, /* I input signal */ 105 const opus_int16 *in, /* I input signal */
97 const opus_int32 *B_Q28, /* I MA coefficients [3] */ 106 const opus_int32 *B_Q28, /* I MA coefficients [3] */
98 const opus_int32 *A_Q28, /* I AR coefficients [2] */ 107 const opus_int32 *A_Q28, /* I AR coefficients [2] */
99 opus_int32 *S, /* I/O State vector [2] */ 108 opus_int32 *S, /* I/O State vector [2] */
100 opus_int16 *out, /* O output signal */ 109 opus_int16 *out, /* O output signal */
101 const opus_int32 len, /* I signal length (must be even) */ 110 const opus_int32 len /* I signal length (must be even) */
102 opus_int stride /* I Operate on interleaved signal if > 1 */ 111);
112
113void silk_biquad_alt_stride2_c(
114 const opus_int16 *in, /* I input signal */
115 const opus_int32 *B_Q28, /* I MA coefficients [3] */
116 const opus_int32 *A_Q28, /* I AR coefficients [2] */
117 opus_int32 *S, /* I/O State vector [4] */
118 opus_int16 *out, /* O output signal */
119 const opus_int32 len /* I signal length (must be even) */
103); 120);
104 121
105/* Variable order MA prediction error filter. */ 122/* Variable order MA prediction error filter. */
@@ -108,7 +125,8 @@ void silk_LPC_analysis_filter(
108 const opus_int16 *in, /* I Input signal */ 125 const opus_int16 *in, /* I Input signal */
109 const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ 126 const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */
110 const opus_int32 len, /* I Signal length */ 127 const opus_int32 len, /* I Signal length */
111 const opus_int32 d /* I Filter order */ 128 const opus_int32 d, /* I Filter order */
129 int arch /* I Run-time architecture */
112); 130);
113 131
114/* Chirp (bandwidth expand) LP AR filter */ 132/* Chirp (bandwidth expand) LP AR filter */
@@ -127,17 +145,11 @@ void silk_bwexpander_32(
127 145
128/* Compute inverse of LPC prediction gain, and */ 146/* Compute inverse of LPC prediction gain, and */
129/* test if LPC coefficients are stable (all poles within unit circle) */ 147/* test if LPC coefficients are stable (all poles within unit circle) */
130opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ 148opus_int32 silk_LPC_inverse_pred_gain_c( /* O Returns inverse prediction gain in energy domain, Q30 */
131 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ 149 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
132 const opus_int order /* I Prediction order */ 150 const opus_int order /* I Prediction order */
133); 151);
134 152
135/* For input in Q24 domain */
136opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */
137 const opus_int32 *A_Q24, /* I Prediction coefficients [order] */
138 const opus_int order /* I Prediction order */
139);
140
141/* Split signal in two decimated bands using first-order allpass filters */ 153/* Split signal in two decimated bands using first-order allpass filters */
142void silk_ana_filt_bank_1( 154void silk_ana_filt_bank_1(
143 const opus_int16 *in, /* I Input signal [N] */ 155 const opus_int16 *in, /* I Input signal [N] */
@@ -147,6 +159,14 @@ void silk_ana_filt_bank_1(
147 const opus_int32 N /* I Number of input samples */ 159 const opus_int32 N /* I Number of input samples */
148); 160);
149 161
162#if !defined(OVERRIDE_silk_biquad_alt_stride2)
163#define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), silk_biquad_alt_stride2_c(in, B_Q28, A_Q28, S, out, len))
164#endif
165
166#if !defined(OVERRIDE_silk_LPC_inverse_pred_gain)
167#define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_c(A_Q12, order))
168#endif
169
150/********************************************************************/ 170/********************************************************************/
151/* SCALAR FUNCTIONS */ 171/* SCALAR FUNCTIONS */
152/********************************************************************/ 172/********************************************************************/
@@ -266,7 +286,17 @@ void silk_A2NLSF(
266void silk_NLSF2A( 286void silk_NLSF2A(
267 opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ 287 opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */
268 const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ 288 const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */
269 const opus_int d /* I filter order (should be even) */ 289 const opus_int d, /* I filter order (should be even) */
290 int arch /* I Run-time architecture */
291);
292
293/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */
294void silk_LPC_fit(
295 opus_int16 *a_QOUT, /* O Output signal */
296 opus_int32 *a_QIN, /* I/O Input signal */
297 const opus_int QOUT, /* I Input Q domain */
298 const opus_int QIN, /* I Input Q domain */
299 const opus_int d /* I Filter order */
270); 300);
271 301
272void silk_insertion_sort_increasing( 302void silk_insertion_sort_increasing(
@@ -303,7 +333,7 @@ void silk_NLSF_VQ_weights_laroia(
303); 333);
304 334
305/* Compute reflection coefficients from input signal */ 335/* Compute reflection coefficients from input signal */
306void silk_burg_modified( 336void silk_burg_modified_c(
307 opus_int32 *res_nrg, /* O Residual energy */ 337 opus_int32 *res_nrg, /* O Residual energy */
308 opus_int *res_nrg_Q, /* O Residual energy Q value */ 338 opus_int *res_nrg_Q, /* O Residual energy Q value */
309 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ 339 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
@@ -335,12 +365,15 @@ void silk_scale_vector32_Q26_lshift_18(
335/********************************************************************/ 365/********************************************************************/
336 366
337/* return sum( inVec1[i] * inVec2[i] ) */ 367/* return sum( inVec1[i] * inVec2[i] ) */
368
338opus_int32 silk_inner_prod_aligned( 369opus_int32 silk_inner_prod_aligned(
339 const opus_int16 *const inVec1, /* I input vector 1 */ 370 const opus_int16 *const inVec1, /* I input vector 1 */
340 const opus_int16 *const inVec2, /* I input vector 2 */ 371 const opus_int16 *const inVec2, /* I input vector 2 */
341 const opus_int len /* I vector lengths */ 372 const opus_int len, /* I vector lengths */
373 int arch /* I Run-time architecture */
342); 374);
343 375
376
344opus_int32 silk_inner_prod_aligned_scale( 377opus_int32 silk_inner_prod_aligned_scale(
345 const opus_int16 *const inVec1, /* I input vector 1 */ 378 const opus_int16 *const inVec1, /* I input vector 1 */
346 const opus_int16 *const inVec2, /* I input vector 2 */ 379 const opus_int16 *const inVec2, /* I input vector 2 */
@@ -348,7 +381,7 @@ opus_int32 silk_inner_prod_aligned_scale(
348 const opus_int len /* I vector lengths */ 381 const opus_int len /* I vector lengths */
349); 382);
350 383
351opus_int64 silk_inner_prod16_aligned_64( 384opus_int64 silk_inner_prod16_aligned_64_c(
352 const opus_int16 *inVec1, /* I input vector 1 */ 385 const opus_int16 *inVec1, /* I input vector 1 */
353 const opus_int16 *inVec2, /* I input vector 2 */ 386 const opus_int16 *inVec2, /* I input vector 2 */
354 const opus_int len /* I vector lengths */ 387 const opus_int len /* I vector lengths */
@@ -463,8 +496,7 @@ static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
463/* Add with saturation for positive input values */ 496/* Add with saturation for positive input values */
464#define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))) 497#define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b)))
465#define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))) 498#define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b)))
466#define silk_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))) 499#define silk_ADD_POS_SAT32(a, b) ((((opus_uint32)(a)+(opus_uint32)(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)))
467#define silk_ADD_POS_SAT64(a, b) ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)))
468 500
469#define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */ 501#define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */
470#define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */ 502#define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */
@@ -564,7 +596,9 @@ static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
564/* Make sure to store the result as the seed for the next call (also in between */ 596/* Make sure to store the result as the seed for the next call (also in between */
565/* frames), otherwise result won't be random at all. When only using some of the */ 597/* frames), otherwise result won't be random at all. When only using some of the */
566/* bits, take the most significant bits by right-shifting. */ 598/* bits, take the most significant bits by right-shifting. */
567#define silk_RAND(seed) (silk_MLA_ovflw(907633515, (seed), 196314165)) 599#define RAND_MULTIPLIER 196314165
600#define RAND_INCREMENT 907633515
601#define silk_RAND(seed) (silk_MLA_ovflw((RAND_INCREMENT), (seed), (RAND_MULTIPLIER)))
568 602
569/* Add some multiplication functions that can be easily mapped to ARM. */ 603/* Add some multiplication functions that can be easily mapped to ARM. */
570 604
@@ -575,6 +609,14 @@ static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
575/* the following seems faster on x86 */ 609/* the following seems faster on x86 */
576#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) 610#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32)
577 611
612#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
613#define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \
614 ((void)(arch), silk_burg_modified_c(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch))
615
616#define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \
617 ((void)(arch),silk_inner_prod16_aligned_64_c(inVec1, inVec2, len))
618#endif
619
578#include "Inlines.h" 620#include "Inlines.h"
579#include "MacroCount.h" 621#include "MacroCount.h"
580#include "MacroDebug.h" 622#include "MacroDebug.h"
diff --git a/lib/rbcodec/codecs/libopus/silk/VAD.c b/lib/rbcodec/codecs/libopus/silk/VAD.c
new file mode 100644
index 0000000000..d0cda52162
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/VAD.c
@@ -0,0 +1,360 @@
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.h"
33#include "stack_alloc.h"
34
35/* Silk VAD noise level estimation */
36# if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
37static OPUS_INLINE void silk_VAD_GetNoiseLevels(
38 const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */
39 silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
40);
41#endif
42
43/**********************************/
44/* Initialization of the Silk VAD */
45/**********************************/
46opus_int silk_VAD_Init( /* O Return value, 0 if success */
47 silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
48)
49{
50 opus_int b, ret = 0;
51
52 /* reset state memory */
53 silk_memset( psSilk_VAD, 0, sizeof( silk_VAD_state ) );
54
55 /* init noise levels */
56 /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */
57 for( b = 0; b < VAD_N_BANDS; b++ ) {
58 psSilk_VAD->NoiseLevelBias[ b ] = silk_max_32( silk_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 );
59 }
60
61 /* Initialize state */
62 for( b = 0; b < VAD_N_BANDS; b++ ) {
63 psSilk_VAD->NL[ b ] = silk_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] );
64 psSilk_VAD->inv_NL[ b ] = silk_DIV32( silk_int32_MAX, psSilk_VAD->NL[ b ] );
65 }
66 psSilk_VAD->counter = 15;
67
68 /* init smoothed energy-to-noise ratio*/
69 for( b = 0; b < VAD_N_BANDS; b++ ) {
70 psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */
71 }
72
73 return( ret );
74}
75
76/* Weighting factors for tilt measure */
77static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };
78
79/***************************************/
80/* Get the speech activity level in Q8 */
81/***************************************/
82opus_int silk_VAD_GetSA_Q8_c( /* O Return value, 0 if success */
83 silk_encoder_state *psEncC, /* I/O Encoder state */
84 const opus_int16 pIn[] /* I PCM input */
85)
86{
87 opus_int SA_Q15, pSNR_dB_Q7, input_tilt;
88 opus_int decimated_framelength1, decimated_framelength2;
89 opus_int decimated_framelength;
90 opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
91 opus_int32 sumSquared, smooth_coef_Q16;
92 opus_int16 HPstateTmp;
93 VARDECL( opus_int16, X );
94 opus_int32 Xnrg[ VAD_N_BANDS ];
95 opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
96 opus_int32 speech_nrg, x_tmp;
97 opus_int X_offset[ VAD_N_BANDS ];
98 opus_int ret = 0;
99 silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
100 SAVE_STACK;
101
102 /* Safety checks */
103 silk_assert( VAD_N_BANDS == 4 );
104 celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
105 celt_assert( psEncC->frame_length <= 512 );
106 celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
107
108 /***********************/
109 /* Filter and Decimate */
110 /***********************/
111 decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
112 decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
113 decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
114 /* Decimate into 4 bands:
115 0 L 3L L 3L 5L
116 - -- - -- --
117 8 8 2 4 4
118
119 [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz |
120
121 They're arranged to allow the minimal ( frame_length / 4 ) extra
122 scratch space during the downsampling process */
123 X_offset[ 0 ] = 0;
124 X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
125 X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
126 X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
127 ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
128
129 /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
130 silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ],
131 X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
132
133 /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
134 silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
135 X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
136
137 /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
138 silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
139 X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
140
141 /*********************************************/
142 /* HP filter on lowest band (differentiator) */
143 /*********************************************/
144 X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
145 HPstateTmp = X[ decimated_framelength - 1 ];
146 for( i = decimated_framelength - 1; i > 0; i-- ) {
147 X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 );
148 X[ i ] -= X[ i - 1 ];
149 }
150 X[ 0 ] -= psSilk_VAD->HPstate;
151 psSilk_VAD->HPstate = HPstateTmp;
152
153 /*************************************/
154 /* Calculate the energy in each band */
155 /*************************************/
156 for( b = 0; b < VAD_N_BANDS; b++ ) {
157 /* Find the decimated framelength in the non-uniformly divided bands */
158 decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
159
160 /* Split length into subframe lengths */
161 dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
162 dec_subframe_offset = 0;
163
164 /* Compute energy per sub-frame */
165 /* initialize with summed energy of last subframe */
166 Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
167 for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
168 sumSquared = 0;
169 for( i = 0; i < dec_subframe_length; i++ ) {
170 /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */
171 /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */
172 x_tmp = silk_RSHIFT(
173 X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
174 sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
175
176 /* Safety check */
177 silk_assert( sumSquared >= 0 );
178 }
179
180 /* Add/saturate summed energy of current subframe */
181 if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
182 Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
183 } else {
184 /* Look-ahead subframe */
185 Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
186 }
187
188 dec_subframe_offset += dec_subframe_length;
189 }
190 psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
191 }
192
193 /********************/
194 /* Noise estimation */
195 /********************/
196 silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
197
198 /***********************************************/
199 /* Signal-plus-noise to noise ratio estimation */
200 /***********************************************/
201 sumSquared = 0;
202 input_tilt = 0;
203 for( b = 0; b < VAD_N_BANDS; b++ ) {
204 speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
205 if( speech_nrg > 0 ) {
206 /* Divide, with sufficient resolution */
207 if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
208 NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
209 } else {
210 NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
211 }
212
213 /* Convert to log domain */
214 SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
215
216 /* Sum-of-squares */
217 sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */
218
219 /* Tilt measure */
220 if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
221 /* Scale down SNR value for small subband speech energies */
222 SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
223 }
224 input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
225 } else {
226 NrgToNoiseRatio_Q8[ b ] = 256;
227 }
228 }
229
230 /* Mean-of-squares */
231 sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
232
233 /* Root-mean-square approximation, scale to dBs, and write to output pointer */
234 pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
235
236 /*********************************/
237 /* Speech Probability Estimation */
238 /*********************************/
239 SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
240
241 /**************************/
242 /* Frequency Tilt Measure */
243 /**************************/
244 psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );
245
246 /**************************************************/
247 /* Scale the sigmoid output based on power levels */
248 /**************************************************/
249 speech_nrg = 0;
250 for( b = 0; b < VAD_N_BANDS; b++ ) {
251 /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
252 speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
253 }
254
255 if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
256 speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
257 }
258 /* Power scaling */
259 if( speech_nrg <= 0 ) {
260 SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
261 } else if( speech_nrg < 16384 ) {
262 speech_nrg = silk_LSHIFT32( speech_nrg, 16 );
263
264 /* square-root */
265 speech_nrg = silk_SQRT_APPROX( speech_nrg );
266 SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );
267 }
268
269 /* Copy the resulting speech activity in Q8 */
270 psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );
271
272 /***********************************/
273 /* Energy Level and SNR estimation */
274 /***********************************/
275 /* Smoothing coefficient */
276 smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
277
278 if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
279 smooth_coef_Q16 >>= 1;
280 }
281
282 for( b = 0; b < VAD_N_BANDS; b++ ) {
283 /* compute smoothed energy-to-noise ratio per band */
284 psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
285 NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
286
287 /* signal to noise ratio in dB per band */
288 SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
289 /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
290 psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
291 }
292
293 RESTORE_STACK;
294 return( ret );
295}
296
297/**************************/
298/* Noise level estimation */
299/**************************/
300# if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
301static OPUS_INLINE
302#endif
303void silk_VAD_GetNoiseLevels(
304 const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */
305 silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
306)
307{
308 opus_int k;
309 opus_int32 nl, nrg, inv_nrg;
310 opus_int coef, min_coef;
311
312 /* Initially faster smoothing */
313 if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */
314 min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );
315 /* Increment frame counter */
316 psSilk_VAD->counter++;
317 } else {
318 min_coef = 0;
319 }
320
321 for( k = 0; k < VAD_N_BANDS; k++ ) {
322 /* Get old noise level estimate for current band */
323 nl = psSilk_VAD->NL[ k ];
324 silk_assert( nl >= 0 );
325
326 /* Add bias */
327 nrg = silk_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] );
328 silk_assert( nrg > 0 );
329
330 /* Invert energies */
331 inv_nrg = silk_DIV32( silk_int32_MAX, nrg );
332 silk_assert( inv_nrg >= 0 );
333
334 /* Less update when subband energy is high */
335 if( nrg > silk_LSHIFT( nl, 3 ) ) {
336 coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3;
337 } else if( nrg < nl ) {
338 coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16;
339 } else {
340 coef = silk_SMULWB( silk_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 );
341 }
342
343 /* Initially faster smoothing */
344 coef = silk_max_int( coef, min_coef );
345
346 /* Smooth inverse energies */
347 psSilk_VAD->inv_NL[ k ] = silk_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef );
348 silk_assert( psSilk_VAD->inv_NL[ k ] >= 0 );
349
350 /* Compute noise level by inverting again */
351 nl = silk_DIV32( silk_int32_MAX, psSilk_VAD->inv_NL[ k ] );
352 silk_assert( nl >= 0 );
353
354 /* Limit noise levels (guarantee 7 bits of head room) */
355 nl = silk_min( nl, 0x00FFFFFF );
356
357 /* Store as part of state */
358 psSilk_VAD->NL[ k ] = nl;
359 }
360}
diff --git a/lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c b/lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c
new file mode 100644
index 0000000000..0f3d545c4e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c
@@ -0,0 +1,131 @@
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.h"
33
34/* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */
35void silk_VQ_WMat_EC_c(
36 opus_int8 *ind, /* O index of best codebook vector */
37 opus_int32 *res_nrg_Q15, /* O best residual energy */
38 opus_int32 *rate_dist_Q8, /* O best total bitrate */
39 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
40 const opus_int32 *XX_Q17, /* I correlation matrix */
41 const opus_int32 *xX_Q17, /* I correlation vector */
42 const opus_int8 *cb_Q7, /* I codebook */
43 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
44 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
45 const opus_int subfr_len, /* I number of samples per subframe */
46 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
47 const opus_int L /* I number of vectors in codebook */
48)
49{
50 opus_int k, gain_tmp_Q7;
51 const opus_int8 *cb_row_Q7;
52 opus_int32 neg_xX_Q24[ 5 ];
53 opus_int32 sum1_Q15, sum2_Q24;
54 opus_int32 bits_res_Q8, bits_tot_Q8;
55
56 /* Negate and convert to new Q domain */
57 neg_xX_Q24[ 0 ] = -silk_LSHIFT32( xX_Q17[ 0 ], 7 );
58 neg_xX_Q24[ 1 ] = -silk_LSHIFT32( xX_Q17[ 1 ], 7 );
59 neg_xX_Q24[ 2 ] = -silk_LSHIFT32( xX_Q17[ 2 ], 7 );
60 neg_xX_Q24[ 3 ] = -silk_LSHIFT32( xX_Q17[ 3 ], 7 );
61 neg_xX_Q24[ 4 ] = -silk_LSHIFT32( xX_Q17[ 4 ], 7 );
62
63 /* Loop over codebook */
64 *rate_dist_Q8 = silk_int32_MAX;
65 *res_nrg_Q15 = silk_int32_MAX;
66 cb_row_Q7 = cb_Q7;
67 /* In things go really bad, at least *ind is set to something safe. */
68 *ind = 0;
69 for( k = 0; k < L; k++ ) {
70 opus_int32 penalty;
71 gain_tmp_Q7 = cb_gain_Q7[k];
72 /* Weighted rate */
73 /* Quantization error: 1 - 2 * xX * cb + cb' * XX * cb */
74 sum1_Q15 = SILK_FIX_CONST( 1.001, 15 );
75
76 /* Penalty for too large gain */
77 penalty = silk_LSHIFT32( silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 11 );
78
79 /* first row of XX_Q17 */
80 sum2_Q24 = silk_MLA( neg_xX_Q24[ 0 ], XX_Q17[ 1 ], cb_row_Q7[ 1 ] );
81 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 2 ], cb_row_Q7[ 2 ] );
82 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 3 ], cb_row_Q7[ 3 ] );
83 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 4 ], cb_row_Q7[ 4 ] );
84 sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
85 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 0 ], cb_row_Q7[ 0 ] );
86 sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 0 ] );
87
88 /* second row of XX_Q17 */
89 sum2_Q24 = silk_MLA( neg_xX_Q24[ 1 ], XX_Q17[ 7 ], cb_row_Q7[ 2 ] );
90 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 8 ], cb_row_Q7[ 3 ] );
91 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 9 ], cb_row_Q7[ 4 ] );
92 sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
93 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 6 ], cb_row_Q7[ 1 ] );
94 sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 1 ] );
95
96 /* third row of XX_Q17 */
97 sum2_Q24 = silk_MLA( neg_xX_Q24[ 2 ], XX_Q17[ 13 ], cb_row_Q7[ 3 ] );
98 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 14 ], cb_row_Q7[ 4 ] );
99 sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
100 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 12 ], cb_row_Q7[ 2 ] );
101 sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 2 ] );
102
103 /* fourth row of XX_Q17 */
104 sum2_Q24 = silk_MLA( neg_xX_Q24[ 3 ], XX_Q17[ 19 ], cb_row_Q7[ 4 ] );
105 sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
106 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 18 ], cb_row_Q7[ 3 ] );
107 sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 3 ] );
108
109 /* last row of XX_Q17 */
110 sum2_Q24 = silk_LSHIFT32( neg_xX_Q24[ 4 ], 1 );
111 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 24 ], cb_row_Q7[ 4 ] );
112 sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 4 ] );
113
114 /* find best */
115 if( sum1_Q15 >= 0 ) {
116 /* Translate residual energy to bits using high-rate assumption (6 dB ==> 1 bit/sample) */
117 bits_res_Q8 = silk_SMULBB( subfr_len, silk_lin2log( sum1_Q15 + penalty) - (15 << 7) );
118 /* In the following line we reduce the codelength component by half ("-1"); seems to slghtly improve quality */
119 bits_tot_Q8 = silk_ADD_LSHIFT32( bits_res_Q8, cl_Q5[ k ], 3-1 );
120 if( bits_tot_Q8 <= *rate_dist_Q8 ) {
121 *rate_dist_Q8 = bits_tot_Q8;
122 *res_nrg_Q15 = sum1_Q15 + penalty;
123 *ind = (opus_int8)k;
124 *gain_Q7 = gain_tmp_Q7;
125 }
126 }
127
128 /* Go to next cbk vector */
129 cb_row_Q7 += LTP_ORDER;
130 }
131}
diff --git a/lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c b/lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c
new file mode 100644
index 0000000000..24cfb03fdb
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c
@@ -0,0 +1,74 @@
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/* Coefficients for 2-band filter bank based on first-order allpass filters */
35static opus_int16 A_fb1_20 = 5394 << 1;
36static opus_int16 A_fb1_21 = -24290; /* (opus_int16)(20623 << 1) */
37
38/* Split signal into two decimated bands using first-order allpass filters */
39void silk_ana_filt_bank_1(
40 const opus_int16 *in, /* I Input signal [N] */
41 opus_int32 *S, /* I/O State vector [2] */
42 opus_int16 *outL, /* O Low band [N/2] */
43 opus_int16 *outH, /* O High band [N/2] */
44 const opus_int32 N /* I Number of input samples */
45)
46{
47 opus_int k, N2 = silk_RSHIFT( N, 1 );
48 opus_int32 in32, X, Y, out_1, out_2;
49
50 /* Internal variables and state are in Q10 format */
51 for( k = 0; k < N2; k++ ) {
52 /* Convert to Q10 */
53 in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 );
54
55 /* All-pass section for even input sample */
56 Y = silk_SUB32( in32, S[ 0 ] );
57 X = silk_SMLAWB( Y, Y, A_fb1_21 );
58 out_1 = silk_ADD32( S[ 0 ], X );
59 S[ 0 ] = silk_ADD32( in32, X );
60
61 /* Convert to Q10 */
62 in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 );
63
64 /* All-pass section for odd input sample, and add to output of previous section */
65 Y = silk_SUB32( in32, S[ 1 ] );
66 X = silk_SMULWB( Y, A_fb1_20 );
67 out_2 = silk_ADD32( S[ 1 ], X );
68 S[ 1 ] = silk_ADD32( in32, X );
69
70 /* Add/subtract, convert back to int16 and store to output */
71 outL[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_ADD32( out_2, out_1 ), 11 ) );
72 outH[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SUB32( out_2, out_1 ), 11 ) );
73 }
74}
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h
new file mode 100644
index 0000000000..9895b555c8
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h
@@ -0,0 +1,57 @@
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_LPC_INV_PRED_GAIN_ARM_H
29# define SILK_LPC_INV_PRED_GAIN_ARM_H
30
31# include "celt/arm/armcpu.h"
32
33# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
34opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse prediction gain in energy domain, Q30 */
35 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
36 const opus_int order /* I Prediction order */
37);
38
39# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
40# define OVERRIDE_silk_LPC_inverse_pred_gain (1)
41# define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), PRESUME_NEON(silk_LPC_inverse_pred_gain)(A_Q12, order))
42# endif
43# endif
44
45# if !defined(OVERRIDE_silk_LPC_inverse_pred_gain)
46/*Is run-time CPU detection enabled on this platform?*/
47# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
48extern opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK+1])(const opus_int16 *A_Q12, const opus_int order);
49# define OVERRIDE_silk_LPC_inverse_pred_gain (1)
50# define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((*SILK_LPC_INVERSE_PRED_GAIN_IMPL[(arch)&OPUS_ARCHMASK])(A_Q12, order))
51# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
52# define OVERRIDE_silk_LPC_inverse_pred_gain (1)
53# define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_neon(A_Q12, order))
54# endif
55# endif
56
57#endif /* end SILK_LPC_INV_PRED_GAIN_ARM_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c
new file mode 100644
index 0000000000..ab426bcd66
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c
@@ -0,0 +1,280 @@
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#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <arm_neon.h>
33#include "SigProc_FIX.h"
34#include "define.h"
35
36#define QA 24
37#define A_LIMIT SILK_FIX_CONST( 0.99975, QA )
38
39#define MUL32_FRAC_Q(a32, b32, Q) ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q)))
40
41/* The difficulty is how to judge a 64-bit signed integer tmp64 is 32-bit overflowed,
42 * since NEON has no 64-bit min, max or comparison instructions.
43 * A failed idea is to compare the results of vmovn(tmp64) and vqmovn(tmp64) whether they are equal or not.
44 * However, this idea fails when the tmp64 is something like 0xFFFFFFF980000000.
45 * Here we know that mult2Q >= 1, so the highest bit (bit 63, sign bit) of tmp64 must equal to bit 62.
46 * tmp64 was shifted left by 1 and we got tmp64'. If high_half(tmp64') != 0 and high_half(tmp64') != -1,
47 * then we know that bit 31 to bit 63 of tmp64 can not all be the sign bit, and therefore tmp64 is 32-bit overflowed.
48 * That is, we judge if tmp64' > 0x00000000FFFFFFFF, or tmp64' <= 0xFFFFFFFF00000000.
49 * We use narrowing shift right 31 bits to tmp32' to save data bandwidth and instructions.
50 * That is, we judge if tmp32' > 0x00000000, or tmp32' <= 0xFFFFFFFF.
51 */
52
53/* Compute inverse of LPC prediction gain, and */
54/* test if LPC coefficients are stable (all poles within unit circle) */
55static OPUS_INLINE opus_int32 LPC_inverse_pred_gain_QA_neon( /* O Returns inverse prediction gain in energy domain, Q30 */
56 opus_int32 A_QA[ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */
57 const opus_int order /* I Prediction order */
58)
59{
60 opus_int k, n, mult2Q;
61 opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2;
62 opus_int32 max, min;
63 int32x4_t max_s32x4, min_s32x4;
64 int32x2_t max_s32x2, min_s32x2;
65
66 max_s32x4 = vdupq_n_s32( silk_int32_MIN );
67 min_s32x4 = vdupq_n_s32( silk_int32_MAX );
68 invGain_Q30 = SILK_FIX_CONST( 1, 30 );
69 for( k = order - 1; k > 0; k-- ) {
70 int32x2_t rc_Q31_s32x2, rc_mult2_s32x2;
71 int64x2_t mult2Q_s64x2;
72
73 /* Check for stability */
74 if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
75 return 0;
76 }
77
78 /* Set RC equal to negated AR coef */
79 rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA );
80
81 /* rc_mult1_Q30 range: [ 1 : 2^30 ] */
82 rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
83 silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */
84 silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );
85
86 /* Update inverse gain */
87 /* invGain_Q30 range: [ 0 : 2^30 ] */
88 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
89 silk_assert( invGain_Q30 >= 0 );
90 silk_assert( invGain_Q30 <= ( 1 << 30 ) );
91 if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
92 return 0;
93 }
94
95 /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
96 mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
97 rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
98
99 /* Update AR coefficient */
100 rc_Q31_s32x2 = vdup_n_s32( rc_Q31 );
101 mult2Q_s64x2 = vdupq_n_s64( -mult2Q );
102 rc_mult2_s32x2 = vdup_n_s32( rc_mult2 );
103
104 for( n = 0; n < ( ( k + 1 ) >> 1 ) - 3; n += 4 ) {
105 /* We always calculate extra elements of A_QA buffer when ( k % 4 ) != 0, to take the advantage of SIMD parallelization. */
106 int32x4_t tmp1_s32x4, tmp2_s32x4, t0_s32x4, t1_s32x4, s0_s32x4, s1_s32x4, t_QA0_s32x4, t_QA1_s32x4;
107 int64x2_t t0_s64x2, t1_s64x2, t2_s64x2, t3_s64x2;
108 tmp1_s32x4 = vld1q_s32( A_QA + n );
109 tmp2_s32x4 = vld1q_s32( A_QA + k - n - 4 );
110 tmp2_s32x4 = vrev64q_s32( tmp2_s32x4 );
111 tmp2_s32x4 = vcombine_s32( vget_high_s32( tmp2_s32x4 ), vget_low_s32( tmp2_s32x4 ) );
112 t0_s32x4 = vqrdmulhq_lane_s32( tmp2_s32x4, rc_Q31_s32x2, 0 );
113 t1_s32x4 = vqrdmulhq_lane_s32( tmp1_s32x4, rc_Q31_s32x2, 0 );
114 t_QA0_s32x4 = vqsubq_s32( tmp1_s32x4, t0_s32x4 );
115 t_QA1_s32x4 = vqsubq_s32( tmp2_s32x4, t1_s32x4 );
116 t0_s64x2 = vmull_s32( vget_low_s32 ( t_QA0_s32x4 ), rc_mult2_s32x2 );
117 t1_s64x2 = vmull_s32( vget_high_s32( t_QA0_s32x4 ), rc_mult2_s32x2 );
118 t2_s64x2 = vmull_s32( vget_low_s32 ( t_QA1_s32x4 ), rc_mult2_s32x2 );
119 t3_s64x2 = vmull_s32( vget_high_s32( t_QA1_s32x4 ), rc_mult2_s32x2 );
120 t0_s64x2 = vrshlq_s64( t0_s64x2, mult2Q_s64x2 );
121 t1_s64x2 = vrshlq_s64( t1_s64x2, mult2Q_s64x2 );
122 t2_s64x2 = vrshlq_s64( t2_s64x2, mult2Q_s64x2 );
123 t3_s64x2 = vrshlq_s64( t3_s64x2, mult2Q_s64x2 );
124 t0_s32x4 = vcombine_s32( vmovn_s64( t0_s64x2 ), vmovn_s64( t1_s64x2 ) );
125 t1_s32x4 = vcombine_s32( vmovn_s64( t2_s64x2 ), vmovn_s64( t3_s64x2 ) );
126 s0_s32x4 = vcombine_s32( vshrn_n_s64( t0_s64x2, 31 ), vshrn_n_s64( t1_s64x2, 31 ) );
127 s1_s32x4 = vcombine_s32( vshrn_n_s64( t2_s64x2, 31 ), vshrn_n_s64( t3_s64x2, 31 ) );
128 max_s32x4 = vmaxq_s32( max_s32x4, s0_s32x4 );
129 min_s32x4 = vminq_s32( min_s32x4, s0_s32x4 );
130 max_s32x4 = vmaxq_s32( max_s32x4, s1_s32x4 );
131 min_s32x4 = vminq_s32( min_s32x4, s1_s32x4 );
132 t1_s32x4 = vrev64q_s32( t1_s32x4 );
133 t1_s32x4 = vcombine_s32( vget_high_s32( t1_s32x4 ), vget_low_s32( t1_s32x4 ) );
134 vst1q_s32( A_QA + n, t0_s32x4 );
135 vst1q_s32( A_QA + k - n - 4, t1_s32x4 );
136 }
137 for( ; n < (k + 1) >> 1; n++ ) {
138 opus_int64 tmp64;
139 tmp1 = A_QA[ n ];
140 tmp2 = A_QA[ k - n - 1 ];
141 tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1,
142 MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q);
143 if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
144 return 0;
145 }
146 A_QA[ n ] = ( opus_int32 )tmp64;
147 tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2,
148 MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q);
149 if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
150 return 0;
151 }
152 A_QA[ k - n - 1 ] = ( opus_int32 )tmp64;
153 }
154 }
155
156 /* Check for stability */
157 if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
158 return 0;
159 }
160
161 max_s32x2 = vmax_s32( vget_low_s32( max_s32x4 ), vget_high_s32( max_s32x4 ) );
162 min_s32x2 = vmin_s32( vget_low_s32( min_s32x4 ), vget_high_s32( min_s32x4 ) );
163 max_s32x2 = vmax_s32( max_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( max_s32x2 ), 32 ) ) );
164 min_s32x2 = vmin_s32( min_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( min_s32x2 ), 32 ) ) );
165 max = vget_lane_s32( max_s32x2, 0 );
166 min = vget_lane_s32( min_s32x2, 0 );
167 if( ( max > 0 ) || ( min < -1 ) ) {
168 return 0;
169 }
170
171 /* Set RC equal to negated AR coef */
172 rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA );
173
174 /* Range: [ 1 : 2^30 ] */
175 rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
176
177 /* Update inverse gain */
178 /* Range: [ 0 : 2^30 ] */
179 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
180 silk_assert( invGain_Q30 >= 0 );
181 silk_assert( invGain_Q30 <= ( 1 << 30 ) );
182 if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
183 return 0;
184 }
185
186 return invGain_Q30;
187}
188
189/* For input in Q12 domain */
190opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse prediction gain in energy domain, Q30 */
191 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
192 const opus_int order /* I Prediction order */
193)
194{
195#ifdef OPUS_CHECK_ASM
196 const opus_int32 invGain_Q30_c = silk_LPC_inverse_pred_gain_c( A_Q12, order );
197#endif
198
199 opus_int32 invGain_Q30;
200 if( ( SILK_MAX_ORDER_LPC != 24 ) || ( order & 1 )) {
201 invGain_Q30 = silk_LPC_inverse_pred_gain_c( A_Q12, order );
202 }
203 else {
204 opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ];
205 opus_int32 DC_resp;
206 int16x8_t t0_s16x8, t1_s16x8, t2_s16x8;
207 int32x4_t t0_s32x4;
208 const opus_int leftover = order & 7;
209
210 /* Increase Q domain of the AR coefficients */
211 t0_s16x8 = vld1q_s16( A_Q12 + 0 );
212 t1_s16x8 = vld1q_s16( A_Q12 + 8 );
213 t2_s16x8 = vld1q_s16( A_Q12 + 16 );
214 t0_s32x4 = vpaddlq_s16( t0_s16x8 );
215
216 switch( order - leftover )
217 {
218 case 24:
219 t0_s32x4 = vpadalq_s16( t0_s32x4, t2_s16x8 );
220 /* FALLTHROUGH */
221
222 case 16:
223 t0_s32x4 = vpadalq_s16( t0_s32x4, t1_s16x8 );
224 vst1q_s32( Atmp_QA + 16, vshll_n_s16( vget_low_s16 ( t2_s16x8 ), QA - 12 ) );
225 vst1q_s32( Atmp_QA + 20, vshll_n_s16( vget_high_s16( t2_s16x8 ), QA - 12 ) );
226 /* FALLTHROUGH */
227
228 case 8:
229 {
230 const int32x2_t t_s32x2 = vpadd_s32( vget_low_s32( t0_s32x4 ), vget_high_s32( t0_s32x4 ) );
231 const int64x1_t t_s64x1 = vpaddl_s32( t_s32x2 );
232 DC_resp = vget_lane_s32( vreinterpret_s32_s64( t_s64x1 ), 0 );
233 vst1q_s32( Atmp_QA + 8, vshll_n_s16( vget_low_s16 ( t1_s16x8 ), QA - 12 ) );
234 vst1q_s32( Atmp_QA + 12, vshll_n_s16( vget_high_s16( t1_s16x8 ), QA - 12 ) );
235 }
236 break;
237
238 default:
239 DC_resp = 0;
240 break;
241 }
242 A_Q12 += order - leftover;
243
244 switch( leftover )
245 {
246 case 6:
247 DC_resp += (opus_int32)A_Q12[ 5 ];
248 DC_resp += (opus_int32)A_Q12[ 4 ];
249 /* FALLTHROUGH */
250
251 case 4:
252 DC_resp += (opus_int32)A_Q12[ 3 ];
253 DC_resp += (opus_int32)A_Q12[ 2 ];
254 /* FALLTHROUGH */
255
256 case 2:
257 DC_resp += (opus_int32)A_Q12[ 1 ];
258 DC_resp += (opus_int32)A_Q12[ 0 ];
259 /* FALLTHROUGH */
260
261 default:
262 break;
263 }
264
265 /* If the DC is unstable, we don't even need to do the full calculations */
266 if( DC_resp >= 4096 ) {
267 invGain_Q30 = 0;
268 } else {
269 vst1q_s32( Atmp_QA + 0, vshll_n_s16( vget_low_s16 ( t0_s16x8 ), QA - 12 ) );
270 vst1q_s32( Atmp_QA + 4, vshll_n_s16( vget_high_s16( t0_s16x8 ), QA - 12 ) );
271 invGain_Q30 = LPC_inverse_pred_gain_QA_neon( Atmp_QA, order );
272 }
273 }
274
275#ifdef OPUS_CHECK_ASM
276 silk_assert( invGain_Q30_c == invGain_Q30 );
277#endif
278
279 return invGain_Q30;
280}
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h
new file mode 100644
index 0000000000..9e76e16927
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h
@@ -0,0 +1,100 @@
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_NSQ_DEL_DEC_ARM_H
29#define SILK_NSQ_DEL_DEC_ARM_H
30
31#include "celt/arm/armcpu.h"
32
33#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
34void silk_NSQ_del_dec_neon(
35 const silk_encoder_state *psEncC, silk_nsq_state *NSQ,
36 SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[],
37 const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER],
38 const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR],
39 const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER],
40 const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR],
41 const opus_int Tilt_Q14[MAX_NB_SUBFR],
42 const opus_int32 LF_shp_Q14[MAX_NB_SUBFR],
43 const opus_int32 Gains_Q16[MAX_NB_SUBFR],
44 const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10,
45 const opus_int LTP_scale_Q14);
46
47#if !defined(OPUS_HAVE_RTCD)
48#define OVERRIDE_silk_NSQ_del_dec (1)
49#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
50 LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
51 LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
52 LTP_scale_Q14, arch) \
53 ((void)(arch), \
54 PRESUME_NEON(silk_NSQ_del_dec)( \
55 psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, \
56 AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \
57 Lambda_Q10, LTP_scale_Q14))
58#endif
59#endif
60
61#if !defined(OVERRIDE_silk_NSQ_del_dec)
62/*Is run-time CPU detection enabled on this platform?*/
63#if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \
64 !defined(OPUS_ARM_PRESUME_NEON_INTR))
65extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
66 const silk_encoder_state *psEncC, silk_nsq_state *NSQ,
67 SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[],
68 const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER],
69 const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR],
70 const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER],
71 const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR],
72 const opus_int Tilt_Q14[MAX_NB_SUBFR],
73 const opus_int32 LF_shp_Q14[MAX_NB_SUBFR],
74 const opus_int32 Gains_Q16[MAX_NB_SUBFR],
75 const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10,
76 const opus_int LTP_scale_Q14);
77#define OVERRIDE_silk_NSQ_del_dec (1)
78#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
79 LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
80 LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
81 LTP_scale_Q14, arch) \
82 ((*SILK_NSQ_DEL_DEC_IMPL[(arch)&OPUS_ARCHMASK])( \
83 psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, \
84 AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \
85 Lambda_Q10, LTP_scale_Q14))
86#elif defined(OPUS_ARM_PRESUME_NEON_INTR)
87#define OVERRIDE_silk_NSQ_del_dec (1)
88#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
89 LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
90 LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
91 LTP_scale_Q14, arch) \
92 ((void)(arch), \
93 silk_NSQ_del_dec_neon(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
94 LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
95 LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
96 LTP_scale_Q14))
97#endif
98#endif
99
100#endif /* end SILK_NSQ_DEL_DEC_ARM_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c
new file mode 100644
index 0000000000..212410f362
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c
@@ -0,0 +1,1124 @@
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#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 "main.h"
37#include "stack_alloc.h"
38
39/* NEON intrinsics optimization now can only parallelize up to 4 delay decision states. */
40/* If there are more states, C function is called, and this optimization must be expanded. */
41#define NEON_MAX_DEL_DEC_STATES 4
42
43typedef struct {
44 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ][ NEON_MAX_DEL_DEC_STATES ];
45 opus_int32 RandState[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
46 opus_int32 Q_Q10[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
47 opus_int32 Xq_Q14[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
48 opus_int32 Pred_Q15[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
49 opus_int32 Shape_Q14[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
50 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ][ NEON_MAX_DEL_DEC_STATES ];
51 opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ];
52 opus_int32 Diff_Q14[ NEON_MAX_DEL_DEC_STATES ];
53 opus_int32 Seed[ NEON_MAX_DEL_DEC_STATES ];
54 opus_int32 SeedInit[ NEON_MAX_DEL_DEC_STATES ];
55 opus_int32 RD_Q10[ NEON_MAX_DEL_DEC_STATES ];
56} NSQ_del_decs_struct;
57
58typedef struct {
59 opus_int32 Q_Q10[ NEON_MAX_DEL_DEC_STATES ];
60 opus_int32 RD_Q10[ NEON_MAX_DEL_DEC_STATES ];
61 opus_int32 xq_Q14[ NEON_MAX_DEL_DEC_STATES ];
62 opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ];
63 opus_int32 Diff_Q14[ NEON_MAX_DEL_DEC_STATES ];
64 opus_int32 sLTP_shp_Q14[ NEON_MAX_DEL_DEC_STATES ];
65 opus_int32 LPC_exc_Q14[ NEON_MAX_DEL_DEC_STATES ];
66} NSQ_samples_struct;
67
68static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon(
69 const silk_encoder_state *psEncC, /* I Encoder State */
70 silk_nsq_state *NSQ, /* I/O NSQ state */
71 NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
72 const opus_int16 x16[], /* I Input */
73 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
74 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
75 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
76 opus_int subfr, /* I Subframe number */
77 const opus_int LTP_scale_Q14, /* I LTP state scaling */
78 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
79 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
80 const opus_int signal_type, /* I Signal type */
81 const opus_int decisionDelay /* I Decision delay */
82);
83
84/******************************************/
85/* Noise shape quantizer for one subframe */
86/******************************************/
87static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon(
88 silk_nsq_state *NSQ, /* I/O NSQ state */
89 NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
90 opus_int signalType, /* I Signal type */
91 const opus_int32 x_Q10[], /* I */
92 opus_int8 pulses[], /* O */
93 opus_int16 xq[], /* O */
94 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
95 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
96 const opus_int16 a_Q12[], /* I Short term prediction coefs */
97 const opus_int16 b_Q14[], /* I Long term prediction coefs */
98 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
99 opus_int lag, /* I Pitch lag */
100 opus_int32 HarmShapeFIRPacked_Q14, /* I */
101 opus_int Tilt_Q14, /* I Spectral tilt */
102 opus_int32 LF_shp_Q14, /* I */
103 opus_int32 Gain_Q16, /* I */
104 opus_int Lambda_Q10, /* I */
105 opus_int offset_Q10, /* I */
106 opus_int length, /* I Input length */
107 opus_int subfr, /* I Subframe number */
108 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
109 opus_int predictLPCOrder, /* I Prediction filter order */
110 opus_int warping_Q16, /* I */
111 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
112 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
113 opus_int decisionDelay /* I */
114);
115
116static OPUS_INLINE void copy_winner_state_kernel(
117 const NSQ_del_decs_struct *psDelDec,
118 const opus_int offset,
119 const opus_int last_smple_idx,
120 const opus_int Winner_ind,
121 const int32x2_t gain_lo_s32x2,
122 const int32x2_t gain_hi_s32x2,
123 const int32x4_t shift_s32x4,
124 int32x4_t t0_s32x4,
125 int32x4_t t1_s32x4,
126 opus_int8 *const pulses,
127 opus_int16 *pxq,
128 silk_nsq_state *NSQ
129)
130{
131 int16x8_t t_s16x8;
132 int32x4_t o0_s32x4, o1_s32x4;
133
134 t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
135 t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
136 t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
137 t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
138 t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
139 t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
140 t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
141 t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
142 t_s16x8 = vcombine_s16( vrshrn_n_s32( t0_s32x4, 10 ), vrshrn_n_s32( t1_s32x4, 10 ) );
143 vst1_s8( &pulses[ offset ], vmovn_s16( t_s16x8 ) );
144
145 t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
146 t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
147 t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
148 t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
149 t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
150 t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
151 t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
152 t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
153 o0_s32x4 = vqdmulhq_lane_s32( t0_s32x4, gain_lo_s32x2, 0 );
154 o1_s32x4 = vqdmulhq_lane_s32( t1_s32x4, gain_lo_s32x2, 0 );
155 o0_s32x4 = vmlaq_lane_s32( o0_s32x4, t0_s32x4, gain_hi_s32x2, 0 );
156 o1_s32x4 = vmlaq_lane_s32( o1_s32x4, t1_s32x4, gain_hi_s32x2, 0 );
157 o0_s32x4 = vrshlq_s32( o0_s32x4, shift_s32x4 );
158 o1_s32x4 = vrshlq_s32( o1_s32x4, shift_s32x4 );
159 vst1_s16( &pxq[ offset + 0 ], vqmovn_s32( o0_s32x4 ) );
160 vst1_s16( &pxq[ offset + 4 ], vqmovn_s32( o1_s32x4 ) );
161
162 t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
163 t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
164 t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
165 t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
166 t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
167 t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
168 t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
169 t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
170 vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 0 ], t0_s32x4 );
171 vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 4 ], t1_s32x4 );
172}
173
174static OPUS_INLINE void copy_winner_state(
175 const NSQ_del_decs_struct *psDelDec,
176 const opus_int decisionDelay,
177 const opus_int smpl_buf_idx,
178 const opus_int Winner_ind,
179 const opus_int32 gain,
180 const opus_int32 shift,
181 opus_int8 *const pulses,
182 opus_int16 *pxq,
183 silk_nsq_state *NSQ
184)
185{
186 opus_int i, last_smple_idx;
187 const int32x2_t gain_lo_s32x2 = vdup_n_s32( silk_LSHIFT32( gain & 0x0000FFFF, 15 ) );
188 const int32x2_t gain_hi_s32x2 = vdup_n_s32( gain >> 16 );
189 const int32x4_t shift_s32x4 = vdupq_n_s32( -shift );
190 int32x4_t t0_s32x4, t1_s32x4;
191
192 t0_s32x4 = t1_s32x4 = vdupq_n_s32( 0 ); /* initialization */
193 last_smple_idx = smpl_buf_idx + decisionDelay - 1 + DECISION_DELAY;
194 if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
195 if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
196
197 for( i = 0; ( i < ( decisionDelay - 7 ) ) && ( last_smple_idx >= 7 ); i += 8, last_smple_idx -= 8 ) {
198 copy_winner_state_kernel( psDelDec, i - decisionDelay, last_smple_idx, Winner_ind, gain_lo_s32x2, gain_hi_s32x2, shift_s32x4, t0_s32x4, t1_s32x4, pulses, pxq, NSQ );
199 }
200 for( ; ( i < decisionDelay ) && ( last_smple_idx >= 0 ); i++, last_smple_idx-- ) {
201 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
202 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) );
203 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
204 }
205
206 last_smple_idx += DECISION_DELAY;
207 for( ; i < ( decisionDelay - 7 ); i++, last_smple_idx-- ) {
208 copy_winner_state_kernel( psDelDec, i - decisionDelay, last_smple_idx, Winner_ind, gain_lo_s32x2, gain_hi_s32x2, shift_s32x4, t0_s32x4, t1_s32x4, pulses, pxq, NSQ );
209 }
210 for( ; i < decisionDelay; i++, last_smple_idx-- ) {
211 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
212 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) );
213 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
214 }
215}
216
217void silk_NSQ_del_dec_neon(
218 const silk_encoder_state *psEncC, /* I Encoder State */
219 silk_nsq_state *NSQ, /* I/O NSQ state */
220 SideInfoIndices *psIndices, /* I/O Quantization Indices */
221 const opus_int16 x16[], /* I Input */
222 opus_int8 pulses[], /* O Quantized pulse signal */
223 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
224 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
225 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
226 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
227 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
228 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
229 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
230 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
231 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
232 const opus_int LTP_scale_Q14 /* I LTP state scaling */
233)
234{
235#ifdef OPUS_CHECK_ASM
236 silk_nsq_state NSQ_c;
237 SideInfoIndices psIndices_c;
238 opus_int8 pulses_c[ MAX_FRAME_LENGTH ];
239 const opus_int8 *const pulses_a = pulses;
240
241 ( void )pulses_a;
242 silk_memcpy( &NSQ_c, NSQ, sizeof( NSQ_c ) );
243 silk_memcpy( &psIndices_c, psIndices, sizeof( psIndices_c ) );
244 silk_memcpy( pulses_c, pulses, sizeof( pulses_c ) );
245 silk_NSQ_del_dec_c( psEncC, &NSQ_c, &psIndices_c, x16, pulses_c, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16,
246 pitchL, Lambda_Q10, LTP_scale_Q14 );
247#endif
248
249 /* The optimization parallelizes the different delay decision states. */
250 if(( psEncC->nStatesDelayedDecision > NEON_MAX_DEL_DEC_STATES ) || ( psEncC->nStatesDelayedDecision <= 2 )) {
251 /* NEON intrinsics optimization now can only parallelize up to 4 delay decision states. */
252 /* If there are more states, C function is called, and this optimization must be expanded. */
253 /* When the number of delay decision states is less than 3, there are penalties using this */
254 /* optimization, and C function is called. */
255 /* When the number of delay decision states is 2, it's better to specialize another */
256 /* structure NSQ_del_dec2_struct and optimize with shorter NEON registers. (Low priority) */
257 silk_NSQ_del_dec_c( psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14,
258 Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14 );
259 } else {
260 opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
261 opus_int smpl_buf_idx, decisionDelay;
262 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
263 opus_int16 *pxq;
264 VARDECL( opus_int32, sLTP_Q15 );
265 VARDECL( opus_int16, sLTP );
266 opus_int32 HarmShapeFIRPacked_Q14;
267 opus_int offset_Q10;
268 opus_int32 RDmin_Q10, Gain_Q10;
269 VARDECL( opus_int32, x_sc_Q10 );
270 VARDECL( opus_int32, delayedGain_Q10 );
271 VARDECL( NSQ_del_decs_struct, psDelDec );
272 int32x4_t t_s32x4;
273 SAVE_STACK;
274
275 /* Set unvoiced lag to the previous one, overwrite later for voiced */
276 lag = NSQ->lagPrev;
277
278 silk_assert( NSQ->prev_gain_Q16 != 0 );
279
280 /* Initialize delayed decision states */
281 ALLOC( psDelDec, 1, NSQ_del_decs_struct );
282 /* Only RandState and RD_Q10 need to be initialized to 0. */
283 silk_memset( psDelDec->RandState, 0, sizeof( psDelDec->RandState ) );
284 vst1q_s32( psDelDec->RD_Q10, vdupq_n_s32( 0 ) );
285
286 for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
287 psDelDec->SeedInit[ k ] = psDelDec->Seed[ k ] = ( k + psIndices->Seed ) & 3;
288 }
289 vst1q_s32( psDelDec->LF_AR_Q14, vld1q_dup_s32( &NSQ->sLF_AR_shp_Q14 ) );
290 vst1q_s32( psDelDec->Diff_Q14, vld1q_dup_s32( &NSQ->sDiff_shp_Q14 ) );
291 vst1q_s32( psDelDec->Shape_Q14[ 0 ], vld1q_dup_s32( &NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ] ) );
292 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
293 vst1q_s32( psDelDec->sLPC_Q14[ i ], vld1q_dup_s32( &NSQ->sLPC_Q14[ i ] ) );
294 }
295 for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) {
296 vst1q_s32( psDelDec->sAR2_Q14[ i ], vld1q_dup_s32( &NSQ->sAR2_Q14[ i ] ) );
297 }
298
299 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
300 smpl_buf_idx = 0; /* index of oldest samples */
301
302 decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
303
304 /* For voiced frames limit the decision delay to lower than the pitch lag */
305 if( psIndices->signalType == TYPE_VOICED ) {
306 opus_int pitch_min = pitchL[ 0 ];
307 for( k = 1; k < psEncC->nb_subfr; k++ ) {
308 pitch_min = silk_min_int( pitch_min, pitchL[ k ] );
309 }
310 decisionDelay = silk_min_int( decisionDelay, pitch_min - LTP_ORDER / 2 - 1 );
311 } else {
312 if( lag > 0 ) {
313 decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
314 }
315 }
316
317 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
318 LSF_interpolation_flag = 0;
319 } else {
320 LSF_interpolation_flag = 1;
321 }
322
323 ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
324 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
325 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
326 ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
327 /* Set up pointers to start of sub frame */
328 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
329 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
330 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
331 subfr = 0;
332 for( k = 0; k < psEncC->nb_subfr; k++ ) {
333 A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
334 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
335 AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
336
337 /* Noise shape parameters */
338 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
339 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
340 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
341
342 NSQ->rewhite_flag = 0;
343 if( psIndices->signalType == TYPE_VOICED ) {
344 /* Voiced */
345 lag = pitchL[ k ];
346
347 /* Re-whitening */
348 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
349 if( k == 2 ) {
350 /* RESET DELAYED DECISIONS */
351 /* Find winner */
352 int32x4_t RD_Q10_s32x4;
353 RDmin_Q10 = psDelDec->RD_Q10[ 0 ];
354 Winner_ind = 0;
355 for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
356 if( psDelDec->RD_Q10[ i ] < RDmin_Q10 ) {
357 RDmin_Q10 = psDelDec->RD_Q10[ i ];
358 Winner_ind = i;
359 }
360 }
361 psDelDec->RD_Q10[ Winner_ind ] -= ( silk_int32_MAX >> 4 );
362 RD_Q10_s32x4 = vld1q_s32( psDelDec->RD_Q10 );
363 RD_Q10_s32x4 = vaddq_s32( RD_Q10_s32x4, vdupq_n_s32( silk_int32_MAX >> 4 ) );
364 vst1q_s32( psDelDec->RD_Q10, RD_Q10_s32x4 );
365
366 /* Copy final part of signals from winner state to output and long-term filter states */
367 copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gains_Q16[ 1 ], 14, pulses, pxq, NSQ );
368
369 subfr = 0;
370 }
371
372 /* Rewhiten with new A coefs */
373 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
374 silk_assert( start_idx > 0 );
375
376 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
377 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
378
379 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
380 NSQ->rewhite_flag = 1;
381 }
382 }
383
384 silk_nsq_del_dec_scale_states_neon( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k,
385 LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
386
387 silk_noise_shape_quantizer_del_dec_neon( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
388 delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
389 Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
390 psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
391
392 x16 += psEncC->subfr_length;
393 pulses += psEncC->subfr_length;
394 pxq += psEncC->subfr_length;
395 }
396
397 /* Find winner */
398 RDmin_Q10 = psDelDec->RD_Q10[ 0 ];
399 Winner_ind = 0;
400 for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
401 if( psDelDec->RD_Q10[ k ] < RDmin_Q10 ) {
402 RDmin_Q10 = psDelDec->RD_Q10[ k ];
403 Winner_ind = k;
404 }
405 }
406
407 /* Copy final part of signals from winner state to output and long-term filter states */
408 psIndices->Seed = psDelDec->SeedInit[ Winner_ind ];
409 Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
410 copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gain_Q10, 8, pulses, pxq, NSQ );
411
412 t_s32x4 = vdupq_n_s32( 0 ); /* initialization */
413 for( i = 0; i < ( NSQ_LPC_BUF_LENGTH - 3 ); i += 4 ) {
414 t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 );
415 t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 );
416 t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 );
417 t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 );
418 vst1q_s32( &NSQ->sLPC_Q14[ i ], t_s32x4 );
419 }
420
421 for( ; i < NSQ_LPC_BUF_LENGTH; i++ ) {
422 NSQ->sLPC_Q14[ i ] = psDelDec->sLPC_Q14[ i ][ Winner_ind ];
423 }
424
425 for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) - 3 ); i += 4 ) {
426 t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 );
427 t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 );
428 t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 );
429 t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 );
430 vst1q_s32( &NSQ->sAR2_Q14[ i ], t_s32x4 );
431 }
432
433 for( ; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) {
434 NSQ->sAR2_Q14[ i ] = psDelDec->sAR2_Q14[ i ][ Winner_ind ];
435 }
436
437 /* Update states */
438 NSQ->sLF_AR_shp_Q14 = psDelDec->LF_AR_Q14[ Winner_ind ];
439 NSQ->sDiff_shp_Q14 = psDelDec->Diff_Q14[ Winner_ind ];
440 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
441
442 /* Save quantized speech signal */
443 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
444 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
445 RESTORE_STACK;
446 }
447
448#ifdef OPUS_CHECK_ASM
449 silk_assert( !memcmp( &NSQ_c, NSQ, sizeof( NSQ_c ) ) );
450 silk_assert( !memcmp( &psIndices_c, psIndices, sizeof( psIndices_c ) ) );
451 silk_assert( !memcmp( pulses_c, pulses_a, sizeof( pulses_c ) ) );
452#endif
453}
454
455/******************************************/
456/* Noise shape quantizer for one subframe */
457/******************************************/
458/* Note: Function silk_short_prediction_create_arch_coef_neon() defined in NSQ_neon.h is actually a hacking C function. */
459/* Therefore here we append "_local" to the NEON function name to avoid confusion. */
460static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon_local(opus_int32 *out, const opus_int16 *in, opus_int order)
461{
462 int16x8_t t_s16x8;
463 int32x4_t t0_s32x4, t1_s32x4, t2_s32x4, t3_s32x4;
464 silk_assert( order == 10 || order == 16 );
465
466 t_s16x8 = vld1q_s16( in + 0 ); /* 7 6 5 4 3 2 1 0 */
467 t_s16x8 = vrev64q_s16( t_s16x8 ); /* 4 5 6 7 0 1 2 3 */
468 t2_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ); /* 4 5 6 7 */
469 t3_s32x4 = vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ); /* 0 1 2 3 */
470
471 if( order == 16 ) {
472 t_s16x8 = vld1q_s16( in + 8 ); /* F E D C B A 9 8 */
473 t_s16x8 = vrev64q_s16( t_s16x8 ); /* C D E F 8 9 A B */
474 t0_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ); /* C D E F */
475 t1_s32x4 = vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ); /* 8 9 A B */
476 } else {
477 int16x4_t t_s16x4;
478
479 t0_s32x4 = vdupq_n_s32( 0 ); /* zero zero zero zero */
480 t_s16x4 = vld1_s16( in + 6 ); /* 9 8 7 6 */
481 t_s16x4 = vrev64_s16( t_s16x4 ); /* 6 7 8 9 */
482 t1_s32x4 = vshll_n_s16( t_s16x4, 15 );
483 t1_s32x4 = vcombine_s32( vget_low_s32(t0_s32x4), vget_low_s32( t1_s32x4 ) ); /* 8 9 zero zero */
484 }
485 vst1q_s32( out + 0, t0_s32x4 );
486 vst1q_s32( out + 4, t1_s32x4 );
487 vst1q_s32( out + 8, t2_s32x4 );
488 vst1q_s32( out + 12, t3_s32x4 );
489}
490
491static OPUS_INLINE int32x4_t silk_SMLAWB_lane0_neon(
492 const int32x4_t out_s32x4,
493 const int32x4_t in_s32x4,
494 const int32x2_t coef_s32x2
495)
496{
497 return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 0 ) );
498}
499
500static OPUS_INLINE int32x4_t silk_SMLAWB_lane1_neon(
501 const int32x4_t out_s32x4,
502 const int32x4_t in_s32x4,
503 const int32x2_t coef_s32x2
504)
505{
506 return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 1 ) );
507}
508
509/* Note: This function has different return value than silk_noise_shape_quantizer_short_prediction_neon(). */
510/* Therefore here we append "_local" to the function name to avoid confusion. */
511static OPUS_INLINE int32x4_t silk_noise_shape_quantizer_short_prediction_neon_local(const opus_int32 *buf32, const opus_int32 *a_Q12_arch, opus_int order)
512{
513 const int32x4_t a_Q12_arch0_s32x4 = vld1q_s32( a_Q12_arch + 0 );
514 const int32x4_t a_Q12_arch1_s32x4 = vld1q_s32( a_Q12_arch + 4 );
515 const int32x4_t a_Q12_arch2_s32x4 = vld1q_s32( a_Q12_arch + 8 );
516 const int32x4_t a_Q12_arch3_s32x4 = vld1q_s32( a_Q12_arch + 12 );
517 int32x4_t LPC_pred_Q14_s32x4;
518
519 silk_assert( order == 10 || order == 16 );
520 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
521 LPC_pred_Q14_s32x4 = vdupq_n_s32( silk_RSHIFT( order, 1 ) );
522 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 0 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch0_s32x4 ) );
523 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 1 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch0_s32x4 ) );
524 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 2 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch0_s32x4 ) );
525 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 3 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch0_s32x4 ) );
526 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 4 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch1_s32x4 ) );
527 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 5 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch1_s32x4 ) );
528 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 6 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch1_s32x4 ) );
529 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 7 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch1_s32x4 ) );
530 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 8 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch2_s32x4 ) );
531 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 9 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch2_s32x4 ) );
532 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 10 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch2_s32x4 ) );
533 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 11 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch2_s32x4 ) );
534 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 12 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch3_s32x4 ) );
535 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 13 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch3_s32x4 ) );
536 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 14 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch3_s32x4 ) );
537 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 15 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch3_s32x4 ) );
538
539 return LPC_pred_Q14_s32x4;
540}
541
542static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon(
543 silk_nsq_state *NSQ, /* I/O NSQ state */
544 NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
545 opus_int signalType, /* I Signal type */
546 const opus_int32 x_Q10[], /* I */
547 opus_int8 pulses[], /* O */
548 opus_int16 xq[], /* O */
549 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
550 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
551 const opus_int16 a_Q12[], /* I Short term prediction coefs */
552 const opus_int16 b_Q14[], /* I Long term prediction coefs */
553 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
554 opus_int lag, /* I Pitch lag */
555 opus_int32 HarmShapeFIRPacked_Q14, /* I */
556 opus_int Tilt_Q14, /* I Spectral tilt */
557 opus_int32 LF_shp_Q14, /* I */
558 opus_int32 Gain_Q16, /* I */
559 opus_int Lambda_Q10, /* I */
560 opus_int offset_Q10, /* I */
561 opus_int length, /* I Input length */
562 opus_int subfr, /* I Subframe number */
563 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
564 opus_int predictLPCOrder, /* I Prediction filter order */
565 opus_int warping_Q16, /* I */
566 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
567 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
568 opus_int decisionDelay /* I */
569)
570{
571 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
572 opus_int32 Winner_rand_state;
573 opus_int32 LTP_pred_Q14, n_LTP_Q14;
574 opus_int32 RDmin_Q10, RDmax_Q10;
575 opus_int32 Gain_Q10;
576 opus_int32 *pred_lag_ptr, *shp_lag_ptr;
577 opus_int32 a_Q12_arch[MAX_LPC_ORDER];
578 const int32x2_t warping_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( warping_Q16, 16 ) >> 1 );
579 const opus_int32 LF_shp_Q29 = silk_LSHIFT32( LF_shp_Q14, 16 ) >> 1;
580 opus_int32 AR_shp_Q28[ MAX_SHAPE_LPC_ORDER ];
581 const uint32x4_t rand_multiplier_u32x4 = vdupq_n_u32( RAND_MULTIPLIER );
582 const uint32x4_t rand_increment_u32x4 = vdupq_n_u32( RAND_INCREMENT );
583
584 VARDECL( NSQ_samples_struct, psSampleState );
585 SAVE_STACK;
586
587 silk_assert( nStatesDelayedDecision > 0 );
588 silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
589 ALLOC( psSampleState, 2, NSQ_samples_struct );
590
591 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
592 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
593 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
594
595 for( i = 0; i < ( MAX_SHAPE_LPC_ORDER - 7 ); i += 8 ) {
596 const int16x8_t t_s16x8 = vld1q_s16( AR_shp_Q13 + i );
597 vst1q_s32( AR_shp_Q28 + i + 0, vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ) );
598 vst1q_s32( AR_shp_Q28 + i + 4, vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ) );
599 }
600
601 for( ; i < MAX_SHAPE_LPC_ORDER; i++ ) {
602 AR_shp_Q28[i] = silk_LSHIFT32( AR_shp_Q13[i], 15 );
603 }
604
605 silk_short_prediction_create_arch_coef_neon_local( a_Q12_arch, a_Q12, predictLPCOrder );
606
607 for( i = 0; i < length; i++ ) {
608 int32x4_t Seed_s32x4, LPC_pred_Q14_s32x4;
609 int32x4_t sign_s32x4, tmp1_s32x4, tmp2_s32x4;
610 int32x4_t n_AR_Q14_s32x4, n_LF_Q14_s32x4;
611 int32x2_t AR_shp_Q28_s32x2;
612 int16x4_t r_Q10_s16x4, rr_Q10_s16x4;
613
614 /* Perform common calculations used in all states */
615
616 /* Long-term prediction */
617 if( signalType == TYPE_VOICED ) {
618 /* Unrolled loop */
619 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
620 LTP_pred_Q14 = 2;
621 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
622 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
623 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
624 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
625 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
626 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
627 pred_lag_ptr++;
628 } else {
629 LTP_pred_Q14 = 0;
630 }
631
632 /* Long-term shaping */
633 if( lag > 0 ) {
634 /* Symmetric, packed FIR coefficients */
635 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
636 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
637 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
638 shp_lag_ptr++;
639 } else {
640 n_LTP_Q14 = 0;
641 }
642
643 /* Generate dither */
644 Seed_s32x4 = vld1q_s32( psDelDec->Seed );
645 Seed_s32x4 = vreinterpretq_s32_u32( vmlaq_u32( rand_increment_u32x4, vreinterpretq_u32_s32( Seed_s32x4 ), rand_multiplier_u32x4 ) );
646 vst1q_s32( psDelDec->Seed, Seed_s32x4 );
647
648 /* Short-term prediction */
649 LPC_pred_Q14_s32x4 = silk_noise_shape_quantizer_short_prediction_neon_local(psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 16 + i ], a_Q12_arch, predictLPCOrder);
650 LPC_pred_Q14_s32x4 = vshlq_n_s32( LPC_pred_Q14_s32x4, 4 ); /* Q10 -> Q14 */
651
652 /* Noise shape feedback */
653 /* Output of lowpass section */
654 tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->Diff_Q14 ), vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), warping_Q16_s32x2 );
655 /* Output of allpass section */
656 tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ 1 ] ), tmp2_s32x4 );
657 tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), tmp1_s32x4, warping_Q16_s32x2 );
658 vst1q_s32( psDelDec->sAR2_Q14[ 0 ], tmp2_s32x4 );
659 AR_shp_Q28_s32x2 = vld1_s32( AR_shp_Q28 );
660 n_AR_Q14_s32x4 = vaddq_s32( vdupq_n_s32( silk_RSHIFT( shapingLPCOrder, 1 ) ), vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) );
661
662 /* Loop over allpass sections */
663 for( j = 2; j < shapingLPCOrder; j += 2 ) {
664 /* Output of allpass section */
665 tmp2_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4 );
666 tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j - 1 ] ), tmp2_s32x4, warping_Q16_s32x2 );
667 vst1q_s32( psDelDec->sAR2_Q14[ j - 1 ], tmp1_s32x4 );
668 n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) );
669 /* Output of allpass section */
670 tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 1 ] ), tmp2_s32x4 );
671 tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4, warping_Q16_s32x2 );
672 vst1q_s32( psDelDec->sAR2_Q14[ j + 0 ], tmp2_s32x4 );
673 AR_shp_Q28_s32x2 = vld1_s32( &AR_shp_Q28[ j ] );
674 n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) );
675 }
676 vst1q_s32( psDelDec->sAR2_Q14[ shapingLPCOrder - 1 ], tmp1_s32x4 );
677 n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) );
678 n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 1 ); /* Q11 -> Q12 */
679 n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_n_s32( vld1q_s32( psDelDec->LF_AR_Q14 ), silk_LSHIFT32( Tilt_Q14, 16 ) >> 1 ) ); /* Q12 */
680 n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 2 ); /* Q12 -> Q14 */
681 n_LF_Q14_s32x4 = vqdmulhq_n_s32( vld1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ] ), LF_shp_Q29 ); /* Q12 */
682 n_LF_Q14_s32x4 = vaddq_s32( n_LF_Q14_s32x4, vqdmulhq_n_s32( vld1q_s32( psDelDec->LF_AR_Q14 ), silk_LSHIFT32( LF_shp_Q14 >> 16 , 15 ) ) ); /* Q12 */
683 n_LF_Q14_s32x4 = vshlq_n_s32( n_LF_Q14_s32x4, 2 ); /* Q12 -> Q14 */
684
685 /* Input minus prediction plus noise feedback */
686 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
687 tmp1_s32x4 = vaddq_s32( n_AR_Q14_s32x4, n_LF_Q14_s32x4 ); /* Q14 */
688 tmp2_s32x4 = vaddq_s32( vdupq_n_s32( n_LTP_Q14 ), LPC_pred_Q14_s32x4 ); /* Q13 */
689 tmp1_s32x4 = vsubq_s32( tmp2_s32x4, tmp1_s32x4 ); /* Q13 */
690 tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 4 ); /* Q10 */
691 tmp1_s32x4 = vsubq_s32( vdupq_n_s32( x_Q10[ i ] ), tmp1_s32x4 ); /* residual error Q10 */
692
693 /* Flip sign depending on dither */
694 sign_s32x4 = vreinterpretq_s32_u32( vcltq_s32( Seed_s32x4, vdupq_n_s32( 0 ) ) );
695 tmp1_s32x4 = veorq_s32( tmp1_s32x4, sign_s32x4 );
696 tmp1_s32x4 = vsubq_s32( tmp1_s32x4, sign_s32x4 );
697 tmp1_s32x4 = vmaxq_s32( tmp1_s32x4, vdupq_n_s32( -( 31 << 10 ) ) );
698 tmp1_s32x4 = vminq_s32( tmp1_s32x4, vdupq_n_s32( 30 << 10 ) );
699 r_Q10_s16x4 = vmovn_s32( tmp1_s32x4 );
700
701 /* Find two quantization level candidates and measure their rate-distortion */
702 {
703 int16x4_t q1_Q10_s16x4 = vsub_s16( r_Q10_s16x4, vdup_n_s16( offset_Q10 ) );
704 int16x4_t q1_Q0_s16x4 = vshr_n_s16( q1_Q10_s16x4, 10 );
705 int16x4_t q2_Q10_s16x4;
706 int32x4_t rd1_Q10_s32x4, rd2_Q10_s32x4;
707 uint32x4_t t_u32x4;
708
709 if( Lambda_Q10 > 2048 ) {
710 /* For aggressive RDO, the bias becomes more than one pulse. */
711 const int rdo_offset = Lambda_Q10/2 - 512;
712 const uint16x4_t greaterThanRdo = vcgt_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) );
713 const uint16x4_t lessThanMinusRdo = vclt_s16( q1_Q10_s16x4, vdup_n_s16( -rdo_offset ) );
714 /* If Lambda_Q10 > 32767, then q1_Q0, q1_Q10 and q2_Q10 must change to 32-bit. */
715 silk_assert( Lambda_Q10 <= 32767 );
716
717 q1_Q0_s16x4 = vreinterpret_s16_u16( vclt_s16( q1_Q10_s16x4, vdup_n_s16( 0 ) ) );
718 q1_Q0_s16x4 = vbsl_s16( greaterThanRdo, vsub_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 );
719 q1_Q0_s16x4 = vbsl_s16( lessThanMinusRdo, vadd_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 );
720 q1_Q0_s16x4 = vshr_n_s16( q1_Q0_s16x4, 10 );
721 }
722 {
723 const uint16x4_t equal0_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( 0 ) );
724 const uint16x4_t equalMinus1_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) );
725 const uint16x4_t lessThanMinus1_u16x4 = vclt_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) );
726 int16x4_t tmp1_s16x4, tmp2_s16x4;
727
728 q1_Q10_s16x4 = vshl_n_s16( q1_Q0_s16x4, 10 );
729 tmp1_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 - QUANT_LEVEL_ADJUST_Q10 ) );
730 q1_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 + QUANT_LEVEL_ADJUST_Q10 ) );
731 q1_Q10_s16x4 = vbsl_s16( lessThanMinus1_u16x4, q1_Q10_s16x4, tmp1_s16x4 );
732 q1_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 ), q1_Q10_s16x4 );
733 q1_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 ) ), q1_Q10_s16x4 );
734 q2_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( 1024 ) );
735 q2_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 + 1024 - QUANT_LEVEL_ADJUST_Q10 ), q2_Q10_s16x4 );
736 q2_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 ), q2_Q10_s16x4 );
737 tmp1_s16x4 = q1_Q10_s16x4;
738 tmp2_s16x4 = q2_Q10_s16x4;
739 tmp1_s16x4 = vbsl_s16( vorr_u16( equalMinus1_u16x4, lessThanMinus1_u16x4 ), vneg_s16( tmp1_s16x4 ), tmp1_s16x4 );
740 tmp2_s16x4 = vbsl_s16( lessThanMinus1_u16x4, vneg_s16( tmp2_s16x4 ), tmp2_s16x4 );
741 rd1_Q10_s32x4 = vmull_s16( tmp1_s16x4, vdup_n_s16( Lambda_Q10 ) );
742 rd2_Q10_s32x4 = vmull_s16( tmp2_s16x4, vdup_n_s16( Lambda_Q10 ) );
743 }
744
745 rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q1_Q10_s16x4 );
746 rd1_Q10_s32x4 = vmlal_s16( rd1_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 );
747 rd1_Q10_s32x4 = vshrq_n_s32( rd1_Q10_s32x4, 10 );
748
749 rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q2_Q10_s16x4 );
750 rd2_Q10_s32x4 = vmlal_s16( rd2_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 );
751 rd2_Q10_s32x4 = vshrq_n_s32( rd2_Q10_s32x4, 10 );
752
753 tmp2_s32x4 = vld1q_s32( psDelDec->RD_Q10 );
754 tmp1_s32x4 = vaddq_s32( tmp2_s32x4, vminq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) );
755 tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vmaxq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) );
756 vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 );
757 vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 );
758 t_u32x4 = vcltq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 );
759 tmp1_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q1_Q10_s16x4 ), vmovl_s16( q2_Q10_s16x4 ) );
760 tmp2_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q2_Q10_s16x4 ), vmovl_s16( q1_Q10_s16x4 ) );
761 vst1q_s32( psSampleState[ 0 ].Q_Q10, tmp1_s32x4 );
762 vst1q_s32( psSampleState[ 1 ].Q_Q10, tmp2_s32x4 );
763 }
764
765 {
766 /* Update states for best quantization */
767 int32x4_t exc_Q14_s32x4, LPC_exc_Q14_s32x4, xq_Q14_s32x4, sLF_AR_shp_Q14_s32x4;
768
769 /* Quantized excitation */
770 exc_Q14_s32x4 = vshlq_n_s32( tmp1_s32x4, 4 );
771 exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 );
772 exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 );
773
774 /* Add predictions */
775 LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) );
776 xq_Q14_s32x4 = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 );
777
778 /* Update states */
779 tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) );
780 vst1q_s32( psSampleState[ 0 ].Diff_Q14, tmp1_s32x4 );
781 sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 );
782 vst1q_s32( psSampleState[ 0 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) );
783 vst1q_s32( psSampleState[ 0 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 );
784 vst1q_s32( psSampleState[ 0 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 );
785 vst1q_s32( psSampleState[ 0 ].xq_Q14, xq_Q14_s32x4 );
786
787 /* Quantized excitation */
788 exc_Q14_s32x4 = vshlq_n_s32( tmp2_s32x4, 4 );
789 exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 );
790 exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 );
791
792 /* Add predictions */
793 LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) );
794 xq_Q14_s32x4 = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 );
795
796 /* Update states */
797 tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) );
798 vst1q_s32( psSampleState[ 1 ].Diff_Q14, tmp1_s32x4 );
799 sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 );
800 vst1q_s32( psSampleState[ 1 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) );
801 vst1q_s32( psSampleState[ 1 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 );
802 vst1q_s32( psSampleState[ 1 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 );
803 vst1q_s32( psSampleState[ 1 ].xq_Q14, xq_Q14_s32x4 );
804 }
805
806 *smpl_buf_idx = *smpl_buf_idx ? ( *smpl_buf_idx - 1 ) : ( DECISION_DELAY - 1);
807 last_smple_idx = *smpl_buf_idx + decisionDelay + DECISION_DELAY;
808 if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
809 if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
810
811 /* Find winner */
812 RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ];
813 Winner_ind = 0;
814 for( k = 1; k < nStatesDelayedDecision; k++ ) {
815 if( psSampleState[ 0 ].RD_Q10[ k ] < RDmin_Q10 ) {
816 RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ k ];
817 Winner_ind = k;
818 }
819 }
820
821 /* Increase RD values of expired states */
822 {
823 uint32x4_t t_u32x4;
824 Winner_rand_state = psDelDec->RandState[ last_smple_idx ][ Winner_ind ];
825 t_u32x4 = vceqq_s32( vld1q_s32( psDelDec->RandState[ last_smple_idx ] ), vdupq_n_s32( Winner_rand_state ) );
826 t_u32x4 = vmvnq_u32( t_u32x4 );
827 t_u32x4 = vshrq_n_u32( t_u32x4, 5 );
828 tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].RD_Q10 );
829 tmp2_s32x4 = vld1q_s32( psSampleState[ 1 ].RD_Q10 );
830 tmp1_s32x4 = vaddq_s32( tmp1_s32x4, vreinterpretq_s32_u32( t_u32x4 ) );
831 tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vreinterpretq_s32_u32( t_u32x4 ) );
832 vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 );
833 vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 );
834
835 /* Find worst in first set and best in second set */
836 RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ];
837 RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ 0 ];
838 RDmax_ind = 0;
839 RDmin_ind = 0;
840 for( k = 1; k < nStatesDelayedDecision; k++ ) {
841 /* find worst in first set */
842 if( psSampleState[ 0 ].RD_Q10[ k ] > RDmax_Q10 ) {
843 RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ k ];
844 RDmax_ind = k;
845 }
846 /* find best in second set */
847 if( psSampleState[ 1 ].RD_Q10[ k ] < RDmin_Q10 ) {
848 RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ k ];
849 RDmin_ind = k;
850 }
851 }
852 }
853
854 /* Replace a state if best from second set outperforms worst in first set */
855 if( RDmin_Q10 < RDmax_Q10 ) {
856 opus_int32 (*ptr)[NEON_MAX_DEL_DEC_STATES] = psDelDec->RandState;
857 const int numOthers = (int)( ( sizeof( NSQ_del_decs_struct ) - sizeof( ( (NSQ_del_decs_struct *)0 )->sLPC_Q14 ) )
858 / ( NEON_MAX_DEL_DEC_STATES * sizeof( opus_int32 ) ) );
859 /* Only ( predictLPCOrder - 1 ) of sLPC_Q14 buffer need to be updated, though the first several */
860 /* useless sLPC_Q14[] will be different comparing with C when predictLPCOrder < NSQ_LPC_BUF_LENGTH. */
861 /* Here just update constant ( NSQ_LPC_BUF_LENGTH - 1 ) for simplicity. */
862 for( j = i + 1; j < i + NSQ_LPC_BUF_LENGTH; j++ ) {
863 psDelDec->sLPC_Q14[ j ][ RDmax_ind ] = psDelDec->sLPC_Q14[ j ][ RDmin_ind ];
864 }
865 for( j = 0; j < numOthers; j++ ) {
866 ptr[ j ][ RDmax_ind ] = ptr[ j ][ RDmin_ind ];
867 }
868
869 psSampleState[ 0 ].Q_Q10[ RDmax_ind ] = psSampleState[ 1 ].Q_Q10[ RDmin_ind ];
870 psSampleState[ 0 ].RD_Q10[ RDmax_ind ] = psSampleState[ 1 ].RD_Q10[ RDmin_ind ];
871 psSampleState[ 0 ].xq_Q14[ RDmax_ind ] = psSampleState[ 1 ].xq_Q14[ RDmin_ind ];
872 psSampleState[ 0 ].LF_AR_Q14[ RDmax_ind ] = psSampleState[ 1 ].LF_AR_Q14[ RDmin_ind ];
873 psSampleState[ 0 ].Diff_Q14[ RDmax_ind ] = psSampleState[ 1 ].Diff_Q14[ RDmin_ind ];
874 psSampleState[ 0 ].sLTP_shp_Q14[ RDmax_ind ] = psSampleState[ 1 ].sLTP_shp_Q14[ RDmin_ind ];
875 psSampleState[ 0 ].LPC_exc_Q14[ RDmax_ind ] = psSampleState[ 1 ].LPC_exc_Q14[ RDmin_ind ];
876 }
877
878 /* Write samples from winner to output and long-term filter states */
879 if( subfr > 0 || i >= decisionDelay ) {
880 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
881 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
882 silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
883 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
884 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDelDec->Pred_Q15[ last_smple_idx ][ Winner_ind ];
885 }
886 NSQ->sLTP_shp_buf_idx++;
887 NSQ->sLTP_buf_idx++;
888
889 /* Update states */
890 vst1q_s32( psDelDec->LF_AR_Q14, vld1q_s32( psSampleState[ 0 ].LF_AR_Q14 ) );
891 vst1q_s32( psDelDec->Diff_Q14, vld1q_s32( psSampleState[ 0 ].Diff_Q14 ) );
892 vst1q_s32( psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) );
893 vst1q_s32( psDelDec->Xq_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) );
894 tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].Q_Q10 );
895 vst1q_s32( psDelDec->Q_Q10[ *smpl_buf_idx ], tmp1_s32x4 );
896 vst1q_s32( psDelDec->Pred_Q15[ *smpl_buf_idx ], vshlq_n_s32( vld1q_s32( psSampleState[ 0 ].LPC_exc_Q14 ), 1 ) );
897 vst1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].sLTP_shp_Q14 ) );
898 tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 10 );
899 tmp1_s32x4 = vaddq_s32( vld1q_s32( psDelDec->Seed ), tmp1_s32x4 );
900 vst1q_s32( psDelDec->Seed, tmp1_s32x4 );
901 vst1q_s32( psDelDec->RandState[ *smpl_buf_idx ], tmp1_s32x4 );
902 vst1q_s32( psDelDec->RD_Q10, vld1q_s32( psSampleState[ 0 ].RD_Q10 ) );
903 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
904 }
905 /* Update LPC states */
906 silk_memcpy( psDelDec->sLPC_Q14[ 0 ], psDelDec->sLPC_Q14[ length ], NEON_MAX_DEL_DEC_STATES * NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
907
908 RESTORE_STACK;
909}
910
911static OPUS_INLINE void silk_SMULWB_8_neon(
912 const opus_int16 *a,
913 const int32x2_t b,
914 opus_int32 *o
915)
916{
917 const int16x8_t a_s16x8 = vld1q_s16( a );
918 int32x4_t o0_s32x4, o1_s32x4;
919
920 o0_s32x4 = vshll_n_s16( vget_low_s16( a_s16x8 ), 15 );
921 o1_s32x4 = vshll_n_s16( vget_high_s16( a_s16x8 ), 15 );
922 o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b, 0 );
923 o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b, 0 );
924 vst1q_s32( o, o0_s32x4 );
925 vst1q_s32( o + 4, o1_s32x4 );
926}
927
928/* Only works when ( b >= -65536 ) && ( b < 65536 ). */
929static OPUS_INLINE void silk_SMULWW_small_b_4_neon(
930 opus_int32 *a,
931 const int32x2_t b_s32x2)
932{
933 int32x4_t o_s32x4;
934
935 o_s32x4 = vld1q_s32( a );
936 o_s32x4 = vqdmulhq_lane_s32( o_s32x4, b_s32x2, 0 );
937 vst1q_s32( a, o_s32x4 );
938}
939
940/* Only works when ( b >= -65536 ) && ( b < 65536 ). */
941static OPUS_INLINE void silk_SMULWW_small_b_8_neon(
942 opus_int32 *a,
943 const int32x2_t b_s32x2
944)
945{
946 int32x4_t o0_s32x4, o1_s32x4;
947
948 o0_s32x4 = vld1q_s32( a );
949 o1_s32x4 = vld1q_s32( a + 4 );
950 o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b_s32x2, 0 );
951 o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b_s32x2, 0 );
952 vst1q_s32( a, o0_s32x4 );
953 vst1q_s32( a + 4, o1_s32x4 );
954}
955
956static OPUS_INLINE void silk_SMULWW_4_neon(
957 opus_int32 *a,
958 const int32x2_t b_s32x2)
959{
960 int32x4_t a_s32x4, o_s32x4;
961
962 a_s32x4 = vld1q_s32( a );
963 o_s32x4 = vqdmulhq_lane_s32( a_s32x4, b_s32x2, 0 );
964 o_s32x4 = vmlaq_lane_s32( o_s32x4, a_s32x4, b_s32x2, 1 );
965 vst1q_s32( a, o_s32x4 );
966}
967
968static OPUS_INLINE void silk_SMULWW_8_neon(
969 opus_int32 *a,
970 const int32x2_t b_s32x2
971)
972{
973 int32x4_t a0_s32x4, a1_s32x4, o0_s32x4, o1_s32x4;
974
975 a0_s32x4 = vld1q_s32( a );
976 a1_s32x4 = vld1q_s32( a + 4 );
977 o0_s32x4 = vqdmulhq_lane_s32( a0_s32x4, b_s32x2, 0 );
978 o1_s32x4 = vqdmulhq_lane_s32( a1_s32x4, b_s32x2, 0 );
979 o0_s32x4 = vmlaq_lane_s32( o0_s32x4, a0_s32x4, b_s32x2, 1 );
980 o1_s32x4 = vmlaq_lane_s32( o1_s32x4, a1_s32x4, b_s32x2, 1 );
981 vst1q_s32( a, o0_s32x4 );
982 vst1q_s32( a + 4, o1_s32x4 );
983}
984
985static OPUS_INLINE void silk_SMULWW_loop_neon(
986 const opus_int16 *a,
987 const opus_int32 b,
988 opus_int32 *o,
989 const opus_int loop_num
990)
991{
992 opus_int i;
993 int32x2_t b_s32x2;
994
995 b_s32x2 = vdup_n_s32( b );
996 for( i = 0; i < loop_num - 7; i += 8 ) {
997 silk_SMULWB_8_neon( a + i, b_s32x2, o + i );
998 }
999 for( ; i < loop_num; i++ ) {
1000 o[ i ] = silk_SMULWW( a[ i ], b );
1001 }
1002}
1003
1004static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon(
1005 const silk_encoder_state *psEncC, /* I Encoder State */
1006 silk_nsq_state *NSQ, /* I/O NSQ state */
1007 NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
1008 const opus_int16 x16[], /* I Input */
1009 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
1010 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
1011 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
1012 opus_int subfr, /* I Subframe number */
1013 const opus_int LTP_scale_Q14, /* I LTP state scaling */
1014 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
1015 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
1016 const opus_int signal_type, /* I Signal type */
1017 const opus_int decisionDelay /* I Decision delay */
1018)
1019{
1020 opus_int i, lag;
1021 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
1022
1023 lag = pitchL[ subfr ];
1024 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
1025 silk_assert( inv_gain_Q31 != 0 );
1026
1027 /* Scale input */
1028 inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
1029 silk_SMULWW_loop_neon( x16, inv_gain_Q26, x_sc_Q10, psEncC->subfr_length );
1030
1031 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
1032 if( NSQ->rewhite_flag ) {
1033 if( subfr == 0 ) {
1034 /* Do LTP downscaling */
1035 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
1036 }
1037 silk_SMULWW_loop_neon( sLTP + NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2, inv_gain_Q31, sLTP_Q15 + NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2, lag + LTP_ORDER / 2 );
1038 }
1039
1040 /* Adjust for changing gain */
1041 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
1042 int32x2_t gain_adj_Q16_s32x2;
1043 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
1044
1045 /* Scale long-term shaping state */
1046 if( ( gain_adj_Q16 >= -65536 ) && ( gain_adj_Q16 < 65536 ) ) {
1047 gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16, 15 ) );
1048 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) {
1049 silk_SMULWW_small_b_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 );
1050 }
1051 for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
1052 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
1053 }
1054
1055 /* Scale long-term prediction state */
1056 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
1057 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) {
1058 silk_SMULWW_small_b_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 );
1059 }
1060 for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
1061 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
1062 }
1063 }
1064
1065 /* Scale scalar states */
1066 silk_SMULWW_small_b_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 );
1067 silk_SMULWW_small_b_4_neon( psDelDec->Diff_Q14, gain_adj_Q16_s32x2 );
1068
1069 /* Scale short-term prediction and shaping states */
1070 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
1071 silk_SMULWW_small_b_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 );
1072 }
1073
1074 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
1075 silk_SMULWW_small_b_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 );
1076 }
1077
1078 for( i = 0; i < DECISION_DELAY; i++ ) {
1079 silk_SMULWW_small_b_4_neon( psDelDec->Pred_Q15[ i ], gain_adj_Q16_s32x2 );
1080 silk_SMULWW_small_b_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 );
1081 }
1082 } else {
1083 gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16 & 0x0000FFFF, 15 ) );
1084 gain_adj_Q16_s32x2 = vset_lane_s32( gain_adj_Q16 >> 16, gain_adj_Q16_s32x2, 1 );
1085 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) {
1086 silk_SMULWW_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 );
1087 }
1088 for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
1089 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
1090 }
1091
1092 /* Scale long-term prediction state */
1093 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
1094 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) {
1095 silk_SMULWW_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 );
1096 }
1097 for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
1098 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
1099 }
1100 }
1101
1102 /* Scale scalar states */
1103 silk_SMULWW_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 );
1104 silk_SMULWW_4_neon( psDelDec->Diff_Q14, gain_adj_Q16_s32x2 );
1105
1106 /* Scale short-term prediction and shaping states */
1107 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
1108 silk_SMULWW_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 );
1109 }
1110
1111 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
1112 silk_SMULWW_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 );
1113 }
1114
1115 for( i = 0; i < DECISION_DELAY; i++ ) {
1116 silk_SMULWW_4_neon( psDelDec->Pred_Q15[ i ], gain_adj_Q16_s32x2 );
1117 silk_SMULWW_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 );
1118 }
1119 }
1120
1121 /* Save inverse gain */
1122 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
1123 }
1124}
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c
new file mode 100644
index 0000000000..9642529973
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c
@@ -0,0 +1,112 @@
1/***********************************************************************
2Copyright (C) 2014 Vidyo
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#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <arm_neon.h>
32#include "main.h"
33#include "stack_alloc.h"
34#include "NSQ.h"
35#include "celt/cpu_support.h"
36#include "celt/arm/armcpu.h"
37
38opus_int32 silk_noise_shape_quantizer_short_prediction_neon(const opus_int32 *buf32, const opus_int32 *coef32, opus_int order)
39{
40 int32x4_t coef0 = vld1q_s32(coef32);
41 int32x4_t coef1 = vld1q_s32(coef32 + 4);
42 int32x4_t coef2 = vld1q_s32(coef32 + 8);
43 int32x4_t coef3 = vld1q_s32(coef32 + 12);
44
45 int32x4_t a0 = vld1q_s32(buf32 - 15);
46 int32x4_t a1 = vld1q_s32(buf32 - 11);
47 int32x4_t a2 = vld1q_s32(buf32 - 7);
48 int32x4_t a3 = vld1q_s32(buf32 - 3);
49
50 int32x4_t b0 = vqdmulhq_s32(coef0, a0);
51 int32x4_t b1 = vqdmulhq_s32(coef1, a1);
52 int32x4_t b2 = vqdmulhq_s32(coef2, a2);
53 int32x4_t b3 = vqdmulhq_s32(coef3, a3);
54
55 int32x4_t c0 = vaddq_s32(b0, b1);
56 int32x4_t c1 = vaddq_s32(b2, b3);
57
58 int32x4_t d = vaddq_s32(c0, c1);
59
60 int64x2_t e = vpaddlq_s32(d);
61
62 int64x1_t f = vadd_s64(vget_low_s64(e), vget_high_s64(e));
63
64 opus_int32 out = vget_lane_s32(vreinterpret_s32_s64(f), 0);
65
66 out += silk_RSHIFT( order, 1 );
67
68 return out;
69}
70
71
72opus_int32 silk_NSQ_noise_shape_feedback_loop_neon(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order)
73{
74 opus_int32 out;
75 if (order == 8)
76 {
77 int32x4_t a00 = vdupq_n_s32(data0[0]);
78 int32x4_t a01 = vld1q_s32(data1); /* data1[0] ... [3] */
79
80 int32x4_t a0 = vextq_s32 (a00, a01, 3); /* data0[0] data1[0] ...[2] */
81 int32x4_t a1 = vld1q_s32(data1 + 3); /* data1[3] ... [6] */
82
83 /*TODO: Convert these once in advance instead of once per sample, like
84 silk_noise_shape_quantizer_short_prediction_neon() does.*/
85 int16x8_t coef16 = vld1q_s16(coef);
86 int32x4_t coef0 = vmovl_s16(vget_low_s16(coef16));
87 int32x4_t coef1 = vmovl_s16(vget_high_s16(coef16));
88
89 /*This is not bit-exact with the C version, since we do not drop the
90 lower 16 bits of each multiply, but wait until the end to truncate
91 precision. This is an encoder-specific calculation (and unlike
92 silk_noise_shape_quantizer_short_prediction_neon(), is not meant to
93 simulate what the decoder will do). We still could use vqdmulhq_s32()
94 like silk_noise_shape_quantizer_short_prediction_neon() and save
95 half the multiplies, but the speed difference is not large, since we
96 then need two extra adds.*/
97 int64x2_t b0 = vmull_s32(vget_low_s32(a0), vget_low_s32(coef0));
98 int64x2_t b1 = vmlal_s32(b0, vget_high_s32(a0), vget_high_s32(coef0));
99 int64x2_t b2 = vmlal_s32(b1, vget_low_s32(a1), vget_low_s32(coef1));
100 int64x2_t b3 = vmlal_s32(b2, vget_high_s32(a1), vget_high_s32(coef1));
101
102 int64x1_t c = vadd_s64(vget_low_s64(b3), vget_high_s64(b3));
103 int64x1_t cS = vrshr_n_s64(c, 15);
104 int32x2_t d = vreinterpret_s32_s64(cS);
105
106 out = vget_lane_s32(d, 0);
107 vst1q_s32(data1, a0);
108 vst1q_s32(data1 + 4, a1);
109 return out;
110 }
111 return silk_NSQ_noise_shape_feedback_loop_c(data0, data1, coef, order);
112}
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h
new file mode 100644
index 0000000000..b31d9442d6
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h
@@ -0,0 +1,114 @@
1/***********************************************************************
2Copyright (C) 2014 Vidyo
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 SILK_NSQ_NEON_H
28#define SILK_NSQ_NEON_H
29
30#include "cpu_support.h"
31#include "SigProc_FIX.h"
32
33#undef silk_short_prediction_create_arch_coef
34/* For vectorized calc, reverse a_Q12 coefs, convert to 32-bit, and shift for vqdmulhq_s32. */
35static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon(opus_int32 *out, const opus_int16 *in, opus_int order)
36{
37 out[15] = silk_LSHIFT32(in[0], 15);
38 out[14] = silk_LSHIFT32(in[1], 15);
39 out[13] = silk_LSHIFT32(in[2], 15);
40 out[12] = silk_LSHIFT32(in[3], 15);
41 out[11] = silk_LSHIFT32(in[4], 15);
42 out[10] = silk_LSHIFT32(in[5], 15);
43 out[9] = silk_LSHIFT32(in[6], 15);
44 out[8] = silk_LSHIFT32(in[7], 15);
45 out[7] = silk_LSHIFT32(in[8], 15);
46 out[6] = silk_LSHIFT32(in[9], 15);
47
48 if (order == 16)
49 {
50 out[5] = silk_LSHIFT32(in[10], 15);
51 out[4] = silk_LSHIFT32(in[11], 15);
52 out[3] = silk_LSHIFT32(in[12], 15);
53 out[2] = silk_LSHIFT32(in[13], 15);
54 out[1] = silk_LSHIFT32(in[14], 15);
55 out[0] = silk_LSHIFT32(in[15], 15);
56 }
57 else
58 {
59 out[5] = 0;
60 out[4] = 0;
61 out[3] = 0;
62 out[2] = 0;
63 out[1] = 0;
64 out[0] = 0;
65 }
66}
67
68#if defined(OPUS_ARM_PRESUME_NEON_INTR)
69
70#define silk_short_prediction_create_arch_coef(out, in, order) \
71 (silk_short_prediction_create_arch_coef_neon(out, in, order))
72
73#elif defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
74
75#define silk_short_prediction_create_arch_coef(out, in, order) \
76 do { if (arch == OPUS_ARCH_ARM_NEON) { silk_short_prediction_create_arch_coef_neon(out, in, order); } } while (0)
77
78#endif
79
80opus_int32 silk_noise_shape_quantizer_short_prediction_neon(const opus_int32 *buf32, const opus_int32 *coef32, opus_int order);
81
82opus_int32 silk_NSQ_noise_shape_feedback_loop_neon(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order);
83
84#if defined(OPUS_ARM_PRESUME_NEON_INTR)
85#undef silk_noise_shape_quantizer_short_prediction
86#define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) \
87 ((void)arch,silk_noise_shape_quantizer_short_prediction_neon(in, coefRev, order))
88
89#undef silk_NSQ_noise_shape_feedback_loop
90#define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) ((void)arch,silk_NSQ_noise_shape_feedback_loop_neon(data0, data1, coef, order))
91
92#elif defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
93
94/* silk_noise_shape_quantizer_short_prediction implementations take different parameters based on arch
95 (coef vs. coefRev) so can't use the usual IMPL table implementation */
96#undef silk_noise_shape_quantizer_short_prediction
97#define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) \
98 (arch == OPUS_ARCH_ARM_NEON ? \
99 silk_noise_shape_quantizer_short_prediction_neon(in, coefRev, order) : \
100 silk_noise_shape_quantizer_short_prediction_c(in, coef, order))
101
102extern opus_int32
103 (*const SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[OPUS_ARCHMASK+1])(
104 const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef,
105 opus_int order);
106
107#undef silk_NSQ_noise_shape_feedback_loop
108#define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) \
109 (SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[(arch)&OPUS_ARCHMASK](data0, data1, \
110 coef, order))
111
112#endif
113
114#endif /* SILK_NSQ_NEON_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c b/lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c
new file mode 100644
index 0000000000..0b9bfec2ca
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c
@@ -0,0 +1,123 @@
1/***********************************************************************
2Copyright (C) 2014 Vidyo
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#ifdef HAVE_CONFIG_H
28# include "config.h"
29#endif
30
31#include "main_FIX.h"
32#include "NSQ.h"
33#include "SigProc_FIX.h"
34
35#if defined(OPUS_HAVE_RTCD)
36
37# if (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \
38 !defined(OPUS_ARM_PRESUME_NEON_INTR))
39
40void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK + 1])(
41 const opus_int16 *in, /* I input signal */
42 const opus_int32 *B_Q28, /* I MA coefficients [3] */
43 const opus_int32 *A_Q28, /* I AR coefficients [2] */
44 opus_int32 *S, /* I/O State vector [4] */
45 opus_int16 *out, /* O output signal */
46 const opus_int32 len /* I signal length (must be even) */
47) = {
48 silk_biquad_alt_stride2_c, /* ARMv4 */
49 silk_biquad_alt_stride2_c, /* EDSP */
50 silk_biquad_alt_stride2_c, /* Media */
51 silk_biquad_alt_stride2_neon, /* Neon */
52};
53
54opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK + 1])( /* O Returns inverse prediction gain in energy domain, Q30 */
55 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
56 const opus_int order /* I Prediction order */
57) = {
58 silk_LPC_inverse_pred_gain_c, /* ARMv4 */
59 silk_LPC_inverse_pred_gain_c, /* EDSP */
60 silk_LPC_inverse_pred_gain_c, /* Media */
61 silk_LPC_inverse_pred_gain_neon, /* Neon */
62};
63
64void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
65 const silk_encoder_state *psEncC, /* I Encoder State */
66 silk_nsq_state *NSQ, /* I/O NSQ state */
67 SideInfoIndices *psIndices, /* I/O Quantization Indices */
68 const opus_int16 x16[], /* I Input */
69 opus_int8 pulses[], /* O Quantized pulse signal */
70 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
71 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
72 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
73 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
74 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
75 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
76 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
77 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
78 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
79 const opus_int LTP_scale_Q14 /* I LTP state scaling */
80) = {
81 silk_NSQ_del_dec_c, /* ARMv4 */
82 silk_NSQ_del_dec_c, /* EDSP */
83 silk_NSQ_del_dec_c, /* Media */
84 silk_NSQ_del_dec_neon, /* Neon */
85};
86
87/*There is no table for silk_noise_shape_quantizer_short_prediction because the
88 NEON version takes different parameters than the C version.
89 Instead RTCD is done via if statements at the call sites.
90 See NSQ_neon.h for details.*/
91
92opus_int32
93 (*const SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[OPUS_ARCHMASK+1])(
94 const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef,
95 opus_int order) = {
96 silk_NSQ_noise_shape_feedback_loop_c, /* ARMv4 */
97 silk_NSQ_noise_shape_feedback_loop_c, /* EDSP */
98 silk_NSQ_noise_shape_feedback_loop_c, /* Media */
99 silk_NSQ_noise_shape_feedback_loop_neon, /* NEON */
100};
101
102# endif
103
104# if defined(FIXED_POINT) && \
105 defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
106
107void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK + 1])(
108 opus_int32 *corr, /* O Result [order + 1] */
109 opus_int *scale, /* O Scaling of the correlation vector */
110 const opus_int16 *input, /* I Input data to correlate */
111 const opus_int warping_Q16, /* I Warping coefficient */
112 const opus_int length, /* I Length of input */
113 const opus_int order /* I Correlation order (even) */
114) = {
115 silk_warped_autocorrelation_FIX_c, /* ARMv4 */
116 silk_warped_autocorrelation_FIX_c, /* EDSP */
117 silk_warped_autocorrelation_FIX_c, /* Media */
118 silk_warped_autocorrelation_FIX_neon, /* Neon */
119};
120
121# endif
122
123#endif /* OPUS_HAVE_RTCD */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_arm.h b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_arm.h
new file mode 100644
index 0000000000..66ea9f43dd
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_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_BIQUAD_ALT_ARM_H
29# define SILK_BIQUAD_ALT_ARM_H
30
31# include "celt/arm/armcpu.h"
32
33# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
34void silk_biquad_alt_stride2_neon(
35 const opus_int16 *in, /* I input signal */
36 const opus_int32 *B_Q28, /* I MA coefficients [3] */
37 const opus_int32 *A_Q28, /* I AR coefficients [2] */
38 opus_int32 *S, /* I/O State vector [4] */
39 opus_int16 *out, /* O output signal */
40 const opus_int32 len /* I signal length (must be even) */
41);
42
43# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
44# define OVERRIDE_silk_biquad_alt_stride2 (1)
45# define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), PRESUME_NEON(silk_biquad_alt_stride2)(in, B_Q28, A_Q28, S, out, len))
46# endif
47# endif
48
49# if !defined(OVERRIDE_silk_biquad_alt_stride2)
50/*Is run-time CPU detection enabled on this platform?*/
51# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
52extern void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK+1])(
53 const opus_int16 *in, /* I input signal */
54 const opus_int32 *B_Q28, /* I MA coefficients [3] */
55 const opus_int32 *A_Q28, /* I AR coefficients [2] */
56 opus_int32 *S, /* I/O State vector [4] */
57 opus_int16 *out, /* O output signal */
58 const opus_int32 len /* I signal length (must be even) */
59 );
60# define OVERRIDE_silk_biquad_alt_stride2 (1)
61# define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((*SILK_BIQUAD_ALT_STRIDE2_IMPL[(arch)&OPUS_ARCHMASK])(in, B_Q28, A_Q28, S, out, len))
62# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
63# define OVERRIDE_silk_biquad_alt_stride2 (1)
64# define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), silk_biquad_alt_stride2_neon(in, B_Q28, A_Q28, S, out, len))
65# endif
66# endif
67
68#endif /* end SILK_BIQUAD_ALT_ARM_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c
new file mode 100644
index 0000000000..9715733185
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c
@@ -0,0 +1,156 @@
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#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# include "stack_alloc.h"
36#endif
37#include "SigProc_FIX.h"
38
39static inline void silk_biquad_alt_stride2_kernel( const int32x4_t A_L_s32x4, const int32x4_t A_U_s32x4, const int32x4_t B_Q28_s32x4, const int32x2_t t_s32x2, const int32x4_t in_s32x4, int32x4_t *S_s32x4, int32x2_t *out32_Q14_s32x2 )
40{
41 int32x4_t t_s32x4, out32_Q14_s32x4;
42
43 *out32_Q14_s32x2 = vadd_s32( vget_low_s32( *S_s32x4 ), t_s32x2 ); /* silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} ) */
44 *S_s32x4 = vcombine_s32( vget_high_s32( *S_s32x4 ), vdup_n_s32( 0 ) ); /* S{0,1} = S{2,3}; S{2,3} = 0; */
45 *out32_Q14_s32x2 = vshl_n_s32( *out32_Q14_s32x2, 2 ); /* out32_Q14_{0,1} = silk_LSHIFT( silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} ), 2 ); */
46 out32_Q14_s32x4 = vcombine_s32( *out32_Q14_s32x2, *out32_Q14_s32x2 ); /* out32_Q14_{0,1,0,1} */
47 t_s32x4 = vqdmulhq_s32( out32_Q14_s32x4, A_L_s32x4 ); /* silk_SMULWB( out32_Q14_{0,1,0,1}, A{0,0,1,1}_L_Q28 ) */
48 *S_s32x4 = vrsraq_n_s32( *S_s32x4, t_s32x4, 14 ); /* S{0,1} = S{2,3} + silk_RSHIFT_ROUND(); S{2,3} = silk_RSHIFT_ROUND(); */
49 t_s32x4 = vqdmulhq_s32( out32_Q14_s32x4, A_U_s32x4 ); /* silk_SMULWB( out32_Q14_{0,1,0,1}, A{0,0,1,1}_U_Q28 ) */
50 *S_s32x4 = vaddq_s32( *S_s32x4, t_s32x4 ); /* S0 = silk_SMLAWB( S{0,1,2,3}, out32_Q14_{0,1,0,1}, A{0,0,1,1}_U_Q28 ); */
51 t_s32x4 = vqdmulhq_s32( in_s32x4, B_Q28_s32x4 ); /* silk_SMULWB( B_Q28[ {1,1,2,2} ], in{0,1,0,1} ) */
52 *S_s32x4 = vaddq_s32( *S_s32x4, t_s32x4 ); /* S0 = silk_SMLAWB( S0, B_Q28[ {1,1,2,2} ], in{0,1,0,1} ); */
53}
54
55void silk_biquad_alt_stride2_neon(
56 const opus_int16 *in, /* I input signal */
57 const opus_int32 *B_Q28, /* I MA coefficients [3] */
58 const opus_int32 *A_Q28, /* I AR coefficients [2] */
59 opus_int32 *S, /* I/O State vector [4] */
60 opus_int16 *out, /* O output signal */
61 const opus_int32 len /* I signal length (must be even) */
62)
63{
64 /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
65 opus_int k = 0;
66 const int32x2_t offset_s32x2 = vdup_n_s32( (1<<14) - 1 );
67 const int32x4_t offset_s32x4 = vcombine_s32( offset_s32x2, offset_s32x2 );
68 int16x4_t in_s16x4 = vdup_n_s16( 0 );
69 int16x4_t out_s16x4;
70 int32x2_t A_Q28_s32x2, A_L_s32x2, A_U_s32x2, B_Q28_s32x2, t_s32x2;
71 int32x4_t A_L_s32x4, A_U_s32x4, B_Q28_s32x4, S_s32x4, out32_Q14_s32x4;
72 int32x2x2_t t0_s32x2x2, t1_s32x2x2, t2_s32x2x2, S_s32x2x2;
73
74#ifdef OPUS_CHECK_ASM
75 opus_int32 S_c[ 4 ];
76 VARDECL( opus_int16, out_c );
77 SAVE_STACK;
78 ALLOC( out_c, 2 * len, opus_int16 );
79
80 silk_memcpy( &S_c, S, sizeof( S_c ) );
81 silk_biquad_alt_stride2_c( in, B_Q28, A_Q28, S_c, out_c, len );
82#endif
83
84 /* Negate A_Q28 values and split in two parts */
85 A_Q28_s32x2 = vld1_s32( A_Q28 );
86 A_Q28_s32x2 = vneg_s32( A_Q28_s32x2 );
87 A_L_s32x2 = vshl_n_s32( A_Q28_s32x2, 18 ); /* ( -A_Q28[] & 0x00003FFF ) << 18 */
88 A_L_s32x2 = vreinterpret_s32_u32( vshr_n_u32( vreinterpret_u32_s32( A_L_s32x2 ), 3 ) ); /* ( -A_Q28[] & 0x00003FFF ) << 15 */
89 A_U_s32x2 = vshr_n_s32( A_Q28_s32x2, 14 ); /* silk_RSHIFT( -A_Q28[], 14 ) */
90 A_U_s32x2 = vshl_n_s32( A_U_s32x2, 16 ); /* silk_RSHIFT( -A_Q28[], 14 ) << 16 (Clip two leading bits to conform to C function.) */
91 A_U_s32x2 = vshr_n_s32( A_U_s32x2, 1 ); /* silk_RSHIFT( -A_Q28[], 14 ) << 15 */
92
93 B_Q28_s32x2 = vld1_s32( B_Q28 );
94 t_s32x2 = vld1_s32( B_Q28 + 1 );
95 t0_s32x2x2 = vzip_s32( A_L_s32x2, A_L_s32x2 );
96 t1_s32x2x2 = vzip_s32( A_U_s32x2, A_U_s32x2 );
97 t2_s32x2x2 = vzip_s32( t_s32x2, t_s32x2 );
98 A_L_s32x4 = vcombine_s32( t0_s32x2x2.val[ 0 ], t0_s32x2x2.val[ 1 ] ); /* A{0,0,1,1}_L_Q28 */
99 A_U_s32x4 = vcombine_s32( t1_s32x2x2.val[ 0 ], t1_s32x2x2.val[ 1 ] ); /* A{0,0,1,1}_U_Q28 */
100 B_Q28_s32x4 = vcombine_s32( t2_s32x2x2.val[ 0 ], t2_s32x2x2.val[ 1 ] ); /* B_Q28[ {1,1,2,2} ] */
101 S_s32x4 = vld1q_s32( S ); /* S0 = S[ 0 ]; S3 = S[ 3 ]; */
102 S_s32x2x2 = vtrn_s32( vget_low_s32( S_s32x4 ), vget_high_s32( S_s32x4 ) ); /* S2 = S[ 1 ]; S1 = S[ 2 ]; */
103 S_s32x4 = vcombine_s32( S_s32x2x2.val[ 0 ], S_s32x2x2.val[ 1 ] );
104
105 for( ; k < len - 1; k += 2 ) {
106 int32x4_t in_s32x4[ 2 ], t_s32x4;
107 int32x2_t out32_Q14_s32x2[ 2 ];
108
109 /* S[ 2 * i + 0 ], S[ 2 * i + 1 ], S[ 2 * i + 2 ], S[ 2 * i + 3 ]: Q12 */
110 in_s16x4 = vld1_s16( &in[ 2 * k ] ); /* in{0,1,2,3} = in[ 2 * k + {0,1,2,3} ]; */
111 in_s32x4[ 0 ] = vshll_n_s16( in_s16x4, 15 ); /* in{0,1,2,3} << 15 */
112 t_s32x4 = vqdmulhq_lane_s32( in_s32x4[ 0 ], B_Q28_s32x2, 0 ); /* silk_SMULWB( B_Q28[ 0 ], in{0,1,2,3} ) */
113 in_s32x4[ 1 ] = vcombine_s32( vget_high_s32( in_s32x4[ 0 ] ), vget_high_s32( in_s32x4[ 0 ] ) ); /* in{2,3,2,3} << 15 */
114 in_s32x4[ 0 ] = vcombine_s32( vget_low_s32 ( in_s32x4[ 0 ] ), vget_low_s32 ( in_s32x4[ 0 ] ) ); /* in{0,1,0,1} << 15 */
115 silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, vget_low_s32 ( t_s32x4 ), in_s32x4[ 0 ], &S_s32x4, &out32_Q14_s32x2[ 0 ] );
116 silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, vget_high_s32( t_s32x4 ), in_s32x4[ 1 ], &S_s32x4, &out32_Q14_s32x2[ 1 ] );
117
118 /* Scale back to Q0 and saturate */
119 out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2[ 0 ], out32_Q14_s32x2[ 1 ] ); /* out32_Q14_{0,1,2,3} */
120 out32_Q14_s32x4 = vaddq_s32( out32_Q14_s32x4, offset_s32x4 ); /* out32_Q14_{0,1,2,3} + (1<<14) - 1 */
121 out_s16x4 = vqshrn_n_s32( out32_Q14_s32x4, 14 ); /* (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,2,3} + (1<<14) - 1, 14 ) ) */
122 vst1_s16( &out[ 2 * k ], out_s16x4 ); /* out[ 2 * k + {0,1,2,3} ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,2,3} + (1<<14) - 1, 14 ) ); */
123 }
124
125 /* Process leftover. */
126 if( k < len ) {
127 int32x4_t in_s32x4;
128 int32x2_t out32_Q14_s32x2;
129
130 /* S[ 2 * i + 0 ], S[ 2 * i + 1 ]: Q12 */
131 in_s16x4 = vld1_lane_s16( &in[ 2 * k + 0 ], in_s16x4, 0 ); /* in{0,1} = in[ 2 * k + {0,1} ]; */
132 in_s16x4 = vld1_lane_s16( &in[ 2 * k + 1 ], in_s16x4, 1 ); /* in{0,1} = in[ 2 * k + {0,1} ]; */
133 in_s32x4 = vshll_n_s16( in_s16x4, 15 ); /* in{0,1} << 15 */
134 t_s32x2 = vqdmulh_lane_s32( vget_low_s32( in_s32x4 ), B_Q28_s32x2, 0 ); /* silk_SMULWB( B_Q28[ 0 ], in{0,1} ) */
135 in_s32x4 = vcombine_s32( vget_low_s32( in_s32x4 ), vget_low_s32( in_s32x4 ) ); /* in{0,1,0,1} << 15 */
136 silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, t_s32x2, in_s32x4, &S_s32x4, &out32_Q14_s32x2 );
137
138 /* Scale back to Q0 and saturate */
139 out32_Q14_s32x2 = vadd_s32( out32_Q14_s32x2, offset_s32x2 ); /* out32_Q14_{0,1} + (1<<14) - 1 */
140 out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2, out32_Q14_s32x2 ); /* out32_Q14_{0,1,0,1} + (1<<14) - 1 */
141 out_s16x4 = vqshrn_n_s32( out32_Q14_s32x4, 14 ); /* (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,0,1} + (1<<14) - 1, 14 ) ) */
142 vst1_lane_s16( &out[ 2 * k + 0 ], out_s16x4, 0 ); /* out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_0 + (1<<14) - 1, 14 ) ); */
143 vst1_lane_s16( &out[ 2 * k + 1 ], out_s16x4, 1 ); /* out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_1 + (1<<14) - 1, 14 ) ); */
144 }
145
146 vst1q_lane_s32( &S[ 0 ], S_s32x4, 0 ); /* S[ 0 ] = S0; */
147 vst1q_lane_s32( &S[ 1 ], S_s32x4, 2 ); /* S[ 1 ] = S2; */
148 vst1q_lane_s32( &S[ 2 ], S_s32x4, 1 ); /* S[ 2 ] = S1; */
149 vst1q_lane_s32( &S[ 3 ], S_s32x4, 3 ); /* S[ 3 ] = S3; */
150
151#ifdef OPUS_CHECK_ASM
152 silk_assert( !memcmp( S_c, S, sizeof( S_c ) ) );
153 silk_assert( !memcmp( out_c, out, 2 * len * sizeof( opus_int16 ) ) );
154 RESTORE_STACK;
155#endif
156}
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h b/lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h
new file mode 100644
index 0000000000..ed030413c5
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h
@@ -0,0 +1,39 @@
1/***********************************************************************
2Copyright (C) 2015 Vidyo
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_MACROS_ARM64_H
29#define SILK_MACROS_ARM64_H
30
31#include <arm_neon.h>
32
33#undef silk_ADD_SAT32
34#define silk_ADD_SAT32(a, b) (vqadds_s32((a), (b)))
35
36#undef silk_SUB_SAT32
37#define silk_SUB_SAT32(a, b) (vqsubs_s32((a), (b)))
38
39#endif /* SILK_MACROS_ARM64_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h
index 3f30e97288..877eb18dd5 100644
--- a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h
+++ b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h
@@ -28,6 +28,11 @@ POSSIBILITY OF SUCH DAMAGE.
28#ifndef SILK_MACROS_ARMv4_H 28#ifndef SILK_MACROS_ARMv4_H
29#define SILK_MACROS_ARMv4_H 29#define SILK_MACROS_ARMv4_H
30 30
31/* This macro only avoids the undefined behaviour from a left shift of
32 a negative value. It should only be used in macros that can't include
33 SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */
34#define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b)))
35
31/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ 36/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
32#undef silk_SMULWB 37#undef silk_SMULWB
33static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b) 38static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b)
@@ -38,7 +43,7 @@ static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b)
38 "#silk_SMULWB\n\t" 43 "#silk_SMULWB\n\t"
39 "smull %0, %1, %2, %3\n\t" 44 "smull %0, %1, %2, %3\n\t"
40 : "=&r"(rd_lo), "=&r"(rd_hi) 45 : "=&r"(rd_lo), "=&r"(rd_hi)
41 : "%r"(a), "r"(b<<16) 46 : "%r"(a), "r"(SAFE_SHL(b,16))
42 ); 47 );
43 return rd_hi; 48 return rd_hi;
44} 49}
@@ -80,7 +85,7 @@ static OPUS_INLINE opus_int32 silk_SMULWW_armv4(opus_int32 a, opus_int32 b)
80 : "=&r"(rd_lo), "=&r"(rd_hi) 85 : "=&r"(rd_lo), "=&r"(rd_hi)
81 : "%r"(a), "r"(b) 86 : "%r"(a), "r"(b)
82 ); 87 );
83 return (rd_hi<<16)+(rd_lo>>16); 88 return SAFE_SHL(rd_hi,16)+(rd_lo>>16);
84} 89}
85#define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b)) 90#define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b))
86 91
@@ -96,8 +101,10 @@ static OPUS_INLINE opus_int32 silk_SMLAWW_armv4(opus_int32 a, opus_int32 b,
96 : "=&r"(rd_lo), "=&r"(rd_hi) 101 : "=&r"(rd_lo), "=&r"(rd_hi)
97 : "%r"(b), "r"(c) 102 : "%r"(b), "r"(c)
98 ); 103 );
99 return a+(rd_hi<<16)+(rd_lo>>16); 104 return a+SAFE_SHL(rd_hi,16)+(rd_lo>>16);
100} 105}
101#define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c)) 106#define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c))
102 107
108#undef SAFE_SHL
109
103#endif /* SILK_MACROS_ARMv4_H */ 110#endif /* SILK_MACROS_ARMv4_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h
index aad4117e46..b14ec65ddb 100644
--- a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h
+++ b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h
@@ -29,6 +29,11 @@ POSSIBILITY OF SUCH DAMAGE.
29#ifndef SILK_MACROS_ARMv5E_H 29#ifndef SILK_MACROS_ARMv5E_H
30#define SILK_MACROS_ARMv5E_H 30#define SILK_MACROS_ARMv5E_H
31 31
32/* This macro only avoids the undefined behaviour from a left shift of
33 a negative value. It should only be used in macros that can't include
34 SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */
35#define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b)))
36
32/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ 37/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
33#undef silk_SMULWB 38#undef silk_SMULWB
34static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b) 39static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b)
@@ -190,7 +195,7 @@ static OPUS_INLINE opus_int32 silk_CLZ16_armv5(opus_int16 in16)
190 "#silk_CLZ16\n\t" 195 "#silk_CLZ16\n\t"
191 "clz %0, %1;\n" 196 "clz %0, %1;\n"
192 : "=r"(res) 197 : "=r"(res)
193 : "r"(in16<<16|0x8000) 198 : "r"(SAFE_SHL(in16,16)|0x8000)
194 ); 199 );
195 return res; 200 return res;
196} 201}
@@ -210,4 +215,6 @@ static OPUS_INLINE opus_int32 silk_CLZ32_armv5(opus_int32 in32)
210} 215}
211#define silk_CLZ32(in32) (silk_CLZ32_armv5(in32)) 216#define silk_CLZ32(in32) (silk_CLZ32_armv5(in32))
212 217
218#undef SAFE_SHL
219
213#endif /* SILK_MACROS_ARMv5E_H */ 220#endif /* SILK_MACROS_ARMv5E_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/biquad_alt.c b/lib/rbcodec/codecs/libopus/silk/biquad_alt.c
new file mode 100644
index 0000000000..54566a43c0
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/biquad_alt.c
@@ -0,0 +1,121 @@
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 * silk_biquad_alt.c *
30 * *
31 * Second order ARMA filter *
32 * Can handle slowly varying filter coefficients *
33 * */
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#include "SigProc_FIX.h"
40
41/* Second order ARMA filter, alternative implementation */
42void silk_biquad_alt_stride1(
43 const opus_int16 *in, /* I input signal */
44 const opus_int32 *B_Q28, /* I MA coefficients [3] */
45 const opus_int32 *A_Q28, /* I AR coefficients [2] */
46 opus_int32 *S, /* I/O State vector [2] */
47 opus_int16 *out, /* O output signal */
48 const opus_int32 len /* I signal length (must be even) */
49)
50{
51 /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
52 opus_int k;
53 opus_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14;
54
55 /* Negate A_Q28 values and split in two parts */
56 A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */
57 A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */
58 A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */
59 A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */
60
61 for( k = 0; k < len; k++ ) {
62 /* S[ 0 ], S[ 1 ]: Q12 */
63 inval = in[ k ];
64 out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 );
65
66 S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 );
67 S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 );
68 S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval);
69
70 S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A1_L_Q28 ), 14 );
71 S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 );
72 S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval );
73
74 /* Scale back to Q0 and saturate */
75 out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );
76 }
77}
78
79void silk_biquad_alt_stride2_c(
80 const opus_int16 *in, /* I input signal */
81 const opus_int32 *B_Q28, /* I MA coefficients [3] */
82 const opus_int32 *A_Q28, /* I AR coefficients [2] */
83 opus_int32 *S, /* I/O State vector [4] */
84 opus_int16 *out, /* O output signal */
85 const opus_int32 len /* I signal length (must be even) */
86)
87{
88 /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
89 opus_int k;
90 opus_int32 A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14[ 2 ];
91
92 /* Negate A_Q28 values and split in two parts */
93 A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */
94 A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */
95 A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */
96 A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */
97
98 for( k = 0; k < len; k++ ) {
99 /* S[ 0 ], S[ 1 ], S[ 2 ], S[ 3 ]: Q12 */
100 out32_Q14[ 0 ] = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], in[ 2 * k + 0 ] ), 2 );
101 out32_Q14[ 1 ] = silk_LSHIFT( silk_SMLAWB( S[ 2 ], B_Q28[ 0 ], in[ 2 * k + 1 ] ), 2 );
102
103 S[ 0 ] = S[ 1 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A0_L_Q28 ), 14 );
104 S[ 2 ] = S[ 3 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A0_L_Q28 ), 14 );
105 S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14[ 0 ], A0_U_Q28 );
106 S[ 2 ] = silk_SMLAWB( S[ 2 ], out32_Q14[ 1 ], A0_U_Q28 );
107 S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], in[ 2 * k + 0 ] );
108 S[ 2 ] = silk_SMLAWB( S[ 2 ], B_Q28[ 1 ], in[ 2 * k + 1 ] );
109
110 S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A1_L_Q28 ), 14 );
111 S[ 3 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A1_L_Q28 ), 14 );
112 S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14[ 0 ], A1_U_Q28 );
113 S[ 3 ] = silk_SMLAWB( S[ 3 ], out32_Q14[ 1 ], A1_U_Q28 );
114 S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], in[ 2 * k + 0 ] );
115 S[ 3 ] = silk_SMLAWB( S[ 3 ], B_Q28[ 2 ], in[ 2 * k + 1 ] );
116
117 /* Scale back to Q0 and saturate */
118 out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 0 ] + (1<<14) - 1, 14 ) );
119 out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 1 ] + (1<<14) - 1, 14 ) );
120 }
121}
diff --git a/lib/rbcodec/codecs/libopus/silk/bwexpander.c b/lib/rbcodec/codecs/libopus/silk/bwexpander.c
index 2eb4456695..afa97907ec 100644
--- a/lib/rbcodec/codecs/libopus/silk/bwexpander.c
+++ b/lib/rbcodec/codecs/libopus/silk/bwexpander.c
@@ -45,7 +45,7 @@ void silk_bwexpander(
45 /* Bias in silk_SMULWB can lead to unstable filters */ 45 /* Bias in silk_SMULWB can lead to unstable filters */
46 for( i = 0; i < d - 1; i++ ) { 46 for( i = 0; i < d - 1; i++ ) {
47 ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 ); 47 ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 );
48 chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); 48 chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
49 } 49 }
50 ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 ); 50 ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 );
51} 51}
diff --git a/lib/rbcodec/codecs/libopus/silk/check_control_input.c b/lib/rbcodec/codecs/libopus/silk/check_control_input.c
new file mode 100644
index 0000000000..739fb01f1e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/check_control_input.c
@@ -0,0 +1,106 @@
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.h"
33#include "control.h"
34#include "errors.h"
35
36/* Check encoder control struct */
37opus_int check_control_input(
38 silk_EncControlStruct *encControl /* I Control structure */
39)
40{
41 celt_assert( encControl != NULL );
42
43 if( ( ( encControl->API_sampleRate != 8000 ) &&
44 ( encControl->API_sampleRate != 12000 ) &&
45 ( encControl->API_sampleRate != 16000 ) &&
46 ( encControl->API_sampleRate != 24000 ) &&
47 ( encControl->API_sampleRate != 32000 ) &&
48 ( encControl->API_sampleRate != 44100 ) &&
49 ( encControl->API_sampleRate != 48000 ) ) ||
50 ( ( encControl->desiredInternalSampleRate != 8000 ) &&
51 ( encControl->desiredInternalSampleRate != 12000 ) &&
52 ( encControl->desiredInternalSampleRate != 16000 ) ) ||
53 ( ( encControl->maxInternalSampleRate != 8000 ) &&
54 ( encControl->maxInternalSampleRate != 12000 ) &&
55 ( encControl->maxInternalSampleRate != 16000 ) ) ||
56 ( ( encControl->minInternalSampleRate != 8000 ) &&
57 ( encControl->minInternalSampleRate != 12000 ) &&
58 ( encControl->minInternalSampleRate != 16000 ) ) ||
59 ( encControl->minInternalSampleRate > encControl->desiredInternalSampleRate ) ||
60 ( encControl->maxInternalSampleRate < encControl->desiredInternalSampleRate ) ||
61 ( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) {
62 celt_assert( 0 );
63 return SILK_ENC_FS_NOT_SUPPORTED;
64 }
65 if( encControl->payloadSize_ms != 10 &&
66 encControl->payloadSize_ms != 20 &&
67 encControl->payloadSize_ms != 40 &&
68 encControl->payloadSize_ms != 60 ) {
69 celt_assert( 0 );
70 return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
71 }
72 if( encControl->packetLossPercentage < 0 || encControl->packetLossPercentage > 100 ) {
73 celt_assert( 0 );
74 return SILK_ENC_INVALID_LOSS_RATE;
75 }
76 if( encControl->useDTX < 0 || encControl->useDTX > 1 ) {
77 celt_assert( 0 );
78 return SILK_ENC_INVALID_DTX_SETTING;
79 }
80 if( encControl->useCBR < 0 || encControl->useCBR > 1 ) {
81 celt_assert( 0 );
82 return SILK_ENC_INVALID_CBR_SETTING;
83 }
84 if( encControl->useInBandFEC < 0 || encControl->useInBandFEC > 1 ) {
85 celt_assert( 0 );
86 return SILK_ENC_INVALID_INBAND_FEC_SETTING;
87 }
88 if( encControl->nChannelsAPI < 1 || encControl->nChannelsAPI > ENCODER_NUM_CHANNELS ) {
89 celt_assert( 0 );
90 return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
91 }
92 if( encControl->nChannelsInternal < 1 || encControl->nChannelsInternal > ENCODER_NUM_CHANNELS ) {
93 celt_assert( 0 );
94 return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
95 }
96 if( encControl->nChannelsInternal > encControl->nChannelsAPI ) {
97 celt_assert( 0 );
98 return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
99 }
100 if( encControl->complexity < 0 || encControl->complexity > 10 ) {
101 celt_assert( 0 );
102 return SILK_ENC_INVALID_COMPLEXITY_SETTING;
103 }
104
105 return SILK_NO_ERROR;
106}
diff --git a/lib/rbcodec/codecs/libopus/silk/code_signs.c b/lib/rbcodec/codecs/libopus/silk/code_signs.c
index 6ac25cb389..dfd1dca9a1 100644
--- a/lib/rbcodec/codecs/libopus/silk/code_signs.c
+++ b/lib/rbcodec/codecs/libopus/silk/code_signs.c
@@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
37#define silk_enc_map(a) ( silk_RSHIFT( (a), 15 ) + 1 ) 37#define silk_enc_map(a) ( silk_RSHIFT( (a), 15 ) + 1 )
38#define silk_dec_map(a) ( silk_LSHIFT( (a), 1 ) - 1 ) 38#define silk_dec_map(a) ( silk_LSHIFT( (a), 1 ) - 1 )
39 39
40#if 0
41/* Encodes signs of excitation */ 40/* Encodes signs of excitation */
42void silk_encode_signs( 41void silk_encode_signs(
43 ec_enc *psRangeEnc, /* I/O Compressor data structure */ 42 ec_enc *psRangeEnc, /* I/O Compressor data structure */
@@ -71,7 +70,6 @@ void silk_encode_signs(
71 q_ptr += SHELL_CODEC_FRAME_LENGTH; 70 q_ptr += SHELL_CODEC_FRAME_LENGTH;
72 } 71 }
73} 72}
74#endif
75 73
76/* Decodes signs of excitation */ 74/* Decodes signs of excitation */
77void silk_decode_signs( 75void silk_decode_signs(
diff --git a/lib/rbcodec/codecs/libopus/silk/control.h b/lib/rbcodec/codecs/libopus/silk/control.h
index 747e5426a0..b76ec33cd6 100644
--- a/lib/rbcodec/codecs/libopus/silk/control.h
+++ b/lib/rbcodec/codecs/libopus/silk/control.h
@@ -77,6 +77,9 @@ typedef struct {
77 /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */ 77 /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */
78 opus_int useInBandFEC; 78 opus_int useInBandFEC;
79 79
80 /* I: Flag to actually code in-band Forward Error Correction (FEC) in the current packet; 0/1 */
81 opus_int LBRR_coded;
82
80 /* I: Flag to enable discontinuous transmission (DTX); 0/1 */ 83 /* I: Flag to enable discontinuous transmission (DTX); 0/1 */
81 opus_int useDTX; 84 opus_int useDTX;
82 85
@@ -110,6 +113,11 @@ typedef struct {
110 /* O: Tells the Opus encoder we're ready to switch */ 113 /* O: Tells the Opus encoder we're ready to switch */
111 opus_int switchReady; 114 opus_int switchReady;
112 115
116 /* O: SILK Signal type */
117 opus_int signalType;
118
119 /* O: SILK offset (dithering) */
120 opus_int offset;
113} silk_EncControlStruct; 121} silk_EncControlStruct;
114 122
115/**************************************************************************/ 123/**************************************************************************/
diff --git a/lib/rbcodec/codecs/libopus/silk/control_SNR.c b/lib/rbcodec/codecs/libopus/silk/control_SNR.c
new file mode 100644
index 0000000000..9a6db27543
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/control_SNR.c
@@ -0,0 +1,113 @@
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.h"
33#include "tuning_parameters.h"
34
35/* These tables hold SNR values divided by 21 (so they fit in 8 bits)
36 for different target bitrates spaced at 400 bps interval. The first
37 10 values are omitted (0-4 kb/s) because they're all zeros.
38 These tables were obtained by running different SNRs through the
39 encoder and measuring the active bitrate. */
40static const unsigned char silk_TargetRate_NB_21[117 - 10] = {
41 0, 15, 39, 52, 61, 68,
42 74, 79, 84, 88, 92, 95, 99,102,105,108,111,114,117,119,122,124,
43 126,129,131,133,135,137,139,142,143,145,147,149,151,153,155,157,
44 158,160,162,163,165,167,168,170,171,173,174,176,177,179,180,182,
45 183,185,186,187,189,190,192,193,194,196,197,199,200,201,203,204,
46 205,207,208,209,211,212,213,215,216,217,219,220,221,223,224,225,
47 227,228,230,231,232,234,235,236,238,239,241,242,243,245,246,248,
48 249,250,252,253,255
49};
50
51static const unsigned char silk_TargetRate_MB_21[165 - 10] = {
52 0, 0, 28, 43, 52, 59,
53 65, 70, 74, 78, 81, 85, 87, 90, 93, 95, 98,100,102,105,107,109,
54 111,113,115,116,118,120,122,123,125,127,128,130,131,133,134,136,
55 137,138,140,141,143,144,145,147,148,149,151,152,153,154,156,157,
56 158,159,160,162,163,164,165,166,167,168,169,171,172,173,174,175,
57 176,177,178,179,180,181,182,183,184,185,186,187,188,188,189,190,
58 191,192,193,194,195,196,197,198,199,200,201,202,203,203,204,205,
59 206,207,208,209,210,211,212,213,214,214,215,216,217,218,219,220,
60 221,222,223,224,224,225,226,227,228,229,230,231,232,233,234,235,
61 236,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,
62 251,252,253,254,255
63};
64
65static const unsigned char silk_TargetRate_WB_21[201 - 10] = {
66 0, 0, 0, 8, 29, 41,
67 49, 56, 62, 66, 70, 74, 77, 80, 83, 86, 88, 91, 93, 95, 97, 99,
68 101,103,105,107,108,110,112,113,115,116,118,119,121,122,123,125,
69 126,127,129,130,131,132,134,135,136,137,138,140,141,142,143,144,
70 145,146,147,148,149,150,151,152,153,154,156,157,158,159,159,160,
71 161,162,163,164,165,166,167,168,169,170,171,171,172,173,174,175,
72 176,177,177,178,179,180,181,181,182,183,184,185,185,186,187,188,
73 189,189,190,191,192,192,193,194,195,195,196,197,198,198,199,200,
74 200,201,202,203,203,204,205,206,206,207,208,209,209,210,211,211,
75 212,213,214,214,215,216,216,217,218,219,219,220,221,221,222,223,
76 224,224,225,226,226,227,228,229,229,230,231,232,232,233,234,234,
77 235,236,237,237,238,239,240,240,241,242,243,243,244,245,246,246,
78 247,248,249,249,250,251,252,253,255
79};
80
81/* Control SNR of redidual quantizer */
82opus_int silk_control_SNR(
83 silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
84 opus_int32 TargetRate_bps /* I Target max bitrate (bps) */
85)
86{
87 int id;
88 int bound;
89 const unsigned char *snr_table;
90
91 psEncC->TargetRate_bps = TargetRate_bps;
92 if( psEncC->nb_subfr == 2 ) {
93 TargetRate_bps -= 2000 + psEncC->fs_kHz/16;
94 }
95 if( psEncC->fs_kHz == 8 ) {
96 bound = sizeof(silk_TargetRate_NB_21);
97 snr_table = silk_TargetRate_NB_21;
98 } else if( psEncC->fs_kHz == 12 ) {
99 bound = sizeof(silk_TargetRate_MB_21);
100 snr_table = silk_TargetRate_MB_21;
101 } else {
102 bound = sizeof(silk_TargetRate_WB_21);
103 snr_table = silk_TargetRate_WB_21;
104 }
105 id = (TargetRate_bps+200)/400;
106 id = silk_min(id - 10, bound-1);
107 if( id <= 0 ) {
108 psEncC->SNR_dB_Q7 = 0;
109 } else {
110 psEncC->SNR_dB_Q7 = snr_table[id]*21;
111 }
112 return SILK_NO_ERROR;
113}
diff --git a/lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c b/lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c
new file mode 100644
index 0000000000..f6d22d8395
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c
@@ -0,0 +1,132 @@
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.h"
33#include "tuning_parameters.h"
34
35/* Control internal sampling rate */
36opus_int silk_control_audio_bandwidth(
37 silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
38 silk_EncControlStruct *encControl /* I Control structure */
39)
40{
41 opus_int fs_kHz;
42 opus_int orig_kHz;
43 opus_int32 fs_Hz;
44
45 orig_kHz = psEncC->fs_kHz;
46 /* Handle a bandwidth-switching reset where we need to be aware what the last sampling rate was. */
47 if( orig_kHz == 0 ) {
48 orig_kHz = psEncC->sLP.saved_fs_kHz;
49 }
50 fs_kHz = orig_kHz;
51 fs_Hz = silk_SMULBB( fs_kHz, 1000 );
52 if( fs_Hz == 0 ) {
53 /* Encoder has just been initialized */
54 fs_Hz = silk_min( psEncC->desiredInternal_fs_Hz, psEncC->API_fs_Hz );
55 fs_kHz = silk_DIV32_16( fs_Hz, 1000 );
56 } else if( fs_Hz > psEncC->API_fs_Hz || fs_Hz > psEncC->maxInternal_fs_Hz || fs_Hz < psEncC->minInternal_fs_Hz ) {
57 /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */
58 fs_Hz = psEncC->API_fs_Hz;
59 fs_Hz = silk_min( fs_Hz, psEncC->maxInternal_fs_Hz );
60 fs_Hz = silk_max( fs_Hz, psEncC->minInternal_fs_Hz );
61 fs_kHz = silk_DIV32_16( fs_Hz, 1000 );
62 } else {
63 /* State machine for the internal sampling rate switching */
64 if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) {
65 /* Stop transition phase */
66 psEncC->sLP.mode = 0;
67 }
68 if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) {
69 /* Check if we should switch down */
70 if( silk_SMULBB( orig_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz )
71 {
72 /* Switch down */
73 if( psEncC->sLP.mode == 0 ) {
74 /* New transition */
75 psEncC->sLP.transition_frame_no = TRANSITION_FRAMES;
76
77 /* Reset transition filter state */
78 silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );
79 }
80 if( encControl->opusCanSwitch ) {
81 /* Stop transition phase */
82 psEncC->sLP.mode = 0;
83
84 /* Switch to a lower sample frequency */
85 fs_kHz = orig_kHz == 16 ? 12 : 8;
86 } else {
87 if( psEncC->sLP.transition_frame_no <= 0 ) {
88 encControl->switchReady = 1;
89 /* Make room for redundancy */
90 encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
91 } else {
92 /* Direction: down (at double speed) */
93 psEncC->sLP.mode = -2;
94 }
95 }
96 }
97 else
98 /* Check if we should switch up */
99 if( silk_SMULBB( orig_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz )
100 {
101 /* Switch up */
102 if( encControl->opusCanSwitch ) {
103 /* Switch to a higher sample frequency */
104 fs_kHz = orig_kHz == 8 ? 12 : 16;
105
106 /* New transition */
107 psEncC->sLP.transition_frame_no = 0;
108
109 /* Reset transition filter state */
110 silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );
111
112 /* Direction: up */
113 psEncC->sLP.mode = 1;
114 } else {
115 if( psEncC->sLP.mode == 0 ) {
116 encControl->switchReady = 1;
117 /* Make room for redundancy */
118 encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
119 } else {
120 /* Direction: up */
121 psEncC->sLP.mode = 1;
122 }
123 }
124 } else {
125 if (psEncC->sLP.mode<0)
126 psEncC->sLP.mode = 1;
127 }
128 }
129 }
130
131 return fs_kHz;
132}
diff --git a/lib/rbcodec/codecs/libopus/silk/control_codec.c b/lib/rbcodec/codecs/libopus/silk/control_codec.c
new file mode 100644
index 0000000000..52aa8fded3
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/control_codec.c
@@ -0,0 +1,423 @@
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#ifdef FIXED_POINT
32#include "main_FIX.h"
33#define silk_encoder_state_Fxx silk_encoder_state_FIX
34#else
35#include "main_FLP.h"
36#define silk_encoder_state_Fxx silk_encoder_state_FLP
37#endif
38#include "stack_alloc.h"
39#include "tuning_parameters.h"
40#include "pitch_est_defines.h"
41
42static opus_int silk_setup_resamplers(
43 silk_encoder_state_Fxx *psEnc, /* I/O */
44 opus_int fs_kHz /* I */
45);
46
47static opus_int silk_setup_fs(
48 silk_encoder_state_Fxx *psEnc, /* I/O */
49 opus_int fs_kHz, /* I */
50 opus_int PacketSize_ms /* I */
51);
52
53static opus_int silk_setup_complexity(
54 silk_encoder_state *psEncC, /* I/O */
55 opus_int Complexity /* I */
56);
57
58static OPUS_INLINE opus_int silk_setup_LBRR(
59 silk_encoder_state *psEncC, /* I/O */
60 const silk_EncControlStruct *encControl /* I */
61);
62
63
64/* Control encoder */
65opus_int silk_control_encoder(
66 silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
67 silk_EncControlStruct *encControl, /* I Control structure */
68 const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
69 const opus_int channelNb, /* I Channel number */
70 const opus_int force_fs_kHz
71)
72{
73 opus_int fs_kHz, ret = 0;
74
75 psEnc->sCmn.useDTX = encControl->useDTX;
76 psEnc->sCmn.useCBR = encControl->useCBR;
77 psEnc->sCmn.API_fs_Hz = encControl->API_sampleRate;
78 psEnc->sCmn.maxInternal_fs_Hz = encControl->maxInternalSampleRate;
79 psEnc->sCmn.minInternal_fs_Hz = encControl->minInternalSampleRate;
80 psEnc->sCmn.desiredInternal_fs_Hz = encControl->desiredInternalSampleRate;
81 psEnc->sCmn.useInBandFEC = encControl->useInBandFEC;
82 psEnc->sCmn.nChannelsAPI = encControl->nChannelsAPI;
83 psEnc->sCmn.nChannelsInternal = encControl->nChannelsInternal;
84 psEnc->sCmn.allow_bandwidth_switch = allow_bw_switch;
85 psEnc->sCmn.channelNb = channelNb;
86
87 if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) {
88 if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) {
89 /* Change in API sampling rate in the middle of encoding a packet */
90 ret += silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz );
91 }
92 return ret;
93 }
94
95 /* Beyond this point we know that there are no previously coded frames in the payload buffer */
96
97 /********************************************/
98 /* Determine internal sampling rate */
99 /********************************************/
100 fs_kHz = silk_control_audio_bandwidth( &psEnc->sCmn, encControl );
101 if( force_fs_kHz ) {
102 fs_kHz = force_fs_kHz;
103 }
104 /********************************************/
105 /* Prepare resampler and buffered data */
106 /********************************************/
107 ret += silk_setup_resamplers( psEnc, fs_kHz );
108
109 /********************************************/
110 /* Set internal sampling frequency */
111 /********************************************/
112 ret += silk_setup_fs( psEnc, fs_kHz, encControl->payloadSize_ms );
113
114 /********************************************/
115 /* Set encoding complexity */
116 /********************************************/
117 ret += silk_setup_complexity( &psEnc->sCmn, encControl->complexity );
118
119 /********************************************/
120 /* Set packet loss rate measured by farend */
121 /********************************************/
122 psEnc->sCmn.PacketLoss_perc = encControl->packetLossPercentage;
123
124 /********************************************/
125 /* Set LBRR usage */
126 /********************************************/
127 ret += silk_setup_LBRR( &psEnc->sCmn, encControl );
128
129 psEnc->sCmn.controlled_since_last_payload = 1;
130
131 return ret;
132}
133
134static opus_int silk_setup_resamplers(
135 silk_encoder_state_Fxx *psEnc, /* I/O */
136 opus_int fs_kHz /* I */
137)
138{
139 opus_int ret = SILK_NO_ERROR;
140 SAVE_STACK;
141
142 if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz )
143 {
144 if( psEnc->sCmn.fs_kHz == 0 ) {
145 /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
146 ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 );
147 } else {
148 VARDECL( opus_int16, x_buf_API_fs_Hz );
149 VARDECL( silk_resampler_state_struct, temp_resampler_state );
150#ifdef FIXED_POINT
151 opus_int16 *x_bufFIX = psEnc->x_buf;
152#else
153 VARDECL( opus_int16, x_bufFIX );
154 opus_int32 new_buf_samples;
155#endif
156 opus_int32 api_buf_samples;
157 opus_int32 old_buf_samples;
158 opus_int32 buf_length_ms;
159
160 buf_length_ms = silk_LSHIFT( psEnc->sCmn.nb_subfr * 5, 1 ) + LA_SHAPE_MS;
161 old_buf_samples = buf_length_ms * psEnc->sCmn.fs_kHz;
162
163#ifndef FIXED_POINT
164 new_buf_samples = buf_length_ms * fs_kHz;
165 ALLOC( x_bufFIX, silk_max( old_buf_samples, new_buf_samples ),
166 opus_int16 );
167 silk_float2short_array( x_bufFIX, psEnc->x_buf, old_buf_samples );
168#endif
169
170 /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */
171 ALLOC( temp_resampler_state, 1, silk_resampler_state_struct );
172 ret += silk_resampler_init( temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 );
173
174 /* Calculate number of samples to temporarily upsample */
175 api_buf_samples = buf_length_ms * silk_DIV32_16( psEnc->sCmn.API_fs_Hz, 1000 );
176
177 /* Temporary resampling of x_buf data to API_fs_Hz */
178 ALLOC( x_buf_API_fs_Hz, api_buf_samples, opus_int16 );
179 ret += silk_resampler( temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, old_buf_samples );
180
181 /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
182 ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 );
183
184 /* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */
185 ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, api_buf_samples );
186
187#ifndef FIXED_POINT
188 silk_short2float_array( psEnc->x_buf, x_bufFIX, new_buf_samples);
189#endif
190 }
191 }
192
193 psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz;
194
195 RESTORE_STACK;
196 return ret;
197}
198
199static opus_int silk_setup_fs(
200 silk_encoder_state_Fxx *psEnc, /* I/O */
201 opus_int fs_kHz, /* I */
202 opus_int PacketSize_ms /* I */
203)
204{
205 opus_int ret = SILK_NO_ERROR;
206
207 /* Set packet size */
208 if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) {
209 if( ( PacketSize_ms != 10 ) &&
210 ( PacketSize_ms != 20 ) &&
211 ( PacketSize_ms != 40 ) &&
212 ( PacketSize_ms != 60 ) ) {
213 ret = SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
214 }
215 if( PacketSize_ms <= 10 ) {
216 psEnc->sCmn.nFramesPerPacket = 1;
217 psEnc->sCmn.nb_subfr = PacketSize_ms == 10 ? 2 : 1;
218 psEnc->sCmn.frame_length = silk_SMULBB( PacketSize_ms, fs_kHz );
219 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );
220 if( psEnc->sCmn.fs_kHz == 8 ) {
221 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;
222 } else {
223 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;
224 }
225 } else {
226 psEnc->sCmn.nFramesPerPacket = silk_DIV32_16( PacketSize_ms, MAX_FRAME_LENGTH_MS );
227 psEnc->sCmn.nb_subfr = MAX_NB_SUBFR;
228 psEnc->sCmn.frame_length = silk_SMULBB( 20, fs_kHz );
229 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
230 if( psEnc->sCmn.fs_kHz == 8 ) {
231 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;
232 } else {
233 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF;
234 }
235 }
236 psEnc->sCmn.PacketSize_ms = PacketSize_ms;
237 psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */
238 }
239
240 /* Set internal sampling frequency */
241 celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
242 celt_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );
243 if( psEnc->sCmn.fs_kHz != fs_kHz ) {
244 /* reset part of the state */
245 silk_memset( &psEnc->sShape, 0, sizeof( psEnc->sShape ) );
246 silk_memset( &psEnc->sCmn.sNSQ, 0, sizeof( psEnc->sCmn.sNSQ ) );
247 silk_memset( psEnc->sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
248 silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) );
249 psEnc->sCmn.inputBufIx = 0;
250 psEnc->sCmn.nFramesEncoded = 0;
251 psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */
252
253 /* Initialize non-zero parameters */
254 psEnc->sCmn.prevLag = 100;
255 psEnc->sCmn.first_frame_after_reset = 1;
256 psEnc->sShape.LastGainIndex = 10;
257 psEnc->sCmn.sNSQ.lagPrev = 100;
258 psEnc->sCmn.sNSQ.prev_gain_Q16 = 65536;
259 psEnc->sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY;
260
261 psEnc->sCmn.fs_kHz = fs_kHz;
262 if( psEnc->sCmn.fs_kHz == 8 ) {
263 if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
264 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;
265 } else {
266 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;
267 }
268 } else {
269 if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
270 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF;
271 } else {
272 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;
273 }
274 }
275 if( psEnc->sCmn.fs_kHz == 8 || psEnc->sCmn.fs_kHz == 12 ) {
276 psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;
277 psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_NB_MB;
278 } else {
279 psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;
280 psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_WB;
281 }
282 psEnc->sCmn.subfr_length = SUB_FRAME_LENGTH_MS * fs_kHz;
283 psEnc->sCmn.frame_length = silk_SMULBB( psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );
284 psEnc->sCmn.ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz );
285 psEnc->sCmn.la_pitch = silk_SMULBB( LA_PITCH_MS, fs_kHz );
286 psEnc->sCmn.max_pitch_lag = silk_SMULBB( 18, fs_kHz );
287 if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
288 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
289 } else {
290 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );
291 }
292 if( psEnc->sCmn.fs_kHz == 16 ) {
293 psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF;
294 } else if( psEnc->sCmn.fs_kHz == 12 ) {
295 psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF;
296 } else {
297 psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
298 }
299 }
300
301 /* Check that settings are valid */
302 celt_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length );
303
304 return ret;
305}
306
307static opus_int silk_setup_complexity(
308 silk_encoder_state *psEncC, /* I/O */
309 opus_int Complexity /* I */
310)
311{
312 opus_int ret = 0;
313
314 /* Set encoding complexity */
315 celt_assert( Complexity >= 0 && Complexity <= 10 );
316 if( Complexity < 1 ) {
317 psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX;
318 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 );
319 psEncC->pitchEstimationLPCOrder = 6;
320 psEncC->shapingLPCOrder = 12;
321 psEncC->la_shape = 3 * psEncC->fs_kHz;
322 psEncC->nStatesDelayedDecision = 1;
323 psEncC->useInterpolatedNLSFs = 0;
324 psEncC->NLSF_MSVQ_Survivors = 2;
325 psEncC->warping_Q16 = 0;
326 } else if( Complexity < 2 ) {
327 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
328 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 );
329 psEncC->pitchEstimationLPCOrder = 8;
330 psEncC->shapingLPCOrder = 14;
331 psEncC->la_shape = 5 * psEncC->fs_kHz;
332 psEncC->nStatesDelayedDecision = 1;
333 psEncC->useInterpolatedNLSFs = 0;
334 psEncC->NLSF_MSVQ_Survivors = 3;
335 psEncC->warping_Q16 = 0;
336 } else if( Complexity < 3 ) {
337 psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX;
338 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 );
339 psEncC->pitchEstimationLPCOrder = 6;
340 psEncC->shapingLPCOrder = 12;
341 psEncC->la_shape = 3 * psEncC->fs_kHz;
342 psEncC->nStatesDelayedDecision = 2;
343 psEncC->useInterpolatedNLSFs = 0;
344 psEncC->NLSF_MSVQ_Survivors = 2;
345 psEncC->warping_Q16 = 0;
346 } else if( Complexity < 4 ) {
347 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
348 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 );
349 psEncC->pitchEstimationLPCOrder = 8;
350 psEncC->shapingLPCOrder = 14;
351 psEncC->la_shape = 5 * psEncC->fs_kHz;
352 psEncC->nStatesDelayedDecision = 2;
353 psEncC->useInterpolatedNLSFs = 0;
354 psEncC->NLSF_MSVQ_Survivors = 4;
355 psEncC->warping_Q16 = 0;
356 } else if( Complexity < 6 ) {
357 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
358 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.74, 16 );
359 psEncC->pitchEstimationLPCOrder = 10;
360 psEncC->shapingLPCOrder = 16;
361 psEncC->la_shape = 5 * psEncC->fs_kHz;
362 psEncC->nStatesDelayedDecision = 2;
363 psEncC->useInterpolatedNLSFs = 1;
364 psEncC->NLSF_MSVQ_Survivors = 6;
365 psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
366 } else if( Complexity < 8 ) {
367 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
368 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.72, 16 );
369 psEncC->pitchEstimationLPCOrder = 12;
370 psEncC->shapingLPCOrder = 20;
371 psEncC->la_shape = 5 * psEncC->fs_kHz;
372 psEncC->nStatesDelayedDecision = 3;
373 psEncC->useInterpolatedNLSFs = 1;
374 psEncC->NLSF_MSVQ_Survivors = 8;
375 psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
376 } else {
377 psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX;
378 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.7, 16 );
379 psEncC->pitchEstimationLPCOrder = 16;
380 psEncC->shapingLPCOrder = 24;
381 psEncC->la_shape = 5 * psEncC->fs_kHz;
382 psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES;
383 psEncC->useInterpolatedNLSFs = 1;
384 psEncC->NLSF_MSVQ_Survivors = 16;
385 psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
386 }
387
388 /* Do not allow higher pitch estimation LPC order than predict LPC order */
389 psEncC->pitchEstimationLPCOrder = silk_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder );
390 psEncC->shapeWinLength = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape;
391 psEncC->Complexity = Complexity;
392
393 celt_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );
394 celt_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER );
395 celt_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES );
396 celt_assert( psEncC->warping_Q16 <= 32767 );
397 celt_assert( psEncC->la_shape <= LA_SHAPE_MAX );
398 celt_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX );
399
400 return ret;
401}
402
403static OPUS_INLINE opus_int silk_setup_LBRR(
404 silk_encoder_state *psEncC, /* I/O */
405 const silk_EncControlStruct *encControl /* I */
406)
407{
408 opus_int LBRR_in_previous_packet, ret = SILK_NO_ERROR;
409
410 LBRR_in_previous_packet = psEncC->LBRR_enabled;
411 psEncC->LBRR_enabled = encControl->LBRR_coded;
412 if( psEncC->LBRR_enabled ) {
413 /* Set gain increase for coding LBRR excitation */
414 if( LBRR_in_previous_packet == 0 ) {
415 /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */
416 psEncC->LBRR_GainIncreases = 7;
417 } else {
418 psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 );
419 }
420 }
421
422 return ret;
423}
diff --git a/lib/rbcodec/codecs/libopus/silk/debug.c b/lib/rbcodec/codecs/libopus/silk/debug.c
new file mode 100644
index 0000000000..9253faf71b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/debug.c
@@ -0,0 +1,170 @@
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 "debug.h"
33#include "SigProc_FIX.h"
34
35#if SILK_TIC_TOC
36
37#ifdef _WIN32
38
39#if (defined(_WIN32) || defined(_WINCE))
40#include <windows.h> /* timer */
41#else /* Linux or Mac*/
42#include <sys/time.h>
43#endif
44
45unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/
46{
47 /* Returns a time counter in microsec */
48 /* the resolution is platform dependent */
49 /* but is typically 1.62 us resolution */
50 LARGE_INTEGER lpPerformanceCount;
51 LARGE_INTEGER lpFrequency;
52 QueryPerformanceCounter(&lpPerformanceCount);
53 QueryPerformanceFrequency(&lpFrequency);
54 return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart);
55}
56#else /* Linux or Mac*/
57unsigned long GetHighResolutionTime(void) /* O time in usec*/
58{
59 struct timeval tv;
60 gettimeofday(&tv, 0);
61 return((tv.tv_sec*1000000)+(tv.tv_usec));
62}
63#endif
64
65int silk_Timer_nTimers = 0;
66int silk_Timer_depth_ctr = 0;
67char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN];
68#ifdef WIN32
69LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX];
70#else
71unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX];
72#endif
73unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX];
74opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX];
75opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX];
76opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX];
77opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX];
78
79#ifdef WIN32
80void silk_TimerSave(char *file_name)
81{
82 if( silk_Timer_nTimers > 0 )
83 {
84 int k;
85 FILE *fp;
86 LARGE_INTEGER lpFrequency;
87 LARGE_INTEGER lpPerformanceCount1, lpPerformanceCount2;
88 int del = 0x7FFFFFFF;
89 double avg, sum_avg;
90 /* estimate overhead of calling performance counters */
91 for( k = 0; k < 1000; k++ ) {
92 QueryPerformanceCounter(&lpPerformanceCount1);
93 QueryPerformanceCounter(&lpPerformanceCount2);
94 lpPerformanceCount2.QuadPart -= lpPerformanceCount1.QuadPart;
95 if( (int)lpPerformanceCount2.LowPart < del )
96 del = lpPerformanceCount2.LowPart;
97 }
98 QueryPerformanceFrequency(&lpFrequency);
99 /* print results to file */
100 sum_avg = 0.0f;
101 for( k = 0; k < silk_Timer_nTimers; k++ ) {
102 if (silk_Timer_depth[k] == 0) {
103 sum_avg += (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart * silk_Timer_cnt[k];
104 }
105 }
106 fp = fopen(file_name, "w");
107 fprintf(fp, " min avg %% max count\n");
108 for( k = 0; k < silk_Timer_nTimers; k++ ) {
109 if (silk_Timer_depth[k] == 0) {
110 fprintf(fp, "%-28s", silk_Timer_tags[k]);
111 } else if (silk_Timer_depth[k] == 1) {
112 fprintf(fp, " %-27s", silk_Timer_tags[k]);
113 } else if (silk_Timer_depth[k] == 2) {
114 fprintf(fp, " %-26s", silk_Timer_tags[k]);
115 } else if (silk_Timer_depth[k] == 3) {
116 fprintf(fp, " %-25s", silk_Timer_tags[k]);
117 } else {
118 fprintf(fp, " %-24s", silk_Timer_tags[k]);
119 }
120 avg = (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart;
121 fprintf(fp, "%8.2f", (1e6 * (silk_max_64(silk_Timer_min[k] - del, 0))) / lpFrequency.QuadPart);
122 fprintf(fp, "%12.2f %6.2f", avg, 100.0 * avg / sum_avg * silk_Timer_cnt[k]);
123 fprintf(fp, "%12.2f", (1e6 * (silk_max_64(silk_Timer_max[k] - del, 0))) / lpFrequency.QuadPart);
124 fprintf(fp, "%10d\n", silk_Timer_cnt[k]);
125 }
126 fprintf(fp, " microseconds\n");
127 fclose(fp);
128 }
129}
130#else
131void silk_TimerSave(char *file_name)
132{
133 if( silk_Timer_nTimers > 0 )
134 {
135 int k;
136 FILE *fp;
137 /* print results to file */
138 fp = fopen(file_name, "w");
139 fprintf(fp, " min avg max count\n");
140 for( k = 0; k < silk_Timer_nTimers; k++ )
141 {
142 if (silk_Timer_depth[k] == 0) {
143 fprintf(fp, "%-28s", silk_Timer_tags[k]);
144 } else if (silk_Timer_depth[k] == 1) {
145 fprintf(fp, " %-27s", silk_Timer_tags[k]);
146 } else if (silk_Timer_depth[k] == 2) {
147 fprintf(fp, " %-26s", silk_Timer_tags[k]);
148 } else if (silk_Timer_depth[k] == 3) {
149 fprintf(fp, " %-25s", silk_Timer_tags[k]);
150 } else {
151 fprintf(fp, " %-24s", silk_Timer_tags[k]);
152 }
153 fprintf(fp, "%d ", silk_Timer_min[k]);
154 fprintf(fp, "%f ", (double)silk_Timer_sum[k] / (double)silk_Timer_cnt[k]);
155 fprintf(fp, "%d ", silk_Timer_max[k]);
156 fprintf(fp, "%10d\n", silk_Timer_cnt[k]);
157 }
158 fprintf(fp, " microseconds\n");
159 fclose(fp);
160 }
161}
162#endif
163
164#endif /* SILK_TIC_TOC */
165
166#if SILK_DEBUG
167FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ];
168int silk_debug_store_count = 0;
169#endif /* SILK_DEBUG */
170
diff --git a/lib/rbcodec/codecs/libopus/silk/debug.h b/lib/rbcodec/codecs/libopus/silk/debug.h
new file mode 100644
index 0000000000..6f68c1ca0f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/debug.h
@@ -0,0 +1,266 @@
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_DEBUG_H
29#define SILK_DEBUG_H
30
31#include "typedef.h"
32#include <stdio.h> /* file writing */
33#include <string.h> /* strcpy, strcmp */
34
35#ifdef __cplusplus
36extern "C"
37{
38#endif
39
40unsigned long GetHighResolutionTime(void); /* O time in usec*/
41
42/* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping
43 * intermediate signals from the codec.
44 */
45#define SILK_DEBUG 0
46
47/* Flag for using timers */
48#define SILK_TIC_TOC 0
49
50
51#if SILK_TIC_TOC
52
53#if (defined(_WIN32) || defined(_WINCE))
54#include <windows.h> /* timer */
55#else /* Linux or Mac*/
56#include <sys/time.h>
57#endif
58
59/*********************************/
60/* timer functions for profiling */
61/*********************************/
62/* example: */
63/* */
64/* TIC(LPC) */
65/* do_LPC(in_vec, order, acoef); // do LPC analysis */
66/* TOC(LPC) */
67/* */
68/* and call the following just before exiting (from main) */
69/* */
70/* silk_TimerSave("silk_TimingData.txt"); */
71/* */
72/* results are now in silk_TimingData.txt */
73
74void silk_TimerSave(char *file_name);
75
76/* max number of timers (in different locations) */
77#define silk_NUM_TIMERS_MAX 50
78/* max length of name tags in TIC(..), TOC(..) */
79#define silk_NUM_TIMERS_MAX_TAG_LEN 30
80
81extern int silk_Timer_nTimers;
82extern int silk_Timer_depth_ctr;
83extern char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN];
84#ifdef _WIN32
85extern LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX];
86#else
87extern unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX];
88#endif
89extern unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX];
90extern opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX];
91extern opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX];
92extern opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX];
93extern opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX];
94
95/* WARNING: TIC()/TOC can measure only up to 0.1 seconds at a time */
96#ifdef _WIN32
97#define TIC(TAG_NAME) { \
98 static int init = 0; \
99 static int ID = -1; \
100 if( init == 0 ) \
101 { \
102 int k; \
103 init = 1; \
104 for( k = 0; k < silk_Timer_nTimers; k++ ) { \
105 if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
106 ID = k; \
107 break; \
108 } \
109 } \
110 if (ID == -1) { \
111 ID = silk_Timer_nTimers; \
112 silk_Timer_nTimers++; \
113 silk_Timer_depth[ID] = silk_Timer_depth_ctr; \
114 strcpy(silk_Timer_tags[ID], #TAG_NAME); \
115 silk_Timer_cnt[ID] = 0; \
116 silk_Timer_sum[ID] = 0; \
117 silk_Timer_min[ID] = 0xFFFFFFFF; \
118 silk_Timer_max[ID] = 0; \
119 } \
120 } \
121 silk_Timer_depth_ctr++; \
122 QueryPerformanceCounter(&silk_Timer_start[ID]); \
123}
124#else
125#define TIC(TAG_NAME) { \
126 static int init = 0; \
127 static int ID = -1; \
128 if( init == 0 ) \
129 { \
130 int k; \
131 init = 1; \
132 for( k = 0; k < silk_Timer_nTimers; k++ ) { \
133 if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
134 ID = k; \
135 break; \
136 } \
137 } \
138 if (ID == -1) { \
139 ID = silk_Timer_nTimers; \
140 silk_Timer_nTimers++; \
141 silk_Timer_depth[ID] = silk_Timer_depth_ctr; \
142 strcpy(silk_Timer_tags[ID], #TAG_NAME); \
143 silk_Timer_cnt[ID] = 0; \
144 silk_Timer_sum[ID] = 0; \
145 silk_Timer_min[ID] = 0xFFFFFFFF; \
146 silk_Timer_max[ID] = 0; \
147 } \
148 } \
149 silk_Timer_depth_ctr++; \
150 silk_Timer_start[ID] = GetHighResolutionTime(); \
151}
152#endif
153
154#ifdef _WIN32
155#define TOC(TAG_NAME) { \
156 LARGE_INTEGER lpPerformanceCount; \
157 static int init = 0; \
158 static int ID = 0; \
159 if( init == 0 ) \
160 { \
161 int k; \
162 init = 1; \
163 for( k = 0; k < silk_Timer_nTimers; k++ ) { \
164 if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
165 ID = k; \
166 break; \
167 } \
168 } \
169 } \
170 QueryPerformanceCounter(&lpPerformanceCount); \
171 lpPerformanceCount.QuadPart -= silk_Timer_start[ID].QuadPart; \
172 if((lpPerformanceCount.QuadPart < 100000000) && \
173 (lpPerformanceCount.QuadPart >= 0)) { \
174 silk_Timer_cnt[ID]++; \
175 silk_Timer_sum[ID] += lpPerformanceCount.QuadPart; \
176 if( lpPerformanceCount.QuadPart > silk_Timer_max[ID] ) \
177 silk_Timer_max[ID] = lpPerformanceCount.QuadPart; \
178 if( lpPerformanceCount.QuadPart < silk_Timer_min[ID] ) \
179 silk_Timer_min[ID] = lpPerformanceCount.QuadPart; \
180 } \
181 silk_Timer_depth_ctr--; \
182}
183#else
184#define TOC(TAG_NAME) { \
185 unsigned long endTime; \
186 static int init = 0; \
187 static int ID = 0; \
188 if( init == 0 ) \
189 { \
190 int k; \
191 init = 1; \
192 for( k = 0; k < silk_Timer_nTimers; k++ ) { \
193 if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
194 ID = k; \
195 break; \
196 } \
197 } \
198 } \
199 endTime = GetHighResolutionTime(); \
200 endTime -= silk_Timer_start[ID]; \
201 if((endTime < 100000000) && \
202 (endTime >= 0)) { \
203 silk_Timer_cnt[ID]++; \
204 silk_Timer_sum[ID] += endTime; \
205 if( endTime > silk_Timer_max[ID] ) \
206 silk_Timer_max[ID] = endTime; \
207 if( endTime < silk_Timer_min[ID] ) \
208 silk_Timer_min[ID] = endTime; \
209 } \
210 silk_Timer_depth_ctr--; \
211}
212#endif
213
214#else /* SILK_TIC_TOC */
215
216/* define macros as empty strings */
217#define TIC(TAG_NAME)
218#define TOC(TAG_NAME)
219#define silk_TimerSave(FILE_NAME)
220
221#endif /* SILK_TIC_TOC */
222
223
224#if SILK_DEBUG
225/************************************/
226/* write data to file for debugging */
227/************************************/
228/* Example: DEBUG_STORE_DATA(testfile.pcm, &RIN[0], 160*sizeof(opus_int16)); */
229
230#define silk_NUM_STORES_MAX 100
231extern FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ];
232extern int silk_debug_store_count;
233
234/* Faster way of storing the data */
235#define DEBUG_STORE_DATA( FILE_NAME, DATA_PTR, N_BYTES ) { \
236 static opus_int init = 0, cnt = 0; \
237 static FILE **fp; \
238 if (init == 0) { \
239 init = 1; \
240 cnt = silk_debug_store_count++; \
241 silk_debug_store_fp[ cnt ] = fopen(#FILE_NAME, "wb"); \
242 } \
243 fwrite((DATA_PTR), (N_BYTES), 1, silk_debug_store_fp[ cnt ]); \
244}
245
246/* Call this at the end of main() */
247#define SILK_DEBUG_STORE_CLOSE_FILES { \
248 opus_int i; \
249 for( i = 0; i < silk_debug_store_count; i++ ) { \
250 fclose( silk_debug_store_fp[ i ] ); \
251 } \
252}
253
254#else /* SILK_DEBUG */
255
256/* define macros as empty strings */
257#define DEBUG_STORE_DATA(FILE_NAME, DATA_PTR, N_BYTES)
258#define SILK_DEBUG_STORE_CLOSE_FILES
259
260#endif /* SILK_DEBUG */
261
262#ifdef __cplusplus
263}
264#endif
265
266#endif /* SILK_DEBUG_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/dec_API.c b/lib/rbcodec/codecs/libopus/silk/dec_API.c
index 1087c6726a..7d5ca7fb9f 100644
--- a/lib/rbcodec/codecs/libopus/silk/dec_API.c
+++ b/lib/rbcodec/codecs/libopus/silk/dec_API.c
@@ -85,7 +85,8 @@ opus_int silk_Decode( /* O Returns error co
85 opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ 85 opus_int newPacketFlag, /* I Indicates first decoder call for this packet */
86 ec_dec *psRangeDec, /* I/O Compressor data structure */ 86 ec_dec *psRangeDec, /* I/O Compressor data structure */
87 opus_int16 *samplesOut, /* O Decoded output speech vector */ 87 opus_int16 *samplesOut, /* O Decoded output speech vector */
88 opus_int32 *nSamplesOut /* O Number of samples decoded */ 88 opus_int32 *nSamplesOut, /* O Number of samples decoded */
89 int arch /* I Run-time architecture */
89) 90)
90{ 91{
91 opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR; 92 opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR;
@@ -103,7 +104,7 @@ opus_int silk_Decode( /* O Returns error co
103 int delay_stack_alloc; 104 int delay_stack_alloc;
104 SAVE_STACK; 105 SAVE_STACK;
105 106
106 silk_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 ); 107 celt_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 );
107 108
108 /**********************************/ 109 /**********************************/
109 /* Test if first frame in payload */ 110 /* Test if first frame in payload */
@@ -142,13 +143,13 @@ opus_int silk_Decode( /* O Returns error co
142 channel_state[ n ].nFramesPerPacket = 3; 143 channel_state[ n ].nFramesPerPacket = 3;
143 channel_state[ n ].nb_subfr = 4; 144 channel_state[ n ].nb_subfr = 4;
144 } else { 145 } else {
145 silk_assert( 0 ); 146 celt_assert( 0 );
146 RESTORE_STACK; 147 RESTORE_STACK;
147 return SILK_DEC_INVALID_FRAME_SIZE; 148 return SILK_DEC_INVALID_FRAME_SIZE;
148 } 149 }
149 fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1; 150 fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1;
150 if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) { 151 if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) {
151 silk_assert( 0 ); 152 celt_assert( 0 );
152 RESTORE_STACK; 153 RESTORE_STACK;
153 return SILK_DEC_INVALID_SAMPLING_FREQUENCY; 154 return SILK_DEC_INVALID_SAMPLING_FREQUENCY;
154 } 155 }
@@ -296,7 +297,7 @@ opus_int silk_Decode( /* O Returns error co
296 } else { 297 } else {
297 condCoding = CODE_CONDITIONALLY; 298 condCoding = CODE_CONDITIONALLY;
298 } 299 }
299 ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding); 300 ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding, arch);
300 } else { 301 } else {
301 silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) ); 302 silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) );
302 } 303 }
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_core.c b/lib/rbcodec/codecs/libopus/silk/decode_core.c
index af68b75da9..1c352a6522 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_core.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_core.c
@@ -39,7 +39,8 @@ void silk_decode_core(
39 silk_decoder_state *psDec, /* I/O Decoder state */ 39 silk_decoder_state *psDec, /* I/O Decoder state */
40 silk_decoder_control *psDecCtrl, /* I Decoder control */ 40 silk_decoder_control *psDecCtrl, /* I Decoder control */
41 opus_int16 xq[], /* O Decoded speech */ 41 opus_int16 xq[], /* O Decoded speech */
42 const opus_int16 pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ 42 const opus_int16 pulses[ MAX_FRAME_LENGTH ], /* I Pulse signal */
43 int arch /* I Run-time architecture */
43) 44)
44{ 45{
45 opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType; 46 opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType;
@@ -140,14 +141,14 @@ void silk_decode_core(
140 if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) { 141 if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) {
141 /* Rewhiten with new A coefs */ 142 /* Rewhiten with new A coefs */
142 start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; 143 start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
143 silk_assert( start_idx > 0 ); 144 celt_assert( start_idx > 0 );
144 145
145 if( k == 2 ) { 146 if( k == 2 ) {
146 silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) ); 147 silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) );
147 } 148 }
148 149
149 silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ], 150 silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ],
150 A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order ); 151 A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order, arch );
151 152
152 /* After rewhitening the LTP state is unscaled */ 153 /* After rewhitening the LTP state is unscaled */
153 if( k == 0 ) { 154 if( k == 0 ) {
@@ -195,7 +196,7 @@ void silk_decode_core(
195 196
196 for( i = 0; i < psDec->subfr_length; i++ ) { 197 for( i = 0; i < psDec->subfr_length; i++ ) {
197 /* Short-term prediction */ 198 /* Short-term prediction */
198 silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); 199 celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
199 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 200 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
200 LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); 201 LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
201 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); 202 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] );
@@ -218,14 +219,12 @@ void silk_decode_core(
218 } 219 }
219 220
220 /* Add prediction to LPC excitation */ 221 /* Add prediction to LPC excitation */
221 sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( pres_Q14[ i ], LPC_pred_Q10, 4 ); 222 sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( pres_Q14[ i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) );
222 223
223 /* Scale with gain */ 224 /* Scale with gain */
224 pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) ); 225 pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) );
225 } 226 }
226 227
227 /* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */
228
229 /* Update LPC filter state */ 228 /* Update LPC filter state */
230 silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); 229 silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
231 pexc_Q14 += psDec->subfr_length; 230 pexc_Q14 += psDec->subfr_length;
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_frame.c b/lib/rbcodec/codecs/libopus/silk/decode_frame.c
index 6a7cffbbe0..e73825b267 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_frame.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_frame.c
@@ -42,7 +42,8 @@ opus_int silk_decode_frame(
42 opus_int16 pOut[], /* O Pointer to output speech frame */ 42 opus_int16 pOut[], /* O Pointer to output speech frame */
43 opus_int32 *pN, /* O Pointer to size of output frame */ 43 opus_int32 *pN, /* O Pointer to size of output frame */
44 opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ 44 opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */
45 opus_int condCoding /* I The type of conditional coding to use */ 45 opus_int condCoding, /* I The type of conditional coding to use */
46 int arch /* I Run-time architecture */
46) 47)
47{ 48{
48 VARDECL( silk_decoder_control, psDecCtrl ); 49 VARDECL( silk_decoder_control, psDecCtrl );
@@ -54,7 +55,7 @@ opus_int silk_decode_frame(
54 psDecCtrl->LTP_scale_Q14 = 0; 55 psDecCtrl->LTP_scale_Q14 = 0;
55 56
56 /* Safety checks */ 57 /* Safety checks */
57 silk_assert( L > 0 && L <= MAX_FRAME_LENGTH ); 58 celt_assert( L > 0 && L <= MAX_FRAME_LENGTH );
58 59
59 if( lostFlag == FLAG_DECODE_NORMAL || 60 if( lostFlag == FLAG_DECODE_NORMAL ||
60 ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) ) 61 ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) )
@@ -81,28 +82,29 @@ opus_int silk_decode_frame(
81 /********************************************************/ 82 /********************************************************/
82 /* Run inverse NSQ */ 83 /* Run inverse NSQ */
83 /********************************************************/ 84 /********************************************************/
84 silk_decode_core( psDec, psDecCtrl, pOut, pulses ); 85 silk_decode_core( psDec, psDecCtrl, pOut, pulses, arch );
85 86
86 /********************************************************/ 87 /********************************************************/
87 /* Update PLC state */ 88 /* Update PLC state */
88 /********************************************************/ 89 /********************************************************/
89 silk_PLC( psDec, psDecCtrl, pOut, 0 ); 90 silk_PLC( psDec, psDecCtrl, pOut, 0, arch );
90 91
91 psDec->lossCnt = 0; 92 psDec->lossCnt = 0;
92 psDec->prevSignalType = psDec->indices.signalType; 93 psDec->prevSignalType = psDec->indices.signalType;
93 silk_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 ); 94 celt_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 );
94 95
95 /* A frame has been decoded without errors */ 96 /* A frame has been decoded without errors */
96 psDec->first_frame_after_reset = 0; 97 psDec->first_frame_after_reset = 0;
97 } else { 98 } else {
98 /* Handle packet loss by extrapolation */ 99 /* Handle packet loss by extrapolation */
99 silk_PLC( psDec, psDecCtrl, pOut, 1 ); 100 psDec->indices.signalType = psDec->prevSignalType;
101 silk_PLC( psDec, psDecCtrl, pOut, 1, arch );
100 } 102 }
101 103
102 /*************************/ 104 /*************************/
103 /* Update output buffer. */ 105 /* Update output buffer. */
104 /*************************/ 106 /*************************/
105 silk_assert( psDec->ltp_mem_length >= psDec->frame_length ); 107 celt_assert( psDec->ltp_mem_length >= psDec->frame_length );
106 mv_len = psDec->ltp_mem_length - psDec->frame_length; 108 mv_len = psDec->ltp_mem_length - psDec->frame_length;
107 silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) ); 109 silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) );
108 silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) ); 110 silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) );
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_indices.c b/lib/rbcodec/codecs/libopus/silk/decode_indices.c
index 7afe5c26c1..0bb4a997a5 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_indices.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_indices.c
@@ -79,7 +79,7 @@ void silk_decode_indices(
79 /**********************/ 79 /**********************/
80 psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 ); 80 psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 );
81 silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] ); 81 silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] );
82 silk_assert( psDec->psNLSF_CB->order == psDec->LPC_order ); 82 celt_assert( psDec->psNLSF_CB->order == psDec->LPC_order );
83 for( i = 0; i < psDec->psNLSF_CB->order; i++ ) { 83 for( i = 0; i < psDec->psNLSF_CB->order; i++ ) {
84 Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); 84 Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
85 if( Ix == 0 ) { 85 if( Ix == 0 ) {
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_parameters.c b/lib/rbcodec/codecs/libopus/silk/decode_parameters.c
index e345b1dcef..a56a409858 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_parameters.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_parameters.c
@@ -52,7 +52,7 @@ void silk_decode_parameters(
52 silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB ); 52 silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB );
53 53
54 /* Convert NLSF parameters to AR prediction filter coefficients */ 54 /* Convert NLSF parameters to AR prediction filter coefficients */
55 silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order ); 55 silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order, psDec->arch );
56 56
57 /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ 57 /* If just reset, e.g., because internal Fs changed, do not allow interpolation */
58 /* improves the case of packet loss in the first frame after a switch */ 58 /* improves the case of packet loss in the first frame after a switch */
@@ -69,7 +69,7 @@ void silk_decode_parameters(
69 } 69 }
70 70
71 /* Convert NLSF parameters to AR prediction filter coefficients */ 71 /* Convert NLSF parameters to AR prediction filter coefficients */
72 silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order ); 72 silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order, psDec->arch );
73 } else { 73 } else {
74 /* Copy LPC coefficients for first half from second half */ 74 /* Copy LPC coefficients for first half from second half */
75 silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) ); 75 silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) );
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_pitch.c b/lib/rbcodec/codecs/libopus/silk/decode_pitch.c
index fedbc6a525..fd1b6bf551 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_pitch.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_pitch.c
@@ -51,7 +51,7 @@ void silk_decode_pitch(
51 Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; 51 Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
52 cbk_size = PE_NB_CBKS_STAGE2_EXT; 52 cbk_size = PE_NB_CBKS_STAGE2_EXT;
53 } else { 53 } else {
54 silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); 54 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
55 Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; 55 Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
56 cbk_size = PE_NB_CBKS_STAGE2_10MS; 56 cbk_size = PE_NB_CBKS_STAGE2_10MS;
57 } 57 }
@@ -60,7 +60,7 @@ void silk_decode_pitch(
60 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; 60 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
61 cbk_size = PE_NB_CBKS_STAGE3_MAX; 61 cbk_size = PE_NB_CBKS_STAGE3_MAX;
62 } else { 62 } else {
63 silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); 63 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
64 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; 64 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
65 cbk_size = PE_NB_CBKS_STAGE3_10MS; 65 cbk_size = PE_NB_CBKS_STAGE3_10MS;
66 } 66 }
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_pulses.c b/lib/rbcodec/codecs/libopus/silk/decode_pulses.c
index 1e14bc37b4..a56d2d3074 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_pulses.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_pulses.c
@@ -56,7 +56,7 @@ void silk_decode_pulses(
56 silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); 56 silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );
57 iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); 57 iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );
58 if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { 58 if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {
59 silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ 59 celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
60 iter++; 60 iter++;
61 } 61 }
62 62
@@ -69,9 +69,9 @@ void silk_decode_pulses(
69 sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 ); 69 sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 );
70 70
71 /* LSB indication */ 71 /* LSB indication */
72 while( sum_pulses[ i ] == MAX_PULSES + 1 ) { 72 while( sum_pulses[ i ] == SILK_MAX_PULSES + 1 ) {
73 nLshifts[ i ]++; 73 nLshifts[ i ]++;
74 /* When we've already got 10 LSBs, we shift the table to not allow (MAX_PULSES + 1) */ 74 /* When we've already got 10 LSBs, we shift the table to not allow (SILK_MAX_PULSES + 1) */
75 sum_pulses[ i ] = ec_dec_icdf( psRangeDec, 75 sum_pulses[ i ] = ec_dec_icdf( psRangeDec,
76 silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 ); 76 silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 );
77 } 77 }
diff --git a/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c b/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c
index eef0fd25e1..d9a13d0f0c 100644
--- a/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c
+++ b/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c
@@ -40,8 +40,8 @@ opus_int silk_decoder_set_fs(
40{ 40{
41 opus_int frame_length, ret = 0; 41 opus_int frame_length, ret = 0;
42 42
43 silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); 43 celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
44 silk_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 ); 44 celt_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 );
45 45
46 /* New (sub)frame length */ 46 /* New (sub)frame length */
47 psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz ); 47 psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz );
@@ -86,7 +86,7 @@ opus_int silk_decoder_set_fs(
86 psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; 86 psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
87 } else { 87 } else {
88 /* unsupported sampling rate */ 88 /* unsupported sampling rate */
89 silk_assert( 0 ); 89 celt_assert( 0 );
90 } 90 }
91 psDec->first_frame_after_reset = 1; 91 psDec->first_frame_after_reset = 1;
92 psDec->lagPrev = 100; 92 psDec->lagPrev = 100;
@@ -101,7 +101,7 @@ opus_int silk_decoder_set_fs(
101 } 101 }
102 102
103 /* Check that settings are valid */ 103 /* Check that settings are valid */
104 silk_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH ); 104 celt_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );
105 105
106 return ret; 106 return ret;
107} 107}
diff --git a/lib/rbcodec/codecs/libopus/silk/define.h b/lib/rbcodec/codecs/libopus/silk/define.h
index c47aca9f58..247cb0bf71 100644
--- a/lib/rbcodec/codecs/libopus/silk/define.h
+++ b/lib/rbcodec/codecs/libopus/silk/define.h
@@ -46,7 +46,6 @@ extern "C"
46/* Limits on bitrate */ 46/* Limits on bitrate */
47#define MIN_TARGET_RATE_BPS 5000 47#define MIN_TARGET_RATE_BPS 5000
48#define MAX_TARGET_RATE_BPS 80000 48#define MAX_TARGET_RATE_BPS 80000
49#define TARGET_RATE_TAB_SZ 8
50 49
51/* LBRR thresholds */ 50/* LBRR thresholds */
52#define LBRR_NB_MIN_RATE_BPS 12000 51#define LBRR_NB_MIN_RATE_BPS 12000
@@ -56,6 +55,12 @@ extern "C"
56/* DTX settings */ 55/* DTX settings */
57#define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */ 56#define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */
58#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */ 57#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */
58#define DTX_ACTIVITY_THRESHOLD 0.1f
59
60/* VAD decision */
61#define VAD_NO_DECISION -1
62#define VAD_NO_ACTIVITY 0
63#define VAD_ACTIVITY 1
59 64
60/* Maximum sampling frequency */ 65/* Maximum sampling frequency */
61#define MAX_FS_KHZ 16 66#define MAX_FS_KHZ 16
@@ -147,7 +152,7 @@ extern "C"
147#define USE_HARM_SHAPING 1 152#define USE_HARM_SHAPING 1
148 153
149/* Max LPC order of noise shaping filters */ 154/* Max LPC order of noise shaping filters */
150#define MAX_SHAPE_LPC_ORDER 16 155#define MAX_SHAPE_LPC_ORDER 24
151 156
152#define HARM_SHAPE_FIR_TAPS 3 157#define HARM_SHAPE_FIR_TAPS 3
153 158
@@ -157,8 +162,7 @@ extern "C"
157#define LTP_BUF_LENGTH 512 162#define LTP_BUF_LENGTH 512
158#define LTP_MASK ( LTP_BUF_LENGTH - 1 ) 163#define LTP_MASK ( LTP_BUF_LENGTH - 1 )
159 164
160#define DECISION_DELAY 32 165#define DECISION_DELAY 40
161#define DECISION_DELAY_MASK ( DECISION_DELAY - 1 )
162 166
163/* Number of subframes for excitation entropy coding */ 167/* Number of subframes for excitation entropy coding */
164#define SHELL_CODEC_FRAME_LENGTH 16 168#define SHELL_CODEC_FRAME_LENGTH 16
@@ -169,15 +173,11 @@ extern "C"
169#define N_RATE_LEVELS 10 173#define N_RATE_LEVELS 10
170 174
171/* Maximum sum of pulses per shell coding frame */ 175/* Maximum sum of pulses per shell coding frame */
172#define MAX_PULSES 16 176#define SILK_MAX_PULSES 16
173 177
174#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */ 178#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */
175 179
176#if( MAX_LPC_ORDER > DECISION_DELAY )
177# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER 180# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER
178#else
179# define NSQ_LPC_BUF_LENGTH DECISION_DELAY
180#endif
181 181
182/***************************/ 182/***************************/
183/* Voice activity detector */ 183/* Voice activity detector */
@@ -205,7 +205,6 @@ extern "C"
205/******************/ 205/******************/
206#define NLSF_W_Q 2 206#define NLSF_W_Q 2
207#define NLSF_VQ_MAX_VECTORS 32 207#define NLSF_VQ_MAX_VECTORS 32
208#define NLSF_VQ_MAX_SURVIVORS 32
209#define NLSF_QUANT_MAX_AMPLITUDE 4 208#define NLSF_QUANT_MAX_AMPLITUDE 4
210#define NLSF_QUANT_MAX_AMPLITUDE_EXT 10 209#define NLSF_QUANT_MAX_AMPLITUDE_EXT 10
211#define NLSF_QUANT_LEVEL_ADJ 0.1 210#define NLSF_QUANT_LEVEL_ADJ 0.1
diff --git a/lib/rbcodec/codecs/libopus/silk/enc_API.c b/lib/rbcodec/codecs/libopus/silk/enc_API.c
new file mode 100644
index 0000000000..55a33f37e9
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/enc_API.c
@@ -0,0 +1,576 @@
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#include "define.h"
32#include "API.h"
33#include "control.h"
34#include "typedef.h"
35#include "stack_alloc.h"
36#include "structs.h"
37#include "tuning_parameters.h"
38#ifdef FIXED_POINT
39#include "main_FIX.h"
40#else
41#include "main_FLP.h"
42#endif
43
44/***************************************/
45/* Read control structure from encoder */
46/***************************************/
47static opus_int silk_QueryEncoder( /* O Returns error code */
48 const void *encState, /* I State */
49 silk_EncControlStruct *encStatus /* O Encoder Status */
50);
51
52/****************************************/
53/* Encoder functions */
54/****************************************/
55
56opus_int silk_Get_Encoder_Size( /* O Returns error code */
57 opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */
58)
59{
60 opus_int ret = SILK_NO_ERROR;
61
62 *encSizeBytes = sizeof( silk_encoder );
63
64 return ret;
65}
66
67/*************************/
68/* Init or Reset encoder */
69/*************************/
70opus_int silk_InitEncoder( /* O Returns error code */
71 void *encState, /* I/O State */
72 int arch, /* I Run-time architecture */
73 silk_EncControlStruct *encStatus /* O Encoder Status */
74)
75{
76 silk_encoder *psEnc;
77 opus_int n, ret = SILK_NO_ERROR;
78
79 psEnc = (silk_encoder *)encState;
80
81 /* Reset encoder */
82 silk_memset( psEnc, 0, sizeof( silk_encoder ) );
83 for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) {
84 if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) {
85 celt_assert( 0 );
86 }
87 }
88
89 psEnc->nChannelsAPI = 1;
90 psEnc->nChannelsInternal = 1;
91
92 /* Read control structure */
93 if( ret += silk_QueryEncoder( encState, encStatus ) ) {
94 celt_assert( 0 );
95 }
96
97 return ret;
98}
99
100/***************************************/
101/* Read control structure from encoder */
102/***************************************/
103static opus_int silk_QueryEncoder( /* O Returns error code */
104 const void *encState, /* I State */
105 silk_EncControlStruct *encStatus /* O Encoder Status */
106)
107{
108 opus_int ret = SILK_NO_ERROR;
109 silk_encoder_state_Fxx *state_Fxx;
110 silk_encoder *psEnc = (silk_encoder *)encState;
111
112 state_Fxx = psEnc->state_Fxx;
113
114 encStatus->nChannelsAPI = psEnc->nChannelsAPI;
115 encStatus->nChannelsInternal = psEnc->nChannelsInternal;
116 encStatus->API_sampleRate = state_Fxx[ 0 ].sCmn.API_fs_Hz;
117 encStatus->maxInternalSampleRate = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz;
118 encStatus->minInternalSampleRate = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz;
119 encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz;
120 encStatus->payloadSize_ms = state_Fxx[ 0 ].sCmn.PacketSize_ms;
121 encStatus->bitRate = state_Fxx[ 0 ].sCmn.TargetRate_bps;
122 encStatus->packetLossPercentage = state_Fxx[ 0 ].sCmn.PacketLoss_perc;
123 encStatus->complexity = state_Fxx[ 0 ].sCmn.Complexity;
124 encStatus->useInBandFEC = state_Fxx[ 0 ].sCmn.useInBandFEC;
125 encStatus->useDTX = state_Fxx[ 0 ].sCmn.useDTX;
126 encStatus->useCBR = state_Fxx[ 0 ].sCmn.useCBR;
127 encStatus->internalSampleRate = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
128 encStatus->allowBandwidthSwitch = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch;
129 encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0;
130
131 return ret;
132}
133
134
135/**************************/
136/* Encode frame with Silk */
137/**************************/
138/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */
139/* encControl->payloadSize_ms is set to */
140opus_int silk_Encode( /* O Returns error code */
141 void *encState, /* I/O State */
142 silk_EncControlStruct *encControl, /* I Control status */
143 const opus_int16 *samplesIn, /* I Speech sample input vector */
144 opus_int nSamplesIn, /* I Number of samples in input vector */
145 ec_enc *psRangeEnc, /* I/O Compressor data structure */
146 opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
147 const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */
148 opus_int activity /* I Decision of Opus voice activity detector */
149)
150{
151 opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
152 opus_int nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms;
153 opus_int nSamplesFromInput = 0, nSamplesFromInputMax;
154 opus_int speech_act_thr_for_switch_Q8;
155 opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum;
156 silk_encoder *psEnc = ( silk_encoder * )encState;
157 VARDECL( opus_int16, buf );
158 opus_int transition, curr_block, tot_blocks;
159 SAVE_STACK;
160
161 if (encControl->reducedDependency)
162 {
163 psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1;
164 psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1;
165 }
166 psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;
167
168 /* Check values in encoder control structure */
169 if( ( ret = check_control_input( encControl ) ) != 0 ) {
170 celt_assert( 0 );
171 RESTORE_STACK;
172 return ret;
173 }
174
175 encControl->switchReady = 0;
176
177 if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) {
178 /* Mono -> Stereo transition: init state of second channel and stereo state */
179 ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch );
180 silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) );
181 silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) );
182 psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0;
183 psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1;
184 psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0;
185 psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1;
186 psEnc->sStereo.width_prev_Q14 = 0;
187 psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 );
188 if( psEnc->nChannelsAPI == 2 ) {
189 silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) );
190 silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State, &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State, sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) );
191 }
192 }
193
194 transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal);
195
196 psEnc->nChannelsAPI = encControl->nChannelsAPI;
197 psEnc->nChannelsInternal = encControl->nChannelsInternal;
198
199 nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate );
200 tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1;
201 curr_block = 0;
202 if( prefillFlag ) {
203 silk_LP_state save_LP;
204 /* Only accept input length of 10 ms */
205 if( nBlocksOf10ms != 1 ) {
206 celt_assert( 0 );
207 RESTORE_STACK;
208 return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
209 }
210 if ( prefillFlag == 2 ) {
211 save_LP = psEnc->state_Fxx[ 0 ].sCmn.sLP;
212 /* Save the sampling rate so the bandwidth switching code can keep handling transitions. */
213 save_LP.saved_fs_kHz = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
214 }
215 /* Reset Encoder */
216 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
217 ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch );
218 /* Restore the variable LP state. */
219 if ( prefillFlag == 2 ) {
220 psEnc->state_Fxx[ n ].sCmn.sLP = save_LP;
221 }
222 celt_assert( !ret );
223 }
224 tmp_payloadSize_ms = encControl->payloadSize_ms;
225 encControl->payloadSize_ms = 10;
226 tmp_complexity = encControl->complexity;
227 encControl->complexity = 0;
228 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
229 psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
230 psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1;
231 }
232 } else {
233 /* Only accept input lengths that are a multiple of 10 ms */
234 if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) {
235 celt_assert( 0 );
236 RESTORE_STACK;
237 return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
238 }
239 /* Make sure no more than one packet can be produced */
240 if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) {
241 celt_assert( 0 );
242 RESTORE_STACK;
243 return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
244 }
245 }
246
247 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
248 /* Force the side channel to the same rate as the mid */
249 opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0;
250 if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {
251 silk_assert( 0 );
252 RESTORE_STACK;
253 return ret;
254 }
255 if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) {
256 for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
257 psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0;
258 }
259 }
260 psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX;
261 }
262 celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
263
264 /* Input buffering/resampling and encoding */
265 nSamplesToBufferMax =
266 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
267 nSamplesFromInputMax =
268 silk_DIV32_16( nSamplesToBufferMax *
269 psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz,
270 psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
271 ALLOC( buf, nSamplesFromInputMax, opus_int16 );
272 while( 1 ) {
273 nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;
274 nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax );
275 nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
276 /* Resample and write to buffer */
277 if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {
278 opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
279 for( n = 0; n < nSamplesFromInput; n++ ) {
280 buf[ n ] = samplesIn[ 2 * n ];
281 }
282 /* Making sure to start both resamplers from the same state when switching from mono to stereo */
283 if( psEnc->nPrevChannelsInternal == 1 && id==0 ) {
284 silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state));
285 }
286
287 ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
288 &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
289 psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
290
291 nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx;
292 nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
293 for( n = 0; n < nSamplesFromInput; n++ ) {
294 buf[ n ] = samplesIn[ 2 * n + 1 ];
295 }
296 ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
297 &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
298
299 psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer;
300 } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) {
301 /* Combine left and right channels before resampling */
302 for( n = 0; n < nSamplesFromInput; n++ ) {
303 sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ];
304 buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 );
305 }
306 ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
307 &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
308 /* On the first mono frame, average the results for the two resampler states */
309 if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) {
310 ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
311 &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
312 for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) {
313 psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] =
314 silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ]
315 + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1);
316 }
317 }
318 psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
319 } else {
320 celt_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
321 silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));
322 ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
323 &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
324 psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
325 }
326
327 samplesIn += nSamplesFromInput * encControl->nChannelsAPI;
328 nSamplesIn -= nSamplesFromInput;
329
330 /* Default */
331 psEnc->allowBandwidthSwitch = 0;
332
333 /* Silk encoder */
334 if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) {
335 /* Enough data in input buffer, so encode */
336 celt_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );
337 celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );
338
339 /* Deal with LBRR data */
340 if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) {
341 /* Create space at start of payload for VAD and FEC flags */
342 opus_uint8 iCDF[ 2 ] = { 0, 0 };
343 iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
344 ec_enc_icdf( psRangeEnc, 0, iCDF, 8 );
345
346 /* Encode any LBRR data from previous packet */
347 /* Encode LBRR flags */
348 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
349 LBRR_symbol = 0;
350 for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
351 LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i );
352 }
353 psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0;
354 if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) {
355 ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 );
356 }
357 }
358
359 /* Code LBRR indices and excitation signals */
360 for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
361 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
362 if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) {
363 opus_int condCoding;
364
365 if( encControl->nChannelsInternal == 2 && n == 0 ) {
366 silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] );
367 /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */
368 if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) {
369 silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] );
370 }
371 }
372 /* Use conditional coding if previous frame available */
373 if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) {
374 condCoding = CODE_CONDITIONALLY;
375 } else {
376 condCoding = CODE_INDEPENDENTLY;
377 }
378 silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding );
379 silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType,
380 psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length );
381 }
382 }
383 }
384
385 /* Reset LBRR flags */
386 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
387 silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) );
388 }
389
390 psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc );
391 }
392
393 silk_HP_variable_cutoff( psEnc->state_Fxx );
394
395 /* Total target bits for packet */
396 nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
397 /* Subtract bits used for LBRR */
398 if( !prefillFlag ) {
399 nBits -= psEnc->nBitsUsedLBRR;
400 }
401 /* Divide by number of uncoded frames left in packet */
402 nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket );
403 /* Convert to bits/second */
404 if( encControl->payloadSize_ms == 10 ) {
405 TargetRate_bps = silk_SMULBB( nBits, 100 );
406 } else {
407 TargetRate_bps = silk_SMULBB( nBits, 50 );
408 }
409 /* Subtract fraction of bits in excess of target in previous frames and packets */
410 TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
411 if( !prefillFlag && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded > 0 ) {
412 /* Compare actual vs target bits so far in this packet */
413 opus_int32 bitsBalance = ec_tell( psRangeEnc ) - psEnc->nBitsUsedLBRR - nBits * psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
414 TargetRate_bps -= silk_DIV32_16( silk_MUL( bitsBalance, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
415 }
416 /* Never exceed input bitrate */
417 TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 );
418
419 /* Convert Left/Right to Mid/Side */
420 if( encControl->nChannelsInternal == 2 ) {
421 silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ],
422 psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ],
423 MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono,
424 psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length );
425 if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
426 /* Reset side channel encoder memory for first frame with side coding */
427 if( psEnc->prev_decode_only_middle == 1 ) {
428 silk_memset( &psEnc->state_Fxx[ 1 ].sShape, 0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) );
429 silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) );
430 silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) );
431 silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) );
432 psEnc->state_Fxx[ 1 ].sCmn.prevLag = 100;
433 psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev = 100;
434 psEnc->state_Fxx[ 1 ].sShape.LastGainIndex = 10;
435 psEnc->state_Fxx[ 1 ].sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY;
436 psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16 = 65536;
437 psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1;
438 }
439 silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ], activity );
440 } else {
441 psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0;
442 }
443 if( !prefillFlag ) {
444 silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
445 if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
446 silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
447 }
448 }
449 } else {
450 /* Buffering */
451 silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) );
452 silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) );
453 }
454 silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ], activity );
455
456 /* Encode */
457 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
458 opus_int maxBits, useCBR;
459
460 /* Handling rate constraints */
461 maxBits = encControl->maxBits;
462 if( tot_blocks == 2 && curr_block == 0 ) {
463 maxBits = maxBits * 3 / 5;
464 } else if( tot_blocks == 3 ) {
465 if( curr_block == 0 ) {
466 maxBits = maxBits * 2 / 5;
467 } else if( curr_block == 1 ) {
468 maxBits = maxBits * 3 / 4;
469 }
470 }
471 useCBR = encControl->useCBR && curr_block == tot_blocks - 1;
472
473 if( encControl->nChannelsInternal == 1 ) {
474 channelRate_bps = TargetRate_bps;
475 } else {
476 channelRate_bps = MStargetRates_bps[ n ];
477 if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) {
478 useCBR = 0;
479 /* Give mid up to 1/2 of the max bits for that frame */
480 maxBits -= encControl->maxBits / ( tot_blocks * 2 );
481 }
482 }
483
484 if( channelRate_bps > 0 ) {
485 opus_int condCoding;
486
487 silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps );
488
489 /* Use independent coding if no previous frame available */
490 if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) {
491 condCoding = CODE_INDEPENDENTLY;
492 } else if( n > 0 && psEnc->prev_decode_only_middle ) {
493 /* If we skipped a side frame in this packet, we don't
494 need LTP scaling; the LTP state is well-defined. */
495 condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING;
496 } else {
497 condCoding = CODE_CONDITIONALLY;
498 }
499 if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) {
500 silk_assert( 0 );
501 }
502 }
503 psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
504 psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0;
505 psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++;
506 }
507 psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ];
508
509 /* Insert VAD and FEC flags at beginning of bitstream */
510 if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) {
511 flags = 0;
512 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
513 for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
514 flags = silk_LSHIFT( flags, 1 );
515 flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ];
516 }
517 flags = silk_LSHIFT( flags, 1 );
518 flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag;
519 }
520 if( !prefillFlag ) {
521 ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
522 }
523
524 /* Return zero bytes if all channels DTXed */
525 if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) {
526 *nBytesOut = 0;
527 }
528
529 psEnc->nBitsExceeded += *nBytesOut * 8;
530 psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
531 psEnc->nBitsExceeded = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 );
532
533 /* Update flag indicating if bandwidth switching is allowed */
534 speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ),
535 SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms );
536 if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) {
537 psEnc->allowBandwidthSwitch = 1;
538 psEnc->timeSinceSwitchAllowed_ms = 0;
539 } else {
540 psEnc->allowBandwidthSwitch = 0;
541 psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms;
542 }
543 }
544
545 if( nSamplesIn == 0 ) {
546 break;
547 }
548 } else {
549 break;
550 }
551 curr_block++;
552 }
553
554 psEnc->nPrevChannelsInternal = encControl->nChannelsInternal;
555
556 encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch;
557 encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0;
558 encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
559 encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14;
560 if( prefillFlag ) {
561 encControl->payloadSize_ms = tmp_payloadSize_ms;
562 encControl->complexity = tmp_complexity;
563 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
564 psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
565 psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0;
566 }
567 }
568
569 encControl->signalType = psEnc->state_Fxx[0].sCmn.indices.signalType;
570 encControl->offset = silk_Quantization_Offsets_Q10
571 [ psEnc->state_Fxx[0].sCmn.indices.signalType >> 1 ]
572 [ psEnc->state_Fxx[0].sCmn.indices.quantOffsetType ];
573 RESTORE_STACK;
574 return ret;
575}
576
diff --git a/lib/rbcodec/codecs/libopus/silk/encode_indices.c b/lib/rbcodec/codecs/libopus/silk/encode_indices.c
new file mode 100644
index 0000000000..4bcbc3347b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/encode_indices.c
@@ -0,0 +1,181 @@
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.h"
33
34/* Encode side-information parameters to payload */
35void silk_encode_indices(
36 silk_encoder_state *psEncC, /* I/O Encoder state */
37 ec_enc *psRangeEnc, /* I/O Compressor data structure */
38 opus_int FrameIndex, /* I Frame number */
39 opus_int encode_LBRR, /* I Flag indicating LBRR data is being encoded */
40 opus_int condCoding /* I The type of conditional coding to use */
41)
42{
43 opus_int i, k, typeOffset;
44 opus_int encode_absolute_lagIndex, delta_lagIndex;
45 opus_int16 ec_ix[ MAX_LPC_ORDER ];
46 opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
47 const SideInfoIndices *psIndices;
48
49 if( encode_LBRR ) {
50 psIndices = &psEncC->indices_LBRR[ FrameIndex ];
51 } else {
52 psIndices = &psEncC->indices;
53 }
54
55 /*******************************************/
56 /* Encode signal type and quantizer offset */
57 /*******************************************/
58 typeOffset = 2 * psIndices->signalType + psIndices->quantOffsetType;
59 celt_assert( typeOffset >= 0 && typeOffset < 6 );
60 celt_assert( encode_LBRR == 0 || typeOffset >= 2 );
61 if( encode_LBRR || typeOffset >= 2 ) {
62 ec_enc_icdf( psRangeEnc, typeOffset - 2, silk_type_offset_VAD_iCDF, 8 );
63 } else {
64 ec_enc_icdf( psRangeEnc, typeOffset, silk_type_offset_no_VAD_iCDF, 8 );
65 }
66
67 /****************/
68 /* Encode gains */
69 /****************/
70 /* first subframe */
71 if( condCoding == CODE_CONDITIONALLY ) {
72 /* conditional coding */
73 silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 );
74 ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ], silk_delta_gain_iCDF, 8 );
75 } else {
76 /* independent coding, in two stages: MSB bits followed by 3 LSBs */
77 silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < N_LEVELS_QGAIN );
78 ec_enc_icdf( psRangeEnc, silk_RSHIFT( psIndices->GainsIndices[ 0 ], 3 ), silk_gain_iCDF[ psIndices->signalType ], 8 );
79 ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ] & 7, silk_uniform8_iCDF, 8 );
80 }
81
82 /* remaining subframes */
83 for( i = 1; i < psEncC->nb_subfr; i++ ) {
84 silk_assert( psIndices->GainsIndices[ i ] >= 0 && psIndices->GainsIndices[ i ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 );
85 ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ i ], silk_delta_gain_iCDF, 8 );
86 }
87
88 /****************/
89 /* Encode NLSFs */
90 /****************/
91 ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ 0 ], &psEncC->psNLSF_CB->CB1_iCDF[ ( psIndices->signalType >> 1 ) * psEncC->psNLSF_CB->nVectors ], 8 );
92 silk_NLSF_unpack( ec_ix, pred_Q8, psEncC->psNLSF_CB, psIndices->NLSFIndices[ 0 ] );
93 celt_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder );
94 for( i = 0; i < psEncC->psNLSF_CB->order; i++ ) {
95 if( psIndices->NLSFIndices[ i+1 ] >= NLSF_QUANT_MAX_AMPLITUDE ) {
96 ec_enc_icdf( psRangeEnc, 2 * NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
97 ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 );
98 } else if( psIndices->NLSFIndices[ i+1 ] <= -NLSF_QUANT_MAX_AMPLITUDE ) {
99 ec_enc_icdf( psRangeEnc, 0, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
100 ec_enc_icdf( psRangeEnc, -psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 );
101 } else {
102 ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] + NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
103 }
104 }
105
106 /* Encode NLSF interpolation factor */
107 if( psEncC->nb_subfr == MAX_NB_SUBFR ) {
108 silk_assert( psIndices->NLSFInterpCoef_Q2 >= 0 && psIndices->NLSFInterpCoef_Q2 < 5 );
109 ec_enc_icdf( psRangeEnc, psIndices->NLSFInterpCoef_Q2, silk_NLSF_interpolation_factor_iCDF, 8 );
110 }
111
112 if( psIndices->signalType == TYPE_VOICED )
113 {
114 /*********************/
115 /* Encode pitch lags */
116 /*********************/
117 /* lag index */
118 encode_absolute_lagIndex = 1;
119 if( condCoding == CODE_CONDITIONALLY && psEncC->ec_prevSignalType == TYPE_VOICED ) {
120 /* Delta Encoding */
121 delta_lagIndex = psIndices->lagIndex - psEncC->ec_prevLagIndex;
122 if( delta_lagIndex < -8 || delta_lagIndex > 11 ) {
123 delta_lagIndex = 0;
124 } else {
125 delta_lagIndex = delta_lagIndex + 9;
126 encode_absolute_lagIndex = 0; /* Only use delta */
127 }
128 silk_assert( delta_lagIndex >= 0 && delta_lagIndex < 21 );
129 ec_enc_icdf( psRangeEnc, delta_lagIndex, silk_pitch_delta_iCDF, 8 );
130 }
131 if( encode_absolute_lagIndex ) {
132 /* Absolute encoding */
133 opus_int32 pitch_high_bits, pitch_low_bits;
134 pitch_high_bits = silk_DIV32_16( psIndices->lagIndex, silk_RSHIFT( psEncC->fs_kHz, 1 ) );
135 pitch_low_bits = psIndices->lagIndex - silk_SMULBB( pitch_high_bits, silk_RSHIFT( psEncC->fs_kHz, 1 ) );
136 silk_assert( pitch_low_bits < psEncC->fs_kHz / 2 );
137 silk_assert( pitch_high_bits < 32 );
138 ec_enc_icdf( psRangeEnc, pitch_high_bits, silk_pitch_lag_iCDF, 8 );
139 ec_enc_icdf( psRangeEnc, pitch_low_bits, psEncC->pitch_lag_low_bits_iCDF, 8 );
140 }
141 psEncC->ec_prevLagIndex = psIndices->lagIndex;
142
143 /* Countour index */
144 silk_assert( psIndices->contourIndex >= 0 );
145 silk_assert( ( psIndices->contourIndex < 34 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 4 ) ||
146 ( psIndices->contourIndex < 11 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 4 ) ||
147 ( psIndices->contourIndex < 12 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 2 ) ||
148 ( psIndices->contourIndex < 3 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 2 ) );
149 ec_enc_icdf( psRangeEnc, psIndices->contourIndex, psEncC->pitch_contour_iCDF, 8 );
150
151 /********************/
152 /* Encode LTP gains */
153 /********************/
154 /* PERIndex value */
155 silk_assert( psIndices->PERIndex >= 0 && psIndices->PERIndex < 3 );
156 ec_enc_icdf( psRangeEnc, psIndices->PERIndex, silk_LTP_per_index_iCDF, 8 );
157
158 /* Codebook Indices */
159 for( k = 0; k < psEncC->nb_subfr; k++ ) {
160 silk_assert( psIndices->LTPIndex[ k ] >= 0 && psIndices->LTPIndex[ k ] < ( 8 << psIndices->PERIndex ) );
161 ec_enc_icdf( psRangeEnc, psIndices->LTPIndex[ k ], silk_LTP_gain_iCDF_ptrs[ psIndices->PERIndex ], 8 );
162 }
163
164 /**********************/
165 /* Encode LTP scaling */
166 /**********************/
167 if( condCoding == CODE_INDEPENDENTLY ) {
168 silk_assert( psIndices->LTP_scaleIndex >= 0 && psIndices->LTP_scaleIndex < 3 );
169 ec_enc_icdf( psRangeEnc, psIndices->LTP_scaleIndex, silk_LTPscale_iCDF, 8 );
170 }
171 silk_assert( !condCoding || psIndices->LTP_scaleIndex == 0 );
172 }
173
174 psEncC->ec_prevSignalType = psIndices->signalType;
175
176 /***************/
177 /* Encode seed */
178 /***************/
179 silk_assert( psIndices->Seed >= 0 && psIndices->Seed < 4 );
180 ec_enc_icdf( psRangeEnc, psIndices->Seed, silk_uniform4_iCDF, 8 );
181}
diff --git a/lib/rbcodec/codecs/libopus/silk/encode_pulses.c b/lib/rbcodec/codecs/libopus/silk/encode_pulses.c
new file mode 100644
index 0000000000..8a1999138b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/encode_pulses.c
@@ -0,0 +1,206 @@
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.h"
33#include "stack_alloc.h"
34
35/*********************************************/
36/* Encode quantization indices of excitation */
37/*********************************************/
38
39static OPUS_INLINE opus_int combine_and_check( /* return ok */
40 opus_int *pulses_comb, /* O */
41 const opus_int *pulses_in, /* I */
42 opus_int max_pulses, /* I max value for sum of pulses */
43 opus_int len /* I number of output values */
44)
45{
46 opus_int k, sum;
47
48 for( k = 0; k < len; k++ ) {
49 sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ];
50 if( sum > max_pulses ) {
51 return 1;
52 }
53 pulses_comb[ k ] = sum;
54 }
55
56 return 0;
57}
58
59/* Encode quantization indices of excitation */
60void silk_encode_pulses(
61 ec_enc *psRangeEnc, /* I/O compressor data structure */
62 const opus_int signalType, /* I Signal type */
63 const opus_int quantOffsetType, /* I quantOffsetType */
64 opus_int8 pulses[], /* I quantization indices */
65 const opus_int frame_length /* I Frame length */
66)
67{
68 opus_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0;
69 opus_int32 abs_q, minSumBits_Q5, sumBits_Q5;
70 VARDECL( opus_int, abs_pulses );
71 VARDECL( opus_int, sum_pulses );
72 VARDECL( opus_int, nRshifts );
73 opus_int pulses_comb[ 8 ];
74 opus_int *abs_pulses_ptr;
75 const opus_int8 *pulses_ptr;
76 const opus_uint8 *cdf_ptr;
77 const opus_uint8 *nBits_ptr;
78 SAVE_STACK;
79
80 silk_memset( pulses_comb, 0, 8 * sizeof( opus_int ) ); /* Fixing Valgrind reported problem*/
81
82 /****************************/
83 /* Prepare for shell coding */
84 /****************************/
85 /* Calculate number of shell blocks */
86 silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );
87 iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );
88 if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {
89 celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
90 iter++;
91 silk_memset( &pulses[ frame_length ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof(opus_int8));
92 }
93
94 /* Take the absolute value of the pulses */
95 ALLOC( abs_pulses, iter * SHELL_CODEC_FRAME_LENGTH, opus_int );
96 silk_assert( !( SHELL_CODEC_FRAME_LENGTH & 3 ) );
97 for( i = 0; i < iter * SHELL_CODEC_FRAME_LENGTH; i+=4 ) {
98 abs_pulses[i+0] = ( opus_int )silk_abs( pulses[ i + 0 ] );
99 abs_pulses[i+1] = ( opus_int )silk_abs( pulses[ i + 1 ] );
100 abs_pulses[i+2] = ( opus_int )silk_abs( pulses[ i + 2 ] );
101 abs_pulses[i+3] = ( opus_int )silk_abs( pulses[ i + 3 ] );
102 }
103
104 /* Calc sum pulses per shell code frame */
105 ALLOC( sum_pulses, iter, opus_int );
106 ALLOC( nRshifts, iter, opus_int );
107 abs_pulses_ptr = abs_pulses;
108 for( i = 0; i < iter; i++ ) {
109 nRshifts[ i ] = 0;
110
111 while( 1 ) {
112 /* 1+1 -> 2 */
113 scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, silk_max_pulses_table[ 0 ], 8 );
114 /* 2+2 -> 4 */
115 scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 1 ], 4 );
116 /* 4+4 -> 8 */
117 scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 2 ], 2 );
118 /* 8+8 -> 16 */
119 scale_down += combine_and_check( &sum_pulses[ i ], pulses_comb, silk_max_pulses_table[ 3 ], 1 );
120
121 if( scale_down ) {
122 /* We need to downscale the quantization signal */
123 nRshifts[ i ]++;
124 for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
125 abs_pulses_ptr[ k ] = silk_RSHIFT( abs_pulses_ptr[ k ], 1 );
126 }
127 } else {
128 /* Jump out of while(1) loop and go to next shell coding frame */
129 break;
130 }
131 }
132 abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH;
133 }
134
135 /**************/
136 /* Rate level */
137 /**************/
138 /* find rate level that leads to fewest bits for coding of pulses per block info */
139 minSumBits_Q5 = silk_int32_MAX;
140 for( k = 0; k < N_RATE_LEVELS - 1; k++ ) {
141 nBits_ptr = silk_pulses_per_block_BITS_Q5[ k ];
142 sumBits_Q5 = silk_rate_levels_BITS_Q5[ signalType >> 1 ][ k ];
143 for( i = 0; i < iter; i++ ) {
144 if( nRshifts[ i ] > 0 ) {
145 sumBits_Q5 += nBits_ptr[ SILK_MAX_PULSES + 1 ];
146 } else {
147 sumBits_Q5 += nBits_ptr[ sum_pulses[ i ] ];
148 }
149 }
150 if( sumBits_Q5 < minSumBits_Q5 ) {
151 minSumBits_Q5 = sumBits_Q5;
152 RateLevelIndex = k;
153 }
154 }
155 ec_enc_icdf( psRangeEnc, RateLevelIndex, silk_rate_levels_iCDF[ signalType >> 1 ], 8 );
156
157 /***************************************************/
158 /* Sum-Weighted-Pulses Encoding */
159 /***************************************************/
160 cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ];
161 for( i = 0; i < iter; i++ ) {
162 if( nRshifts[ i ] == 0 ) {
163 ec_enc_icdf( psRangeEnc, sum_pulses[ i ], cdf_ptr, 8 );
164 } else {
165 ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, cdf_ptr, 8 );
166 for( k = 0; k < nRshifts[ i ] - 1; k++ ) {
167 ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 );
168 }
169 ec_enc_icdf( psRangeEnc, sum_pulses[ i ], silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 );
170 }
171 }
172
173 /******************/
174 /* Shell Encoding */
175 /******************/
176 for( i = 0; i < iter; i++ ) {
177 if( sum_pulses[ i ] > 0 ) {
178 silk_shell_encoder( psRangeEnc, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] );
179 }
180 }
181
182 /****************/
183 /* LSB Encoding */
184 /****************/
185 for( i = 0; i < iter; i++ ) {
186 if( nRshifts[ i ] > 0 ) {
187 pulses_ptr = &pulses[ i * SHELL_CODEC_FRAME_LENGTH ];
188 nLS = nRshifts[ i ] - 1;
189 for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
190 abs_q = (opus_int8)silk_abs( pulses_ptr[ k ] );
191 for( j = nLS; j > 0; j-- ) {
192 bit = silk_RSHIFT( abs_q, j ) & 1;
193 ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 );
194 }
195 bit = abs_q & 1;
196 ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 );
197 }
198 }
199 }
200
201 /****************/
202 /* Encode signs */
203 /****************/
204 silk_encode_signs( psRangeEnc, pulses, frame_length, signalType, quantOffsetType, sum_pulses );
205 RESTORE_STACK;
206}
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}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c
new file mode 100644
index 0000000000..0e1a1fed0f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c
@@ -0,0 +1,249 @@
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_FLP.h"
34
35/************************************************/
36/* LPC analysis filter */
37/* NB! State is kept internally and the */
38/* filter always starts with zero state */
39/* first Order output samples are set to zero */
40/************************************************/
41
42/* 16th order LPC analysis filter, does not write first 16 samples */
43static OPUS_INLINE void silk_LPC_analysis_filter16_FLP(
44 silk_float r_LPC[], /* O LPC residual signal */
45 const silk_float PredCoef[], /* I LPC coefficients */
46 const silk_float s[], /* I Input signal */
47 const opus_int length /* I Length of input signal */
48)
49{
50 opus_int ix;
51 silk_float LPC_pred;
52 const silk_float *s_ptr;
53
54 for( ix = 16; ix < length; ix++ ) {
55 s_ptr = &s[ix - 1];
56
57 /* short-term prediction */
58 LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
59 s_ptr[ -1 ] * PredCoef[ 1 ] +
60 s_ptr[ -2 ] * PredCoef[ 2 ] +
61 s_ptr[ -3 ] * PredCoef[ 3 ] +
62 s_ptr[ -4 ] * PredCoef[ 4 ] +
63 s_ptr[ -5 ] * PredCoef[ 5 ] +
64 s_ptr[ -6 ] * PredCoef[ 6 ] +
65 s_ptr[ -7 ] * PredCoef[ 7 ] +
66 s_ptr[ -8 ] * PredCoef[ 8 ] +
67 s_ptr[ -9 ] * PredCoef[ 9 ] +
68 s_ptr[ -10 ] * PredCoef[ 10 ] +
69 s_ptr[ -11 ] * PredCoef[ 11 ] +
70 s_ptr[ -12 ] * PredCoef[ 12 ] +
71 s_ptr[ -13 ] * PredCoef[ 13 ] +
72 s_ptr[ -14 ] * PredCoef[ 14 ] +
73 s_ptr[ -15 ] * PredCoef[ 15 ];
74
75 /* prediction error */
76 r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
77 }
78}
79
80/* 12th order LPC analysis filter, does not write first 12 samples */
81static OPUS_INLINE void silk_LPC_analysis_filter12_FLP(
82 silk_float r_LPC[], /* O LPC residual signal */
83 const silk_float PredCoef[], /* I LPC coefficients */
84 const silk_float s[], /* I Input signal */
85 const opus_int length /* I Length of input signal */
86)
87{
88 opus_int ix;
89 silk_float LPC_pred;
90 const silk_float *s_ptr;
91
92 for( ix = 12; ix < length; ix++ ) {
93 s_ptr = &s[ix - 1];
94
95 /* short-term prediction */
96 LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
97 s_ptr[ -1 ] * PredCoef[ 1 ] +
98 s_ptr[ -2 ] * PredCoef[ 2 ] +
99 s_ptr[ -3 ] * PredCoef[ 3 ] +
100 s_ptr[ -4 ] * PredCoef[ 4 ] +
101 s_ptr[ -5 ] * PredCoef[ 5 ] +
102 s_ptr[ -6 ] * PredCoef[ 6 ] +
103 s_ptr[ -7 ] * PredCoef[ 7 ] +
104 s_ptr[ -8 ] * PredCoef[ 8 ] +
105 s_ptr[ -9 ] * PredCoef[ 9 ] +
106 s_ptr[ -10 ] * PredCoef[ 10 ] +
107 s_ptr[ -11 ] * PredCoef[ 11 ];
108
109 /* prediction error */
110 r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
111 }
112}
113
114/* 10th order LPC analysis filter, does not write first 10 samples */
115static OPUS_INLINE void silk_LPC_analysis_filter10_FLP(
116 silk_float r_LPC[], /* O LPC residual signal */
117 const silk_float PredCoef[], /* I LPC coefficients */
118 const silk_float s[], /* I Input signal */
119 const opus_int length /* I Length of input signal */
120)
121{
122 opus_int ix;
123 silk_float LPC_pred;
124 const silk_float *s_ptr;
125
126 for( ix = 10; ix < length; ix++ ) {
127 s_ptr = &s[ix - 1];
128
129 /* short-term prediction */
130 LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
131 s_ptr[ -1 ] * PredCoef[ 1 ] +
132 s_ptr[ -2 ] * PredCoef[ 2 ] +
133 s_ptr[ -3 ] * PredCoef[ 3 ] +
134 s_ptr[ -4 ] * PredCoef[ 4 ] +
135 s_ptr[ -5 ] * PredCoef[ 5 ] +
136 s_ptr[ -6 ] * PredCoef[ 6 ] +
137 s_ptr[ -7 ] * PredCoef[ 7 ] +
138 s_ptr[ -8 ] * PredCoef[ 8 ] +
139 s_ptr[ -9 ] * PredCoef[ 9 ];
140
141 /* prediction error */
142 r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
143 }
144}
145
146/* 8th order LPC analysis filter, does not write first 8 samples */
147static OPUS_INLINE void silk_LPC_analysis_filter8_FLP(
148 silk_float r_LPC[], /* O LPC residual signal */
149 const silk_float PredCoef[], /* I LPC coefficients */
150 const silk_float s[], /* I Input signal */
151 const opus_int length /* I Length of input signal */
152)
153{
154 opus_int ix;
155 silk_float LPC_pred;
156 const silk_float *s_ptr;
157
158 for( ix = 8; ix < length; ix++ ) {
159 s_ptr = &s[ix - 1];
160
161 /* short-term prediction */
162 LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
163 s_ptr[ -1 ] * PredCoef[ 1 ] +
164 s_ptr[ -2 ] * PredCoef[ 2 ] +
165 s_ptr[ -3 ] * PredCoef[ 3 ] +
166 s_ptr[ -4 ] * PredCoef[ 4 ] +
167 s_ptr[ -5 ] * PredCoef[ 5 ] +
168 s_ptr[ -6 ] * PredCoef[ 6 ] +
169 s_ptr[ -7 ] * PredCoef[ 7 ];
170
171 /* prediction error */
172 r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
173 }
174}
175
176/* 6th order LPC analysis filter, does not write first 6 samples */
177static OPUS_INLINE void silk_LPC_analysis_filter6_FLP(
178 silk_float r_LPC[], /* O LPC residual signal */
179 const silk_float PredCoef[], /* I LPC coefficients */
180 const silk_float s[], /* I Input signal */
181 const opus_int length /* I Length of input signal */
182)
183{
184 opus_int ix;
185 silk_float LPC_pred;
186 const silk_float *s_ptr;
187
188 for( ix = 6; ix < length; ix++ ) {
189 s_ptr = &s[ix - 1];
190
191 /* short-term prediction */
192 LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
193 s_ptr[ -1 ] * PredCoef[ 1 ] +
194 s_ptr[ -2 ] * PredCoef[ 2 ] +
195 s_ptr[ -3 ] * PredCoef[ 3 ] +
196 s_ptr[ -4 ] * PredCoef[ 4 ] +
197 s_ptr[ -5 ] * PredCoef[ 5 ];
198
199 /* prediction error */
200 r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
201 }
202}
203
204/************************************************/
205/* LPC analysis filter */
206/* NB! State is kept internally and the */
207/* filter always starts with zero state */
208/* first Order output samples are set to zero */
209/************************************************/
210void silk_LPC_analysis_filter_FLP(
211 silk_float r_LPC[], /* O LPC residual signal */
212 const silk_float PredCoef[], /* I LPC coefficients */
213 const silk_float s[], /* I Input signal */
214 const opus_int length, /* I Length of input signal */
215 const opus_int Order /* I LPC order */
216)
217{
218 celt_assert( Order <= length );
219
220 switch( Order ) {
221 case 6:
222 silk_LPC_analysis_filter6_FLP( r_LPC, PredCoef, s, length );
223 break;
224
225 case 8:
226 silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, length );
227 break;
228
229 case 10:
230 silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length );
231 break;
232
233 case 12:
234 silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length );
235 break;
236
237 case 16:
238 silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length );
239 break;
240
241 default:
242 celt_assert( 0 );
243 break;
244 }
245
246 /* Set first Order output samples to zero */
247 silk_memset( r_LPC, 0, Order * sizeof( silk_float ) );
248}
249
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c
new file mode 100644
index 0000000000..2be2122d61
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c
@@ -0,0 +1,73 @@
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 "SigProc_FLP.h"
34#include "define.h"
35
36/* compute inverse of LPC prediction gain, and */
37/* test if LPC coefficients are stable (all poles within unit circle) */
38/* this code is based on silk_a2k_FLP() */
39silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */
40 const silk_float *A, /* I prediction coefficients [order] */
41 opus_int32 order /* I prediction order */
42)
43{
44 opus_int k, n;
45 double invGain, rc, rc_mult1, rc_mult2, tmp1, tmp2;
46 silk_float Atmp[ SILK_MAX_ORDER_LPC ];
47
48 silk_memcpy( Atmp, A, order * sizeof(silk_float) );
49
50 invGain = 1.0;
51 for( k = order - 1; k > 0; k-- ) {
52 rc = -Atmp[ k ];
53 rc_mult1 = 1.0f - rc * rc;
54 invGain *= rc_mult1;
55 if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) {
56 return 0.0f;
57 }
58 rc_mult2 = 1.0f / rc_mult1;
59 for( n = 0; n < (k + 1) >> 1; n++ ) {
60 tmp1 = Atmp[ n ];
61 tmp2 = Atmp[ k - n - 1 ];
62 Atmp[ n ] = (silk_float)( ( tmp1 - tmp2 * rc ) * rc_mult2 );
63 Atmp[ k - n - 1 ] = (silk_float)( ( tmp2 - tmp1 * rc ) * rc_mult2 );
64 }
65 }
66 rc = -Atmp[ 0 ];
67 rc_mult1 = 1.0f - rc * rc;
68 invGain *= rc_mult1;
69 if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) {
70 return 0.0f;
71 }
72 return (silk_float)invGain;
73}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c
new file mode 100644
index 0000000000..849b7c1c52
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c
@@ -0,0 +1,75 @@
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_FLP.h"
33
34void silk_LTP_analysis_filter_FLP(
35 silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */
36 const silk_float *x, /* I Input signal, with preceding samples */
37 const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */
38 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
39 const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */
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 Preceding samples for each subframe */
43)
44{
45 const silk_float *x_ptr, *x_lag_ptr;
46 silk_float Btmp[ LTP_ORDER ];
47 silk_float *LTP_res_ptr;
48 silk_float inv_gain;
49 opus_int k, i, j;
50
51 x_ptr = x;
52 LTP_res_ptr = LTP_res;
53 for( k = 0; k < nb_subfr; k++ ) {
54 x_lag_ptr = x_ptr - pitchL[ k ];
55 inv_gain = invGains[ k ];
56 for( i = 0; i < LTP_ORDER; i++ ) {
57 Btmp[ i ] = B[ k * LTP_ORDER + i ];
58 }
59
60 /* LTP analysis FIR filter */
61 for( i = 0; i < subfr_length + pre_length; i++ ) {
62 LTP_res_ptr[ i ] = x_ptr[ i ];
63 /* Subtract long-term prediction */
64 for( j = 0; j < LTP_ORDER; j++ ) {
65 LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ];
66 }
67 LTP_res_ptr[ i ] *= inv_gain;
68 x_lag_ptr++;
69 }
70
71 /* Update pointers */
72 LTP_res_ptr += subfr_length + pre_length;
73 x_ptr += subfr_length;
74 }
75}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c
new file mode 100644
index 0000000000..8dbe29d0fa
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c
@@ -0,0 +1,52 @@
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_FLP.h"
33
34void silk_LTP_scale_ctrl_FLP(
35 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
36 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
37 opus_int condCoding /* I The type of conditional coding to use */
38)
39{
40 opus_int round_loss;
41
42 if( condCoding == CODE_INDEPENDENTLY ) {
43 /* Only scale if first frame in packet */
44 round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
45 psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEncCtrl->LTPredCodGain * 0.1f, 0.0f, 2.0f );
46 } else {
47 /* Default is minimum scaling */
48 psEnc->sCmn.indices.LTP_scaleIndex = 0;
49 }
50
51 psEncCtrl->LTP_scale = (silk_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f;
52}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h b/lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h
new file mode 100644
index 0000000000..953de8b09e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h
@@ -0,0 +1,197 @@
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_SIGPROC_FLP_H
29#define SILK_SIGPROC_FLP_H
30
31#include "SigProc_FIX.h"
32#include "float_cast.h"
33#include <math.h>
34
35#ifdef __cplusplus
36extern "C"
37{
38#endif
39
40/********************************************************************/
41/* SIGNAL PROCESSING FUNCTIONS */
42/********************************************************************/
43
44/* Chirp (bw expand) LP AR filter */
45void silk_bwexpander_FLP(
46 silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */
47 const opus_int d, /* I length of ar */
48 const silk_float chirp /* I chirp factor (typically in range (0..1) ) */
49);
50
51/* compute inverse of LPC prediction gain, and */
52/* test if LPC coefficients are stable (all poles within unit circle) */
53/* this code is based on silk_FLP_a2k() */
54silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */
55 const silk_float *A, /* I prediction coefficients [order] */
56 opus_int32 order /* I prediction order */
57);
58
59silk_float silk_schur_FLP( /* O returns residual energy */
60 silk_float refl_coef[], /* O reflection coefficients (length order) */
61 const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */
62 opus_int order /* I order */
63);
64
65void silk_k2a_FLP(
66 silk_float *A, /* O prediction coefficients [order] */
67 const silk_float *rc, /* I reflection coefficients [order] */
68 opus_int32 order /* I prediction order */
69);
70
71/* compute autocorrelation */
72void silk_autocorrelation_FLP(
73 silk_float *results, /* O result (length correlationCount) */
74 const silk_float *inputData, /* I input data to correlate */
75 opus_int inputDataSize, /* I length of input */
76 opus_int correlationCount /* I number of correlation taps to compute */
77);
78
79opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */
80 const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
81 opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */
82 opus_int16 *lagIndex, /* O Lag Index */
83 opus_int8 *contourIndex, /* O Pitch contour Index */
84 silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */
85 opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
86 const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */
87 const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */
88 const opus_int Fs_kHz, /* I sample frequency (kHz) */
89 const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
90 const opus_int nb_subfr, /* I Number of 5 ms subframes */
91 int arch /* I Run-time architecture */
92);
93
94void silk_insertion_sort_decreasing_FLP(
95 silk_float *a, /* I/O Unsorted / Sorted vector */
96 opus_int *idx, /* O Index vector for the sorted elements */
97 const opus_int L, /* I Vector length */
98 const opus_int K /* I Number of correctly sorted positions */
99);
100
101/* Compute reflection coefficients from input signal */
102silk_float silk_burg_modified_FLP( /* O returns residual energy */
103 silk_float A[], /* O prediction coefficients (length order) */
104 const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
105 const silk_float minInvGain, /* I minimum inverse prediction gain */
106 const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */
107 const opus_int nb_subfr, /* I number of subframes stacked in x */
108 const opus_int D /* I order */
109);
110
111/* multiply a vector by a constant */
112void silk_scale_vector_FLP(
113 silk_float *data1,
114 silk_float gain,
115 opus_int dataSize
116);
117
118/* copy and multiply a vector by a constant */
119void silk_scale_copy_vector_FLP(
120 silk_float *data_out,
121 const silk_float *data_in,
122 silk_float gain,
123 opus_int dataSize
124);
125
126/* inner product of two silk_float arrays, with result as double */
127double silk_inner_product_FLP(
128 const silk_float *data1,
129 const silk_float *data2,
130 opus_int dataSize
131);
132
133/* sum of squares of a silk_float array, with result as double */
134double silk_energy_FLP(
135 const silk_float *data,
136 opus_int dataSize
137);
138
139/********************************************************************/
140/* MACROS */
141/********************************************************************/
142
143#define PI (3.1415926536f)
144
145#define silk_min_float( a, b ) (((a) < (b)) ? (a) : (b))
146#define silk_max_float( a, b ) (((a) > (b)) ? (a) : (b))
147#define silk_abs_float( a ) ((silk_float)fabs(a))
148
149/* sigmoid function */
150static OPUS_INLINE silk_float silk_sigmoid( silk_float x )
151{
152 return (silk_float)(1.0 / (1.0 + exp(-x)));
153}
154
155/* floating-point to integer conversion (rounding) */
156static OPUS_INLINE opus_int32 silk_float2int( silk_float x )
157{
158 return (opus_int32)float2int( x );
159}
160
161/* floating-point to integer conversion (rounding) */
162static OPUS_INLINE void silk_float2short_array(
163 opus_int16 *out,
164 const silk_float *in,
165 opus_int32 length
166)
167{
168 opus_int32 k;
169 for( k = length - 1; k >= 0; k-- ) {
170 out[k] = silk_SAT16( (opus_int32)float2int( in[k] ) );
171 }
172}
173
174/* integer to floating-point conversion */
175static OPUS_INLINE void silk_short2float_array(
176 silk_float *out,
177 const opus_int16 *in,
178 opus_int32 length
179)
180{
181 opus_int32 k;
182 for( k = length - 1; k >= 0; k-- ) {
183 out[k] = (silk_float)in[k];
184 }
185}
186
187/* using log2() helps the fixed-point conversion */
188static OPUS_INLINE silk_float silk_log2( double x )
189{
190 return ( silk_float )( 3.32192809488736 * log10( x ) );
191}
192
193#ifdef __cplusplus
194}
195#endif
196
197#endif /* SILK_SIGPROC_FLP_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c
new file mode 100644
index 0000000000..e49e717991
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c
@@ -0,0 +1,81 @@
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_FLP.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 */
38void silk_apply_sine_window_FLP(
39 silk_float px_win[], /* O Pointer to windowed signal */
40 const silk_float px[], /* I Pointer to input signal */
41 const opus_int win_type, /* I Selects a window type */
42 const opus_int length /* I Window length, multiple of 4 */
43)
44{
45 opus_int k;
46 silk_float freq, c, S0, S1;
47
48 celt_assert( win_type == 1 || win_type == 2 );
49
50 /* Length must be multiple of 4 */
51 celt_assert( ( length & 3 ) == 0 );
52
53 freq = PI / ( length + 1 );
54
55 /* Approximation of 2 * cos(f) */
56 c = 2.0f - freq * freq;
57
58 /* Initialize state */
59 if( win_type < 2 ) {
60 /* Start from 0 */
61 S0 = 0.0f;
62 /* Approximation of sin(f) */
63 S1 = freq;
64 } else {
65 /* Start from 1 */
66 S0 = 1.0f;
67 /* Approximation of cos(f) */
68 S1 = 0.5f * c;
69 }
70
71 /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
72 /* 4 samples at a time */
73 for( k = 0; k < length; k += 4 ) {
74 px_win[ k + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 );
75 px_win[ k + 1 ] = px[ k + 1 ] * S1;
76 S0 = c * S1 - S0;
77 px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 );
78 px_win[ k + 3 ] = px[ k + 3 ] * S0;
79 S1 = c * S0 - S1;
80 }
81}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c
new file mode 100644
index 0000000000..8b8a9e659a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c
@@ -0,0 +1,52 @@
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 "typedef.h"
33#include "SigProc_FLP.h"
34
35/* compute autocorrelation */
36void silk_autocorrelation_FLP(
37 silk_float *results, /* O result (length correlationCount) */
38 const silk_float *inputData, /* I input data to correlate */
39 opus_int inputDataSize, /* I length of input */
40 opus_int correlationCount /* I number of correlation taps to compute */
41)
42{
43 opus_int i;
44
45 if( correlationCount > inputDataSize ) {
46 correlationCount = inputDataSize;
47 }
48
49 for( i = 0; i < correlationCount; i++ ) {
50 results[ i ] = (silk_float)silk_inner_product_FLP( inputData, inputData + i, inputDataSize - i );
51 }
52}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c
new file mode 100644
index 0000000000..756b76a35b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c
@@ -0,0 +1,186 @@
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_FLP.h"
33#include "tuning_parameters.h"
34#include "define.h"
35
36#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/
37
38/* Compute reflection coefficients from input signal */
39silk_float silk_burg_modified_FLP( /* O returns residual energy */
40 silk_float A[], /* O prediction coefficients (length order) */
41 const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
42 const silk_float minInvGain, /* I minimum inverse prediction gain */
43 const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */
44 const opus_int nb_subfr, /* I number of subframes stacked in x */
45 const opus_int D /* I order */
46)
47{
48 opus_int k, n, s, reached_max_gain;
49 double C0, invGain, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2;
50 const silk_float *x_ptr;
51 double C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ];
52 double CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ];
53 double Af[ SILK_MAX_ORDER_LPC ];
54
55 celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
56
57 /* Compute autocorrelations, added over subframes */
58 C0 = silk_energy_FLP( x, nb_subfr * subfr_length );
59 silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( double ) );
60 for( s = 0; s < nb_subfr; s++ ) {
61 x_ptr = x + s * subfr_length;
62 for( n = 1; n < D + 1; n++ ) {
63 C_first_row[ n - 1 ] += silk_inner_product_FLP( x_ptr, x_ptr + n, subfr_length - n );
64 }
65 }
66 silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) );
67
68 /* Initialize */
69 CAb[ 0 ] = CAf[ 0 ] = C0 + FIND_LPC_COND_FAC * C0 + 1e-9f;
70 invGain = 1.0f;
71 reached_max_gain = 0;
72 for( n = 0; n < D; n++ ) {
73 /* Update first row of correlation matrix (without first element) */
74 /* Update last row of correlation matrix (without last element, stored in reversed order) */
75 /* Update C * Af */
76 /* Update C * flipud(Af) (stored in reversed order) */
77 for( s = 0; s < nb_subfr; s++ ) {
78 x_ptr = x + s * subfr_length;
79 tmp1 = x_ptr[ n ];
80 tmp2 = x_ptr[ subfr_length - n - 1 ];
81 for( k = 0; k < n; k++ ) {
82 C_first_row[ k ] -= x_ptr[ n ] * x_ptr[ n - k - 1 ];
83 C_last_row[ k ] -= x_ptr[ subfr_length - n - 1 ] * x_ptr[ subfr_length - n + k ];
84 Atmp = Af[ k ];
85 tmp1 += x_ptr[ n - k - 1 ] * Atmp;
86 tmp2 += x_ptr[ subfr_length - n + k ] * Atmp;
87 }
88 for( k = 0; k <= n; k++ ) {
89 CAf[ k ] -= tmp1 * x_ptr[ n - k ];
90 CAb[ k ] -= tmp2 * x_ptr[ subfr_length - n + k - 1 ];
91 }
92 }
93 tmp1 = C_first_row[ n ];
94 tmp2 = C_last_row[ n ];
95 for( k = 0; k < n; k++ ) {
96 Atmp = Af[ k ];
97 tmp1 += C_last_row[ n - k - 1 ] * Atmp;
98 tmp2 += C_first_row[ n - k - 1 ] * Atmp;
99 }
100 CAf[ n + 1 ] = tmp1;
101 CAb[ n + 1 ] = tmp2;
102
103 /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
104 num = CAb[ n + 1 ];
105 nrg_b = CAb[ 0 ];
106 nrg_f = CAf[ 0 ];
107 for( k = 0; k < n; k++ ) {
108 Atmp = Af[ k ];
109 num += CAb[ n - k ] * Atmp;
110 nrg_b += CAb[ k + 1 ] * Atmp;
111 nrg_f += CAf[ k + 1 ] * Atmp;
112 }
113 silk_assert( nrg_f > 0.0 );
114 silk_assert( nrg_b > 0.0 );
115
116 /* Calculate the next order reflection (parcor) coefficient */
117 rc = -2.0 * num / ( nrg_f + nrg_b );
118 silk_assert( rc > -1.0 && rc < 1.0 );
119
120 /* Update inverse prediction gain */
121 tmp1 = invGain * ( 1.0 - rc * rc );
122 if( tmp1 <= minInvGain ) {
123 /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
124 rc = sqrt( 1.0 - minInvGain / invGain );
125 if( num > 0 ) {
126 /* Ensure adjusted reflection coefficients has the original sign */
127 rc = -rc;
128 }
129 invGain = minInvGain;
130 reached_max_gain = 1;
131 } else {
132 invGain = tmp1;
133 }
134
135 /* Update the AR coefficients */
136 for( k = 0; k < (n + 1) >> 1; k++ ) {
137 tmp1 = Af[ k ];
138 tmp2 = Af[ n - k - 1 ];
139 Af[ k ] = tmp1 + rc * tmp2;
140 Af[ n - k - 1 ] = tmp2 + rc * tmp1;
141 }
142 Af[ n ] = rc;
143
144 if( reached_max_gain ) {
145 /* Reached max prediction gain; set remaining coefficients to zero and exit loop */
146 for( k = n + 1; k < D; k++ ) {
147 Af[ k ] = 0.0;
148 }
149 break;
150 }
151
152 /* Update C * Af and C * Ab */
153 for( k = 0; k <= n + 1; k++ ) {
154 tmp1 = CAf[ k ];
155 CAf[ k ] += rc * CAb[ n - k + 1 ];
156 CAb[ n - k + 1 ] += rc * tmp1;
157 }
158 }
159
160 if( reached_max_gain ) {
161 /* Convert to silk_float */
162 for( k = 0; k < D; k++ ) {
163 A[ k ] = (silk_float)( -Af[ k ] );
164 }
165 /* Subtract energy of preceding samples from C0 */
166 for( s = 0; s < nb_subfr; s++ ) {
167 C0 -= silk_energy_FLP( x + s * subfr_length, D );
168 }
169 /* Approximate residual energy */
170 nrg_f = C0 * invGain;
171 } else {
172 /* Compute residual energy and store coefficients as silk_float */
173 nrg_f = CAf[ 0 ];
174 tmp1 = 1.0;
175 for( k = 0; k < D; k++ ) {
176 Atmp = Af[ k ];
177 nrg_f += CAf[ k + 1 ] * Atmp;
178 tmp1 += Atmp * Atmp;
179 A[ k ] = (silk_float)(-Atmp);
180 }
181 nrg_f -= FIND_LPC_COND_FAC * C0 * tmp1;
182 }
183
184 /* Return residual energy */
185 return (silk_float)nrg_f;
186}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c
new file mode 100644
index 0000000000..d55a4d79ab
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c
@@ -0,0 +1,49 @@
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_FLP.h"
33
34/* Chirp (bw expand) LP AR filter */
35void silk_bwexpander_FLP(
36 silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */
37 const opus_int d, /* I length of ar */
38 const silk_float chirp /* I chirp factor (typically in range (0..1) ) */
39)
40{
41 opus_int i;
42 silk_float cfac = chirp;
43
44 for( i = 0; i < d - 1; i++ ) {
45 ar[ i ] *= cfac;
46 cfac *= chirp;
47 }
48 ar[ d - 1 ] *= cfac;
49}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.c
new file mode 100644
index 0000000000..eae6a1cfca
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.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/**********************************************************************
33 * Correlation matrix computations for LS estimate.
34 **********************************************************************/
35
36#include "main_FLP.h"
37
38/* Calculates correlation vector X'*t */
39void silk_corrVector_FLP(
40 const silk_float *x, /* I x vector [L+order-1] used to create X */
41 const silk_float *t, /* I Target vector [L] */
42 const opus_int L, /* I Length of vecors */
43 const opus_int Order, /* I Max lag for correlation */
44 silk_float *Xt /* O X'*t correlation vector [order] */
45)
46{
47 opus_int lag;
48 const silk_float *ptr1;
49
50 ptr1 = &x[ Order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
51 for( lag = 0; lag < Order; lag++ ) {
52 /* Calculate X[:,lag]'*t */
53 Xt[ lag ] = (silk_float)silk_inner_product_FLP( ptr1, t, L );
54 ptr1--; /* Next column of X */
55 }
56}
57
58/* Calculates correlation matrix X'*X */
59void silk_corrMatrix_FLP(
60 const silk_float *x, /* I x vector [ L+order-1 ] used to create X */
61 const opus_int L, /* I Length of vectors */
62 const opus_int Order, /* I Max lag for correlation */
63 silk_float *XX /* O X'*X correlation matrix [order x order] */
64)
65{
66 opus_int j, lag;
67 double energy;
68 const silk_float *ptr1, *ptr2;
69
70 ptr1 = &x[ Order - 1 ]; /* First sample of column 0 of X */
71 energy = silk_energy_FLP( ptr1, L ); /* X[:,0]'*X[:,0] */
72 matrix_ptr( XX, 0, 0, Order ) = ( silk_float )energy;
73 for( j = 1; j < Order; j++ ) {
74 /* Calculate X[:,j]'*X[:,j] */
75 energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ];
76 matrix_ptr( XX, j, j, Order ) = ( silk_float )energy;
77 }
78
79 ptr2 = &x[ Order - 2 ]; /* First sample of column 1 of X */
80 for( lag = 1; lag < Order; lag++ ) {
81 /* Calculate X[:,0]'*X[:,lag] */
82 energy = silk_inner_product_FLP( ptr1, ptr2, L );
83 matrix_ptr( XX, lag, 0, Order ) = ( silk_float )energy;
84 matrix_ptr( XX, 0, lag, Order ) = ( silk_float )energy;
85 /* Calculate X[:,j]'*X[:,j + lag] */
86 for( j = 1; j < ( Order - lag ); j++ ) {
87 energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ];
88 matrix_ptr( XX, lag + j, j, Order ) = ( silk_float )energy;
89 matrix_ptr( XX, j, lag + j, Order ) = ( silk_float )energy;
90 }
91 ptr2--; /* Next column of X */
92 }
93}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c
new file mode 100644
index 0000000000..b029c3f5ca
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c
@@ -0,0 +1,435 @@
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_FLP.h"
34#include "tuning_parameters.h"
35
36/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */
37static OPUS_INLINE void silk_LBRR_encode_FLP(
38 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
39 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
40 const silk_float xfw[], /* I Input signal */
41 opus_int condCoding /* I The type of conditional coding used so far for this frame */
42);
43
44void silk_encode_do_VAD_FLP(
45 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
46 opus_int activity /* I Decision of Opus voice activity detector */
47)
48{
49 const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
50
51 /****************************/
52 /* Voice Activity Detection */
53 /****************************/
54 silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
55 /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */
56 if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
57 psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
58 }
59
60 /**************************************************/
61 /* Convert speech activity into VAD and DTX flags */
62 /**************************************************/
63 if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
64 psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
65 psEnc->sCmn.noSpeechCounter++;
66 if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
67 psEnc->sCmn.inDTX = 0;
68 } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
69 psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
70 psEnc->sCmn.inDTX = 0;
71 }
72 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
73 } else {
74 psEnc->sCmn.noSpeechCounter = 0;
75 psEnc->sCmn.inDTX = 0;
76 psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
77 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
78 }
79}
80
81/****************/
82/* Encode frame */
83/****************/
84opus_int silk_encode_frame_FLP(
85 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
86 opus_int32 *pnBytesOut, /* O Number of payload bytes; */
87 ec_enc *psRangeEnc, /* I/O compressor data structure */
88 opus_int condCoding, /* I The type of conditional coding to use */
89 opus_int maxBits, /* I If > 0: maximum number of output bits */
90 opus_int useCBR /* I Flag to force constant-bitrate operation */
91)
92{
93 silk_encoder_control_FLP sEncCtrl;
94 opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
95 silk_float *x_frame, *res_pitch_frame;
96 silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
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_int32 pGains_Q16[ MAX_NB_SUBFR ];
106 opus_uint8 ec_buf_copy[ 1275 ];
107 opus_int gain_lock[ MAX_NB_SUBFR ] = {0};
108 opus_int16 best_gain_mult[ MAX_NB_SUBFR ];
109 opus_int best_sum[ MAX_NB_SUBFR ];
110
111 /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
112 LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
113
114 psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
115
116 /**************************************************************/
117 /* Set up Input Pointers, and insert frame in input buffer */
118 /**************************************************************/
119 /* pointers aligned with start of frame to encode */
120 x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */
121 res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */
122
123 /***************************************/
124 /* Ensure smooth bandwidth transitions */
125 /***************************************/
126 silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
127
128 /*******************************************/
129 /* Copy new frame to front of input buffer */
130 /*******************************************/
131 silk_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
132
133 /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */
134 for( i = 0; i < 8; i++ ) {
135 x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f;
136 }
137
138 if( !psEnc->sCmn.prefillFlag ) {
139 /*****************************************/
140 /* Find pitch lags, initial LPC analysis */
141 /*****************************************/
142 silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );
143
144 /************************/
145 /* Noise shape analysis */
146 /************************/
147 silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
148
149 /***************************************************/
150 /* Find linear prediction coefficients (LPC + LTP) */
151 /***************************************************/
152 silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
153
154 /****************************************/
155 /* Process gains */
156 /****************************************/
157 silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding );
158
159 /****************************************/
160 /* Low Bitrate Redundant Encoding */
161 /****************************************/
162 silk_LBRR_encode_FLP( psEnc, &sEncCtrl, x_frame, condCoding );
163
164 /* Loop over quantizer and entroy coding to control bitrate */
165 maxIter = 6;
166 gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
167 found_lower = 0;
168 found_upper = 0;
169 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
170 gainsID_lower = -1;
171 gainsID_upper = -1;
172 /* Copy part of the input state */
173 silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
174 silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
175 seed_copy = psEnc->sCmn.indices.Seed;
176 ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
177 ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
178 for( iter = 0; ; iter++ ) {
179 if( gainsID == gainsID_lower ) {
180 nBits = nBits_lower;
181 } else if( gainsID == gainsID_upper ) {
182 nBits = nBits_upper;
183 } else {
184 /* Restore part of the input state */
185 if( iter > 0 ) {
186 silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
187 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
188 psEnc->sCmn.indices.Seed = seed_copy;
189 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
190 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
191 }
192
193 /*****************************************/
194 /* Noise shaping quantization */
195 /*****************************************/
196 silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, x_frame );
197
198 if ( iter == maxIter && !found_lower ) {
199 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
200 }
201
202 /****************************************/
203 /* Encode Parameters */
204 /****************************************/
205 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
206
207 /****************************************/
208 /* Encode Excitation Signal */
209 /****************************************/
210 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
211 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
212
213 nBits = ec_tell( psRangeEnc );
214
215 /* If we still bust after the last iteration, do some damage control. */
216 if ( iter == maxIter && !found_lower && nBits > maxBits ) {
217 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
218
219 /* Keep gains the same as the last frame. */
220 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
221 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
222 psEnc->sCmn.indices.GainsIndices[ i ] = 4;
223 }
224 if (condCoding != CODE_CONDITIONALLY) {
225 psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
226 }
227 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
228 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
229 /* Clear all pulses. */
230 for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
231 psEnc->sCmn.pulses[ i ] = 0;
232 }
233
234 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
235
236 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
237 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
238
239 nBits = ec_tell( psRangeEnc );
240 }
241
242 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
243 break;
244 }
245 }
246
247 if( iter == maxIter ) {
248 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
249 /* Restore output state from earlier iteration that did meet the bitrate budget */
250 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
251 celt_assert( sRangeEnc_copy2.offs <= 1275 );
252 silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
253 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
254 psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
255 }
256 break;
257 }
258
259 if( nBits > maxBits ) {
260 if( found_lower == 0 && iter >= 2 ) {
261 /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
262 sEncCtrl.Lambda = silk_max_float(sEncCtrl.Lambda*1.5f, 1.5f);
263 /* Reducing dithering can help us hit the target. */
264 psEnc->sCmn.indices.quantOffsetType = 0;
265 found_upper = 0;
266 gainsID_upper = -1;
267 } else {
268 found_upper = 1;
269 nBits_upper = nBits;
270 gainMult_upper = gainMult_Q8;
271 gainsID_upper = gainsID;
272 }
273 } else if( nBits < maxBits - 5 ) {
274 found_lower = 1;
275 nBits_lower = nBits;
276 gainMult_lower = gainMult_Q8;
277 if( gainsID != gainsID_lower ) {
278 gainsID_lower = gainsID;
279 /* Copy part of the output state */
280 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
281 celt_assert( psRangeEnc->offs <= 1275 );
282 silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
283 silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
284 LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
285 }
286 } else {
287 /* Within 5 bits of budget: close enough */
288 break;
289 }
290
291 if ( !found_lower && nBits > maxBits ) {
292 int j;
293 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
294 int sum=0;
295 for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
296 sum += abs( psEnc->sCmn.pulses[j] );
297 }
298 if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
299 best_sum[i] = sum;
300 best_gain_mult[i] = gainMult_Q8;
301 } else {
302 gain_lock[i] = 1;
303 }
304 }
305 }
306 if( ( found_lower & found_upper ) == 0 ) {
307 /* Adjust gain according to high-rate rate/distortion curve */
308 if( nBits > maxBits ) {
309 if (gainMult_Q8 < 16384) {
310 gainMult_Q8 *= 2;
311 } else {
312 gainMult_Q8 = 32767;
313 }
314 } else {
315 opus_int32 gain_factor_Q16;
316 gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
317 gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
318 }
319 } else {
320 /* Adjust gain by interpolating */
321 gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower );
322 /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
323 if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
324 gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
325 } else
326 if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
327 gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
328 }
329 }
330
331 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
332 opus_int16 tmp;
333 if ( gain_lock[i] ) {
334 tmp = best_gain_mult[i];
335 } else {
336 tmp = gainMult_Q8;
337 }
338 pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
339 }
340
341 /* Quantize gains */
342 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
343 silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16,
344 &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
345
346 /* Unique identifier of gains vector */
347 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
348
349 /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
350 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
351 sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f;
352 }
353 }
354 }
355
356 /* Update input buffer */
357 silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
358 ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( silk_float ) );
359
360 /* Exit without entropy coding */
361 if( psEnc->sCmn.prefillFlag ) {
362 /* No payload */
363 *pnBytesOut = 0;
364 return ret;
365 }
366
367 /* Parameters needed for next frame */
368 psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
369 psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
370
371 /****************************************/
372 /* Finalize payload */
373 /****************************************/
374 psEnc->sCmn.first_frame_after_reset = 0;
375 /* Payload size */
376 *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
377
378 return ret;
379}
380
381/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */
382static OPUS_INLINE void silk_LBRR_encode_FLP(
383 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
384 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
385 const silk_float xfw[], /* I Input signal */
386 opus_int condCoding /* I The type of conditional coding used so far for this frame */
387)
388{
389 opus_int k;
390 opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
391 silk_float TempGains[ MAX_NB_SUBFR ];
392 SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
393 silk_nsq_state sNSQ_LBRR;
394
395 /*******************************************/
396 /* Control use of inband LBRR */
397 /*******************************************/
398 if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
399 psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
400
401 /* Copy noise shaping quantizer state and quantization indices from regular encoding */
402 silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
403 silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
404
405 /* Save original gains */
406 silk_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );
407
408 if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
409 /* First frame in packet or previous frame not LBRR coded */
410 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
411
412 /* Increase Gains to get target LBRR rate */
413 psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases;
414 psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
415 }
416
417 /* Decode to get gains in sync with decoder */
418 silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices,
419 &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
420
421 /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
422 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
423 psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f );
424 }
425
426 /*****************************************/
427 /* Noise shaping quantization */
428 /*****************************************/
429 silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR,
430 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw );
431
432 /* Restore original gains */
433 silk_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );
434 }
435}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c
new file mode 100644
index 0000000000..7bc7173c9c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c
@@ -0,0 +1,59 @@
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_FLP.h"
33
34/* sum of squares of a silk_float array, with result as double */
35double silk_energy_FLP(
36 const silk_float *data,
37 opus_int dataSize
38)
39{
40 opus_int i;
41 double result;
42
43 /* 4x unrolled loop */
44 result = 0.0;
45 for( i = 0; i < dataSize - 3; i += 4 ) {
46 result += data[ i + 0 ] * (double)data[ i + 0 ] +
47 data[ i + 1 ] * (double)data[ i + 1 ] +
48 data[ i + 2 ] * (double)data[ i + 2 ] +
49 data[ i + 3 ] * (double)data[ i + 3 ];
50 }
51
52 /* add any remaining products */
53 for( ; i < dataSize; i++ ) {
54 result += data[ i ] * (double)data[ i ];
55 }
56
57 silk_assert( result >= 0.0 );
58 return result;
59}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c
new file mode 100644
index 0000000000..fa3ffe7f8b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c
@@ -0,0 +1,104 @@
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 "define.h"
33#include "main_FLP.h"
34#include "tuning_parameters.h"
35
36/* LPC analysis */
37void silk_find_LPC_FLP(
38 silk_encoder_state *psEncC, /* I/O Encoder state */
39 opus_int16 NLSF_Q15[], /* O NLSFs */
40 const silk_float x[], /* I Input signal */
41 const silk_float minInvGain /* I Inverse of max prediction gain */
42)
43{
44 opus_int k, subfr_length;
45 silk_float a[ MAX_LPC_ORDER ];
46
47 /* Used only for NLSF interpolation */
48 silk_float res_nrg, res_nrg_2nd, res_nrg_interp;
49 opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
50 silk_float a_tmp[ MAX_LPC_ORDER ];
51 silk_float LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ];
52
53 subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;
54
55 /* Default: No interpolation */
56 psEncC->indices.NLSFInterpCoef_Q2 = 4;
57
58 /* Burg AR analysis for the full frame */
59 res_nrg = silk_burg_modified_FLP( a, x, minInvGain, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder );
60
61 if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
62 /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */
63 /* adding it to the residual energy of the first 10 ms in each iteration of the search below */
64 res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, minInvGain, subfr_length, MAX_NB_SUBFR / 2, psEncC->predictLPCOrder );
65
66 /* Convert to NLSFs */
67 silk_A2NLSF_FLP( NLSF_Q15, a_tmp, psEncC->predictLPCOrder );
68
69 /* Search over interpolation indices to find the one with lowest residual energy */
70 res_nrg_2nd = silk_float_MAX;
71 for( k = 3; k >= 0; k-- ) {
72 /* Interpolate NLSFs for first half */
73 silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
74
75 /* Convert to LPC for residual energy evaluation */
76 silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
77
78 /* Calculate residual energy with LSF interpolation */
79 silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder );
80 res_nrg_interp = (silk_float)(
81 silk_energy_FLP( LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ) +
82 silk_energy_FLP( LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ) );
83
84 /* Determine whether current interpolated NLSFs are best so far */
85 if( res_nrg_interp < res_nrg ) {
86 /* Interpolation has lower residual energy */
87 res_nrg = res_nrg_interp;
88 psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
89 } else if( res_nrg_interp > res_nrg_2nd ) {
90 /* No reason to continue iterating - residual energies will continue to climb */
91 break;
92 }
93 res_nrg_2nd = res_nrg_interp;
94 }
95 }
96
97 if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
98 /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
99 silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder );
100 }
101
102 celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
103 ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
104}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c
new file mode 100644
index 0000000000..f97064930e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c
@@ -0,0 +1,64 @@
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_FLP.h"
33#include "tuning_parameters.h"
34
35void silk_find_LTP_FLP(
36 silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
37 silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */
38 const silk_float r_ptr[], /* I LPC residual */
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)
43{
44 opus_int k;
45 silk_float *xX_ptr, *XX_ptr;
46 const silk_float *lag_ptr;
47 silk_float xx, temp;
48
49 xX_ptr = xX;
50 XX_ptr = XX;
51 for( k = 0; k < nb_subfr; k++ ) {
52 lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
53 silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, XX_ptr );
54 silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xX_ptr );
55 xx = ( silk_float )silk_energy_FLP( r_ptr, subfr_length + LTP_ORDER );
56 temp = 1.0f / silk_max( xx, LTP_CORR_INV_MAX * 0.5f * ( XX_ptr[ 0 ] + XX_ptr[ 24 ] ) + 1.0f );
57 silk_scale_vector_FLP( XX_ptr, temp, LTP_ORDER * LTP_ORDER );
58 silk_scale_vector_FLP( xX_ptr, temp, LTP_ORDER );
59
60 r_ptr += subfr_length;
61 XX_ptr += LTP_ORDER * LTP_ORDER;
62 xX_ptr += LTP_ORDER;
63 }
64}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c
new file mode 100644
index 0000000000..dedbcd2836
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c
@@ -0,0 +1,132 @@
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_FLP.h"
34#include "tuning_parameters.h"
35
36void silk_find_pitch_lags_FLP(
37 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
38 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
39 silk_float res[], /* O Residual */
40 const silk_float x[], /* I Speech signal */
41 int arch /* I Run-time architecture */
42)
43{
44 opus_int buf_len;
45 silk_float thrhld, res_nrg;
46 const silk_float *x_buf_ptr, *x_buf;
47 silk_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
48 silk_float A[ MAX_FIND_PITCH_LPC_ORDER ];
49 silk_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ];
50 silk_float Wsig[ FIND_PITCH_LPC_WIN_MAX ];
51 silk_float *Wsig_ptr;
52
53 /******************************************/
54 /* Set up buffer lengths etc based on Fs */
55 /******************************************/
56 buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
57
58 /* Safety check */
59 celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
60
61 x_buf = x - psEnc->sCmn.ltp_mem_length;
62
63 /******************************************/
64 /* Estimate LPC AR coeficients */
65 /******************************************/
66
67 /* Calculate windowed signal */
68
69 /* First LA_LTP samples */
70 x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;
71 Wsig_ptr = Wsig;
72 silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );
73
74 /* Middle non-windowed samples */
75 Wsig_ptr += psEnc->sCmn.la_pitch;
76 x_buf_ptr += psEnc->sCmn.la_pitch;
77 silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( silk_float ) );
78
79 /* Last LA_LTP samples */
80 Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 );
81 x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 );
82 silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );
83
84 /* Calculate autocorrelation sequence */
85 silk_autocorrelation_FLP( auto_corr, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 );
86
87 /* Add white noise, as a fraction of the energy */
88 auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION + 1;
89
90 /* Calculate the reflection coefficients using Schur */
91 res_nrg = silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );
92
93 /* Prediction gain */
94 psEncCtrl->predGain = auto_corr[ 0 ] / silk_max_float( res_nrg, 1.0f );
95
96 /* Convert reflection coefficients to prediction coefficients */
97 silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder );
98
99 /* Bandwidth expansion */
100 silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWIDTH_EXPANSION );
101
102 /*****************************************/
103 /* LPC analysis filtering */
104 /*****************************************/
105 silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder );
106
107 if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {
108 /* Threshold for pitch estimator */
109 thrhld = 0.6f;
110 thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder;
111 thrhld -= 0.1f * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
112 thrhld -= 0.15f * (psEnc->sCmn.prevSignalType >> 1);
113 thrhld -= 0.1f * psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f );
114
115 /*****************************************/
116 /* Call Pitch estimator */
117 /*****************************************/
118 if( silk_pitch_analysis_core_FLP( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex,
119 &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f,
120 thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, arch ) == 0 )
121 {
122 psEnc->sCmn.indices.signalType = TYPE_VOICED;
123 } else {
124 psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
125 }
126 } else {
127 silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) );
128 psEnc->sCmn.indices.lagIndex = 0;
129 psEnc->sCmn.indices.contourIndex = 0;
130 psEnc->LTPCorr = 0;
131 }
132}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c
new file mode 100644
index 0000000000..dcf7c5202d
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c
@@ -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#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33
34/* Find LPC and LTP coefficients */
35void silk_find_pred_coefs_FLP(
36 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
37 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
38 const silk_float res_pitch[], /* I Residual from pitch analysis */
39 const silk_float x[], /* I Speech signal */
40 opus_int condCoding /* I The type of conditional coding to use */
41)
42{
43 opus_int i;
44 silk_float XXLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
45 silk_float xXLTP[ MAX_NB_SUBFR * LTP_ORDER ];
46 silk_float invGains[ MAX_NB_SUBFR ];
47 opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
48 const silk_float *x_ptr;
49 silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
50 silk_float minInvGain;
51
52 /* Weighting for weighted least squares */
53 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
54 silk_assert( psEncCtrl->Gains[ i ] > 0.0f );
55 invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ];
56 }
57
58 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
59 /**********/
60 /* VOICED */
61 /**********/
62 celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
63
64 /* LTP analysis */
65 silk_find_LTP_FLP( XXLTP, xXLTP, res_pitch, psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );
66
67 /* Quantize LTP gain parameters */
68 silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
69 &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain, XXLTP, xXLTP, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
70
71 /* Control LTP scaling */
72 silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding );
73
74 /* Create LTP residual */
75 silk_LTP_analysis_filter_FLP( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef,
76 psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
77 } else {
78 /************/
79 /* UNVOICED */
80 /************/
81 /* Create signal with prepended subframes, scaled by inverse gains */
82 x_ptr = x - psEnc->sCmn.predictLPCOrder;
83 x_pre_ptr = LPC_in_pre;
84 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
85 silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ],
86 psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
87 x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
88 x_ptr += psEnc->sCmn.subfr_length;
89 }
90 silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) );
91 psEncCtrl->LTPredCodGain = 0.0f;
92 psEnc->sCmn.sum_log_gain_Q7 = 0;
93 }
94
95 /* Limit on total predictive coding gain */
96 if( psEnc->sCmn.first_frame_after_reset ) {
97 minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET;
98 } else {
99 minInvGain = (silk_float)pow( 2, psEncCtrl->LTPredCodGain / 3 ) / MAX_PREDICTION_POWER_GAIN;
100 minInvGain /= 0.25f + 0.75f * psEncCtrl->coding_quality;
101 }
102
103 /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
104 silk_find_LPC_FLP( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain );
105
106 /* Quantize LSFs */
107 silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
108
109 /* Calculate residual energy using quantized LPC coefficients */
110 silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains,
111 psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
112
113 /* Copy to prediction struct for use in next frame for interpolation */
114 silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
115}
116
diff --git a/lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c
new file mode 100644
index 0000000000..cdd39d24ce
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c
@@ -0,0 +1,59 @@
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_FLP.h"
33
34/* inner product of two silk_float arrays, with result as double */
35double silk_inner_product_FLP(
36 const silk_float *data1,
37 const silk_float *data2,
38 opus_int dataSize
39)
40{
41 opus_int i;
42 double result;
43
44 /* 4x unrolled loop */
45 result = 0.0;
46 for( i = 0; i < dataSize - 3; i += 4 ) {
47 result += data1[ i + 0 ] * (double)data2[ i + 0 ] +
48 data1[ i + 1 ] * (double)data2[ i + 1 ] +
49 data1[ i + 2 ] * (double)data2[ i + 2 ] +
50 data1[ i + 3 ] * (double)data2[ i + 3 ];
51 }
52
53 /* add any remaining products */
54 for( ; i < dataSize; i++ ) {
55 result += data1[ i ] * (double)data2[ i ];
56 }
57
58 return result;
59}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.c
new file mode 100644
index 0000000000..1448008dbb
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.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_FLP.h"
33
34/* step up function, converts reflection coefficients to prediction coefficients */
35void silk_k2a_FLP(
36 silk_float *A, /* O prediction coefficients [order] */
37 const silk_float *rc, /* I reflection coefficients [order] */
38 opus_int32 order /* I prediction order */
39)
40{
41 opus_int k, n;
42 silk_float rck, tmp1, tmp2;
43
44 for( k = 0; k < order; k++ ) {
45 rck = rc[ k ];
46 for( n = 0; n < (k + 1) >> 1; n++ ) {
47 tmp1 = A[ n ];
48 tmp2 = A[ k - n - 1 ];
49 A[ n ] = tmp1 + tmp2 * rck;
50 A[ k - n - 1 ] = tmp2 + tmp1 * rck;
51 }
52 A[ k ] = -rck;
53 }
54}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/main_FLP.h b/lib/rbcodec/codecs/libopus/silk/float/main_FLP.h
new file mode 100644
index 0000000000..5dc0ccf4a4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/main_FLP.h
@@ -0,0 +1,286 @@
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_FLP_H
29#define SILK_MAIN_FLP_H
30
31#include "SigProc_FLP.h"
32#include "SigProc_FIX.h"
33#include "structs_FLP.h"
34#include "main.h"
35#include "define.h"
36#include "debug.h"
37#include "entenc.h"
38
39#ifdef __cplusplus
40extern "C"
41{
42#endif
43
44#define silk_encoder_state_Fxx silk_encoder_state_FLP
45#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FLP
46#define silk_encode_frame_Fxx silk_encode_frame_FLP
47
48/*********************/
49/* Encoder Functions */
50/*********************/
51
52/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
53void silk_HP_variable_cutoff(
54 silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */
55);
56
57/* Encoder main function */
58void silk_encode_do_VAD_FLP(
59 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
60 opus_int activity /* I Decision of Opus voice activity detector */
61);
62
63/* Encoder main function */
64opus_int silk_encode_frame_FLP(
65 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
66 opus_int32 *pnBytesOut, /* O Number of payload bytes; */
67 ec_enc *psRangeEnc, /* I/O compressor data structure */
68 opus_int condCoding, /* I The type of conditional coding to use */
69 opus_int maxBits, /* I If > 0: maximum number of output bits */
70 opus_int useCBR /* I Flag to force constant-bitrate operation */
71);
72
73/* Initializes the Silk encoder state */
74opus_int silk_init_encoder(
75 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
76 int arch /* I Run-tim architecture */
77);
78
79/* Control the Silk encoder */
80opus_int silk_control_encoder(
81 silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
82 silk_EncControlStruct *encControl, /* I Control structure */
83 const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
84 const opus_int channelNb, /* I Channel number */
85 const opus_int force_fs_kHz
86);
87
88/**************************/
89/* Noise shaping analysis */
90/**************************/
91/* Compute noise shaping coefficients and initial gain values */
92void silk_noise_shape_analysis_FLP(
93 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
94 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
95 const silk_float *pitch_res, /* I LPC residual from pitch analysis */
96 const silk_float *x /* I Input signal [frame_length + la_shape] */
97);
98
99/* Autocorrelations for a warped frequency axis */
100void silk_warped_autocorrelation_FLP(
101 silk_float *corr, /* O Result [order + 1] */
102 const silk_float *input, /* I Input data to correlate */
103 const silk_float warping, /* I Warping coefficient */
104 const opus_int length, /* I Length of input */
105 const opus_int order /* I Correlation order (even) */
106);
107
108/* Calculation of LTP state scaling */
109void silk_LTP_scale_ctrl_FLP(
110 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
111 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
112 opus_int condCoding /* I The type of conditional coding to use */
113);
114
115/**********************************************/
116/* Prediction Analysis */
117/**********************************************/
118/* Find pitch lags */
119void silk_find_pitch_lags_FLP(
120 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
121 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
122 silk_float res[], /* O Residual */
123 const silk_float x[], /* I Speech signal */
124 int arch /* I Run-time architecture */
125);
126
127/* Find LPC and LTP coefficients */
128void silk_find_pred_coefs_FLP(
129 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
130 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
131 const silk_float res_pitch[], /* I Residual from pitch analysis */
132 const silk_float x[], /* I Speech signal */
133 opus_int condCoding /* I The type of conditional coding to use */
134);
135
136/* LPC analysis */
137void silk_find_LPC_FLP(
138 silk_encoder_state *psEncC, /* I/O Encoder state */
139 opus_int16 NLSF_Q15[], /* O NLSFs */
140 const silk_float x[], /* I Input signal */
141 const silk_float minInvGain /* I Prediction gain from LTP (dB) */
142);
143
144/* LTP analysis */
145void silk_find_LTP_FLP(
146 silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
147 silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */
148 const silk_float r_ptr[], /* I LPC residual */
149 const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
150 const opus_int subfr_length, /* I Subframe length */
151 const opus_int nb_subfr /* I number of subframes */
152);
153
154void silk_LTP_analysis_filter_FLP(
155 silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */
156 const silk_float *x, /* I Input signal, with preceding samples */
157 const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */
158 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
159 const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */
160 const opus_int subfr_length, /* I Length of each subframe */
161 const opus_int nb_subfr, /* I number of subframes */
162 const opus_int pre_length /* I Preceding samples for each subframe */
163);
164
165/* Calculates residual energies of input subframes where all subframes have LPC_order */
166/* of preceding samples */
167void silk_residual_energy_FLP(
168 silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
169 const silk_float x[], /* I Input signal */
170 silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
171 const silk_float gains[], /* I Quantization gains */
172 const opus_int subfr_length, /* I Subframe length */
173 const opus_int nb_subfr, /* I number of subframes */
174 const opus_int LPC_order /* I LPC order */
175);
176
177/* 16th order LPC analysis filter */
178void silk_LPC_analysis_filter_FLP(
179 silk_float r_LPC[], /* O LPC residual signal */
180 const silk_float PredCoef[], /* I LPC coefficients */
181 const silk_float s[], /* I Input signal */
182 const opus_int length, /* I Length of input signal */
183 const opus_int Order /* I LPC order */
184);
185
186/* LTP tap quantizer */
187void silk_quant_LTP_gains_FLP(
188 silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
189 opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */
190 opus_int8 *periodicity_index, /* O Periodicity index */
191 opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
192 silk_float *pred_gain_dB, /* O LTP prediction gain */
193 const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */
194 const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */
195 const opus_int subfr_len, /* I Number of samples per subframe */
196 const opus_int nb_subfr, /* I Number of subframes */
197 int arch /* I Run-time architecture */
198);
199
200/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
201silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */
202 const silk_float *c, /* I Filter coefficients */
203 silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */
204 const silk_float *wXx, /* I Weighted correlation vector */
205 const silk_float wxx, /* I Weighted correlation value */
206 const opus_int D /* I Dimension */
207);
208
209/* Processing of gains */
210void silk_process_gains_FLP(
211 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
212 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
213 opus_int condCoding /* I The type of conditional coding to use */
214);
215
216/******************/
217/* Linear Algebra */
218/******************/
219/* Calculates correlation matrix X'*X */
220void silk_corrMatrix_FLP(
221 const silk_float *x, /* I x vector [ L+order-1 ] used to create X */
222 const opus_int L, /* I Length of vectors */
223 const opus_int Order, /* I Max lag for correlation */
224 silk_float *XX /* O X'*X correlation matrix [order x order] */
225);
226
227/* Calculates correlation vector X'*t */
228void silk_corrVector_FLP(
229 const silk_float *x, /* I x vector [L+order-1] used to create X */
230 const silk_float *t, /* I Target vector [L] */
231 const opus_int L, /* I Length of vecors */
232 const opus_int Order, /* I Max lag for correlation */
233 silk_float *Xt /* O X'*t correlation vector [order] */
234);
235
236/* Apply sine window to signal vector. */
237/* Window types: */
238/* 1 -> sine window from 0 to pi/2 */
239/* 2 -> sine window from pi/2 to pi */
240void silk_apply_sine_window_FLP(
241 silk_float px_win[], /* O Pointer to windowed signal */
242 const silk_float px[], /* I Pointer to input signal */
243 const opus_int win_type, /* I Selects a window type */
244 const opus_int length /* I Window length, multiple of 4 */
245);
246
247/* Wrapper functions. Call flp / fix code */
248
249/* Convert AR filter coefficients to NLSF parameters */
250void silk_A2NLSF_FLP(
251 opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */
252 const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */
253 const opus_int LPC_order /* I LPC order */
254);
255
256/* Convert NLSF parameters to AR prediction filter coefficients */
257void silk_NLSF2A_FLP(
258 silk_float *pAR, /* O LPC coefficients [ LPC_order ] */
259 const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
260 const opus_int LPC_order, /* I LPC order */
261 int arch /* I Run-time architecture */
262);
263
264/* Limit, stabilize, and quantize NLSFs */
265void silk_process_NLSFs_FLP(
266 silk_encoder_state *psEncC, /* I/O Encoder state */
267 silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */
268 opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */
269 const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */
270);
271
272/* Floating-point Silk NSQ wrapper */
273void silk_NSQ_wrapper_FLP(
274 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
275 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
276 SideInfoIndices *psIndices, /* I/O Quantization indices */
277 silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */
278 opus_int8 pulses[], /* O Quantized pulse signal */
279 const silk_float x[] /* I Prefiltered input signal */
280);
281
282#ifdef __cplusplus
283}
284#endif
285
286#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c
new file mode 100644
index 0000000000..cb3d8a50b7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c
@@ -0,0 +1,350 @@
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_FLP.h"
33#include "tuning_parameters.h"
34
35/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */
36/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */
37/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */
38/* coefficient in an array of coefficients, for monic filters. */
39static OPUS_INLINE silk_float warped_gain(
40 const silk_float *coefs,
41 silk_float lambda,
42 opus_int order
43) {
44 opus_int i;
45 silk_float gain;
46
47 lambda = -lambda;
48 gain = coefs[ order - 1 ];
49 for( i = order - 2; i >= 0; i-- ) {
50 gain = lambda * gain + coefs[ i ];
51 }
52 return (silk_float)( 1.0f / ( 1.0f - lambda * gain ) );
53}
54
55/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
56/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
57static OPUS_INLINE void warped_true2monic_coefs(
58 silk_float *coefs,
59 silk_float lambda,
60 silk_float limit,
61 opus_int order
62) {
63 opus_int i, iter, ind = 0;
64 silk_float tmp, maxabs, chirp, gain;
65
66 /* Convert to monic coefficients */
67 for( i = order - 1; i > 0; i-- ) {
68 coefs[ i - 1 ] -= lambda * coefs[ i ];
69 }
70 gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] );
71 for( i = 0; i < order; i++ ) {
72 coefs[ i ] *= gain;
73 }
74
75 /* Limit */
76 for( iter = 0; iter < 10; iter++ ) {
77 /* Find maximum absolute value */
78 maxabs = -1.0f;
79 for( i = 0; i < order; i++ ) {
80 tmp = silk_abs_float( coefs[ i ] );
81 if( tmp > maxabs ) {
82 maxabs = tmp;
83 ind = i;
84 }
85 }
86 if( maxabs <= limit ) {
87 /* Coefficients are within range - done */
88 return;
89 }
90
91 /* Convert back to true warped coefficients */
92 for( i = 1; i < order; i++ ) {
93 coefs[ i - 1 ] += lambda * coefs[ i ];
94 }
95 gain = 1.0f / gain;
96 for( i = 0; i < order; i++ ) {
97 coefs[ i ] *= gain;
98 }
99
100 /* Apply bandwidth expansion */
101 chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
102 silk_bwexpander_FLP( coefs, order, chirp );
103
104 /* Convert to monic warped coefficients */
105 for( i = order - 1; i > 0; i-- ) {
106 coefs[ i - 1 ] -= lambda * coefs[ i ];
107 }
108 gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] );
109 for( i = 0; i < order; i++ ) {
110 coefs[ i ] *= gain;
111 }
112 }
113 silk_assert( 0 );
114}
115
116static OPUS_INLINE void limit_coefs(
117 silk_float *coefs,
118 silk_float limit,
119 opus_int order
120) {
121 opus_int i, iter, ind = 0;
122 silk_float tmp, maxabs, chirp;
123
124 for( iter = 0; iter < 10; iter++ ) {
125 /* Find maximum absolute value */
126 maxabs = -1.0f;
127 for( i = 0; i < order; i++ ) {
128 tmp = silk_abs_float( coefs[ i ] );
129 if( tmp > maxabs ) {
130 maxabs = tmp;
131 ind = i;
132 }
133 }
134 if( maxabs <= limit ) {
135 /* Coefficients are within range - done */
136 return;
137 }
138
139 /* Apply bandwidth expansion */
140 chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
141 silk_bwexpander_FLP( coefs, order, chirp );
142 }
143 silk_assert( 0 );
144}
145
146/* Compute noise shaping coefficients and initial gain values */
147void silk_noise_shape_analysis_FLP(
148 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
149 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
150 const silk_float *pitch_res, /* I LPC residual from pitch analysis */
151 const silk_float *x /* I Input signal [frame_length + la_shape] */
152)
153{
154 silk_shape_state_FLP *psShapeSt = &psEnc->sShape;
155 opus_int k, nSamples, nSegs;
156 silk_float SNR_adj_dB, HarmShapeGain, Tilt;
157 silk_float nrg, log_energy, log_energy_prev, energy_variation;
158 silk_float BWExp, gain_mult, gain_add, strength, b, warping;
159 silk_float x_windowed[ SHAPE_LPC_WIN_MAX ];
160 silk_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
161 silk_float rc[ MAX_SHAPE_LPC_ORDER + 1 ];
162 const silk_float *x_ptr, *pitch_res_ptr;
163
164 /* Point to start of first LPC analysis block */
165 x_ptr = x - psEnc->sCmn.la_shape;
166
167 /****************/
168 /* GAIN CONTROL */
169 /****************/
170 SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f );
171
172 /* Input quality is the average of the quality in the lowest two VAD bands */
173 psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f );
174
175 /* Coding quality level, between 0.0 and 1.0 */
176 psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 20.0f ) );
177
178 if( psEnc->sCmn.useCBR == 0 ) {
179 /* Reduce coding SNR during low speech activity */
180 b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
181 SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b;
182 }
183
184 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
185 /* Reduce gains for periodic signals */
186 SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr;
187 } else {
188 /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
189 SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality );
190 }
191
192 /*************************/
193 /* SPARSENESS PROCESSING */
194 /*************************/
195 /* Set quantizer offset */
196 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
197 /* Initially set to 0; may be overruled in process_gains(..) */
198 psEnc->sCmn.indices.quantOffsetType = 0;
199 } else {
200 /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
201 nSamples = 2 * psEnc->sCmn.fs_kHz;
202 energy_variation = 0.0f;
203 log_energy_prev = 0.0f;
204 pitch_res_ptr = pitch_res;
205 nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
206 for( k = 0; k < nSegs; k++ ) {
207 nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples );
208 log_energy = silk_log2( nrg );
209 if( k > 0 ) {
210 energy_variation += silk_abs_float( log_energy - log_energy_prev );
211 }
212 log_energy_prev = log_energy;
213 pitch_res_ptr += nSamples;
214 }
215
216 /* Set quantization offset depending on sparseness measure */
217 if( energy_variation > ENERGY_VARIATION_THRESHOLD_QNT_OFFSET * (nSegs-1) ) {
218 psEnc->sCmn.indices.quantOffsetType = 0;
219 } else {
220 psEnc->sCmn.indices.quantOffsetType = 1;
221 }
222 }
223
224 /*******************************/
225 /* Control bandwidth expansion */
226 /*******************************/
227 /* More BWE for signals with high prediction gain */
228 strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */
229 BWExp = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );
230
231 /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
232 warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;
233
234 /********************************************/
235 /* Compute noise shaping AR coefs and gains */
236 /********************************************/
237 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
238 /* Apply window: sine slope followed by flat part followed by cosine slope */
239 opus_int shift, slope_part, flat_part;
240 flat_part = psEnc->sCmn.fs_kHz * 3;
241 slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2;
242
243 silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part );
244 shift = slope_part;
245 silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(silk_float) );
246 shift += flat_part;
247 silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part );
248
249 /* Update pointer: next LPC analysis block */
250 x_ptr += psEnc->sCmn.subfr_length;
251
252 if( psEnc->sCmn.warping_Q16 > 0 ) {
253 /* Calculate warped auto correlation */
254 silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping,
255 psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
256 } else {
257 /* Calculate regular auto correlation */
258 silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 );
259 }
260
261 /* Add white noise, as a fraction of energy */
262 auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION + 1.0f;
263
264 /* Convert correlations to prediction coefficients, and compute residual energy */
265 nrg = silk_schur_FLP( rc, auto_corr, psEnc->sCmn.shapingLPCOrder );
266 silk_k2a_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], rc, psEnc->sCmn.shapingLPCOrder );
267 psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg );
268
269 if( psEnc->sCmn.warping_Q16 > 0 ) {
270 /* Adjust gain for warping */
271 psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );
272 }
273
274 /* Bandwidth expansion for synthesis filter shaping */
275 silk_bwexpander_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp );
276
277 if( psEnc->sCmn.warping_Q16 > 0 ) {
278 /* Convert to monic warped prediction coefficients and limit absolute values */
279 warped_true2monic_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, 3.999f, psEnc->sCmn.shapingLPCOrder );
280 } else {
281 /* Limit absolute values */
282 limit_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], 3.999f, psEnc->sCmn.shapingLPCOrder );
283 }
284 }
285
286 /*****************/
287 /* Gain tweaking */
288 /*****************/
289 /* Increase gains during low speech activity */
290 gain_mult = (silk_float)pow( 2.0f, -0.16f * SNR_adj_dB );
291 gain_add = (silk_float)pow( 2.0f, 0.16f * MIN_QGAIN_DB );
292 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
293 psEncCtrl->Gains[ k ] *= gain_mult;
294 psEncCtrl->Gains[ k ] += gain_add;
295 }
296
297 /************************************************/
298 /* Control low-frequency shaping and noise tilt */
299 /************************************************/
300 /* Less low frequency shaping for noisy inputs */
301 strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] * ( 1.0f / 32768.0f ) - 1.0f ) );
302 strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
303 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
304 /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
305 /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
306 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
307 b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ];
308 psEncCtrl->LF_MA_shp[ k ] = -1.0f + b;
309 psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength;
310 }
311 Tilt = - HP_NOISE_COEF -
312 (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
313 } else {
314 b = 1.3f / psEnc->sCmn.fs_kHz;
315 psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b;
316 psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f;
317 for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
318 psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ];
319 psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ];
320 }
321 Tilt = -HP_NOISE_COEF;
322 }
323
324 /****************************/
325 /* HARMONIC SHAPING CONTROL */
326 /****************************/
327 if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
328 /* Harmonic noise shaping */
329 HarmShapeGain = HARMONIC_SHAPING;
330
331 /* More harmonic noise shaping for high bitrates or noisy input */
332 HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING *
333 ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality );
334
335 /* Less harmonic noise shaping for less periodic signals */
336 HarmShapeGain *= ( silk_float )sqrt( psEnc->LTPCorr );
337 } else {
338 HarmShapeGain = 0.0f;
339 }
340
341 /*************************/
342 /* Smooth over subframes */
343 /*************************/
344 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
345 psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth );
346 psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth;
347 psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth );
348 psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth;
349 }
350}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c
new file mode 100644
index 0000000000..f351bc3718
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c
@@ -0,0 +1,630 @@
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_FLP.h"
36#include "SigProc_FIX.h"
37#include "pitch_est_defines.h"
38#include "pitch.h"
39
40#define SCRATCH_SIZE 22
41
42/************************************************************/
43/* Internally used functions */
44/************************************************************/
45static void silk_P_Ana_calc_corr_st3(
46 silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
47 const silk_float frame[], /* I vector to correlate */
48 opus_int start_lag, /* I start lag */
49 opus_int sf_length, /* I sub frame length */
50 opus_int nb_subfr, /* I number of subframes */
51 opus_int complexity, /* I Complexity setting */
52 int arch /* I Run-time architecture */
53);
54
55static void silk_P_Ana_calc_energy_st3(
56 silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
57 const silk_float frame[], /* I vector to correlate */
58 opus_int start_lag, /* I start lag */
59 opus_int sf_length, /* I sub frame length */
60 opus_int nb_subfr, /* I number of subframes */
61 opus_int complexity /* I Complexity setting */
62);
63
64/************************************************************/
65/* CORE PITCH ANALYSIS FUNCTION */
66/************************************************************/
67opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */
68 const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
69 opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */
70 opus_int16 *lagIndex, /* O Lag Index */
71 opus_int8 *contourIndex, /* O Pitch contour Index */
72 silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */
73 opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
74 const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */
75 const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */
76 const opus_int Fs_kHz, /* I sample frequency (kHz) */
77 const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
78 const opus_int nb_subfr, /* I Number of 5 ms subframes */
79 int arch /* I Run-time architecture */
80)
81{
82 opus_int i, k, d, j;
83 silk_float frame_8kHz[ PE_MAX_FRAME_LENGTH_MS * 8 ];
84 silk_float frame_4kHz[ PE_MAX_FRAME_LENGTH_MS * 4 ];
85 opus_int16 frame_8_FIX[ PE_MAX_FRAME_LENGTH_MS * 8 ];
86 opus_int16 frame_4_FIX[ PE_MAX_FRAME_LENGTH_MS * 4 ];
87 opus_int32 filt_state[ 6 ];
88 silk_float threshold, contour_bias;
89 silk_float C[ PE_MAX_NB_SUBFR][ (PE_MAX_LAG >> 1) + 5 ];
90 opus_val32 xcorr[ PE_MAX_LAG_MS * 4 - PE_MIN_LAG_MS * 4 + 1 ];
91 silk_float CC[ PE_NB_CBKS_STAGE2_EXT ];
92 const silk_float *target_ptr, *basis_ptr;
93 double cross_corr, normalizer, energy, energy_tmp;
94 opus_int d_srch[ PE_D_SRCH_LENGTH ];
95 opus_int16 d_comp[ (PE_MAX_LAG >> 1) + 5 ];
96 opus_int length_d_srch, length_d_comp;
97 silk_float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new;
98 opus_int CBimax, CBimax_new, lag, start_lag, end_lag, lag_new;
99 opus_int cbk_size;
100 silk_float lag_log2, prevLag_log2, delta_lag_log2_sqr;
101 silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
102 silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
103 opus_int lag_counter;
104 opus_int frame_length, frame_length_8kHz, frame_length_4kHz;
105 opus_int sf_length, sf_length_8kHz, sf_length_4kHz;
106 opus_int min_lag, min_lag_8kHz, min_lag_4kHz;
107 opus_int max_lag, max_lag_8kHz, max_lag_4kHz;
108 opus_int nb_cbk_search;
109 const opus_int8 *Lag_CB_ptr;
110
111 /* Check for valid sampling frequency */
112 celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
113
114 /* Check for valid complexity setting */
115 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
116 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
117
118 silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f );
119 silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f );
120
121 /* Set up frame lengths max / min lag for the sampling frequency */
122 frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
123 frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
124 frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
125 sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz;
126 sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4;
127 sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8;
128 min_lag = PE_MIN_LAG_MS * Fs_kHz;
129 min_lag_4kHz = PE_MIN_LAG_MS * 4;
130 min_lag_8kHz = PE_MIN_LAG_MS * 8;
131 max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
132 max_lag_4kHz = PE_MAX_LAG_MS * 4;
133 max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1;
134
135 /* Resample from input sampled at Fs_kHz to 8 kHz */
136 if( Fs_kHz == 16 ) {
137 /* Resample to 16 -> 8 khz */
138 opus_int16 frame_16_FIX[ 16 * PE_MAX_FRAME_LENGTH_MS ];
139 silk_float2short_array( frame_16_FIX, frame, frame_length );
140 silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
141 silk_resampler_down2( filt_state, frame_8_FIX, frame_16_FIX, frame_length );
142 silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );
143 } else if( Fs_kHz == 12 ) {
144 /* Resample to 12 -> 8 khz */
145 opus_int16 frame_12_FIX[ 12 * PE_MAX_FRAME_LENGTH_MS ];
146 silk_float2short_array( frame_12_FIX, frame, frame_length );
147 silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
148 silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length );
149 silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );
150 } else {
151 celt_assert( Fs_kHz == 8 );
152 silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz );
153 }
154
155 /* Decimate again to 4 kHz */
156 silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
157 silk_resampler_down2( filt_state, frame_4_FIX, frame_8_FIX, frame_length_8kHz );
158 silk_short2float_array( frame_4kHz, frame_4_FIX, frame_length_4kHz );
159
160 /* Low-pass filter */
161 for( i = frame_length_4kHz - 1; i > 0; i-- ) {
162 frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
163 }
164
165 /******************************************************************************
166 * FIRST STAGE, operating in 4 khz
167 ******************************************************************************/
168 silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5));
169 target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ];
170 for( k = 0; k < nb_subfr >> 1; k++ ) {
171 /* Check that we are within range of the array */
172 celt_assert( target_ptr >= frame_4kHz );
173 celt_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
174
175 basis_ptr = target_ptr - min_lag_4kHz;
176
177 /* Check that we are within range of the array */
178 celt_assert( basis_ptr >= frame_4kHz );
179 celt_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
180
181 celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1, arch );
182
183 /* Calculate first vector products before loop */
184 cross_corr = xcorr[ max_lag_4kHz - min_lag_4kHz ];
185 normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) +
186 silk_energy_FLP( basis_ptr, sf_length_8kHz ) +
187 sf_length_8kHz * 4000.0f;
188
189 C[ 0 ][ min_lag_4kHz ] += (silk_float)( 2 * cross_corr / normalizer );
190
191 /* From now on normalizer is computed recursively */
192 for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) {
193 basis_ptr--;
194
195 /* Check that we are within range of the array */
196 silk_assert( basis_ptr >= frame_4kHz );
197 silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
198
199 cross_corr = xcorr[ max_lag_4kHz - d ];
200
201 /* Add contribution of new sample and remove contribution from oldest sample */
202 normalizer +=
203 basis_ptr[ 0 ] * (double)basis_ptr[ 0 ] -
204 basis_ptr[ sf_length_8kHz ] * (double)basis_ptr[ sf_length_8kHz ];
205 C[ 0 ][ d ] += (silk_float)( 2 * cross_corr / normalizer );
206 }
207 /* Update target pointer */
208 target_ptr += sf_length_8kHz;
209 }
210
211 /* Apply short-lag bias */
212 for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
213 C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f;
214 }
215
216 /* Sort */
217 length_d_srch = 4 + 2 * complexity;
218 celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
219 silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
220
221 /* Escape if correlation is very low already here */
222 Cmax = C[ 0 ][ min_lag_4kHz ];
223 if( Cmax < 0.2f ) {
224 silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
225 *LTPCorr = 0.0f;
226 *lagIndex = 0;
227 *contourIndex = 0;
228 return 1;
229 }
230
231 threshold = search_thres1 * Cmax;
232 for( i = 0; i < length_d_srch; i++ ) {
233 /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
234 if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) {
235 d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 );
236 } else {
237 length_d_srch = i;
238 break;
239 }
240 }
241 celt_assert( length_d_srch > 0 );
242
243 for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
244 d_comp[ i ] = 0;
245 }
246 for( i = 0; i < length_d_srch; i++ ) {
247 d_comp[ d_srch[ i ] ] = 1;
248 }
249
250 /* Convolution */
251 for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
252 d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ];
253 }
254
255 length_d_srch = 0;
256 for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) {
257 if( d_comp[ i + 1 ] > 0 ) {
258 d_srch[ length_d_srch ] = i;
259 length_d_srch++;
260 }
261 }
262
263 /* Convolution */
264 for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
265 d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ];
266 }
267
268 length_d_comp = 0;
269 for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) {
270 if( d_comp[ i ] > 0 ) {
271 d_comp[ length_d_comp ] = (opus_int16)( i - 2 );
272 length_d_comp++;
273 }
274 }
275
276 /**********************************************************************************
277 ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
278 *************************************************************************************/
279 /*********************************************************************************
280 * Find energy of each subframe projected onto its history, for a range of delays
281 *********************************************************************************/
282 silk_memset( C, 0, PE_MAX_NB_SUBFR*((PE_MAX_LAG >> 1) + 5) * sizeof(silk_float));
283
284 if( Fs_kHz == 8 ) {
285 target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * 8 ];
286 } else {
287 target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];
288 }
289 for( k = 0; k < nb_subfr; k++ ) {
290 energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ) + 1.0;
291 for( j = 0; j < length_d_comp; j++ ) {
292 d = d_comp[ j ];
293 basis_ptr = target_ptr - d;
294 cross_corr = silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz );
295 if( cross_corr > 0.0f ) {
296 energy = silk_energy_FLP( basis_ptr, sf_length_8kHz );
297 C[ k ][ d ] = (silk_float)( 2 * cross_corr / ( energy + energy_tmp ) );
298 } else {
299 C[ k ][ d ] = 0.0f;
300 }
301 }
302 target_ptr += sf_length_8kHz;
303 }
304
305 /* search over lag range and lags codebook */
306 /* scale factor for lag codebook, as a function of center lag */
307
308 CCmax = 0.0f; /* This value doesn't matter */
309 CCmax_b = -1000.0f;
310
311 CBimax = 0; /* To avoid returning undefined lag values */
312 lag = -1; /* To check if lag with strong enough correlation has been found */
313
314 if( prevLag > 0 ) {
315 if( Fs_kHz == 12 ) {
316 prevLag = silk_LSHIFT( prevLag, 1 ) / 3;
317 } else if( Fs_kHz == 16 ) {
318 prevLag = silk_RSHIFT( prevLag, 1 );
319 }
320 prevLag_log2 = silk_log2( (silk_float)prevLag );
321 } else {
322 prevLag_log2 = 0;
323 }
324
325 /* Set up stage 2 codebook based on number of subframes */
326 if( nb_subfr == PE_MAX_NB_SUBFR ) {
327 cbk_size = PE_NB_CBKS_STAGE2_EXT;
328 Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
329 if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {
330 /* If input is 8 khz use a larger codebook here because it is last stage */
331 nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;
332 } else {
333 nb_cbk_search = PE_NB_CBKS_STAGE2;
334 }
335 } else {
336 cbk_size = PE_NB_CBKS_STAGE2_10MS;
337 Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
338 nb_cbk_search = PE_NB_CBKS_STAGE2_10MS;
339 }
340
341 for( k = 0; k < length_d_srch; k++ ) {
342 d = d_srch[ k ];
343 for( j = 0; j < nb_cbk_search; j++ ) {
344 CC[j] = 0.0f;
345 for( i = 0; i < nb_subfr; i++ ) {
346 /* Try all codebooks */
347 CC[ j ] += C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )];
348 }
349 }
350 /* Find best codebook */
351 CCmax_new = -1000.0f;
352 CBimax_new = 0;
353 for( i = 0; i < nb_cbk_search; i++ ) {
354 if( CC[ i ] > CCmax_new ) {
355 CCmax_new = CC[ i ];
356 CBimax_new = i;
357 }
358 }
359
360 /* Bias towards shorter lags */
361 lag_log2 = silk_log2( (silk_float)d );
362 CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr * lag_log2;
363
364 /* Bias towards previous lag */
365 if( prevLag > 0 ) {
366 delta_lag_log2_sqr = lag_log2 - prevLag_log2;
367 delta_lag_log2_sqr *= delta_lag_log2_sqr;
368 CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / ( delta_lag_log2_sqr + 0.5f );
369 }
370
371 if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
372 CCmax_new > nb_subfr * search_thres2 /* Correlation needs to be high enough to be voiced */
373 ) {
374 CCmax_b = CCmax_new_b;
375 CCmax = CCmax_new;
376 lag = d;
377 CBimax = CBimax_new;
378 }
379 }
380
381 if( lag == -1 ) {
382 /* No suitable candidate found */
383 silk_memset( pitch_out, 0, PE_MAX_NB_SUBFR * sizeof(opus_int) );
384 *LTPCorr = 0.0f;
385 *lagIndex = 0;
386 *contourIndex = 0;
387 return 1;
388 }
389
390 /* Output normalized correlation */
391 *LTPCorr = (silk_float)( CCmax / nb_subfr );
392 silk_assert( *LTPCorr >= 0.0f );
393
394 if( Fs_kHz > 8 ) {
395 /* Search in original signal */
396
397 /* Compensate for decimation */
398 silk_assert( lag == silk_SAT16( lag ) );
399 if( Fs_kHz == 12 ) {
400 lag = silk_RSHIFT_ROUND( silk_SMULBB( lag, 3 ), 1 );
401 } else { /* Fs_kHz == 16 */
402 lag = silk_LSHIFT( lag, 1 );
403 }
404
405 lag = silk_LIMIT_int( lag, min_lag, max_lag );
406 start_lag = silk_max_int( lag - 2, min_lag );
407 end_lag = silk_min_int( lag + 2, max_lag );
408 lag_new = lag; /* to avoid undefined lag */
409 CBimax = 0; /* to avoid undefined lag */
410
411 CCmax = -1000.0f;
412
413 /* Calculate the correlations and energies needed in stage 3 */
414 silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
415 silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity );
416
417 lag_counter = 0;
418 silk_assert( lag == silk_SAT16( lag ) );
419 contour_bias = PE_FLATCONTOUR_BIAS / lag;
420
421 /* Set up cbk parameters according to complexity setting and frame length */
422 if( nb_subfr == PE_MAX_NB_SUBFR ) {
423 nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
424 cbk_size = PE_NB_CBKS_STAGE3_MAX;
425 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
426 } else {
427 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
428 cbk_size = PE_NB_CBKS_STAGE3_10MS;
429 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
430 }
431
432 target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
433 energy_tmp = silk_energy_FLP( target_ptr, nb_subfr * sf_length ) + 1.0;
434 for( d = start_lag; d <= end_lag; d++ ) {
435 for( j = 0; j < nb_cbk_search; j++ ) {
436 cross_corr = 0.0;
437 energy = energy_tmp;
438 for( k = 0; k < nb_subfr; k++ ) {
439 cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ];
440 energy += energies_st3[ k ][ j ][ lag_counter ];
441 }
442 if( cross_corr > 0.0 ) {
443 CCmax_new = (silk_float)( 2 * cross_corr / energy );
444 /* Reduce depending on flatness of contour */
445 CCmax_new *= 1.0f - contour_bias * j;
446 } else {
447 CCmax_new = 0.0f;
448 }
449
450 if( CCmax_new > CCmax && ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) {
451 CCmax = CCmax_new;
452 lag_new = d;
453 CBimax = j;
454 }
455 }
456 lag_counter++;
457 }
458
459 for( k = 0; k < nb_subfr; k++ ) {
460 pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
461 pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );
462 }
463 *lagIndex = (opus_int16)( lag_new - min_lag );
464 *contourIndex = (opus_int8)CBimax;
465 } else { /* Fs_kHz == 8 */
466 /* Save Lags */
467 for( k = 0; k < nb_subfr; k++ ) {
468 pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
469 pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * 8 );
470 }
471 *lagIndex = (opus_int16)( lag - min_lag_8kHz );
472 *contourIndex = (opus_int8)CBimax;
473 }
474 celt_assert( *lagIndex >= 0 );
475 /* return as voiced */
476 return 0;
477}
478
479/***********************************************************************
480 * Calculates the correlations used in stage 3 search. In order to cover
481 * the whole lag codebook for all the searched offset lags (lag +- 2),
482 * the following correlations are needed in each sub frame:
483 *
484 * sf1: lag range [-8,...,7] total 16 correlations
485 * sf2: lag range [-4,...,4] total 9 correlations
486 * sf3: lag range [-3,....4] total 8 correltions
487 * sf4: lag range [-6,....8] total 15 correlations
488 *
489 * In total 48 correlations. The direct implementation computed in worst
490 * case 4*12*5 = 240 correlations, but more likely around 120.
491 ***********************************************************************/
492static void silk_P_Ana_calc_corr_st3(
493 silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
494 const silk_float frame[], /* I vector to correlate */
495 opus_int start_lag, /* I start lag */
496 opus_int sf_length, /* I sub frame length */
497 opus_int nb_subfr, /* I number of subframes */
498 opus_int complexity, /* I Complexity setting */
499 int arch /* I Run-time architecture */
500)
501{
502 const silk_float *target_ptr;
503 opus_int i, j, k, lag_counter, lag_low, lag_high;
504 opus_int nb_cbk_search, delta, idx, cbk_size;
505 silk_float scratch_mem[ SCRATCH_SIZE ];
506 opus_val32 xcorr[ SCRATCH_SIZE ];
507 const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
508
509 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
510 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
511
512 if( nb_subfr == PE_MAX_NB_SUBFR ) {
513 Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
514 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
515 nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
516 cbk_size = PE_NB_CBKS_STAGE3_MAX;
517 } else {
518 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
519 Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
520 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
521 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
522 cbk_size = PE_NB_CBKS_STAGE3_10MS;
523 }
524
525 target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
526 for( k = 0; k < nb_subfr; k++ ) {
527 lag_counter = 0;
528
529 /* Calculate the correlations for each subframe */
530 lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 );
531 lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
532 silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
533 celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr, sf_length, lag_high - lag_low + 1, arch );
534 for( j = lag_low; j <= lag_high; j++ ) {
535 silk_assert( lag_counter < SCRATCH_SIZE );
536 scratch_mem[ lag_counter ] = xcorr[ lag_high - j ];
537 lag_counter++;
538 }
539
540 delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
541 for( i = 0; i < nb_cbk_search; i++ ) {
542 /* Fill out the 3 dim array that stores the correlations for */
543 /* each code_book vector for each start lag */
544 idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
545 for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
546 silk_assert( idx + j < SCRATCH_SIZE );
547 silk_assert( idx + j < lag_counter );
548 cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
549 }
550 }
551 target_ptr += sf_length;
552 }
553}
554
555/********************************************************************/
556/* Calculate the energies for first two subframes. The energies are */
557/* calculated recursively. */
558/********************************************************************/
559static void silk_P_Ana_calc_energy_st3(
560 silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
561 const silk_float frame[], /* I vector to correlate */
562 opus_int start_lag, /* I start lag */
563 opus_int sf_length, /* I sub frame length */
564 opus_int nb_subfr, /* I number of subframes */
565 opus_int complexity /* I Complexity setting */
566)
567{
568 const silk_float *target_ptr, *basis_ptr;
569 double energy;
570 opus_int k, i, j, lag_counter;
571 opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff;
572 silk_float scratch_mem[ SCRATCH_SIZE ];
573 const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
574
575 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
576 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
577
578 if( nb_subfr == PE_MAX_NB_SUBFR ) {
579 Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
580 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
581 nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
582 cbk_size = PE_NB_CBKS_STAGE3_MAX;
583 } else {
584 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
585 Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
586 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
587 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
588 cbk_size = PE_NB_CBKS_STAGE3_10MS;
589 }
590
591 target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];
592 for( k = 0; k < nb_subfr; k++ ) {
593 lag_counter = 0;
594
595 /* Calculate the energy for first lag */
596 basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );
597 energy = silk_energy_FLP( basis_ptr, sf_length ) + 1e-3;
598 silk_assert( energy >= 0.0 );
599 scratch_mem[lag_counter] = (silk_float)energy;
600 lag_counter++;
601
602 lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );
603 for( i = 1; i < lag_diff; i++ ) {
604 /* remove part outside new window */
605 energy -= basis_ptr[sf_length - i] * (double)basis_ptr[sf_length - i];
606 silk_assert( energy >= 0.0 );
607
608 /* add part that comes into window */
609 energy += basis_ptr[ -i ] * (double)basis_ptr[ -i ];
610 silk_assert( energy >= 0.0 );
611 silk_assert( lag_counter < SCRATCH_SIZE );
612 scratch_mem[lag_counter] = (silk_float)energy;
613 lag_counter++;
614 }
615
616 delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
617 for( i = 0; i < nb_cbk_search; i++ ) {
618 /* Fill out the 3 dim array that stores the correlations for */
619 /* each code_book vector for each start lag */
620 idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
621 for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
622 silk_assert( idx + j < SCRATCH_SIZE );
623 silk_assert( idx + j < lag_counter );
624 energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
625 silk_assert( energies_st3[ k ][ i ][ j ] >= 0.0f );
626 }
627 }
628 target_ptr += sf_length;
629 }
630}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.c
new file mode 100644
index 0000000000..c0da0dae44
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.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_FLP.h"
33#include "tuning_parameters.h"
34
35/* Processing of gains */
36void silk_process_gains_FLP(
37 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
38 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
39 opus_int condCoding /* I The type of conditional coding to use */
40)
41{
42 silk_shape_state_FLP *psShapeSt = &psEnc->sShape;
43 opus_int k;
44 opus_int32 pGains_Q16[ MAX_NB_SUBFR ];
45 silk_float s, InvMaxSqrVal, gain, quant_offset;
46
47 /* Gain reduction when LTP coding gain is high */
48 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
49 s = 1.0f - 0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) );
50 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
51 psEncCtrl->Gains[ k ] *= s;
52 }
53 }
54
55 /* Limit the quantized signal */
56 InvMaxSqrVal = ( silk_float )( pow( 2.0f, 0.33f * ( 21.0f - psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) ) ) / psEnc->sCmn.subfr_length );
57
58 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
59 /* Soft limit on ratio residual energy and squared gains */
60 gain = psEncCtrl->Gains[ k ];
61 gain = ( silk_float )sqrt( gain * gain + psEncCtrl->ResNrg[ k ] * InvMaxSqrVal );
62 psEncCtrl->Gains[ k ] = silk_min_float( gain, 32767.0f );
63 }
64
65 /* Prepare gains for noise shaping quantization */
66 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
67 pGains_Q16[ k ] = (opus_int32)( psEncCtrl->Gains[ k ] * 65536.0f );
68 }
69
70 /* Save unquantized gains and gain Index */
71 silk_memcpy( psEncCtrl->GainsUnq_Q16, pGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
72 psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex;
73
74 /* Quantize gains */
75 silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16,
76 &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
77
78 /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
79 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
80 psEncCtrl->Gains[ k ] = pGains_Q16[ k ] / 65536.0f;
81 }
82
83 /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */
84 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
85 if( psEncCtrl->LTPredCodGain + psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ) > 1.0f ) {
86 psEnc->sCmn.indices.quantOffsetType = 0;
87 } else {
88 psEnc->sCmn.indices.quantOffsetType = 1;
89 }
90 }
91
92 /* Quantizer boundary adjustment */
93 quant_offset = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ] / 1024.0f;
94 psEncCtrl->Lambda = LAMBDA_OFFSET
95 + LAMBDA_DELAYED_DECISIONS * psEnc->sCmn.nStatesDelayedDecision
96 + LAMBDA_SPEECH_ACT * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f )
97 + LAMBDA_INPUT_QUALITY * psEncCtrl->input_quality
98 + LAMBDA_CODING_QUALITY * psEncCtrl->coding_quality
99 + LAMBDA_QUANT_OFFSET * quant_offset;
100
101 silk_assert( psEncCtrl->Lambda > 0.0f );
102 silk_assert( psEncCtrl->Lambda < 2.0f );
103}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.c
new file mode 100644
index 0000000000..df4612604c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.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 "main_FLP.h"
33
34/* Add noise to matrix diagonal */
35void silk_regularize_correlations_FLP(
36 silk_float *XX, /* I/O Correlation matrices */
37 silk_float *xx, /* I/O Correlation values */
38 const silk_float noise, /* I Noise energy to add */
39 const opus_int D /* I Dimension of XX */
40)
41{
42 opus_int i;
43
44 for( i = 0; i < D; i++ ) {
45 matrix_ptr( &XX[ 0 ], i, i, D ) += noise;
46 }
47 xx[ 0 ] += noise;
48}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.c
new file mode 100644
index 0000000000..1bd07b33a4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.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_FLP.h"
33
34#define MAX_ITERATIONS_RESIDUAL_NRG 10
35#define REGULARIZATION_FACTOR 1e-8f
36
37/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
38silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */
39 const silk_float *c, /* I Filter coefficients */
40 silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */
41 const silk_float *wXx, /* I Weighted correlation vector */
42 const silk_float wxx, /* I Weighted correlation value */
43 const opus_int D /* I Dimension */
44)
45{
46 opus_int i, j, k;
47 silk_float tmp, nrg = 0.0f, regularization;
48
49 /* Safety checks */
50 celt_assert( D >= 0 );
51
52 regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] );
53 for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) {
54 nrg = wxx;
55
56 tmp = 0.0f;
57 for( i = 0; i < D; i++ ) {
58 tmp += wXx[ i ] * c[ i ];
59 }
60 nrg -= 2.0f * tmp;
61
62 /* compute c' * wXX * c, assuming wXX is symmetric */
63 for( i = 0; i < D; i++ ) {
64 tmp = 0.0f;
65 for( j = i + 1; j < D; j++ ) {
66 tmp += matrix_c_ptr( wXX, i, j, D ) * c[ j ];
67 }
68 nrg += c[ i ] * ( 2.0f * tmp + matrix_c_ptr( wXX, i, i, D ) * c[ i ] );
69 }
70 if( nrg > 0 ) {
71 break;
72 } else {
73 /* Add white noise */
74 for( i = 0; i < D; i++ ) {
75 matrix_c_ptr( wXX, i, i, D ) += regularization;
76 }
77 /* Increase noise for next run */
78 regularization *= 2.0f;
79 }
80 }
81 if( k == MAX_ITERATIONS_RESIDUAL_NRG ) {
82 silk_assert( nrg == 0 );
83 nrg = 1.0f;
84 }
85
86 return nrg;
87}
88
89/* Calculates residual energies of input subframes where all subframes have LPC_order */
90/* of preceding samples */
91void silk_residual_energy_FLP(
92 silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
93 const silk_float x[], /* I Input signal */
94 silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
95 const silk_float gains[], /* I Quantization gains */
96 const opus_int subfr_length, /* I Subframe length */
97 const opus_int nb_subfr, /* I number of subframes */
98 const opus_int LPC_order /* I LPC order */
99)
100{
101 opus_int shift;
102 silk_float *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ];
103
104 LPC_res_ptr = LPC_res + LPC_order;
105 shift = LPC_order + subfr_length;
106
107 /* Filter input to create the LPC residual for each frame half, and measure subframe energies */
108 silk_LPC_analysis_filter_FLP( LPC_res, a[ 0 ], x + 0 * shift, 2 * shift, LPC_order );
109 nrgs[ 0 ] = ( silk_float )( gains[ 0 ] * gains[ 0 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) );
110 nrgs[ 1 ] = ( silk_float )( gains[ 1 ] * gains[ 1 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) );
111
112 if( nb_subfr == MAX_NB_SUBFR ) {
113 silk_LPC_analysis_filter_FLP( LPC_res, a[ 1 ], x + 2 * shift, 2 * shift, LPC_order );
114 nrgs[ 2 ] = ( silk_float )( gains[ 2 ] * gains[ 2 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) );
115 nrgs[ 3 ] = ( silk_float )( gains[ 3 ] * gains[ 3 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) );
116 }
117}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c
new file mode 100644
index 0000000000..20db32b3b1
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c
@@ -0,0 +1,57 @@
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_FLP.h"
33
34/* copy and multiply a vector by a constant */
35void silk_scale_copy_vector_FLP(
36 silk_float *data_out,
37 const silk_float *data_in,
38 silk_float gain,
39 opus_int dataSize
40)
41{
42 opus_int i, dataSize4;
43
44 /* 4x unrolled loop */
45 dataSize4 = dataSize & 0xFFFC;
46 for( i = 0; i < dataSize4; i += 4 ) {
47 data_out[ i + 0 ] = gain * data_in[ i + 0 ];
48 data_out[ i + 1 ] = gain * data_in[ i + 1 ];
49 data_out[ i + 2 ] = gain * data_in[ i + 2 ];
50 data_out[ i + 3 ] = gain * data_in[ i + 3 ];
51 }
52
53 /* any remaining elements */
54 for( ; i < dataSize; i++ ) {
55 data_out[ i ] = gain * data_in[ i ];
56 }
57}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c
new file mode 100644
index 0000000000..108fdcbed5
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c
@@ -0,0 +1,56 @@
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_FLP.h"
33
34/* multiply a vector by a constant */
35void silk_scale_vector_FLP(
36 silk_float *data1,
37 silk_float gain,
38 opus_int dataSize
39)
40{
41 opus_int i, dataSize4;
42
43 /* 4x unrolled loop */
44 dataSize4 = dataSize & 0xFFFC;
45 for( i = 0; i < dataSize4; i += 4 ) {
46 data1[ i + 0 ] *= gain;
47 data1[ i + 1 ] *= gain;
48 data1[ i + 2 ] *= gain;
49 data1[ i + 3 ] *= gain;
50 }
51
52 /* any remaining elements */
53 for( ; i < dataSize; i++ ) {
54 data1[ i ] *= gain;
55 }
56}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c
new file mode 100644
index 0000000000..8526c748d3
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c
@@ -0,0 +1,70 @@
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_FLP.h"
33
34silk_float silk_schur_FLP( /* O returns residual energy */
35 silk_float refl_coef[], /* O reflection coefficients (length order) */
36 const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */
37 opus_int order /* I order */
38)
39{
40 opus_int k, n;
41 double C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
42 double Ctmp1, Ctmp2, rc_tmp;
43
44 celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
45
46 /* Copy correlations */
47 k = 0;
48 do {
49 C[ k ][ 0 ] = C[ k ][ 1 ] = auto_corr[ k ];
50 } while( ++k <= order );
51
52 for( k = 0; k < order; k++ ) {
53 /* Get reflection coefficient */
54 rc_tmp = -C[ k + 1 ][ 0 ] / silk_max_float( C[ 0 ][ 1 ], 1e-9f );
55
56 /* Save the output */
57 refl_coef[ k ] = (silk_float)rc_tmp;
58
59 /* Update correlations */
60 for( n = 0; n < order - k; n++ ) {
61 Ctmp1 = C[ n + k + 1 ][ 0 ];
62 Ctmp2 = C[ n ][ 1 ];
63 C[ n + k + 1 ][ 0 ] = Ctmp1 + Ctmp2 * rc_tmp;
64 C[ n ][ 1 ] = Ctmp2 + Ctmp1 * rc_tmp;
65 }
66 }
67
68 /* Return residual energy */
69 return (silk_float)C[ 0 ][ 1 ];
70}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c
new file mode 100644
index 0000000000..0e18f31950
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c
@@ -0,0 +1,83 @@
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/* Insertion sort (fast for already almost sorted arrays): */
33/* Best case: O(n) for an already sorted array */
34/* Worst case: O(n^2) for an inversely sorted array */
35
36#include "typedef.h"
37#include "SigProc_FLP.h"
38
39void silk_insertion_sort_decreasing_FLP(
40 silk_float *a, /* I/O Unsorted / Sorted vector */
41 opus_int *idx, /* O Index vector for the sorted elements */
42 const opus_int L, /* I Vector length */
43 const opus_int K /* I Number of correctly sorted positions */
44)
45{
46 silk_float value;
47 opus_int i, j;
48
49 /* Safety checks */
50 celt_assert( K > 0 );
51 celt_assert( L > 0 );
52 celt_assert( L >= K );
53
54 /* Write start indices in index vector */
55 for( i = 0; i < K; i++ ) {
56 idx[ i ] = i;
57 }
58
59 /* Sort vector elements by value, decreasing order */
60 for( i = 1; i < K; i++ ) {
61 value = a[ i ];
62 for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) {
63 a[ j + 1 ] = a[ j ]; /* Shift value */
64 idx[ j + 1 ] = idx[ j ]; /* Shift index */
65 }
66 a[ j + 1 ] = value; /* Write value */
67 idx[ j + 1 ] = i; /* Write index */
68 }
69
70 /* If less than L values are asked check the remaining values, */
71 /* but only spend CPU to ensure that the K first values are correct */
72 for( i = K; i < L; i++ ) {
73 value = a[ i ];
74 if( value > a[ K - 1 ] ) {
75 for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) {
76 a[ j + 1 ] = a[ j ]; /* Shift value */
77 idx[ j + 1 ] = idx[ j ]; /* Shift index */
78 }
79 a[ j + 1 ] = value; /* Write value */
80 idx[ j + 1 ] = i; /* Write index */
81 }
82 }
83}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h b/lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h
new file mode 100644
index 0000000000..3150b386e4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h
@@ -0,0 +1,112 @@
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_FLP_H
29#define SILK_STRUCTS_FLP_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 silk_float HarmShapeGain_smth;
46 silk_float Tilt_smth;
47} silk_shape_state_FLP;
48
49/********************************/
50/* Encoder state FLP */
51/********************************/
52typedef struct {
53 silk_encoder_state sCmn; /* Common struct, shared with fixed-point code */
54 silk_shape_state_FLP sShape; /* Noise shaping state */
55
56 /* Buffer for find pitch and noise shape analysis */
57 silk_float x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
58 silk_float LTPCorr; /* Normalized correlation from pitch lag estimator */
59} silk_encoder_state_FLP;
60
61/************************/
62/* Encoder control FLP */
63/************************/
64typedef struct {
65 /* Prediction and coding parameters */
66 silk_float Gains[ MAX_NB_SUBFR ];
67 silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ]; /* holds interpolated and final coefficients */
68 silk_float LTPCoef[LTP_ORDER * MAX_NB_SUBFR];
69 silk_float LTP_scale;
70 opus_int pitchL[ MAX_NB_SUBFR ];
71
72 /* Noise shaping parameters */
73 silk_float AR[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
74 silk_float LF_MA_shp[ MAX_NB_SUBFR ];
75 silk_float LF_AR_shp[ MAX_NB_SUBFR ];
76 silk_float Tilt[ MAX_NB_SUBFR ];
77 silk_float HarmShapeGain[ MAX_NB_SUBFR ];
78 silk_float Lambda;
79 silk_float input_quality;
80 silk_float coding_quality;
81
82 /* Measures */
83 silk_float predGain;
84 silk_float LTPredCodGain;
85 silk_float ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */
86
87 /* Parameters for CBR mode */
88 opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ];
89 opus_int8 lastGainIndexPrev;
90} silk_encoder_control_FLP;
91
92/************************/
93/* Encoder Super Struct */
94/************************/
95typedef struct {
96 silk_encoder_state_FLP state_Fxx[ ENCODER_NUM_CHANNELS ];
97 stereo_enc_state sStereo;
98 opus_int32 nBitsUsedLBRR;
99 opus_int32 nBitsExceeded;
100 opus_int nChannelsAPI;
101 opus_int nChannelsInternal;
102 opus_int nPrevChannelsInternal;
103 opus_int timeSinceSwitchAllowed_ms;
104 opus_int allowBandwidthSwitch;
105 opus_int prev_decode_only_middle;
106} silk_encoder;
107
108#ifdef __cplusplus
109}
110#endif
111
112#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c
new file mode 100644
index 0000000000..09186e73d4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c
@@ -0,0 +1,73 @@
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_FLP.h"
33
34/* Autocorrelations for a warped frequency axis */
35void silk_warped_autocorrelation_FLP(
36 silk_float *corr, /* O Result [order + 1] */
37 const silk_float *input, /* I Input data to correlate */
38 const silk_float warping, /* I Warping coefficient */
39 const opus_int length, /* I Length of input */
40 const opus_int order /* I Correlation order (even) */
41)
42{
43 opus_int n, i;
44 double tmp1, tmp2;
45 double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
46 double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
47
48 /* Order must be even */
49 celt_assert( ( order & 1 ) == 0 );
50
51 /* Loop over samples */
52 for( n = 0; n < length; n++ ) {
53 tmp1 = input[ n ];
54 /* Loop over allpass sections */
55 for( i = 0; i < order; i += 2 ) {
56 /* Output of allpass section */
57 tmp2 = state[ i ] + warping * ( state[ i + 1 ] - tmp1 );
58 state[ i ] = tmp1;
59 C[ i ] += state[ 0 ] * tmp1;
60 /* Output of allpass section */
61 tmp1 = state[ i + 1 ] + warping * ( state[ i + 2 ] - tmp2 );
62 state[ i + 1 ] = tmp2;
63 C[ i + 1 ] += state[ 0 ] * tmp2;
64 }
65 state[ order ] = tmp1;
66 C[ order ] += state[ 0 ] * tmp1;
67 }
68
69 /* Copy correlations in silk_float output format */
70 for( i = 0; i < order + 1; i++ ) {
71 corr[ i ] = ( silk_float )C[ i ];
72 }
73}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c
new file mode 100644
index 0000000000..ad90b874a4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c
@@ -0,0 +1,207 @@
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_FLP.h"
33
34/* Wrappers. Calls flp / fix code */
35
36/* Convert AR filter coefficients to NLSF parameters */
37void silk_A2NLSF_FLP(
38 opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */
39 const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */
40 const opus_int LPC_order /* I LPC order */
41)
42{
43 opus_int i;
44 opus_int32 a_fix_Q16[ MAX_LPC_ORDER ];
45
46 for( i = 0; i < LPC_order; i++ ) {
47 a_fix_Q16[ i ] = silk_float2int( pAR[ i ] * 65536.0f );
48 }
49
50 silk_A2NLSF( NLSF_Q15, a_fix_Q16, LPC_order );
51}
52
53/* Convert LSF parameters to AR prediction filter coefficients */
54void silk_NLSF2A_FLP(
55 silk_float *pAR, /* O LPC coefficients [ LPC_order ] */
56 const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
57 const opus_int LPC_order, /* I LPC order */
58 int arch /* I Run-time architecture */
59)
60{
61 opus_int i;
62 opus_int16 a_fix_Q12[ MAX_LPC_ORDER ];
63
64 silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order, arch );
65
66 for( i = 0; i < LPC_order; i++ ) {
67 pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f );
68 }
69}
70
71/******************************************/
72/* Floating-point NLSF processing wrapper */
73/******************************************/
74void silk_process_NLSFs_FLP(
75 silk_encoder_state *psEncC, /* I/O Encoder state */
76 silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */
77 opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */
78 const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */
79)
80{
81 opus_int i, j;
82 opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
83
84 silk_process_NLSFs( psEncC, PredCoef_Q12, NLSF_Q15, prev_NLSF_Q15);
85
86 for( j = 0; j < 2; j++ ) {
87 for( i = 0; i < psEncC->predictLPCOrder; i++ ) {
88 PredCoef[ j ][ i ] = ( silk_float )PredCoef_Q12[ j ][ i ] * ( 1.0f / 4096.0f );
89 }
90 }
91}
92
93/****************************************/
94/* Floating-point Silk NSQ wrapper */
95/****************************************/
96void silk_NSQ_wrapper_FLP(
97 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
98 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
99 SideInfoIndices *psIndices, /* I/O Quantization indices */
100 silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */
101 opus_int8 pulses[], /* O Quantized pulse signal */
102 const silk_float x[] /* I Prefiltered input signal */
103)
104{
105 opus_int i, j;
106 opus_int16 x16[ MAX_FRAME_LENGTH ];
107 opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
108 silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
109 opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
110 opus_int LTP_scale_Q14;
111
112 /* Noise shaping parameters */
113 opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
114 opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */
115 opus_int Lambda_Q10;
116 opus_int Tilt_Q14[ MAX_NB_SUBFR ];
117 opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ];
118
119 /* Convert control struct to fix control struct */
120 /* Noise shape parameters */
121 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
122 for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) {
123 AR_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f );
124 }
125 }
126
127 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
128 LF_shp_Q14[ i ] = silk_LSHIFT32( silk_float2int( psEncCtrl->LF_AR_shp[ i ] * 16384.0f ), 16 ) |
129 (opus_uint16)silk_float2int( psEncCtrl->LF_MA_shp[ i ] * 16384.0f );
130 Tilt_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->Tilt[ i ] * 16384.0f );
131 HarmShapeGain_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f );
132 }
133 Lambda_Q10 = ( opus_int )silk_float2int( psEncCtrl->Lambda * 1024.0f );
134
135 /* prediction and coding parameters */
136 for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {
137 LTPCoef_Q14[ i ] = (opus_int16)silk_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f );
138 }
139
140 for( j = 0; j < 2; j++ ) {
141 for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) {
142 PredCoef_Q12[ j ][ i ] = (opus_int16)silk_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f );
143 }
144 }
145
146 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
147 Gains_Q16[ i ] = silk_float2int( psEncCtrl->Gains[ i ] * 65536.0f );
148 silk_assert( Gains_Q16[ i ] > 0 );
149 }
150
151 if( psIndices->signalType == TYPE_VOICED ) {
152 LTP_scale_Q14 = silk_LTPScales_table_Q14[ psIndices->LTP_scaleIndex ];
153 } else {
154 LTP_scale_Q14 = 0;
155 }
156
157 /* Convert input to fix */
158 for( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
159 x16[ i ] = silk_float2int( x[ i ] );
160 }
161
162 /* Call NSQ */
163 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
164 silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
165 AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
166 } else {
167 silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
168 AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
169 }
170}
171
172/***********************************************/
173/* Floating-point Silk LTP quantiation wrapper */
174/***********************************************/
175void silk_quant_LTP_gains_FLP(
176 silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
177 opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */
178 opus_int8 *periodicity_index, /* O Periodicity index */
179 opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
180 silk_float *pred_gain_dB, /* O LTP prediction gain */
181 const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */
182 const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */
183 const opus_int subfr_len, /* I Number of samples per subframe */
184 const opus_int nb_subfr, /* I Number of subframes */
185 int arch /* I Run-time architecture */
186)
187{
188 opus_int i, pred_gain_dB_Q7;
189 opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ];
190 opus_int32 XX_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
191 opus_int32 xX_Q17[ MAX_NB_SUBFR * LTP_ORDER ];
192
193 for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) {
194 XX_Q17[ i ] = (opus_int32)silk_float2int( XX[ i ] * 131072.0f );
195 }
196 for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
197 xX_Q17[ i ] = (opus_int32)silk_float2int( xX[ i ] * 131072.0f );
198 }
199
200 silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, &pred_gain_dB_Q7, XX_Q17, xX_Q17, subfr_len, nb_subfr, arch );
201
202 for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
203 B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f );
204 }
205
206 *pred_gain_dB = (silk_float)pred_gain_dB_Q7 * ( 1.0f / 128.0f );
207}
diff --git a/lib/rbcodec/codecs/libopus/silk/gain_quant.c b/lib/rbcodec/codecs/libopus/silk/gain_quant.c
index ed084073b1..ee65245aa3 100644
--- a/lib/rbcodec/codecs/libopus/silk/gain_quant.c
+++ b/lib/rbcodec/codecs/libopus/silk/gain_quant.c
@@ -35,7 +35,6 @@ POSSIBILITY OF SUCH DAMAGE.
35#define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) 35#define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) )
36#define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) ) 36#define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) )
37 37
38#if 0
39/* Gain scalar quantization with hysteresis, uniform on log scale */ 38/* Gain scalar quantization with hysteresis, uniform on log scale */
40void silk_gains_quant( 39void silk_gains_quant(
41 opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */ 40 opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */
@@ -77,6 +76,7 @@ void silk_gains_quant(
77 /* Accumulate deltas */ 76 /* Accumulate deltas */
78 if( ind[ k ] > double_step_size_threshold ) { 77 if( ind[ k ] > double_step_size_threshold ) {
79 *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold; 78 *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold;
79 *prev_ind = silk_min_int( *prev_ind, N_LEVELS_QGAIN - 1 );
80 } else { 80 } else {
81 *prev_ind += ind[ k ]; 81 *prev_ind += ind[ k ];
82 } 82 }
@@ -89,7 +89,6 @@ void silk_gains_quant(
89 gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ 89 gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */
90 } 90 }
91} 91}
92#endif
93 92
94/* Gains scalar dequantization, uniform on log scale */ 93/* Gains scalar dequantization, uniform on log scale */
95void silk_gains_dequant( 94void silk_gains_dequant(
@@ -125,7 +124,6 @@ void silk_gains_dequant(
125 } 124 }
126} 125}
127 126
128#if 0
129/* Compute unique identifier of gain indices vector */ 127/* Compute unique identifier of gain indices vector */
130opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ 128opus_int32 silk_gains_ID( /* O returns unique identifier of gains */
131 const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ 129 const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */
@@ -142,4 +140,3 @@ opus_int32 silk_gains_ID( /* O returns
142 140
143 return gainsID; 141 return gainsID;
144} 142}
145#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/init_decoder.c b/lib/rbcodec/codecs/libopus/silk/init_decoder.c
index f887c67886..16c03dcd1c 100644
--- a/lib/rbcodec/codecs/libopus/silk/init_decoder.c
+++ b/lib/rbcodec/codecs/libopus/silk/init_decoder.c
@@ -44,6 +44,7 @@ opus_int silk_init_decoder(
44 /* Used to deactivate LSF interpolation */ 44 /* Used to deactivate LSF interpolation */
45 psDec->first_frame_after_reset = 1; 45 psDec->first_frame_after_reset = 1;
46 psDec->prev_gain_Q16 = 65536; 46 psDec->prev_gain_Q16 = 65536;
47 psDec->arch = opus_select_arch();
47 48
48 /* Reset CNG state */ 49 /* Reset CNG state */
49 silk_CNG_Reset( psDec ); 50 silk_CNG_Reset( psDec );
diff --git a/lib/rbcodec/codecs/libopus/silk/init_encoder.c b/lib/rbcodec/codecs/libopus/silk/init_encoder.c
new file mode 100644
index 0000000000..65995c33fa
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/init_encoder.c
@@ -0,0 +1,64 @@
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#ifdef FIXED_POINT
32#include "main_FIX.h"
33#else
34#include "main_FLP.h"
35#endif
36#include "tuning_parameters.h"
37#include "cpu_support.h"
38
39/*********************************/
40/* Initialize Silk Encoder state */
41/*********************************/
42opus_int silk_init_encoder(
43 silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */
44 int arch /* I Run-time architecture */
45)
46{
47 opus_int ret = 0;
48
49 /* Clear the entire encoder state */
50 silk_memset( psEnc, 0, sizeof( silk_encoder_state_Fxx ) );
51
52 psEnc->sCmn.arch = arch;
53
54 psEnc->sCmn.variable_HP_smth1_Q15 = silk_LSHIFT( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ), 8 );
55 psEnc->sCmn.variable_HP_smth2_Q15 = psEnc->sCmn.variable_HP_smth1_Q15;
56
57 /* Used to deactivate LSF interpolation, pitch prediction */
58 psEnc->sCmn.first_frame_after_reset = 1;
59
60 /* Initialize Silk VAD */
61 ret += silk_VAD_Init( &psEnc->sCmn.sVAD );
62
63 return ret;
64}
diff --git a/lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.c b/lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.c
new file mode 100644
index 0000000000..257ae9e04e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.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 "SigProc_FIX.h"
33
34opus_int32 silk_inner_prod_aligned_scale(
35 const opus_int16 *const inVec1, /* I input vector 1 */
36 const opus_int16 *const inVec2, /* I input vector 2 */
37 const opus_int scale, /* I number of bits to shift */
38 const opus_int len /* I vector lengths */
39)
40{
41 opus_int i;
42 opus_int32 sum = 0;
43 for( i = 0; i < len; i++ ) {
44 sum = silk_ADD_RSHIFT32( sum, silk_SMULBB( inVec1[ i ], inVec2[ i ] ), scale );
45 }
46 return sum;
47}
diff --git a/lib/rbcodec/codecs/libopus/silk/interpolate.c b/lib/rbcodec/codecs/libopus/silk/interpolate.c
new file mode 100644
index 0000000000..833c28ef8e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/interpolate.c
@@ -0,0 +1,51 @@
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.h"
33
34/* Interpolate two vectors */
35void silk_interpolate(
36 opus_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */
37 const opus_int16 x0[ MAX_LPC_ORDER ], /* I first vector */
38 const opus_int16 x1[ MAX_LPC_ORDER ], /* I second vector */
39 const opus_int ifact_Q2, /* I interp. factor, weight on 2nd vector */
40 const opus_int d /* I number of parameters */
41)
42{
43 opus_int i;
44
45 celt_assert( ifact_Q2 >= 0 );
46 celt_assert( ifact_Q2 <= 4 );
47
48 for( i = 0; i < d; i++ ) {
49 xi[ i ] = (opus_int16)silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 );
50 }
51}
diff --git a/lib/rbcodec/codecs/libopus/silk/lin2log.c b/lib/rbcodec/codecs/libopus/silk/lin2log.c
new file mode 100644
index 0000000000..0d5155aa86
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/lin2log.c
@@ -0,0 +1,46 @@
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/* Approximation of 128 * log2() (very close inverse of silk_log2lin()) */
34/* Convert input to a log scale */
35opus_int32 silk_lin2log(
36 const opus_int32 inLin /* I input in linear scale */
37)
38{
39 opus_int32 lz, frac_Q7;
40
41 silk_CLZ_FRAC( inLin, &lz, &frac_Q7 );
42
43 /* Piece-wise parabolic approximation */
44 return silk_ADD_LSHIFT32( silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 ), 31 - lz, 7 );
45}
46
diff --git a/lib/rbcodec/codecs/libopus/silk/log2lin.c b/lib/rbcodec/codecs/libopus/silk/log2lin.c
index a692e009db..b7c48e4740 100644
--- a/lib/rbcodec/codecs/libopus/silk/log2lin.c
+++ b/lib/rbcodec/codecs/libopus/silk/log2lin.c
@@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
33 33
34/* Approximation of 2^() (very close inverse of silk_lin2log()) */ 34/* Approximation of 2^() (very close inverse of silk_lin2log()) */
35/* Convert input to a linear scale */ 35/* Convert input to a linear scale */
36opus_int32 silk_log2lin( 36opus_int32 silk_log2lin(
37 const opus_int32 inLog_Q7 /* I input on log scale */ 37 const opus_int32 inLog_Q7 /* I input on log scale */
38) 38)
39{ 39{
@@ -42,8 +42,8 @@ opus_int32 silk_log2lin(
42 if( inLog_Q7 < 0 ) { 42 if( inLog_Q7 < 0 ) {
43 return 0; 43 return 0;
44 } else if ( inLog_Q7 >= 3967 ) { 44 } else if ( inLog_Q7 >= 3967 ) {
45 return silk_int32_MAX; 45 return silk_int32_MAX;
46 } 46 }
47 47
48 out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) ); 48 out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) );
49 frac_Q7 = inLog_Q7 & 0x7F; 49 frac_Q7 = inLog_Q7 & 0x7F;
diff --git a/lib/rbcodec/codecs/libopus/silk/macros.h b/lib/rbcodec/codecs/libopus/silk/macros.h
index 05623b5df8..3c67b6e5d9 100644
--- a/lib/rbcodec/codecs/libopus/silk/macros.h
+++ b/lib/rbcodec/codecs/libopus/silk/macros.h
@@ -34,20 +34,37 @@ POSSIBILITY OF SUCH DAMAGE.
34 34
35#include "opus_types.h" 35#include "opus_types.h"
36#include "opus_defines.h" 36#include "opus_defines.h"
37#include "arch.h"
37 38
38/* This is an OPUS_INLINE header file for general platform. */ 39/* This is an OPUS_INLINE header file for general platform. */
39 40
40/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ 41/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
42#if OPUS_FAST_INT64
43#define silk_SMULWB(a32, b32) ((opus_int32)(((a32) * (opus_int64)((opus_int16)(b32))) >> 16))
44#else
41#define silk_SMULWB(a32, b32) ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16)) 45#define silk_SMULWB(a32, b32) ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16))
46#endif
42 47
43/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ 48/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */
49#if OPUS_FAST_INT64
50#define silk_SMLAWB(a32, b32, c32) ((opus_int32)((a32) + (((b32) * (opus_int64)((opus_int16)(c32))) >> 16)))
51#else
44#define silk_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16))) 52#define silk_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16)))
53#endif
45 54
46/* (a32 * (b32 >> 16)) >> 16 */ 55/* (a32 * (b32 >> 16)) >> 16 */
56#if OPUS_FAST_INT64
57#define silk_SMULWT(a32, b32) ((opus_int32)(((a32) * (opus_int64)((b32) >> 16)) >> 16))
58#else
47#define silk_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16)) 59#define silk_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16))
60#endif
48 61
49/* a32 + (b32 * (c32 >> 16)) >> 16 */ 62/* a32 + (b32 * (c32 >> 16)) >> 16 */
63#if OPUS_FAST_INT64
64#define silk_SMLAWT(a32, b32, c32) ((opus_int32)((a32) + (((b32) * ((opus_int64)(c32) >> 16)) >> 16)))
65#else
50#define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)) 66#define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16))
67#endif
51 68
52/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */ 69/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */
53#define silk_SMULBB(a32, b32) ((opus_int32)((opus_int16)(a32)) * (opus_int32)((opus_int16)(b32))) 70#define silk_SMULBB(a32, b32) ((opus_int32)((opus_int16)(a32)) * (opus_int32)((opus_int16)(b32)))
@@ -65,10 +82,18 @@ POSSIBILITY OF SUCH DAMAGE.
65#define silk_SMLAL(a64, b32, c32) (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32)))) 82#define silk_SMLAL(a64, b32, c32) (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32))))
66 83
67/* (a32 * b32) >> 16 */ 84/* (a32 * b32) >> 16 */
85#if OPUS_FAST_INT64
86#define silk_SMULWW(a32, b32) ((opus_int32)(((opus_int64)(a32) * (b32)) >> 16))
87#else
68#define silk_SMULWW(a32, b32) silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)) 88#define silk_SMULWW(a32, b32) silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16))
89#endif
69 90
70/* a32 + ((b32 * c32) >> 16) */ 91/* a32 + ((b32 * c32) >> 16) */
92#if OPUS_FAST_INT64
93#define silk_SMLAWW(a32, b32, c32) ((opus_int32)((a32) + (((opus_int64)(b32) * (c32)) >> 16)))
94#else
71#define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)) 95#define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16))
96#endif
72 97
73/* add/subtract with output saturated */ 98/* add/subtract with output saturated */
74#define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \ 99#define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \
@@ -118,8 +143,8 @@ static OPUS_INLINE opus_int32 silk_CLZ32(opus_int32 in32)
118#include "arm/macros_armv5e.h" 143#include "arm/macros_armv5e.h"
119#endif 144#endif
120 145
121#ifdef OPUS_CF_INLINE_ASM 146#ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR
122#include "cf/macros_cf.h" 147#include "arm/macros_arm64.h"
123#endif 148#endif
124 149
125#endif /* SILK_MACROS_H */ 150#endif /* SILK_MACROS_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/main.h b/lib/rbcodec/codecs/libopus/silk/main.h
index 77524f5b57..1a33eed549 100644
--- a/lib/rbcodec/codecs/libopus/silk/main.h
+++ b/lib/rbcodec/codecs/libopus/silk/main.h
@@ -38,6 +38,14 @@ POSSIBILITY OF SUCH DAMAGE.
38#include "entenc.h" 38#include "entenc.h"
39#include "entdec.h" 39#include "entdec.h"
40 40
41#if defined(OPUS_X86_MAY_HAVE_SSE4_1)
42#include "x86/main_sse.h"
43#endif
44
45#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
46#include "arm/NSQ_del_dec_arm.h"
47#endif
48
41/* Convert Left/Right stereo signal to adaptive Mid/Side representation */ 49/* Convert Left/Right stereo signal to adaptive Mid/Side representation */
42void silk_stereo_LR_to_MS( 50void silk_stereo_LR_to_MS(
43 stereo_enc_state *state, /* I/O State */ 51 stereo_enc_state *state, /* I/O State */
@@ -105,22 +113,22 @@ void silk_stereo_decode_mid_only(
105 113
106/* Encodes signs of excitation */ 114/* Encodes signs of excitation */
107void silk_encode_signs( 115void silk_encode_signs(
108 ec_enc *psRangeEnc, /* I/O Compressor data structure */ 116 ec_enc *psRangeEnc, /* I/O Compressor data structure */
109 const opus_int8 pulses[], /* I pulse signal */ 117 const opus_int8 pulses[], /* I pulse signal */
110 opus_int length, /* I length of input */ 118 opus_int length, /* I length of input */
111 const opus_int signalType, /* I Signal type */ 119 const opus_int signalType, /* I Signal type */
112 const opus_int quantOffsetType, /* I Quantization offset type */ 120 const opus_int quantOffsetType, /* I Quantization offset type */
113 const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ 121 const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */
114); 122);
115 123
116/* Decodes signs of excitation */ 124/* Decodes signs of excitation */
117void silk_decode_signs( 125void silk_decode_signs(
118 ec_dec *psRangeDec, /* I/O Compressor data structure */ 126 ec_dec *psRangeDec, /* I/O Compressor data structure */
119 opus_int16 pulses[], /* I/O pulse signal */ 127 opus_int16 pulses[], /* I/O pulse signal */
120 opus_int length, /* I length of input */ 128 opus_int length, /* I length of input */
121 const opus_int signalType, /* I Signal type */ 129 const opus_int signalType, /* I Signal type */
122 const opus_int quantOffsetType, /* I Quantization offset type */ 130 const opus_int quantOffsetType, /* I Quantization offset type */
123 const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ 131 const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */
124); 132);
125 133
126/* Check encoder control struct */ 134/* Check encoder control struct */
@@ -201,43 +209,52 @@ void silk_interpolate(
201 209
202/* LTP tap quantizer */ 210/* LTP tap quantizer */
203void silk_quant_LTP_gains( 211void silk_quant_LTP_gains(
204 opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */ 212 opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
205 opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ 213 opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */
206 opus_int8 *periodicity_index, /* O Periodicity Index */ 214 opus_int8 *periodicity_index, /* O Periodicity Index */
207 opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */ 215 opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */
208 const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */ 216 opus_int *pred_gain_dB_Q7, /* O LTP prediction gain */
209 opus_int mu_Q9, /* I Mu value (R/D tradeoff) */ 217 const opus_int32 XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Correlation matrix in Q18 */
210 opus_int lowComplexity, /* I Flag for low complexity */ 218 const opus_int32 xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ], /* I Correlation vector in Q18 */
211 const opus_int nb_subfr /* I number of subframes */ 219 const opus_int subfr_len, /* I Number of samples per subframe */
220 const opus_int nb_subfr, /* I Number of subframes */
221 int arch /* I Run-time architecture */
212); 222);
213 223
214/* Entropy constrained matrix-weighted VQ, for a single input data vector */ 224/* Entropy constrained matrix-weighted VQ, for a single input data vector */
215void silk_VQ_WMat_EC( 225void silk_VQ_WMat_EC_c(
216 opus_int8 *ind, /* O index of best codebook vector */ 226 opus_int8 *ind, /* O index of best codebook vector */
217 opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ 227 opus_int32 *res_nrg_Q15, /* O best residual energy */
228 opus_int32 *rate_dist_Q8, /* O best total bitrate */
218 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ 229 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
219 const opus_int16 *in_Q14, /* I input vector to be quantized */ 230 const opus_int32 *XX_Q17, /* I correlation matrix */
220 const opus_int32 *W_Q18, /* I weighting matrix */ 231 const opus_int32 *xX_Q17, /* I correlation vector */
221 const opus_int8 *cb_Q7, /* I codebook */ 232 const opus_int8 *cb_Q7, /* I codebook */
222 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ 233 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
223 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ 234 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
224 const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ 235 const opus_int subfr_len, /* I number of samples per subframe */
225 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ 236 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
226 opus_int L /* I number of vectors in codebook */ 237 const opus_int L /* I number of vectors in codebook */
227); 238);
228 239
240#if !defined(OVERRIDE_silk_VQ_WMat_EC)
241#define silk_VQ_WMat_EC(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, subfr_len, max_gain_Q7, L, arch) \
242 ((void)(arch),silk_VQ_WMat_EC_c(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, subfr_len, max_gain_Q7, L))
243#endif
244
229/************************************/ 245/************************************/
230/* Noise shaping quantization (NSQ) */ 246/* Noise shaping quantization (NSQ) */
231/************************************/ 247/************************************/
232void silk_NSQ( 248
233 const silk_encoder_state *psEncC, /* I/O Encoder State */ 249void silk_NSQ_c(
250 const silk_encoder_state *psEncC, /* I Encoder State */
234 silk_nsq_state *NSQ, /* I/O NSQ state */ 251 silk_nsq_state *NSQ, /* I/O NSQ state */
235 SideInfoIndices *psIndices, /* I/O Quantization Indices */ 252 SideInfoIndices *psIndices, /* I/O Quantization Indices */
236 const opus_int32 x_Q3[], /* I Prefiltered input signal */ 253 const opus_int16 x16[], /* I Input */
237 opus_int8 pulses[], /* O Quantized pulse signal */ 254 opus_int8 pulses[], /* O Quantized pulse signal */
238 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ 255 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
239 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ 256 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
240 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ 257 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
241 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ 258 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
242 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ 259 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
243 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ 260 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
@@ -247,16 +264,23 @@ void silk_NSQ(
247 const opus_int LTP_scale_Q14 /* I LTP state scaling */ 264 const opus_int LTP_scale_Q14 /* I LTP state scaling */
248); 265);
249 266
267#if !defined(OVERRIDE_silk_NSQ)
268#define silk_NSQ(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
269 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
270 ((void)(arch),silk_NSQ_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
271 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
272#endif
273
250/* Noise shaping using delayed decision */ 274/* Noise shaping using delayed decision */
251void silk_NSQ_del_dec( 275void silk_NSQ_del_dec_c(
252 const silk_encoder_state *psEncC, /* I/O Encoder State */ 276 const silk_encoder_state *psEncC, /* I Encoder State */
253 silk_nsq_state *NSQ, /* I/O NSQ state */ 277 silk_nsq_state *NSQ, /* I/O NSQ state */
254 SideInfoIndices *psIndices, /* I/O Quantization Indices */ 278 SideInfoIndices *psIndices, /* I/O Quantization Indices */
255 const opus_int32 x_Q3[], /* I Prefiltered input signal */ 279 const opus_int16 x16[], /* I Input */
256 opus_int8 pulses[], /* O Quantized pulse signal */ 280 opus_int8 pulses[], /* O Quantized pulse signal */
257 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ 281 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
258 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ 282 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
259 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ 283 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
260 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ 284 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
261 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ 285 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
262 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ 286 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
@@ -266,6 +290,13 @@ void silk_NSQ_del_dec(
266 const opus_int LTP_scale_Q14 /* I LTP state scaling */ 290 const opus_int LTP_scale_Q14 /* I LTP state scaling */
267); 291);
268 292
293#if !defined(OVERRIDE_silk_NSQ_del_dec)
294#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
295 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
296 ((void)(arch),silk_NSQ_del_dec_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
297 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
298#endif
299
269/************/ 300/************/
270/* Silk VAD */ 301/* Silk VAD */
271/************/ 302/************/
@@ -275,11 +306,15 @@ opus_int silk_VAD_Init( /* O Return v
275); 306);
276 307
277/* Get speech activity level in Q8 */ 308/* Get speech activity level in Q8 */
278opus_int silk_VAD_GetSA_Q8( /* O Return value, 0 if success */ 309opus_int silk_VAD_GetSA_Q8_c( /* O Return value, 0 if success */
279 silk_encoder_state *psEncC, /* I/O Encoder state */ 310 silk_encoder_state *psEncC, /* I/O Encoder state */
280 const opus_int16 pIn[] /* I PCM input */ 311 const opus_int16 pIn[] /* I PCM input */
281); 312);
282 313
314#if !defined(OVERRIDE_silk_VAD_GetSA_Q8)
315#define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_c(psEnC, pIn))
316#endif
317
283/* Low-pass filter with variable cutoff frequency based on */ 318/* Low-pass filter with variable cutoff frequency based on */
284/* piece-wise linear interpolation between elliptic filters */ 319/* piece-wise linear interpolation between elliptic filters */
285/* Start by setting transition_frame_no = 1; */ 320/* Start by setting transition_frame_no = 1; */
@@ -315,6 +350,7 @@ void silk_NLSF_VQ(
315 opus_int32 err_Q26[], /* O Quantization errors [K] */ 350 opus_int32 err_Q26[], /* O Quantization errors [K] */
316 const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ 351 const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */
317 const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ 352 const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */
353 const opus_int16 pWght_Q9[], /* I Codebook weights [K*LPC_order] */
318 const opus_int K, /* I Number of codebook vectors */ 354 const opus_int K, /* I Number of codebook vectors */
319 const opus_int LPC_order /* I Number of LPCs */ 355 const opus_int LPC_order /* I Number of LPCs */
320); 356);
@@ -373,7 +409,8 @@ opus_int silk_decode_frame(
373 opus_int16 pOut[], /* O Pointer to output speech frame */ 409 opus_int16 pOut[], /* O Pointer to output speech frame */
374 opus_int32 *pN, /* O Pointer to size of output frame */ 410 opus_int32 *pN, /* O Pointer to size of output frame */
375 opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ 411 opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */
376 opus_int condCoding /* I The type of conditional coding to use */ 412 opus_int condCoding, /* I The type of conditional coding to use */
413 int arch /* I Run-time architecture */
377); 414);
378 415
379/* Decode indices from bitstream */ 416/* Decode indices from bitstream */
@@ -397,7 +434,8 @@ void silk_decode_core(
397 silk_decoder_state *psDec, /* I/O Decoder state */ 434 silk_decoder_state *psDec, /* I/O Decoder state */
398 silk_decoder_control *psDecCtrl, /* I Decoder control */ 435 silk_decoder_control *psDecCtrl, /* I Decoder control */
399 opus_int16 xq[], /* O Decoded speech */ 436 opus_int16 xq[], /* O Decoded speech */
400 const opus_int16 pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ 437 const opus_int16 pulses[ MAX_FRAME_LENGTH ], /* I Pulse signal */
438 int arch /* I Run-time architecture */
401); 439);
402 440
403/* Decode quantization indices of excitation (Shell coding) */ 441/* Decode quantization indices of excitation (Shell coding) */
diff --git a/lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h
new file mode 100644
index 0000000000..cd70713a8f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h
@@ -0,0 +1,410 @@
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 __NSQ_DEL_DEC_MIPSR1_H__
29#define __NSQ_DEL_DEC_MIPSR1_H__
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include "main.h"
36#include "stack_alloc.h"
37
38#define OVERRIDE_silk_noise_shape_quantizer_del_dec
39static inline void silk_noise_shape_quantizer_del_dec(
40 silk_nsq_state *NSQ, /* I/O NSQ state */
41 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
42 opus_int signalType, /* I Signal type */
43 const opus_int32 x_Q10[], /* I */
44 opus_int8 pulses[], /* O */
45 opus_int16 xq[], /* O */
46 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
47 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
48 const opus_int16 a_Q12[], /* I Short term prediction coefs */
49 const opus_int16 b_Q14[], /* I Long term prediction coefs */
50 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
51 opus_int lag, /* I Pitch lag */
52 opus_int32 HarmShapeFIRPacked_Q14, /* I */
53 opus_int Tilt_Q14, /* I Spectral tilt */
54 opus_int32 LF_shp_Q14, /* I */
55 opus_int32 Gain_Q16, /* I */
56 opus_int Lambda_Q10, /* I */
57 opus_int offset_Q10, /* I */
58 opus_int length, /* I Input length */
59 opus_int subfr, /* I Subframe number */
60 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
61 opus_int predictLPCOrder, /* I Prediction filter order */
62 opus_int warping_Q16, /* I */
63 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
64 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
65 opus_int decisionDelay, /* I */
66 int arch /* I */
67)
68{
69 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
70 opus_int32 Winner_rand_state;
71 opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
72 opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
73 opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
74 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
75 opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
76 NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ];
77 NSQ_del_dec_struct *psDD;
78 NSQ_sample_struct *psSS;
79 opus_int16 b_Q14_0, b_Q14_1, b_Q14_2, b_Q14_3, b_Q14_4;
80 opus_int16 a_Q12_0, a_Q12_1, a_Q12_2, a_Q12_3, a_Q12_4, a_Q12_5, a_Q12_6;
81 opus_int16 a_Q12_7, a_Q12_8, a_Q12_9, a_Q12_10, a_Q12_11, a_Q12_12, a_Q12_13;
82 opus_int16 a_Q12_14, a_Q12_15;
83
84 opus_int32 cur, prev, next;
85
86 /*Unused.*/
87 (void)arch;
88
89 //Intialize b_Q14 variables
90 b_Q14_0 = b_Q14[ 0 ];
91 b_Q14_1 = b_Q14[ 1 ];
92 b_Q14_2 = b_Q14[ 2 ];
93 b_Q14_3 = b_Q14[ 3 ];
94 b_Q14_4 = b_Q14[ 4 ];
95
96 //Intialize a_Q12 variables
97 a_Q12_0 = a_Q12[0];
98 a_Q12_1 = a_Q12[1];
99 a_Q12_2 = a_Q12[2];
100 a_Q12_3 = a_Q12[3];
101 a_Q12_4 = a_Q12[4];
102 a_Q12_5 = a_Q12[5];
103 a_Q12_6 = a_Q12[6];
104 a_Q12_7 = a_Q12[7];
105 a_Q12_8 = a_Q12[8];
106 a_Q12_9 = a_Q12[9];
107 a_Q12_10 = a_Q12[10];
108 a_Q12_11 = a_Q12[11];
109 a_Q12_12 = a_Q12[12];
110 a_Q12_13 = a_Q12[13];
111 a_Q12_14 = a_Q12[14];
112 a_Q12_15 = a_Q12[15];
113
114 long long temp64;
115
116 silk_assert( nStatesDelayedDecision > 0 );
117
118 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
119 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
120 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
121
122 for( i = 0; i < length; i++ ) {
123 /* Perform common calculations used in all states */
124
125 /* Long-term prediction */
126 if( signalType == TYPE_VOICED ) {
127 /* Unrolled loop */
128 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
129 temp64 = __builtin_mips_mult(pred_lag_ptr[ 0 ], b_Q14_0 );
130 temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -1 ], b_Q14_1 );
131 temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -2 ], b_Q14_2 );
132 temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -3 ], b_Q14_3 );
133 temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -4 ], b_Q14_4 );
134 temp64 += 32768;
135 LTP_pred_Q14 = __builtin_mips_extr_w(temp64, 16);
136 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
137 pred_lag_ptr++;
138 } else {
139 LTP_pred_Q14 = 0;
140 }
141
142 /* Long-term shaping */
143 if( lag > 0 ) {
144 /* Symmetric, packed FIR coefficients */
145 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
146 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
147 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
148 shp_lag_ptr++;
149 } else {
150 n_LTP_Q14 = 0;
151 }
152
153 for( k = 0; k < nStatesDelayedDecision; k++ ) {
154 /* Delayed decision state */
155 psDD = &psDelDec[ k ];
156
157 /* Sample state */
158 psSS = psSampleState[ k ];
159
160 /* Generate dither */
161 psDD->Seed = silk_RAND( psDD->Seed );
162
163 /* Pointer used in short term prediction and shaping */
164 psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
165 /* Short-term prediction */
166 silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
167 temp64 = __builtin_mips_mult(psLPC_Q14[ 0 ], a_Q12_0 );
168 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -1 ], a_Q12_1 );
169 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -2 ], a_Q12_2 );
170 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -3 ], a_Q12_3 );
171 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -4 ], a_Q12_4 );
172 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -5 ], a_Q12_5 );
173 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -6 ], a_Q12_6 );
174 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -7 ], a_Q12_7 );
175 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -8 ], a_Q12_8 );
176 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -9 ], a_Q12_9 );
177 if( predictLPCOrder == 16 ) {
178 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -10 ], a_Q12_10 );
179 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -11 ], a_Q12_11 );
180 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -12 ], a_Q12_12 );
181 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -13 ], a_Q12_13 );
182 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -14 ], a_Q12_14 );
183 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -15 ], a_Q12_15 );
184 }
185 temp64 += 32768;
186 LPC_pred_Q14 = __builtin_mips_extr_w(temp64, 16);
187
188 LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
189
190 /* Noise shape feedback */
191 silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
192 /* Output of lowpass section */
193 tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
194 /* Output of allpass section */
195 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
196 psDD->sAR2_Q14[ 0 ] = tmp2;
197
198 temp64 = __builtin_mips_mult(tmp2, AR_shp_Q13[ 0 ] );
199
200 prev = psDD->sAR2_Q14[ 1 ];
201
202 /* Loop over allpass sections */
203 for( j = 2; j < shapingLPCOrder; j += 2 ) {
204 cur = psDD->sAR2_Q14[ j ];
205 next = psDD->sAR2_Q14[ j+1 ];
206 /* Output of allpass section */
207 tmp2 = silk_SMLAWB( prev, cur - tmp1, warping_Q16 );
208 psDD->sAR2_Q14[ j - 1 ] = tmp1;
209 temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ j - 1 ] );
210 temp64 = __builtin_mips_madd( temp64, tmp2, AR_shp_Q13[ j ] );
211 /* Output of allpass section */
212 tmp1 = silk_SMLAWB( cur, next - tmp2, warping_Q16 );
213 psDD->sAR2_Q14[ j + 0 ] = tmp2;
214 prev = next;
215 }
216 psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
217 temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
218 temp64 += 32768;
219 n_AR_Q14 = __builtin_mips_extr_w(temp64, 16);
220 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */
221 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */
222 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */
223
224 n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */
225 n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */
226 n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */
227
228 /* Input minus prediction plus noise feedback */
229 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
230 tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
231 tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
232 tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
233 tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
234
235 r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
236
237 /* Flip sign depending on dither */
238 if ( psDD->Seed < 0 ) {
239 r_Q10 = -r_Q10;
240 }
241 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
242
243 /* Find two quantization level candidates and measure their rate-distortion */
244 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
245 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
246 if( q1_Q0 > 0 ) {
247 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
248 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
249 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
250 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
251 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
252 } else if( q1_Q0 == 0 ) {
253 q1_Q10 = offset_Q10;
254 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
255 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
256 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
257 } else if( q1_Q0 == -1 ) {
258 q2_Q10 = offset_Q10;
259 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
260 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
261 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
262 } else { /* q1_Q0 < -1 */
263 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
264 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
265 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
266 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
267 rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
268 }
269 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
270 rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
271 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
272 rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
273
274 if( rd1_Q10 < rd2_Q10 ) {
275 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
276 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
277 psSS[ 0 ].Q_Q10 = q1_Q10;
278 psSS[ 1 ].Q_Q10 = q2_Q10;
279 } else {
280 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
281 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
282 psSS[ 0 ].Q_Q10 = q2_Q10;
283 psSS[ 1 ].Q_Q10 = q1_Q10;
284 }
285
286 /* Update states for best quantization */
287
288 /* Quantized excitation */
289 exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
290 if ( psDD->Seed < 0 ) {
291 exc_Q14 = -exc_Q14;
292 }
293
294 /* Add predictions */
295 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
296 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
297
298 /* Update states */
299 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
300 psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
301 psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
302 psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
303 psSS[ 0 ].xq_Q14 = xq_Q14;
304
305 /* Update states for second best quantization */
306
307 /* Quantized excitation */
308 exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
309 if ( psDD->Seed < 0 ) {
310 exc_Q14 = -exc_Q14;
311 }
312
313
314 /* Add predictions */
315 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
316 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
317
318 /* Update states */
319 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
320 psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
321 psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
322 psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
323 psSS[ 1 ].xq_Q14 = xq_Q14;
324 }
325
326 *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
327 if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
328 last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
329
330 /* Find winner */
331 RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
332 Winner_ind = 0;
333 for( k = 1; k < nStatesDelayedDecision; k++ ) {
334 if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
335 RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
336 Winner_ind = k;
337 }
338 }
339
340 /* Increase RD values of expired states */
341 Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
342 for( k = 0; k < nStatesDelayedDecision; k++ ) {
343 if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
344 psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
345 psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
346 silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
347 }
348 }
349
350 /* Find worst in first set and best in second set */
351 RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
352 RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
353 RDmax_ind = 0;
354 RDmin_ind = 0;
355 for( k = 1; k < nStatesDelayedDecision; k++ ) {
356 /* find worst in first set */
357 if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
358 RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
359 RDmax_ind = k;
360 }
361 /* find best in second set */
362 if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
363 RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
364 RDmin_ind = k;
365 }
366 }
367
368 /* Replace a state if best from second set outperforms worst in first set */
369 if( RDmin_Q10 < RDmax_Q10 ) {
370 silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
371 ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
372 silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
373 }
374
375 /* Write samples from winner to output and long-term filter states */
376 psDD = &psDelDec[ Winner_ind ];
377 if( subfr > 0 || i >= decisionDelay ) {
378 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
379 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
380 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
381 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
382 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ];
383 }
384 NSQ->sLTP_shp_buf_idx++;
385 NSQ->sLTP_buf_idx++;
386
387 /* Update states */
388 for( k = 0; k < nStatesDelayedDecision; k++ ) {
389 psDD = &psDelDec[ k ];
390 psSS = &psSampleState[ k ][ 0 ];
391 psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
392 psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
393 psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
394 psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
395 psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
396 psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14;
397 psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
398 psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
399 psDD->RD_Q10 = psSS->RD_Q10;
400 }
401 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
402 }
403 /* Update LPC states */
404 for( k = 0; k < nStatesDelayedDecision; k++ ) {
405 psDD = &psDelDec[ k ];
406 silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
407 }
408}
409
410#endif /* __NSQ_DEL_DEC_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h
new file mode 100644
index 0000000000..12ed981a6e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h
@@ -0,0 +1,92 @@
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#ifndef __SILK_MACROS_MIPSR1_H__
30#define __SILK_MACROS_MIPSR1_H__
31
32#define mips_clz(x) __builtin_clz(x)
33
34#undef silk_SMULWB
35static inline int silk_SMULWB(int a, int b)
36{
37 long long ac;
38 int c;
39
40 ac = __builtin_mips_mult(a, (opus_int32)(opus_int16)b);
41 c = __builtin_mips_extr_w(ac, 16);
42
43 return c;
44}
45
46#undef silk_SMLAWB
47#define silk_SMLAWB(a32, b32, c32) ((a32) + silk_SMULWB(b32, c32))
48
49#undef silk_SMULWW
50static inline int silk_SMULWW(int a, int b)
51{
52 long long ac;
53 int c;
54
55 ac = __builtin_mips_mult(a, b);
56 c = __builtin_mips_extr_w(ac, 16);
57
58 return c;
59}
60
61#undef silk_SMLAWW
62static inline int silk_SMLAWW(int a, int b, int c)
63{
64 long long ac;
65 int res;
66
67 ac = __builtin_mips_mult(b, c);
68 res = __builtin_mips_extr_w(ac, 16);
69 res += a;
70
71 return res;
72}
73
74#define OVERRIDE_silk_CLZ16
75static inline opus_int32 silk_CLZ16(opus_int16 in16)
76{
77 int re32;
78 opus_int32 in32 = (opus_int32 )in16;
79 re32 = mips_clz(in32);
80 re32-=16;
81 return re32;
82}
83
84#define OVERRIDE_silk_CLZ32
85static inline opus_int32 silk_CLZ32(opus_int32 in32)
86{
87 int re32;
88 re32 = mips_clz(in32);
89 return re32;
90}
91
92#endif /* __SILK_MACROS_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h
new file mode 100644
index 0000000000..51520c0a6f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h
@@ -0,0 +1,60 @@
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_SIGPROC_FIX_MIPSR1_H
29#define SILK_SIGPROC_FIX_MIPSR1_H
30
31#undef silk_SAT16
32static inline short int silk_SAT16(int a)
33{
34 int c;
35 c = __builtin_mips_shll_s_w(a, 16);
36 c = c>>16;
37
38 return c;
39}
40
41#undef silk_LSHIFT_SAT32
42static inline int silk_LSHIFT_SAT32(int a, int shift)
43{
44 int r;
45
46 r = __builtin_mips_shll_s_w(a, shift);
47
48 return r;
49}
50
51#undef silk_RSHIFT_ROUND
52static inline int silk_RSHIFT_ROUND(int a, int shift)
53{
54 int r;
55
56 r = __builtin_mips_shra_r_w(a, shift);
57 return r;
58}
59
60#endif /* SILK_SIGPROC_FIX_MIPSR1_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/process_NLSFs.c b/lib/rbcodec/codecs/libopus/silk/process_NLSFs.c
new file mode 100644
index 0000000000..d130809541
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/process_NLSFs.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 "main.h"
33
34/* Limit, stabilize, convert and quantize NLSFs */
35void silk_process_NLSFs(
36 silk_encoder_state *psEncC, /* I/O Encoder state */
37 opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */
38 opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */
39 const opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */
40)
41{
42 opus_int i, doInterpolate;
43 opus_int NLSF_mu_Q20;
44 opus_int16 i_sqr_Q15;
45 opus_int16 pNLSF0_temp_Q15[ MAX_LPC_ORDER ];
46 opus_int16 pNLSFW_QW[ MAX_LPC_ORDER ];
47 opus_int16 pNLSFW0_temp_QW[ MAX_LPC_ORDER ];
48
49 silk_assert( psEncC->speech_activity_Q8 >= 0 );
50 silk_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) );
51 celt_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) );
52
53 /***********************/
54 /* Calculate mu values */
55 /***********************/
56 /* NLSF_mu = 0.003 - 0.0015 * psEnc->speech_activity; */
57 NLSF_mu_Q20 = silk_SMLAWB( SILK_FIX_CONST( 0.003, 20 ), SILK_FIX_CONST( -0.001, 28 ), psEncC->speech_activity_Q8 );
58 if( psEncC->nb_subfr == 2 ) {
59 /* Multiply by 1.5 for 10 ms packets */
60 NLSF_mu_Q20 = silk_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 );
61 }
62
63 celt_assert( NLSF_mu_Q20 > 0 );
64 silk_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.005, 20 ) );
65
66 /* Calculate NLSF weights */
67 silk_NLSF_VQ_weights_laroia( pNLSFW_QW, pNLSF_Q15, psEncC->predictLPCOrder );
68
69 /* Update NLSF weights for interpolated NLSFs */
70 doInterpolate = ( psEncC->useInterpolatedNLSFs == 1 ) && ( psEncC->indices.NLSFInterpCoef_Q2 < 4 );
71 if( doInterpolate ) {
72 /* Calculate the interpolated NLSF vector for the first half */
73 silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15,
74 psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
75
76 /* Calculate first half NLSF weights for the interpolated NLSFs */
77 silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_QW, pNLSF0_temp_Q15, psEncC->predictLPCOrder );
78
79 /* Update NLSF weights with contribution from first half */
80 i_sqr_Q15 = silk_LSHIFT( silk_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 );
81 for( i = 0; i < psEncC->predictLPCOrder; i++ ) {
82 pNLSFW_QW[ i ] = silk_ADD16( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), silk_RSHIFT(
83 silk_SMULBB( pNLSFW0_temp_QW[ i ], i_sqr_Q15 ), 16) );
84 silk_assert( pNLSFW_QW[ i ] >= 1 );
85 }
86 }
87
88 silk_NLSF_encode( psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_QW,
89 NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType );
90
91 /* Convert quantized NLSFs back to LPC coefficients */
92 silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder, psEncC->arch );
93
94 if( doInterpolate ) {
95 /* Calculate the interpolated, quantized LSF vector for the first half */
96 silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15,
97 psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
98
99 /* Convert back to LPC coefficients */
100 silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder, psEncC->arch );
101
102 } else {
103 /* Copy LPC coefficients for first half from second half */
104 celt_assert( psEncC->predictLPCOrder <= MAX_LPC_ORDER );
105 silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) );
106 }
107}
diff --git a/lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c b/lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c
new file mode 100644
index 0000000000..d6b8eff8d1
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c
@@ -0,0 +1,132 @@
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.h"
33#include "tuning_parameters.h"
34
35void silk_quant_LTP_gains(
36 opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
37 opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */
38 opus_int8 *periodicity_index, /* O Periodicity Index */
39 opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
40 opus_int *pred_gain_dB_Q7, /* O LTP prediction gain */
41 const opus_int32 XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Correlation matrix in Q18 */
42 const opus_int32 xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ], /* I Correlation vector in Q18 */
43 const opus_int subfr_len, /* I Number of samples per subframe */
44 const opus_int nb_subfr, /* I Number of subframes */
45 int arch /* I Run-time architecture */
46)
47{
48 opus_int j, k, cbk_size;
49 opus_int8 temp_idx[ MAX_NB_SUBFR ];
50 const opus_uint8 *cl_ptr_Q5;
51 const opus_int8 *cbk_ptr_Q7;
52 const opus_uint8 *cbk_gain_ptr_Q7;
53 const opus_int32 *XX_Q17_ptr, *xX_Q17_ptr;
54 opus_int32 res_nrg_Q15_subfr, res_nrg_Q15, rate_dist_Q7_subfr, rate_dist_Q7, min_rate_dist_Q7;
55 opus_int32 sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7;
56 opus_int gain_Q7;
57
58 /***************************************************/
59 /* iterate over different codebooks with different */
60 /* rates/distortions, and choose best */
61 /***************************************************/
62 min_rate_dist_Q7 = silk_int32_MAX;
63 best_sum_log_gain_Q7 = 0;
64 for( k = 0; k < 3; k++ ) {
65 /* Safety margin for pitch gain control, to take into account factors
66 such as state rescaling/rewhitening. */
67 opus_int32 gain_safety = SILK_FIX_CONST( 0.4, 7 );
68
69 cl_ptr_Q5 = silk_LTP_gain_BITS_Q5_ptrs[ k ];
70 cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ k ];
71 cbk_gain_ptr_Q7 = silk_LTP_vq_gain_ptrs_Q7[ k ];
72 cbk_size = silk_LTP_vq_sizes[ k ];
73
74 /* Set up pointers to first subframe */
75 XX_Q17_ptr = XX_Q17;
76 xX_Q17_ptr = xX_Q17;
77
78 res_nrg_Q15 = 0;
79 rate_dist_Q7 = 0;
80 sum_log_gain_tmp_Q7 = *sum_log_gain_Q7;
81 for( j = 0; j < nb_subfr; j++ ) {
82 max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 )
83 + SILK_FIX_CONST( 7, 7 ) ) - gain_safety;
84 silk_VQ_WMat_EC(
85 &temp_idx[ j ], /* O index of best codebook vector */
86 &res_nrg_Q15_subfr, /* O residual energy */
87 &rate_dist_Q7_subfr, /* O best weighted quantization error + mu * rate */
88 &gain_Q7, /* O sum of absolute LTP coefficients */
89 XX_Q17_ptr, /* I correlation matrix */
90 xX_Q17_ptr, /* I correlation vector */
91 cbk_ptr_Q7, /* I codebook */
92 cbk_gain_ptr_Q7, /* I codebook effective gains */
93 cl_ptr_Q5, /* I code length for each codebook vector */
94 subfr_len, /* I number of samples per subframe */
95 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
96 cbk_size, /* I number of vectors in codebook */
97 arch /* I Run-time architecture */
98 );
99
100 res_nrg_Q15 = silk_ADD_POS_SAT32( res_nrg_Q15, res_nrg_Q15_subfr );
101 rate_dist_Q7 = silk_ADD_POS_SAT32( rate_dist_Q7, rate_dist_Q7_subfr );
102 sum_log_gain_tmp_Q7 = silk_max(0, sum_log_gain_tmp_Q7
103 + silk_lin2log( gain_safety + gain_Q7 ) - SILK_FIX_CONST( 7, 7 ));
104
105 XX_Q17_ptr += LTP_ORDER * LTP_ORDER;
106 xX_Q17_ptr += LTP_ORDER;
107 }
108
109 if( rate_dist_Q7 <= min_rate_dist_Q7 ) {
110 min_rate_dist_Q7 = rate_dist_Q7;
111 *periodicity_index = (opus_int8)k;
112 silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) );
113 best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7;
114 }
115 }
116
117 cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ *periodicity_index ];
118 for( j = 0; j < nb_subfr; j++ ) {
119 for( k = 0; k < LTP_ORDER; k++ ) {
120 B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 );
121 }
122 }
123
124 if( nb_subfr == 2 ) {
125 res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 1 );
126 } else {
127 res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 2 );
128 }
129
130 *sum_log_gain_Q7 = best_sum_log_gain_Q7;
131 *pred_gain_dB_Q7 = (opus_int)silk_SMULBB( -3, silk_lin2log( res_nrg_Q15 ) - ( 15 << 7 ) );
132}
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler.c b/lib/rbcodec/codecs/libopus/silk/resampler.c
index 374fbb3722..1f11e50891 100644
--- a/lib/rbcodec/codecs/libopus/silk/resampler.c
+++ b/lib/rbcodec/codecs/libopus/silk/resampler.c
@@ -91,14 +91,14 @@ opus_int silk_resampler_init(
91 if( forEnc ) { 91 if( forEnc ) {
92 if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) || 92 if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) ||
93 ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) { 93 ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) {
94 silk_assert( 0 ); 94 celt_assert( 0 );
95 return -1; 95 return -1;
96 } 96 }
97 S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; 97 S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
98 } else { 98 } else {
99 if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) || 99 if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) ||
100 ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) { 100 ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) {
101 silk_assert( 0 ); 101 celt_assert( 0 );
102 return -1; 102 return -1;
103 } 103 }
104 S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; 104 S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
@@ -151,7 +151,7 @@ opus_int silk_resampler_init(
151 S->Coefs = silk_Resampler_1_6_COEFS; 151 S->Coefs = silk_Resampler_1_6_COEFS;
152 } else { 152 } else {
153 /* None available */ 153 /* None available */
154 silk_assert( 0 ); 154 celt_assert( 0 );
155 return -1; 155 return -1;
156 } 156 }
157 } else { 157 } else {
@@ -181,9 +181,9 @@ opus_int silk_resampler(
181 opus_int nSamples; 181 opus_int nSamples;
182 182
183 /* Need at least 1 ms of input data */ 183 /* Need at least 1 ms of input data */
184 silk_assert( inLen >= S->Fs_in_kHz ); 184 celt_assert( inLen >= S->Fs_in_kHz );
185 /* Delay can't exceed the 1 ms of buffering */ 185 /* Delay can't exceed the 1 ms of buffering */
186 silk_assert( S->inputDelay <= S->Fs_in_kHz ); 186 celt_assert( S->inputDelay <= S->Fs_in_kHz );
187 187
188 nSamples = S->Fs_in_kHz - S->inputDelay; 188 nSamples = S->Fs_in_kHz - S->inputDelay;
189 189
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_down2.c b/lib/rbcodec/codecs/libopus/silk/resampler_down2.c
new file mode 100644
index 0000000000..971d7bfd4a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/resampler_down2.c
@@ -0,0 +1,74 @@
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 "resampler_rom.h"
34
35/* Downsample by a factor 2 */
36void silk_resampler_down2(
37 opus_int32 *S, /* I/O State vector [ 2 ] */
38 opus_int16 *out, /* O Output signal [ floor(len/2) ] */
39 const opus_int16 *in, /* I Input signal [ len ] */
40 opus_int32 inLen /* I Number of input samples */
41)
42{
43 opus_int32 k, len2 = silk_RSHIFT32( inLen, 1 );
44 opus_int32 in32, out32, Y, X;
45
46 celt_assert( silk_resampler_down2_0 > 0 );
47 celt_assert( silk_resampler_down2_1 < 0 );
48
49 /* Internal variables and state are in Q10 format */
50 for( k = 0; k < len2; k++ ) {
51 /* Convert to Q10 */
52 in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 );
53
54 /* All-pass section for even input sample */
55 Y = silk_SUB32( in32, S[ 0 ] );
56 X = silk_SMLAWB( Y, Y, silk_resampler_down2_1 );
57 out32 = silk_ADD32( S[ 0 ], X );
58 S[ 0 ] = silk_ADD32( in32, X );
59
60 /* Convert to Q10 */
61 in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 );
62
63 /* All-pass section for odd input sample, and add to output of previous section */
64 Y = silk_SUB32( in32, S[ 1 ] );
65 X = silk_SMULWB( Y, silk_resampler_down2_0 );
66 out32 = silk_ADD32( out32, S[ 1 ] );
67 out32 = silk_ADD32( out32, X );
68 S[ 1 ] = silk_ADD32( in32, X );
69
70 /* Add, convert back to int16 and store to output */
71 out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32, 11 ) );
72 }
73}
74
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_down2_3.c b/lib/rbcodec/codecs/libopus/silk/resampler_down2_3.c
new file mode 100644
index 0000000000..4342614dcc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/resampler_down2_3.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 "SigProc_FIX.h"
33#include "resampler_private.h"
34#include "stack_alloc.h"
35
36#define ORDER_FIR 4
37
38/* Downsample by a factor 2/3, low quality */
39void silk_resampler_down2_3(
40 opus_int32 *S, /* I/O State vector [ 6 ] */
41 opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */
42 const opus_int16 *in, /* I Input signal [ inLen ] */
43 opus_int32 inLen /* I Number of input samples */
44)
45{
46 opus_int32 nSamplesIn, counter, res_Q6;
47 VARDECL( opus_int32, buf );
48 opus_int32 *buf_ptr;
49 SAVE_STACK;
50
51 ALLOC( buf, RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR, opus_int32 );
52
53 /* Copy buffered samples to start of buffer */
54 silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) );
55
56 /* Iterate over blocks of frameSizeIn input samples */
57 while( 1 ) {
58 nSamplesIn = silk_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN );
59
60 /* Second-order AR filter (output in Q8) */
61 silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in,
62 silk_Resampler_2_3_COEFS_LQ, nSamplesIn );
63
64 /* Interpolate filtered signal */
65 buf_ptr = buf;
66 counter = nSamplesIn;
67 while( counter > 2 ) {
68 /* Inner product */
69 res_Q6 = silk_SMULWB( buf_ptr[ 0 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] );
70 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] );
71 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] );
72 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] );
73
74 /* Scale down, saturate and store in output array */
75 *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
76
77 res_Q6 = silk_SMULWB( buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] );
78 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] );
79 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] );
80 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] );
81
82 /* Scale down, saturate and store in output array */
83 *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
84
85 buf_ptr += 3;
86 counter -= 3;
87 }
88
89 in += nSamplesIn;
90 inLen -= nSamplesIn;
91
92 if( inLen > 0 ) {
93 /* More iterations to do; copy last part of filtered signal to beginning of buffer */
94 silk_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) );
95 } else {
96 break;
97 }
98 }
99
100 /* Copy last part of filtered signal to the state for the next call */
101 silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) );
102 RESTORE_STACK;
103}
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c b/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c
index 783e42b356..3e8735a35a 100644
--- a/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c
+++ b/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c
@@ -136,7 +136,7 @@ static OPUS_INLINE opus_int16 *silk_resampler_private_down_FIR_INTERPOL(
136 } 136 }
137 break; 137 break;
138 default: 138 default:
139 silk_assert( 0 ); 139 celt_assert( 0 );
140 } 140 }
141 return out; 141 return out;
142} 142}
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_rom.c b/lib/rbcodec/codecs/libopus/silk/resampler_rom.c
index 2d502706f9..5e6b04476a 100644
--- a/lib/rbcodec/codecs/libopus/silk/resampler_rom.c
+++ b/lib/rbcodec/codecs/libopus/silk/resampler_rom.c
@@ -41,36 +41,36 @@ POSSIBILITY OF SUCH DAMAGE.
41 41
42/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */ 42/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */
43silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { 43silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {
44 -20694, -13867, 44 -20694, -13867,
45 -49, 64, 17, -157, 353, -496, 163, 11047, 22205, 45 -49, 64, 17, -157, 353, -496, 163, 11047, 22205,
46 -39, 6, 91, -170, 186, 23, -896, 6336, 19928, 46 -39, 6, 91, -170, 186, 23, -896, 6336, 19928,
47 -19, -36, 102, -89, -24, 328, -951, 2568, 15909, 47 -19, -36, 102, -89, -24, 328, -951, 2568, 15909,
48}; 48};
49 49
50silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { 50silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {
51 -14457, -14019, 51 -14457, -14019,
52 64, 128, -122, 36, 310, -768, 584, 9267, 17733, 52 64, 128, -122, 36, 310, -768, 584, 9267, 17733,
53 12, 128, 18, -142, 288, -117, -865, 4123, 14459, 53 12, 128, 18, -142, 288, -117, -865, 4123, 14459,
54}; 54};
55 55
56silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = { 56silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = {
57 616, -14323, 57 616, -14323,
58 -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024, 58 -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024,
59}; 59};
60 60
61silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { 61silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
62 16102, -15162, 62 16102, -15162,
63 -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271, 63 -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271,
64}; 64};
65 65
66silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { 66silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
67 22500, -15099, 67 22500, -15099,
68 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464, 68 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464,
69}; 69};
70 70
71silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { 71silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
72 27540, -15257, 72 27540, -15257,
73 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455, 73 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455,
74}; 74};
75 75
76silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = { 76silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {
@@ -81,16 +81,16 @@ silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {
81 81
82/* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */ 82/* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */
83silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = { 83silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = {
84 { 189, -600, 617, 30567 }, 84 { 189, -600, 617, 30567 },
85 { 117, -159, -1070, 29704 }, 85 { 117, -159, -1070, 29704 },
86 { 52, 221, -2392, 28276 }, 86 { 52, 221, -2392, 28276 },
87 { -4, 529, -3350, 26341 }, 87 { -4, 529, -3350, 26341 },
88 { -48, 758, -3956, 23973 }, 88 { -48, 758, -3956, 23973 },
89 { -80, 905, -4235, 21254 }, 89 { -80, 905, -4235, 21254 },
90 { -99, 972, -4222, 18278 }, 90 { -99, 972, -4222, 18278 },
91 { -107, 967, -3957, 15143 }, 91 { -107, 967, -3957, 15143 },
92 { -103, 896, -3487, 11950 }, 92 { -103, 896, -3487, 11950 },
93 { -91, 773, -2865, 8798 }, 93 { -91, 773, -2865, 8798 },
94 { -71, 611, -2143, 5784 }, 94 { -71, 611, -2143, 5784 },
95 { -46, 425, -1375, 2996 }, 95 { -46, 425, -1375, 2996 },
96}; 96};
diff --git a/lib/rbcodec/codecs/libopus/silk/shell_coder.c b/lib/rbcodec/codecs/libopus/silk/shell_coder.c
index d80dd51f9e..4af341474b 100644
--- a/lib/rbcodec/codecs/libopus/silk/shell_coder.c
+++ b/lib/rbcodec/codecs/libopus/silk/shell_coder.c
@@ -45,7 +45,6 @@ static OPUS_INLINE void combine_pulses(
45 } 45 }
46} 46}
47 47
48#if 0
49static OPUS_INLINE void encode_split( 48static OPUS_INLINE void encode_split(
50 ec_enc *psRangeEnc, /* I/O compressor data structure */ 49 ec_enc *psRangeEnc, /* I/O compressor data structure */
51 const opus_int p_child1, /* I pulse amplitude of first child subframe */ 50 const opus_int p_child1, /* I pulse amplitude of first child subframe */
@@ -57,7 +56,6 @@ static OPUS_INLINE void encode_split(
57 ec_enc_icdf( psRangeEnc, p_child1, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 ); 56 ec_enc_icdf( psRangeEnc, p_child1, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 );
58 } 57 }
59} 58}
60#endif
61 59
62static OPUS_INLINE void decode_split( 60static OPUS_INLINE void decode_split(
63 opus_int16 *p_child1, /* O pulse amplitude of first child subframe */ 61 opus_int16 *p_child1, /* O pulse amplitude of first child subframe */
@@ -76,7 +74,6 @@ static OPUS_INLINE void decode_split(
76 } 74 }
77} 75}
78 76
79#if 0
80/* Shell encoder, operates on one shell code frame of 16 pulses */ 77/* Shell encoder, operates on one shell code frame of 16 pulses */
81void silk_shell_encoder( 78void silk_shell_encoder(
82 ec_enc *psRangeEnc, /* I/O compressor data structure */ 79 ec_enc *psRangeEnc, /* I/O compressor data structure */
@@ -116,7 +113,6 @@ void silk_shell_encoder(
116 encode_split( psRangeEnc, pulses0[ 12 ], pulses1[ 6 ], silk_shell_code_table0 ); 113 encode_split( psRangeEnc, pulses0[ 12 ], pulses1[ 6 ], silk_shell_code_table0 );
117 encode_split( psRangeEnc, pulses0[ 14 ], pulses1[ 7 ], silk_shell_code_table0 ); 114 encode_split( psRangeEnc, pulses0[ 14 ], pulses1[ 7 ], silk_shell_code_table0 );
118} 115}
119#endif
120 116
121 117
122/* Shell decoder, operates on one shell code frame of 16 pulses */ 118/* Shell decoder, operates on one shell code frame of 16 pulses */
diff --git a/lib/rbcodec/codecs/libopus/silk/sigm_Q15.c b/lib/rbcodec/codecs/libopus/silk/sigm_Q15.c
new file mode 100644
index 0000000000..3c507d255b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/sigm_Q15.c
@@ -0,0 +1,76 @@
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/* Approximate sigmoid function */
33
34#include "SigProc_FIX.h"
35
36/* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */
37static const opus_int32 sigm_LUT_slope_Q10[ 6 ] = {
38 237, 153, 73, 30, 12, 7
39};
40/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */
41static const opus_int32 sigm_LUT_pos_Q15[ 6 ] = {
42 16384, 23955, 28861, 31213, 32178, 32548
43};
44/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */
45static const opus_int32 sigm_LUT_neg_Q15[ 6 ] = {
46 16384, 8812, 3906, 1554, 589, 219
47};
48
49opus_int silk_sigm_Q15(
50 opus_int in_Q5 /* I */
51)
52{
53 opus_int ind;
54
55 if( in_Q5 < 0 ) {
56 /* Negative input */
57 in_Q5 = -in_Q5;
58 if( in_Q5 >= 6 * 32 ) {
59 return 0; /* Clip */
60 } else {
61 /* Linear interpolation of look up table */
62 ind = silk_RSHIFT( in_Q5, 5 );
63 return( sigm_LUT_neg_Q15[ ind ] - silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) );
64 }
65 } else {
66 /* Positive input */
67 if( in_Q5 >= 6 * 32 ) {
68 return 32767; /* clip */
69 } else {
70 /* Linear interpolation of look up table */
71 ind = silk_RSHIFT( in_Q5, 5 );
72 return( sigm_LUT_pos_Q15[ ind ] + silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) );
73 }
74 }
75}
76
diff --git a/lib/rbcodec/codecs/libopus/silk/sort.c b/lib/rbcodec/codecs/libopus/silk/sort.c
index 2f9930d9ce..4fba16f831 100644
--- a/lib/rbcodec/codecs/libopus/silk/sort.c
+++ b/lib/rbcodec/codecs/libopus/silk/sort.c
@@ -33,11 +33,10 @@ POSSIBILITY OF SUCH DAMAGE.
33/* Best case: O(n) for an already sorted array */ 33/* Best case: O(n) for an already sorted array */
34/* Worst case: O(n^2) for an inversely sorted array */ 34/* Worst case: O(n^2) for an inversely sorted array */
35/* */ 35/* */
36/* Shell short: http://en.wikipedia.org/wiki/Shell_sort */ 36/* Shell short: https://en.wikipedia.org/wiki/Shell_sort */
37 37
38#include "SigProc_FIX.h" 38#include "SigProc_FIX.h"
39 39
40#if 0
41void silk_insertion_sort_increasing( 40void silk_insertion_sort_increasing(
42 opus_int32 *a, /* I/O Unsorted / Sorted vector */ 41 opus_int32 *a, /* I/O Unsorted / Sorted vector */
43 opus_int *idx, /* O Index vector for the sorted elements */ 42 opus_int *idx, /* O Index vector for the sorted elements */
@@ -49,9 +48,9 @@ void silk_insertion_sort_increasing(
49 opus_int i, j; 48 opus_int i, j;
50 49
51 /* Safety checks */ 50 /* Safety checks */
52 silk_assert( K > 0 ); 51 celt_assert( K > 0 );
53 silk_assert( L > 0 ); 52 celt_assert( L > 0 );
54 silk_assert( L >= K ); 53 celt_assert( L >= K );
55 54
56 /* Write start indices in index vector */ 55 /* Write start indices in index vector */
57 for( i = 0; i < K; i++ ) { 56 for( i = 0; i < K; i++ ) {
@@ -83,7 +82,6 @@ void silk_insertion_sort_increasing(
83 } 82 }
84 } 83 }
85} 84}
86#endif
87 85
88#ifdef FIXED_POINT 86#ifdef FIXED_POINT
89/* This function is only used by the fixed-point build */ 87/* This function is only used by the fixed-point build */
@@ -98,9 +96,9 @@ void silk_insertion_sort_decreasing_int16(
98 opus_int value; 96 opus_int value;
99 97
100 /* Safety checks */ 98 /* Safety checks */
101 silk_assert( K > 0 ); 99 celt_assert( K > 0 );
102 silk_assert( L > 0 ); 100 celt_assert( L > 0 );
103 silk_assert( L >= K ); 101 celt_assert( L >= K );
104 102
105 /* Write start indices in index vector */ 103 /* Write start indices in index vector */
106 for( i = 0; i < K; i++ ) { 104 for( i = 0; i < K; i++ ) {
@@ -143,7 +141,7 @@ void silk_insertion_sort_increasing_all_values_int16(
143 opus_int i, j; 141 opus_int i, j;
144 142
145 /* Safety checks */ 143 /* Safety checks */
146 silk_assert( L > 0 ); 144 celt_assert( L > 0 );
147 145
148 /* Sort vector elements by value, increasing order */ 146 /* Sort vector elements by value, increasing order */
149 for( i = 1; i < L; i++ ) { 147 for( i = 1; i < L; i++ ) {
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c b/lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c
new file mode 100644
index 0000000000..c8226663c8
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c
@@ -0,0 +1,229 @@
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.h"
33#include "stack_alloc.h"
34
35/* Convert Left/Right stereo signal to adaptive Mid/Side representation */
36void silk_stereo_LR_to_MS(
37 stereo_enc_state *state, /* I/O State */
38 opus_int16 x1[], /* I/O Left input signal, becomes mid signal */
39 opus_int16 x2[], /* I/O Right input signal, becomes side signal */
40 opus_int8 ix[ 2 ][ 3 ], /* O Quantization indices */
41 opus_int8 *mid_only_flag, /* O Flag: only mid signal coded */
42 opus_int32 mid_side_rates_bps[], /* O Bitrates for mid and side signals */
43 opus_int32 total_rate_bps, /* I Total bitrate */
44 opus_int prev_speech_act_Q8, /* I Speech activity level in previous frame */
45 opus_int toMono, /* I Last frame before a stereo->mono transition */
46 opus_int fs_kHz, /* I Sample rate (kHz) */
47 opus_int frame_length /* I Number of samples */
48)
49{
50 opus_int n, is10msFrame, denom_Q16, delta0_Q13, delta1_Q13;
51 opus_int32 sum, diff, smooth_coef_Q16, pred_Q13[ 2 ], pred0_Q13, pred1_Q13;
52 opus_int32 LP_ratio_Q14, HP_ratio_Q14, frac_Q16, frac_3_Q16, min_mid_rate_bps, width_Q14, w_Q24, deltaw_Q24;
53 VARDECL( opus_int16, side );
54 VARDECL( opus_int16, LP_mid );
55 VARDECL( opus_int16, HP_mid );
56 VARDECL( opus_int16, LP_side );
57 VARDECL( opus_int16, HP_side );
58 opus_int16 *mid = &x1[ -2 ];
59 SAVE_STACK;
60
61 ALLOC( side, frame_length + 2, opus_int16 );
62 /* Convert to basic mid/side signals */
63 for( n = 0; n < frame_length + 2; n++ ) {
64 sum = x1[ n - 2 ] + (opus_int32)x2[ n - 2 ];
65 diff = x1[ n - 2 ] - (opus_int32)x2[ n - 2 ];
66 mid[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 );
67 side[ n ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( diff, 1 ) );
68 }
69
70 /* Buffering */
71 silk_memcpy( mid, state->sMid, 2 * sizeof( opus_int16 ) );
72 silk_memcpy( side, state->sSide, 2 * sizeof( opus_int16 ) );
73 silk_memcpy( state->sMid, &mid[ frame_length ], 2 * sizeof( opus_int16 ) );
74 silk_memcpy( state->sSide, &side[ frame_length ], 2 * sizeof( opus_int16 ) );
75
76 /* LP and HP filter mid signal */
77 ALLOC( LP_mid, frame_length, opus_int16 );
78 ALLOC( HP_mid, frame_length, opus_int16 );
79 for( n = 0; n < frame_length; n++ ) {
80 sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 );
81 LP_mid[ n ] = sum;
82 HP_mid[ n ] = mid[ n + 1 ] - sum;
83 }
84
85 /* LP and HP filter side signal */
86 ALLOC( LP_side, frame_length, opus_int16 );
87 ALLOC( HP_side, frame_length, opus_int16 );
88 for( n = 0; n < frame_length; n++ ) {
89 sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + (opus_int32)side[ n + 2 ], side[ n + 1 ], 1 ), 2 );
90 LP_side[ n ] = sum;
91 HP_side[ n ] = side[ n + 1 ] - sum;
92 }
93
94 /* Find energies and predictors */
95 is10msFrame = frame_length == 10 * fs_kHz;
96 smooth_coef_Q16 = is10msFrame ?
97 SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF / 2, 16 ) :
98 SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF, 16 );
99 smooth_coef_Q16 = silk_SMULWB( silk_SMULBB( prev_speech_act_Q8, prev_speech_act_Q8 ), smooth_coef_Q16 );
100
101 pred_Q13[ 0 ] = silk_stereo_find_predictor( &LP_ratio_Q14, LP_mid, LP_side, &state->mid_side_amp_Q0[ 0 ], frame_length, smooth_coef_Q16 );
102 pred_Q13[ 1 ] = silk_stereo_find_predictor( &HP_ratio_Q14, HP_mid, HP_side, &state->mid_side_amp_Q0[ 2 ], frame_length, smooth_coef_Q16 );
103 /* Ratio of the norms of residual and mid signals */
104 frac_Q16 = silk_SMLABB( HP_ratio_Q14, LP_ratio_Q14, 3 );
105 frac_Q16 = silk_min( frac_Q16, SILK_FIX_CONST( 1, 16 ) );
106
107 /* Determine bitrate distribution between mid and side, and possibly reduce stereo width */
108 total_rate_bps -= is10msFrame ? 1200 : 600; /* Subtract approximate bitrate for coding stereo parameters */
109 if( total_rate_bps < 1 ) {
110 total_rate_bps = 1;
111 }
112 min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 600 );
113 silk_assert( min_mid_rate_bps < 32767 );
114 /* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */
115 frac_3_Q16 = silk_MUL( 3, frac_Q16 );
116 mid_side_rates_bps[ 0 ] = silk_DIV32_varQ( total_rate_bps, SILK_FIX_CONST( 8 + 5, 16 ) + frac_3_Q16, 16+3 );
117 /* If Mid bitrate below minimum, reduce stereo width */
118 if( mid_side_rates_bps[ 0 ] < min_mid_rate_bps ) {
119 mid_side_rates_bps[ 0 ] = min_mid_rate_bps;
120 mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ];
121 /* width = 4 * ( 2 * side_rate - min_rate ) / ( ( 1 + 3 * frac ) * min_rate ) */
122 width_Q14 = silk_DIV32_varQ( silk_LSHIFT( mid_side_rates_bps[ 1 ], 1 ) - min_mid_rate_bps,
123 silk_SMULWB( SILK_FIX_CONST( 1, 16 ) + frac_3_Q16, min_mid_rate_bps ), 14+2 );
124 width_Q14 = silk_LIMIT( width_Q14, 0, SILK_FIX_CONST( 1, 14 ) );
125 } else {
126 mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ];
127 width_Q14 = SILK_FIX_CONST( 1, 14 );
128 }
129
130 /* Smoother */
131 state->smth_width_Q14 = (opus_int16)silk_SMLAWB( state->smth_width_Q14, width_Q14 - state->smth_width_Q14, smooth_coef_Q16 );
132
133 /* At very low bitrates or for inputs that are nearly amplitude panned, switch to panned-mono coding */
134 *mid_only_flag = 0;
135 if( toMono ) {
136 /* Last frame before stereo->mono transition; collapse stereo width */
137 width_Q14 = 0;
138 pred_Q13[ 0 ] = 0;
139 pred_Q13[ 1 ] = 0;
140 silk_stereo_quant_pred( pred_Q13, ix );
141 } else if( state->width_prev_Q14 == 0 &&
142 ( 8 * total_rate_bps < 13 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.05, 14 ) ) )
143 {
144 /* Code as panned-mono; previous frame already had zero width */
145 /* Scale down and quantize predictors */
146 pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );
147 pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );
148 silk_stereo_quant_pred( pred_Q13, ix );
149 /* Collapse stereo width */
150 width_Q14 = 0;
151 pred_Q13[ 0 ] = 0;
152 pred_Q13[ 1 ] = 0;
153 mid_side_rates_bps[ 0 ] = total_rate_bps;
154 mid_side_rates_bps[ 1 ] = 0;
155 *mid_only_flag = 1;
156 } else if( state->width_prev_Q14 != 0 &&
157 ( 8 * total_rate_bps < 11 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.02, 14 ) ) )
158 {
159 /* Transition to zero-width stereo */
160 /* Scale down and quantize predictors */
161 pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );
162 pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );
163 silk_stereo_quant_pred( pred_Q13, ix );
164 /* Collapse stereo width */
165 width_Q14 = 0;
166 pred_Q13[ 0 ] = 0;
167 pred_Q13[ 1 ] = 0;
168 } else if( state->smth_width_Q14 > SILK_FIX_CONST( 0.95, 14 ) ) {
169 /* Full-width stereo coding */
170 silk_stereo_quant_pred( pred_Q13, ix );
171 width_Q14 = SILK_FIX_CONST( 1, 14 );
172 } else {
173 /* Reduced-width stereo coding; scale down and quantize predictors */
174 pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );
175 pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );
176 silk_stereo_quant_pred( pred_Q13, ix );
177 width_Q14 = state->smth_width_Q14;
178 }
179
180 /* Make sure to keep on encoding until the tapered output has been transmitted */
181 if( *mid_only_flag == 1 ) {
182 state->silent_side_len += frame_length - STEREO_INTERP_LEN_MS * fs_kHz;
183 if( state->silent_side_len < LA_SHAPE_MS * fs_kHz ) {
184 *mid_only_flag = 0;
185 } else {
186 /* Limit to avoid wrapping around */
187 state->silent_side_len = 10000;
188 }
189 } else {
190 state->silent_side_len = 0;
191 }
192
193 if( *mid_only_flag == 0 && mid_side_rates_bps[ 1 ] < 1 ) {
194 mid_side_rates_bps[ 1 ] = 1;
195 mid_side_rates_bps[ 0 ] = silk_max_int( 1, total_rate_bps - mid_side_rates_bps[ 1 ]);
196 }
197
198 /* Interpolate predictors and subtract prediction from side channel */
199 pred0_Q13 = -state->pred_prev_Q13[ 0 ];
200 pred1_Q13 = -state->pred_prev_Q13[ 1 ];
201 w_Q24 = silk_LSHIFT( state->width_prev_Q14, 10 );
202 denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz );
203 delta0_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 );
204 delta1_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 );
205 deltaw_Q24 = silk_LSHIFT( silk_SMULWB( width_Q14 - state->width_prev_Q14, denom_Q16 ), 10 );
206 for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) {
207 pred0_Q13 += delta0_Q13;
208 pred1_Q13 += delta1_Q13;
209 w_Q24 += deltaw_Q24;
210 sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
211 sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */
212 sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
213 x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
214 }
215
216 pred0_Q13 = -pred_Q13[ 0 ];
217 pred1_Q13 = -pred_Q13[ 1 ];
218 w_Q24 = silk_LSHIFT( width_Q14, 10 );
219 for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {
220 sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
221 sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */
222 sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
223 x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
224 }
225 state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ];
226 state->pred_prev_Q13[ 1 ] = (opus_int16)pred_Q13[ 1 ];
227 state->width_prev_Q14 = (opus_int16)width_Q14;
228 RESTORE_STACK;
229}
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c b/lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c
new file mode 100644
index 0000000000..03becb6736
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c
@@ -0,0 +1,62 @@
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.h"
33
34/* Entropy code the mid/side quantization indices */
35void silk_stereo_encode_pred(
36 ec_enc *psRangeEnc, /* I/O Compressor data structure */
37 opus_int8 ix[ 2 ][ 3 ] /* I Quantization indices */
38)
39{
40 opus_int n;
41
42 /* Entropy coding */
43 n = 5 * ix[ 0 ][ 2 ] + ix[ 1 ][ 2 ];
44 celt_assert( n < 25 );
45 ec_enc_icdf( psRangeEnc, n, silk_stereo_pred_joint_iCDF, 8 );
46 for( n = 0; n < 2; n++ ) {
47 celt_assert( ix[ n ][ 0 ] < 3 );
48 celt_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS );
49 ec_enc_icdf( psRangeEnc, ix[ n ][ 0 ], silk_uniform3_iCDF, 8 );
50 ec_enc_icdf( psRangeEnc, ix[ n ][ 1 ], silk_uniform5_iCDF, 8 );
51 }
52}
53
54/* Entropy code the mid-only flag */
55void silk_stereo_encode_mid_only(
56 ec_enc *psRangeEnc, /* I/O Compressor data structure */
57 opus_int8 mid_only_flag
58)
59{
60 /* Encode flag that only mid channel is coded */
61 ec_enc_icdf( psRangeEnc, mid_only_flag, silk_stereo_only_code_mid_iCDF, 8 );
62}
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c b/lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c
new file mode 100644
index 0000000000..e30e90bddc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c
@@ -0,0 +1,79 @@
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.h"
33
34/* Find least-squares prediction gain for one signal based on another and quantize it */
35opus_int32 silk_stereo_find_predictor( /* O Returns predictor in Q13 */
36 opus_int32 *ratio_Q14, /* O Ratio of residual and mid energies */
37 const opus_int16 x[], /* I Basis signal */
38 const opus_int16 y[], /* I Target signal */
39 opus_int32 mid_res_amp_Q0[], /* I/O Smoothed mid, residual norms */
40 opus_int length, /* I Number of samples */
41 opus_int smooth_coef_Q16 /* I Smoothing coefficient */
42)
43{
44 opus_int scale, scale1, scale2;
45 opus_int32 nrgx, nrgy, corr, pred_Q13, pred2_Q10;
46
47 /* Find predictor */
48 silk_sum_sqr_shift( &nrgx, &scale1, x, length );
49 silk_sum_sqr_shift( &nrgy, &scale2, y, length );
50 scale = silk_max_int( scale1, scale2 );
51 scale = scale + ( scale & 1 ); /* make even */
52 nrgy = silk_RSHIFT32( nrgy, scale - scale2 );
53 nrgx = silk_RSHIFT32( nrgx, scale - scale1 );
54 nrgx = silk_max_int( nrgx, 1 );
55 corr = silk_inner_prod_aligned_scale( x, y, scale, length );
56 pred_Q13 = silk_DIV32_varQ( corr, nrgx, 13 );
57 pred_Q13 = silk_LIMIT( pred_Q13, -(1 << 14), 1 << 14 );
58 pred2_Q10 = silk_SMULWB( pred_Q13, pred_Q13 );
59
60 /* Faster update for signals with large prediction parameters */
61 smooth_coef_Q16 = (opus_int)silk_max_int( smooth_coef_Q16, silk_abs( pred2_Q10 ) );
62
63 /* Smoothed mid and residual norms */
64 silk_assert( smooth_coef_Q16 < 32768 );
65 scale = silk_RSHIFT( scale, 1 );
66 mid_res_amp_Q0[ 0 ] = silk_SMLAWB( mid_res_amp_Q0[ 0 ], silk_LSHIFT( silk_SQRT_APPROX( nrgx ), scale ) - mid_res_amp_Q0[ 0 ],
67 smooth_coef_Q16 );
68 /* Residual energy = nrgy - 2 * pred * corr + pred^2 * nrgx */
69 nrgy = silk_SUB_LSHIFT32( nrgy, silk_SMULWB( corr, pred_Q13 ), 3 + 1 );
70 nrgy = silk_ADD_LSHIFT32( nrgy, silk_SMULWB( nrgx, pred2_Q10 ), 6 );
71 mid_res_amp_Q0[ 1 ] = silk_SMLAWB( mid_res_amp_Q0[ 1 ], silk_LSHIFT( silk_SQRT_APPROX( nrgy ), scale ) - mid_res_amp_Q0[ 1 ],
72 smooth_coef_Q16 );
73
74 /* Ratio of smoothed residual and mid norms */
75 *ratio_Q14 = silk_DIV32_varQ( mid_res_amp_Q0[ 1 ], silk_max( mid_res_amp_Q0[ 0 ], 1 ), 14 );
76 *ratio_Q14 = silk_LIMIT( *ratio_Q14, 0, 32767 );
77
78 return pred_Q13;
79}
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c b/lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c
new file mode 100644
index 0000000000..d4ced6c3e8
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c
@@ -0,0 +1,73 @@
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.h"
33
34/* Quantize mid/side predictors */
35void silk_stereo_quant_pred(
36 opus_int32 pred_Q13[], /* I/O Predictors (out: quantized) */
37 opus_int8 ix[ 2 ][ 3 ] /* O Quantization indices */
38)
39{
40 opus_int i, j, n;
41 opus_int32 low_Q13, step_Q13, lvl_Q13, err_min_Q13, err_Q13, quant_pred_Q13 = 0;
42
43 /* Quantize */
44 for( n = 0; n < 2; n++ ) {
45 /* Brute-force search over quantization levels */
46 err_min_Q13 = silk_int32_MAX;
47 for( i = 0; i < STEREO_QUANT_TAB_SIZE - 1; i++ ) {
48 low_Q13 = silk_stereo_pred_quant_Q13[ i ];
49 step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ i + 1 ] - low_Q13,
50 SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) );
51 for( j = 0; j < STEREO_QUANT_SUB_STEPS; j++ ) {
52 lvl_Q13 = silk_SMLABB( low_Q13, step_Q13, 2 * j + 1 );
53 err_Q13 = silk_abs( pred_Q13[ n ] - lvl_Q13 );
54 if( err_Q13 < err_min_Q13 ) {
55 err_min_Q13 = err_Q13;
56 quant_pred_Q13 = lvl_Q13;
57 ix[ n ][ 0 ] = i;
58 ix[ n ][ 1 ] = j;
59 } else {
60 /* Error increasing, so we're past the optimum */
61 goto done;
62 }
63 }
64 }
65 done:
66 ix[ n ][ 2 ] = silk_DIV32_16( ix[ n ][ 0 ], 3 );
67 ix[ n ][ 0 ] -= ix[ n ][ 2 ] * 3;
68 pred_Q13[ n ] = quant_pred_Q13;
69 }
70
71 /* Subtract second from first predictor (helps when actually applying these) */
72 pred_Q13[ 0 ] -= pred_Q13[ 1 ];
73}
diff --git a/lib/rbcodec/codecs/libopus/silk/structs.h b/lib/rbcodec/codecs/libopus/silk/structs.h
index 1826b36a80..3380c757b2 100644
--- a/lib/rbcodec/codecs/libopus/silk/structs.h
+++ b/lib/rbcodec/codecs/libopus/silk/structs.h
@@ -48,6 +48,7 @@ typedef struct {
48 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; 48 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
49 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; 49 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
50 opus_int32 sLF_AR_shp_Q14; 50 opus_int32 sLF_AR_shp_Q14;
51 opus_int32 sDiff_shp_Q14;
51 opus_int lagPrev; 52 opus_int lagPrev;
52 opus_int sLTP_buf_idx; 53 opus_int sLTP_buf_idx;
53 opus_int sLTP_shp_buf_idx; 54 opus_int sLTP_shp_buf_idx;
@@ -77,6 +78,7 @@ typedef struct {
77 opus_int32 In_LP_State[ 2 ]; /* Low pass filter state */ 78 opus_int32 In_LP_State[ 2 ]; /* Low pass filter state */
78 opus_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */ 79 opus_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */
79 opus_int mode; /* Operating mode, <0: switch down, >0: switch up; 0: do nothing */ 80 opus_int mode; /* Operating mode, <0: switch down, >0: switch up; 0: do nothing */
81 opus_int32 saved_fs_kHz; /* If non-zero, holds the last sampling rate before a bandwidth switching reset. */
80} silk_LP_state; 82} silk_LP_state;
81 83
82/* Structure containing NLSF codebook */ 84/* Structure containing NLSF codebook */
@@ -86,6 +88,7 @@ typedef struct {
86 const opus_int16 quantStepSize_Q16; 88 const opus_int16 quantStepSize_Q16;
87 const opus_int16 invQuantStepSize_Q6; 89 const opus_int16 invQuantStepSize_Q6;
88 const opus_uint8 *CB1_NLSF_Q8; 90 const opus_uint8 *CB1_NLSF_Q8;
91 const opus_int16 *CB1_Wght_Q9;
89 const opus_uint8 *CB1_iCDF; 92 const opus_uint8 *CB1_iCDF;
90 const opus_uint8 *pred_Q8; 93 const opus_uint8 *pred_Q8;
91 const opus_uint8 *ec_sel; 94 const opus_uint8 *ec_sel;
@@ -169,9 +172,7 @@ typedef struct {
169 opus_int pitchEstimationComplexity; /* Complexity level for pitch estimator */ 172 opus_int pitchEstimationComplexity; /* Complexity level for pitch estimator */
170 opus_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */ 173 opus_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */
171 opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */ 174 opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */
172 opus_int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */ 175 opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */
173 opus_int mu_LTP_Q9; /* Rate-distortion tradeoff in LTP quantization */
174 opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */
175 opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */ 176 opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */
176 opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */ 177 opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */
177 opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */ 178 opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */
@@ -301,6 +302,7 @@ typedef struct {
301 /* Stuff used for PLC */ 302 /* Stuff used for PLC */
302 opus_int lossCnt; 303 opus_int lossCnt;
303 opus_int prevSignalType; 304 opus_int prevSignalType;
305 int arch;
304 306
305 silk_PLC_struct sPLC; 307 silk_PLC_struct sPLC;
306 308
diff --git a/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c b/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c
index 129df191d8..4fd0c3d7d5 100644
--- a/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c
+++ b/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c
@@ -41,43 +41,40 @@ void silk_sum_sqr_shift(
41) 41)
42{ 42{
43 opus_int i, shft; 43 opus_int i, shft;
44 opus_int32 nrg_tmp, nrg; 44 opus_uint32 nrg_tmp;
45 opus_int32 nrg;
45 46
46 nrg = 0; 47 /* Do a first run with the maximum shift we could have. */
47 shft = 0; 48 shft = 31-silk_CLZ32(len);
48 len--; 49 /* Let's be conservative with rounding and start with nrg=len. */
49 for( i = 0; i < len; i += 2 ) { 50 nrg = len;
50 nrg = silk_SMLABB_ovflw( nrg, x[ i ], x[ i ] ); 51 for( i = 0; i < len - 1; i += 2 ) {
51 nrg = silk_SMLABB_ovflw( nrg, x[ i + 1 ], x[ i + 1 ] ); 52 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
52 if( nrg < 0 ) { 53 nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] );
53 /* Scale down */ 54 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
54 nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
55 shft = 2;
56 i+=2;
57 break;
58 }
59 } 55 }
60 for( ; i < len; i += 2 ) { 56 if( i < len ) {
57 /* One sample left to process */
58 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
59 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
60 }
61 silk_assert( nrg >= 0 );
62 /* Make sure the result will fit in a 32-bit signed integer with two bits
63 of headroom. */
64 shft = silk_max_32(0, shft+3 - silk_CLZ32(nrg));
65 nrg = 0;
66 for( i = 0 ; i < len - 1; i += 2 ) {
61 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); 67 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
62 nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); 68 nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] );
63 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, (opus_uint32)nrg_tmp, shft ); 69 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
64 if( nrg < 0 ) {
65 /* Scale down */
66 nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
67 shft += 2;
68 }
69 } 70 }
70 if( i == len ) { 71 if( i < len ) {
71 /* One sample left to process */ 72 /* One sample left to process */
72 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); 73 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
73 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); 74 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
74 } 75 }
75 76
76 /* Make sure to have at least one extra leading zero (two leading zeros in total) */ 77 silk_assert( nrg >= 0 );
77 if( nrg & 0xC0000000 ) {
78 nrg = silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
79 shft += 2;
80 }
81 78
82 /* Output arguments */ 79 /* Output arguments */
83 *shift = shft; 80 *shift = shft;
diff --git a/lib/rbcodec/codecs/libopus/silk/tables.h b/lib/rbcodec/codecs/libopus/silk/tables.h
index a91431e854..95230c451a 100644
--- a/lib/rbcodec/codecs/libopus/silk/tables.h
+++ b/lib/rbcodec/codecs/libopus/silk/tables.h
@@ -47,8 +47,8 @@ extern const opus_uint8 silk_pitch_contour_NB_iCDF[ 11 ];
47extern const opus_uint8 silk_pitch_contour_10_ms_iCDF[ 12 ]; /* 12 */ 47extern const opus_uint8 silk_pitch_contour_10_ms_iCDF[ 12 ]; /* 12 */
48extern const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[ 3 ]; /* 3 */ 48extern const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[ 3 ]; /* 3 */
49 49
50extern const opus_uint8 silk_pulses_per_block_iCDF[ N_RATE_LEVELS ][ MAX_PULSES + 2 ]; /* 180 */ 50extern const opus_uint8 silk_pulses_per_block_iCDF[ N_RATE_LEVELS ][ SILK_MAX_PULSES + 2 ]; /* 180 */
51extern const opus_uint8 silk_pulses_per_block_BITS_Q5[ N_RATE_LEVELS - 1 ][ MAX_PULSES + 2 ]; /* 162 */ 51extern const opus_uint8 silk_pulses_per_block_BITS_Q5[ N_RATE_LEVELS - 1 ][ SILK_MAX_PULSES + 2 ]; /* 162 */
52 52
53extern const opus_uint8 silk_rate_levels_iCDF[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ 53extern const opus_uint8 silk_rate_levels_iCDF[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */
54extern const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ 54extern const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */
@@ -59,7 +59,7 @@ extern const opus_uint8 silk_shell_code_table0[ 152 ];
59extern const opus_uint8 silk_shell_code_table1[ 152 ]; /* 152 */ 59extern const opus_uint8 silk_shell_code_table1[ 152 ]; /* 152 */
60extern const opus_uint8 silk_shell_code_table2[ 152 ]; /* 152 */ 60extern const opus_uint8 silk_shell_code_table2[ 152 ]; /* 152 */
61extern const opus_uint8 silk_shell_code_table3[ 152 ]; /* 152 */ 61extern const opus_uint8 silk_shell_code_table3[ 152 ]; /* 152 */
62extern const opus_uint8 silk_shell_code_table_offsets[ MAX_PULSES + 1 ]; /* 17 */ 62extern const opus_uint8 silk_shell_code_table_offsets[ SILK_MAX_PULSES + 1 ]; /* 17 */
63 63
64extern const opus_uint8 silk_lsb_iCDF[ 2 ]; /* 2 */ 64extern const opus_uint8 silk_lsb_iCDF[ 2 ]; /* 2 */
65 65
@@ -76,10 +76,8 @@ extern const opus_uint8 silk_NLSF_EXT_iCDF[ 7 ];
76extern const opus_uint8 silk_LTP_per_index_iCDF[ 3 ]; /* 3 */ 76extern const opus_uint8 silk_LTP_per_index_iCDF[ 3 ]; /* 3 */
77extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; /* 3 */ 77extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; /* 3 */
78extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */ 78extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */
79extern const opus_int16 silk_LTP_gain_middle_avg_RD_Q14;
80extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */ 79extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */
81extern const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS]; 80extern const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS];
82
83extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */ 81extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */
84 82
85extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */ 83extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */
@@ -99,12 +97,6 @@ extern const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ];
99extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */ 97extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */
100extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */ 98extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */
101 99
102/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
103extern const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ]; /* 32 */
104extern const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ]; /* 32 */
105extern const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ]; /* 32 */
106extern const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ]; /* 32 */
107
108/* Quantization offsets */ 100/* Quantization offsets */
109extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */ 101extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */
110 102
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_LTP.c b/lib/rbcodec/codecs/libopus/silk/tables_LTP.c
index ea518652b8..5e12c8643e 100644
--- a/lib/rbcodec/codecs/libopus/silk/tables_LTP.c
+++ b/lib/rbcodec/codecs/libopus/silk/tables_LTP.c
@@ -51,9 +51,6 @@ static const opus_uint8 silk_LTP_gain_iCDF_2[32] = {
51 24, 20, 16, 12, 9, 5, 2, 0 51 24, 20, 16, 12, 9, 5, 2, 0
52}; 52};
53 53
54#if 0
55const opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304;
56
57static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = { 54static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = {
58 15, 131, 138, 138, 155, 155, 173, 173 55 15, 131, 138, 138, 155, 155, 173, 173
59}; 56};
@@ -69,7 +66,6 @@ static const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = {
69 160, 160, 166, 166, 173, 173, 182, 192, 66 160, 160, 166, 166, 173, 173, 182, 192,
70 182, 192, 192, 192, 205, 192, 205, 224 67 182, 192, 192, 192, 205, 192, 205, 224
71}; 68};
72#endif
73 69
74const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = { 70const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = {
75 silk_LTP_gain_iCDF_0, 71 silk_LTP_gain_iCDF_0,
@@ -77,13 +73,11 @@ const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = {
77 silk_LTP_gain_iCDF_2 73 silk_LTP_gain_iCDF_2
78}; 74};
79 75
80#if 0
81const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = { 76const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = {
82 silk_LTP_gain_BITS_Q5_0, 77 silk_LTP_gain_BITS_Q5_0,
83 silk_LTP_gain_BITS_Q5_1, 78 silk_LTP_gain_BITS_Q5_1,
84 silk_LTP_gain_BITS_Q5_2 79 silk_LTP_gain_BITS_Q5_2
85}; 80};
86#endif
87 81
88static const opus_int8 silk_LTP_gain_vq_0[8][5] = 82static const opus_int8 silk_LTP_gain_vq_0[8][5] =
89{ 83{
@@ -271,7 +265,6 @@ const opus_int8 * const silk_LTP_vq_ptrs_Q7[NB_LTP_CBKS] = {
271 (opus_int8 *)&silk_LTP_gain_vq_2[0][0] 265 (opus_int8 *)&silk_LTP_gain_vq_2[0][0]
272}; 266};
273 267
274#if 0
275/* Maximum frequency-dependent response of the pitch taps above, 268/* Maximum frequency-dependent response of the pitch taps above,
276 computed as max(abs(freqz(taps))) */ 269 computed as max(abs(freqz(taps))) */
277static const opus_uint8 silk_LTP_gain_vq_0_gain[8] = { 270static const opus_uint8 silk_LTP_gain_vq_0_gain[8] = {
@@ -299,4 +292,3 @@ const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS] = {
299const opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = { 292const opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = {
300 8, 16, 32 293 8, 16, 32
301}; 294};
302#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c
index 8c59d207aa..195d5b95bd 100644
--- a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c
+++ b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c
@@ -74,6 +74,41 @@ static const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = {
74 64, 84, 104, 118, 156, 177, 201, 230 74 64, 84, 104, 118, 156, 177, 201, 230
75}; 75};
76 76
77static const opus_int16 silk_NLSF_CB1_Wght_Q9[ 320 ] = {
78 2897, 2314, 2314, 2314, 2287, 2287, 2314, 2300, 2327, 2287,
79 2888, 2580, 2394, 2367, 2314, 2274, 2274, 2274, 2274, 2194,
80 2487, 2340, 2340, 2314, 2314, 2314, 2340, 2340, 2367, 2354,
81 3216, 2766, 2340, 2340, 2314, 2274, 2221, 2207, 2261, 2194,
82 2460, 2474, 2367, 2394, 2394, 2394, 2394, 2367, 2407, 2314,
83 3479, 3056, 2127, 2207, 2274, 2274, 2274, 2287, 2314, 2261,
84 3282, 3141, 2580, 2394, 2247, 2221, 2207, 2194, 2194, 2114,
85 4096, 3845, 2221, 2620, 2620, 2407, 2314, 2394, 2367, 2074,
86 3178, 3244, 2367, 2221, 2553, 2434, 2340, 2314, 2167, 2221,
87 3338, 3488, 2726, 2194, 2261, 2460, 2354, 2367, 2207, 2101,
88 2354, 2420, 2327, 2367, 2394, 2420, 2420, 2420, 2460, 2367,
89 3779, 3629, 2434, 2527, 2367, 2274, 2274, 2300, 2207, 2048,
90 3254, 3225, 2713, 2846, 2447, 2327, 2300, 2300, 2274, 2127,
91 3263, 3300, 2753, 2806, 2447, 2261, 2261, 2247, 2127, 2101,
92 2873, 2981, 2633, 2367, 2407, 2354, 2194, 2247, 2247, 2114,
93 3225, 3197, 2633, 2580, 2274, 2181, 2247, 2221, 2221, 2141,
94 3178, 3310, 2740, 2407, 2274, 2274, 2274, 2287, 2194, 2114,
95 3141, 3272, 2460, 2061, 2287, 2500, 2367, 2487, 2434, 2181,
96 3507, 3282, 2314, 2700, 2647, 2474, 2367, 2394, 2340, 2127,
97 3423, 3535, 3038, 3056, 2300, 1950, 2221, 2274, 2274, 2274,
98 3404, 3366, 2087, 2687, 2873, 2354, 2420, 2274, 2474, 2540,
99 3760, 3488, 1950, 2660, 2897, 2527, 2394, 2367, 2460, 2261,
100 3028, 3272, 2740, 2888, 2740, 2154, 2127, 2287, 2234, 2247,
101 3695, 3657, 2025, 1969, 2660, 2700, 2580, 2500, 2327, 2367,
102 3207, 3413, 2354, 2074, 2888, 2888, 2340, 2487, 2247, 2167,
103 3338, 3366, 2846, 2780, 2327, 2154, 2274, 2287, 2114, 2061,
104 2327, 2300, 2181, 2167, 2181, 2367, 2633, 2700, 2700, 2553,
105 2407, 2434, 2221, 2261, 2221, 2221, 2340, 2420, 2607, 2700,
106 3038, 3244, 2806, 2888, 2474, 2074, 2300, 2314, 2354, 2380,
107 2221, 2154, 2127, 2287, 2500, 2793, 2793, 2620, 2580, 2367,
108 3676, 3713, 2234, 1838, 2181, 2753, 2726, 2673, 2513, 2207,
109 2793, 3160, 2726, 2553, 2846, 2513, 2181, 2394, 2221, 2181
110};
111
77static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = { 112static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = {
78 212, 178, 148, 129, 108, 96, 85, 82, 113 212, 178, 148, 129, 108, 96, 85, 82,
79 79, 77, 61, 59, 57, 56, 51, 49, 114 79, 77, 61, 59, 57, 56, 51, 49,
@@ -150,6 +185,7 @@ const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB =
150 SILK_FIX_CONST( 0.18, 16 ), 185 SILK_FIX_CONST( 0.18, 16 ),
151 SILK_FIX_CONST( 1.0 / 0.18, 6 ), 186 SILK_FIX_CONST( 1.0 / 0.18, 6 ),
152 silk_NLSF_CB1_NB_MB_Q8, 187 silk_NLSF_CB1_NB_MB_Q8,
188 silk_NLSF_CB1_Wght_Q9,
153 silk_NLSF_CB1_iCDF_NB_MB, 189 silk_NLSF_CB1_iCDF_NB_MB,
154 silk_NLSF_PRED_NB_MB_Q8, 190 silk_NLSF_PRED_NB_MB_Q8,
155 silk_NLSF_CB2_SELECT_NB_MB, 191 silk_NLSF_CB2_SELECT_NB_MB,
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c
index 50af87eb2e..5cc9f57bff 100644
--- a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c
+++ b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c
@@ -98,6 +98,41 @@ static const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = {
98 110, 119, 129, 141, 175, 198, 218, 237 98 110, 119, 129, 141, 175, 198, 218, 237
99}; 99};
100 100
101static const opus_int16 silk_NLSF_CB1_WB_Wght_Q9[ 512 ] = {
102 3657, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2963, 2963, 2925, 2846,
103 3216, 3085, 2972, 3056, 3056, 3010, 3010, 3010, 2963, 2963, 3010, 2972, 2888, 2846, 2846, 2726,
104 3920, 4014, 2981, 3207, 3207, 2934, 3056, 2846, 3122, 3244, 2925, 2846, 2620, 2553, 2780, 2925,
105 3516, 3197, 3010, 3103, 3019, 2888, 2925, 2925, 2925, 2925, 2888, 2888, 2888, 2888, 2888, 2753,
106 5054, 5054, 2934, 3573, 3385, 3056, 3085, 2793, 3160, 3160, 2972, 2846, 2513, 2540, 2753, 2888,
107 4428, 4149, 2700, 2753, 2972, 3010, 2925, 2846, 2981, 3019, 2925, 2925, 2925, 2925, 2888, 2726,
108 3620, 3019, 2972, 3056, 3056, 2873, 2806, 3056, 3216, 3047, 2981, 3291, 3291, 2981, 3310, 2991,
109 5227, 5014, 2540, 3338, 3526, 3385, 3197, 3094, 3376, 2981, 2700, 2647, 2687, 2793, 2846, 2673,
110 5081, 5174, 4615, 4428, 2460, 2897, 3047, 3207, 3169, 2687, 2740, 2888, 2846, 2793, 2846, 2700,
111 3122, 2888, 2963, 2925, 2925, 2925, 2925, 2963, 2963, 2963, 2963, 2925, 2925, 2963, 2963, 2963,
112 4202, 3207, 2981, 3103, 3010, 2888, 2888, 2925, 2972, 2873, 2916, 3019, 2972, 3010, 3197, 2873,
113 3760, 3760, 3244, 3103, 2981, 2888, 2925, 2888, 2972, 2934, 2793, 2793, 2846, 2888, 2888, 2660,
114 3854, 4014, 3207, 3122, 3244, 2934, 3047, 2963, 2963, 3085, 2846, 2793, 2793, 2793, 2793, 2580,
115 3845, 4080, 3357, 3516, 3094, 2740, 3010, 2934, 3122, 3085, 2846, 2846, 2647, 2647, 2846, 2806,
116 5147, 4894, 3225, 3845, 3441, 3169, 2897, 3413, 3451, 2700, 2580, 2673, 2740, 2846, 2806, 2753,
117 4109, 3789, 3291, 3160, 2925, 2888, 2888, 2925, 2793, 2740, 2793, 2740, 2793, 2846, 2888, 2806,
118 5081, 5054, 3047, 3545, 3244, 3056, 3085, 2944, 3103, 2897, 2740, 2740, 2740, 2846, 2793, 2620,
119 4309, 4309, 2860, 2527, 3207, 3376, 3376, 3075, 3075, 3376, 3056, 2846, 2647, 2580, 2726, 2753,
120 3056, 2916, 2806, 2888, 2740, 2687, 2897, 3103, 3150, 3150, 3216, 3169, 3056, 3010, 2963, 2846,
121 4375, 3882, 2925, 2888, 2846, 2888, 2846, 2846, 2888, 2888, 2888, 2846, 2888, 2925, 2888, 2846,
122 2981, 2916, 2916, 2981, 2981, 3056, 3122, 3216, 3150, 3056, 3010, 2972, 2972, 2972, 2925, 2740,
123 4229, 4149, 3310, 3347, 2925, 2963, 2888, 2981, 2981, 2846, 2793, 2740, 2846, 2846, 2846, 2793,
124 4080, 4014, 3103, 3010, 2925, 2925, 2925, 2888, 2925, 2925, 2846, 2846, 2846, 2793, 2888, 2780,
125 4615, 4575, 3169, 3441, 3207, 2981, 2897, 3038, 3122, 2740, 2687, 2687, 2687, 2740, 2793, 2700,
126 4149, 4269, 3789, 3657, 2726, 2780, 2888, 2888, 3010, 2972, 2925, 2846, 2687, 2687, 2793, 2888,
127 4215, 3554, 2753, 2846, 2846, 2888, 2888, 2888, 2925, 2925, 2888, 2925, 2925, 2925, 2963, 2888,
128 5174, 4921, 2261, 3432, 3789, 3479, 3347, 2846, 3310, 3479, 3150, 2897, 2460, 2487, 2753, 2925,
129 3451, 3685, 3122, 3197, 3357, 3047, 3207, 3207, 2981, 3216, 3085, 2925, 2925, 2687, 2540, 2434,
130 2981, 3010, 2793, 2793, 2740, 2793, 2846, 2972, 3056, 3103, 3150, 3150, 3150, 3103, 3010, 3010,
131 2944, 2873, 2687, 2726, 2780, 3010, 3432, 3545, 3357, 3244, 3056, 3010, 2963, 2925, 2888, 2846,
132 3019, 2944, 2897, 3010, 3010, 2972, 3019, 3103, 3056, 3056, 3010, 2888, 2846, 2925, 2925, 2888,
133 3920, 3967, 3010, 3197, 3357, 3216, 3291, 3291, 3479, 3704, 3441, 2726, 2181, 2460, 2580, 2607
134};
135
101static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = { 136static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = {
102 225, 204, 201, 184, 183, 175, 158, 154, 137 225, 204, 201, 184, 183, 175, 158, 154,
103 153, 135, 119, 115, 113, 110, 109, 99, 138 153, 135, 119, 115, 113, 110, 109, 99,
@@ -188,6 +223,7 @@ const silk_NLSF_CB_struct silk_NLSF_CB_WB =
188 SILK_FIX_CONST( 0.15, 16 ), 223 SILK_FIX_CONST( 0.15, 16 ),
189 SILK_FIX_CONST( 1.0 / 0.15, 6 ), 224 SILK_FIX_CONST( 1.0 / 0.15, 6 ),
190 silk_NLSF_CB1_WB_Q8, 225 silk_NLSF_CB1_WB_Q8,
226 silk_NLSF_CB1_WB_Wght_Q9,
191 silk_NLSF_CB1_iCDF_WB, 227 silk_NLSF_CB1_iCDF_WB,
192 silk_NLSF_PRED_WB_Q8, 228 silk_NLSF_PRED_WB_Q8,
193 silk_NLSF_CB2_SELECT_WB, 229 silk_NLSF_CB2_SELECT_WB,
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_other.c b/lib/rbcodec/codecs/libopus/silk/tables_other.c
index 398686bf26..e34d90777b 100644
--- a/lib/rbcodec/codecs/libopus/silk/tables_other.c
+++ b/lib/rbcodec/codecs/libopus/silk/tables_other.c
@@ -38,20 +38,6 @@ extern "C"
38{ 38{
39#endif 39#endif
40 40
41/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
42const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = {
43 0, 8000, 9400, 11500, 13500, 17500, 25000, MAX_TARGET_RATE_BPS
44};
45const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = {
46 0, 9000, 12000, 14500, 18500, 24500, 35500, MAX_TARGET_RATE_BPS
47};
48const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = {
49 0, 10500, 14000, 17000, 21500, 28500, 42000, MAX_TARGET_RATE_BPS
50};
51const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = {
52 18, 29, 38, 40, 46, 52, 62, 84
53};
54
55/* Tables for stereo predictor coding */ 41/* Tables for stereo predictor coding */
56const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = { 42const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = {
57 -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820, 43 -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820,
diff --git a/lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c b/lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c
new file mode 100644
index 0000000000..67067cead7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c
@@ -0,0 +1,129 @@
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 <stdio.h>
33#include <stdlib.h>
34#include "celt/stack_alloc.h"
35#include "cpu_support.h"
36#include "SigProc_FIX.h"
37
38/* Computes the impulse response of the filter so we
39 can catch filters that are definitely unstable. Some
40 unstable filters may be classified as stable, but not
41 the other way around. */
42int check_stability(opus_int16 *A_Q12, int order) {
43 int i;
44 int j;
45 int sum_a, sum_abs_a;
46 sum_a = sum_abs_a = 0;
47 for( j = 0; j < order; j++ ) {
48 sum_a += A_Q12[ j ];
49 sum_abs_a += silk_abs( A_Q12[ j ] );
50 }
51 /* Check DC stability. */
52 if( sum_a >= 4096 ) {
53 return 0;
54 }
55 /* If the sum of absolute values is less than 1, the filter
56 has to be stable. */
57 if( sum_abs_a < 4096 ) {
58 return 1;
59 }
60 double y[SILK_MAX_ORDER_LPC] = {0};
61 y[0] = 1;
62 for( i = 0; i < 10000; i++ ) {
63 double sum = 0;
64 for( j = 0; j < order; j++ ) {
65 sum += y[ j ]*A_Q12[ j ];
66 }
67 for( j = order - 1; j > 0; j-- ) {
68 y[ j ] = y[ j - 1 ];
69 }
70 y[ 0 ] = sum*(1./4096);
71 /* If impulse response reaches +/- 10000, the filter
72 is definitely unstable. */
73 if( !(y[ 0 ] < 10000 && y[ 0 ] > -10000) ) {
74 return 0;
75 }
76 /* Test every 8 sample for low amplitude. */
77 if( ( i & 0x7 ) == 0 ) {
78 double amp = 0;
79 for( j = 0; j < order; j++ ) {
80 amp += fabs(y[j]);
81 }
82 if( amp < 0.00001 ) {
83 return 1;
84 }
85 }
86 }
87 return 1;
88}
89
90int main(void) {
91 const int arch = opus_select_arch();
92 /* Set to 10000 so all branches in C function are triggered */
93 const int loop_num = 10000;
94 int count = 0;
95 ALLOC_STACK;
96
97 /* FIXME: Make the seed random (with option to set it explicitly)
98 so we get wider coverage. */
99 srand(0);
100
101 printf("Testing silk_LPC_inverse_pred_gain() optimization ...\n");
102 for( count = 0; count < loop_num; count++ ) {
103 unsigned int i;
104 opus_int order;
105 unsigned int shift;
106 opus_int16 A_Q12[ SILK_MAX_ORDER_LPC ];
107 opus_int32 gain;
108
109 for( order = 2; order <= SILK_MAX_ORDER_LPC; order += 2 ) { /* order must be even. */
110 for( shift = 0; shift < 16; shift++ ) { /* Different dynamic range. */
111 for( i = 0; i < SILK_MAX_ORDER_LPC; i++ ) {
112 A_Q12[i] = ((opus_int16)rand()) >> shift;
113 }
114 gain = silk_LPC_inverse_pred_gain(A_Q12, order, arch);
115 /* Look for filters that silk_LPC_inverse_pred_gain() thinks are
116 stable but definitely aren't. */
117 if( gain != 0 && !check_stability(A_Q12, order) ) {
118 fprintf(stderr, "**Loop %4d failed!**\n", count);
119 return 1;
120 }
121 }
122 }
123 if( !(count % 500) ) {
124 printf("Loop %4d passed\n", count);
125 }
126 }
127 printf("silk_LPC_inverse_pred_gain() optimization passed\n");
128 return 0;
129}
diff --git a/lib/rbcodec/codecs/libopus/silk/tuning_parameters.h b/lib/rbcodec/codecs/libopus/silk/tuning_parameters.h
new file mode 100644
index 0000000000..d70275fd8f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/tuning_parameters.h
@@ -0,0 +1,155 @@
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_TUNING_PARAMETERS_H
29#define SILK_TUNING_PARAMETERS_H
30
31#ifdef __cplusplus
32extern "C"
33{
34#endif
35
36/* Decay time for bitreservoir */
37#define BITRESERVOIR_DECAY_TIME_MS 500
38
39/*******************/
40/* Pitch estimator */
41/*******************/
42
43/* Level of noise floor for whitening filter LPC analysis in pitch analysis */
44#define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f
45
46/* Bandwidth expansion for whitening filter in pitch analysis */
47#define FIND_PITCH_BANDWIDTH_EXPANSION 0.99f
48
49/*********************/
50/* Linear prediction */
51/*********************/
52
53/* LPC analysis regularization */
54#define FIND_LPC_COND_FAC 1e-5f
55
56/* Max cumulative LTP gain */
57#define MAX_SUM_LOG_GAIN_DB 250.0f
58
59/* LTP analysis defines */
60#define LTP_CORR_INV_MAX 0.03f
61
62/***********************/
63/* High pass filtering */
64/***********************/
65
66/* Smoothing parameters for low end of pitch frequency range estimation */
67#define VARIABLE_HP_SMTH_COEF1 0.1f
68#define VARIABLE_HP_SMTH_COEF2 0.015f
69#define VARIABLE_HP_MAX_DELTA_FREQ 0.4f
70
71/* Min and max cut-off frequency values (-3 dB points) */
72#define VARIABLE_HP_MIN_CUTOFF_HZ 60
73#define VARIABLE_HP_MAX_CUTOFF_HZ 100
74
75/***********/
76/* Various */
77/***********/
78
79/* VAD threshold */
80#define SPEECH_ACTIVITY_DTX_THRES 0.05f
81
82/* Speech Activity LBRR enable threshold */
83#define LBRR_SPEECH_ACTIVITY_THRES 0.3f
84
85/*************************/
86/* Perceptual parameters */
87/*************************/
88
89/* reduction in coding SNR during low speech activity */
90#define BG_SNR_DECR_dB 2.0f
91
92/* factor for reducing quantization noise during voiced speech */
93#define HARM_SNR_INCR_dB 2.0f
94
95/* factor for reducing quantization noise for unvoiced sparse signals */
96#define SPARSE_SNR_INCR_dB 2.0f
97
98/* threshold for sparseness measure above which to use lower quantization offset during unvoiced */
99#define ENERGY_VARIATION_THRESHOLD_QNT_OFFSET 0.6f
100
101/* warping control */
102#define WARPING_MULTIPLIER 0.015f
103
104/* fraction added to first autocorrelation value */
105#define SHAPE_WHITE_NOISE_FRACTION 3e-5f
106
107/* noise shaping filter chirp factor */
108#define BANDWIDTH_EXPANSION 0.94f
109
110/* harmonic noise shaping */
111#define HARMONIC_SHAPING 0.3f
112
113/* extra harmonic noise shaping for high bitrates or noisy input */
114#define HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING 0.2f
115
116/* parameter for shaping noise towards higher frequencies */
117#define HP_NOISE_COEF 0.25f
118
119/* parameter for shaping noise even more towards higher frequencies during voiced speech */
120#define HARM_HP_NOISE_COEF 0.35f
121
122/* parameter for applying a high-pass tilt to the input signal */
123#define INPUT_TILT 0.05f
124
125/* parameter for extra high-pass tilt to the input signal at high rates */
126#define HIGH_RATE_INPUT_TILT 0.1f
127
128/* parameter for reducing noise at the very low frequencies */
129#define LOW_FREQ_SHAPING 4.0f
130
131/* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */
132#define LOW_QUALITY_LOW_FREQ_SHAPING_DECR 0.5f
133
134/* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */
135#define SUBFR_SMTH_COEF 0.4f
136
137/* parameters defining the R/D tradeoff in the residual quantizer */
138#define LAMBDA_OFFSET 1.2f
139#define LAMBDA_SPEECH_ACT -0.2f
140#define LAMBDA_DELAYED_DECISIONS -0.05f
141#define LAMBDA_INPUT_QUALITY -0.1f
142#define LAMBDA_CODING_QUALITY -0.2f
143#define LAMBDA_QUANT_OFFSET 0.8f
144
145/* Compensation in bitrate calculations for 10 ms modes */
146#define REDUCE_BITRATE_10_MS_BPS 2200
147
148/* Maximum time before allowing a bandwidth transition */
149#define MAX_BANDWIDTH_SWITCH_DELAY_MS 5000
150
151#ifdef __cplusplus
152}
153#endif
154
155#endif /* SILK_TUNING_PARAMETERS_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c
new file mode 100644
index 0000000000..2c75ede2dd
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c
@@ -0,0 +1,859 @@
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
38#include "stack_alloc.h"
39
40typedef struct {
41 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
42 opus_int32 RandState[ DECISION_DELAY ];
43 opus_int32 Q_Q10[ DECISION_DELAY ];
44 opus_int32 Xq_Q14[ DECISION_DELAY ];
45 opus_int32 Pred_Q15[ DECISION_DELAY ];
46 opus_int32 Shape_Q14[ DECISION_DELAY ];
47 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
48 opus_int32 LF_AR_Q14;
49 opus_int32 Seed;
50 opus_int32 SeedInit;
51 opus_int32 RD_Q10;
52} NSQ_del_dec_struct;
53
54typedef struct {
55 opus_int32 Q_Q10;
56 opus_int32 RD_Q10;
57 opus_int32 xq_Q14;
58 opus_int32 LF_AR_Q14;
59 opus_int32 sLTP_shp_Q14;
60 opus_int32 LPC_exc_Q14;
61} NSQ_sample_struct;
62
63typedef NSQ_sample_struct NSQ_sample_pair[ 2 ];
64
65static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1(
66 const silk_encoder_state *psEncC, /* I Encoder State */
67 silk_nsq_state *NSQ, /* I/O NSQ state */
68 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
69 const opus_int32 x_Q3[], /* I Input in Q3 */
70 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
71 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
72 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
73 opus_int subfr, /* I Subframe number */
74 opus_int nStatesDelayedDecision, /* I Number of del dec states */
75 const opus_int LTP_scale_Q14, /* I LTP state scaling */
76 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
77 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
78 const opus_int signal_type, /* I Signal type */
79 const opus_int decisionDelay /* I Decision delay */
80);
81
82/******************************************/
83/* Noise shape quantizer for one subframe */
84/******************************************/
85static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1(
86 silk_nsq_state *NSQ, /* I/O NSQ state */
87 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
88 opus_int signalType, /* I Signal type */
89 const opus_int32 x_Q10[], /* I */
90 opus_int8 pulses[], /* O */
91 opus_int16 xq[], /* O */
92 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
93 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
94 const opus_int16 a_Q12[], /* I Short term prediction coefs */
95 const opus_int16 b_Q14[], /* I Long term prediction coefs */
96 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
97 opus_int lag, /* I Pitch lag */
98 opus_int32 HarmShapeFIRPacked_Q14, /* I */
99 opus_int Tilt_Q14, /* I Spectral tilt */
100 opus_int32 LF_shp_Q14, /* I */
101 opus_int32 Gain_Q16, /* I */
102 opus_int Lambda_Q10, /* I */
103 opus_int offset_Q10, /* I */
104 opus_int length, /* I Input length */
105 opus_int subfr, /* I Subframe number */
106 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
107 opus_int predictLPCOrder, /* I Prediction filter order */
108 opus_int warping_Q16, /* I */
109 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
110 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
111 opus_int decisionDelay /* I */
112);
113
114void silk_NSQ_del_dec_sse4_1(
115 const silk_encoder_state *psEncC, /* I Encoder State */
116 silk_nsq_state *NSQ, /* I/O NSQ state */
117 SideInfoIndices *psIndices, /* I/O Quantization Indices */
118 const opus_int32 x_Q3[], /* I Prefiltered input signal */
119 opus_int8 pulses[], /* O Quantized pulse signal */
120 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
121 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
122 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
123 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
124 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
125 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
126 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
127 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
128 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
129 const opus_int LTP_scale_Q14 /* I LTP state scaling */
130)
131{
132 opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
133 opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
134 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
135 opus_int16 *pxq;
136 VARDECL( opus_int32, sLTP_Q15 );
137 VARDECL( opus_int16, sLTP );
138 opus_int32 HarmShapeFIRPacked_Q14;
139 opus_int offset_Q10;
140 opus_int32 RDmin_Q10, Gain_Q10;
141 VARDECL( opus_int32, x_sc_Q10 );
142 VARDECL( opus_int32, delayedGain_Q10 );
143 VARDECL( NSQ_del_dec_struct, psDelDec );
144 NSQ_del_dec_struct *psDD;
145 SAVE_STACK;
146
147 /* Set unvoiced lag to the previous one, overwrite later for voiced */
148 lag = NSQ->lagPrev;
149
150 silk_assert( NSQ->prev_gain_Q16 != 0 );
151
152 /* Initialize delayed decision states */
153 ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );
154 silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
155 for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
156 psDD = &psDelDec[ k ];
157 psDD->Seed = ( k + psIndices->Seed ) & 3;
158 psDD->SeedInit = psDD->Seed;
159 psDD->RD_Q10 = 0;
160 psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14;
161 psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];
162 silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
163 silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
164 }
165
166 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
167 smpl_buf_idx = 0; /* index of oldest samples */
168
169 decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
170
171 /* For voiced frames limit the decision delay to lower than the pitch lag */
172 if( psIndices->signalType == TYPE_VOICED ) {
173 for( k = 0; k < psEncC->nb_subfr; k++ ) {
174 decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 );
175 }
176 } else {
177 if( lag > 0 ) {
178 decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
179 }
180 }
181
182 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
183 LSF_interpolation_flag = 0;
184 } else {
185 LSF_interpolation_flag = 1;
186 }
187
188 ALLOC( sLTP_Q15,
189 psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
190 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
191 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
192 ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
193 /* Set up pointers to start of sub frame */
194 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
195 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
196 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
197 subfr = 0;
198 for( k = 0; k < psEncC->nb_subfr; k++ ) {
199 A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
200 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
201 AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
202
203 /* Noise shape parameters */
204 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
205 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
206 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
207
208 NSQ->rewhite_flag = 0;
209 if( psIndices->signalType == TYPE_VOICED ) {
210 /* Voiced */
211 lag = pitchL[ k ];
212
213 /* Re-whitening */
214 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
215 if( k == 2 ) {
216 /* RESET DELAYED DECISIONS */
217 /* Find winner */
218 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
219 Winner_ind = 0;
220 for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
221 if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
222 RDmin_Q10 = psDelDec[ i ].RD_Q10;
223 Winner_ind = i;
224 }
225 }
226 for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
227 if( i != Winner_ind ) {
228 psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 );
229 silk_assert( psDelDec[ i ].RD_Q10 >= 0 );
230 }
231 }
232
233 /* Copy final part of signals from winner state to output and long-term filter states */
234 psDD = &psDelDec[ Winner_ind ];
235 last_smple_idx = smpl_buf_idx + decisionDelay;
236 for( i = 0; i < decisionDelay; i++ ) {
237 last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
238 if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
239 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
240 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
241 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
242 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
243 }
244
245 subfr = 0;
246 }
247
248 /* Rewhiten with new A coefs */
249 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
250 celt_assert( start_idx > 0 );
251
252 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
253 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
254
255 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
256 NSQ->rewhite_flag = 1;
257 }
258 }
259
260 silk_nsq_del_dec_scale_states_sse4_1( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k,
261 psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
262
263 silk_noise_shape_quantizer_del_dec_sse4_1( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
264 delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
265 Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
266 psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
267
268 x_Q3 += psEncC->subfr_length;
269 pulses += psEncC->subfr_length;
270 pxq += psEncC->subfr_length;
271 }
272
273 /* Find winner */
274 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
275 Winner_ind = 0;
276 for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
277 if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
278 RDmin_Q10 = psDelDec[ k ].RD_Q10;
279 Winner_ind = k;
280 }
281 }
282
283 /* Copy final part of signals from winner state to output and long-term filter states */
284 psDD = &psDelDec[ Winner_ind ];
285 psIndices->Seed = psDD->SeedInit;
286 last_smple_idx = smpl_buf_idx + decisionDelay;
287 Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
288 for( i = 0; i < decisionDelay; i++ ) {
289 last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
290 if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
291 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
292 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
293 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
294 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
295 }
296 silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
297 silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
298
299 /* Update states */
300 NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;
301 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
302
303 /* Save quantized speech signal */
304 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
305 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
306 RESTORE_STACK;
307}
308
309/******************************************/
310/* Noise shape quantizer for one subframe */
311/******************************************/
312static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1(
313 silk_nsq_state *NSQ, /* I/O NSQ state */
314 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
315 opus_int signalType, /* I Signal type */
316 const opus_int32 x_Q10[], /* I */
317 opus_int8 pulses[], /* O */
318 opus_int16 xq[], /* O */
319 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
320 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
321 const opus_int16 a_Q12[], /* I Short term prediction coefs */
322 const opus_int16 b_Q14[], /* I Long term prediction coefs */
323 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
324 opus_int lag, /* I Pitch lag */
325 opus_int32 HarmShapeFIRPacked_Q14, /* I */
326 opus_int Tilt_Q14, /* I Spectral tilt */
327 opus_int32 LF_shp_Q14, /* I */
328 opus_int32 Gain_Q16, /* I */
329 opus_int Lambda_Q10, /* I */
330 opus_int offset_Q10, /* I */
331 opus_int length, /* I Input length */
332 opus_int subfr, /* I Subframe number */
333 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
334 opus_int predictLPCOrder, /* I Prediction filter order */
335 opus_int warping_Q16, /* I */
336 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
337 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
338 opus_int decisionDelay /* I */
339)
340{
341 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
342 opus_int32 Winner_rand_state;
343 opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
344 opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
345 opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
346 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
347 opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
348 VARDECL( NSQ_sample_pair, psSampleState );
349 NSQ_del_dec_struct *psDD;
350 NSQ_sample_struct *psSS;
351
352 __m128i a_Q12_0123, a_Q12_4567, a_Q12_89AB, a_Q12_CDEF;
353 __m128i b_Q12_0123, b_sr_Q12_0123;
354 SAVE_STACK;
355
356 celt_assert( nStatesDelayedDecision > 0 );
357 ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
358
359 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
360 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
361 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
362
363 a_Q12_0123 = OP_CVTEPI16_EPI32_M64( a_Q12 );
364 a_Q12_4567 = OP_CVTEPI16_EPI32_M64( a_Q12 + 4 );
365
366 if( opus_likely( predictLPCOrder == 16 ) ) {
367 a_Q12_89AB = OP_CVTEPI16_EPI32_M64( a_Q12 + 8 );
368 a_Q12_CDEF = OP_CVTEPI16_EPI32_M64( a_Q12 + 12 );
369 }
370
371 if( signalType == TYPE_VOICED ){
372 b_Q12_0123 = OP_CVTEPI16_EPI32_M64( b_Q14 );
373 b_sr_Q12_0123 = _mm_shuffle_epi32( b_Q12_0123, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
374 }
375 for( i = 0; i < length; i++ ) {
376 /* Perform common calculations used in all states */
377
378 /* Long-term prediction */
379 if( signalType == TYPE_VOICED ) {
380 /* Unrolled loop */
381 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
382 LTP_pred_Q14 = 2;
383 {
384 __m128i tmpa, tmpb, pred_lag_ptr_tmp;
385 pred_lag_ptr_tmp = _mm_loadu_si128( (__m128i *)(&pred_lag_ptr[ -3 ] ) );
386 pred_lag_ptr_tmp = _mm_shuffle_epi32( pred_lag_ptr_tmp, 0x1B );
387 tmpa = _mm_mul_epi32( pred_lag_ptr_tmp, b_Q12_0123 );
388 tmpa = _mm_srli_si128( tmpa, 2 );
389
390 pred_lag_ptr_tmp = _mm_shuffle_epi32( pred_lag_ptr_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) );/* equal shift right 4 bytes */
391 pred_lag_ptr_tmp = _mm_mul_epi32( pred_lag_ptr_tmp, b_sr_Q12_0123 );
392 pred_lag_ptr_tmp = _mm_srli_si128( pred_lag_ptr_tmp, 2 );
393 pred_lag_ptr_tmp = _mm_add_epi32( pred_lag_ptr_tmp, tmpa );
394
395 tmpb = _mm_shuffle_epi32( pred_lag_ptr_tmp, _MM_SHUFFLE( 0, 0, 3, 2 ) );/* equal shift right 8 bytes */
396 pred_lag_ptr_tmp = _mm_add_epi32( pred_lag_ptr_tmp, tmpb );
397 LTP_pred_Q14 += _mm_cvtsi128_si32( pred_lag_ptr_tmp );
398
399 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
400 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
401 pred_lag_ptr++;
402 }
403 } else {
404 LTP_pred_Q14 = 0;
405 }
406
407 /* Long-term shaping */
408 if( lag > 0 ) {
409 /* Symmetric, packed FIR coefficients */
410 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
411 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
412 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
413 shp_lag_ptr++;
414 } else {
415 n_LTP_Q14 = 0;
416 }
417 {
418 __m128i tmpa, tmpb, psLPC_Q14_tmp, a_Q12_tmp;
419
420 for( k = 0; k < nStatesDelayedDecision; k++ ) {
421 /* Delayed decision state */
422 psDD = &psDelDec[ k ];
423
424 /* Sample state */
425 psSS = psSampleState[ k ];
426
427 /* Generate dither */
428 psDD->Seed = silk_RAND( psDD->Seed );
429
430 /* Pointer used in short term prediction and shaping */
431 psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
432 /* Short-term prediction */
433 silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
434 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
435 LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 );
436
437 tmpb = _mm_setzero_si128();
438
439 /* step 1 */
440 psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -3 ] ) ); /* -3, -2 , -1, 0 */
441 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); /* 0, -1, -2, -3 */
442 tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_0123 ); /* 0, -1, -2, -3 * 0123 -> 0*0, 2*-2 */
443
444 tmpa = _mm_srli_epi64( tmpa, 16 );
445 tmpb = _mm_add_epi32( tmpb, tmpa );
446
447 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
448 a_Q12_tmp = _mm_shuffle_epi32( a_Q12_0123, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
449 psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); /* 1*-1, 3*-3 */
450 psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 );
451 tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp );
452
453 /* step 2 */
454 psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -7 ] ) );
455 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B );
456 tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_4567 );
457 tmpa = _mm_srli_epi64( tmpa, 16 );
458 tmpb = _mm_add_epi32( tmpb, tmpa );
459
460 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
461 a_Q12_tmp = _mm_shuffle_epi32( a_Q12_4567, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
462 psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp );
463 psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 );
464 tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp );
465
466 if ( opus_likely( predictLPCOrder == 16 ) )
467 {
468 /* step 3 */
469 psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -11 ] ) );
470 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B );
471 tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_89AB );
472 tmpa = _mm_srli_epi64( tmpa, 16 );
473 tmpb = _mm_add_epi32( tmpb, tmpa );
474
475 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
476 a_Q12_tmp = _mm_shuffle_epi32( a_Q12_89AB, _MM_SHUFFLE(0, 3, 2, 1 ) );/* equal shift right 4 bytes */
477 psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp );
478 psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 );
479 tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp );
480
481 /* setp 4 */
482 psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -15 ] ) );
483 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B );
484 tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_CDEF );
485 tmpa = _mm_srli_epi64( tmpa, 16 );
486 tmpb = _mm_add_epi32( tmpb, tmpa );
487
488 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
489 a_Q12_tmp = _mm_shuffle_epi32( a_Q12_CDEF, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
490 psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp );
491 psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 );
492 tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp );
493
494 /* add at last */
495 /* equal shift right 8 bytes*/
496 tmpa = _mm_shuffle_epi32( tmpb, _MM_SHUFFLE( 0, 0, 3, 2 ) );
497 tmpb = _mm_add_epi32( tmpb, tmpa );
498 LPC_pred_Q14 += _mm_cvtsi128_si32( tmpb );
499 }
500 else
501 {
502 /* add at last */
503 tmpa = _mm_shuffle_epi32( tmpb, _MM_SHUFFLE( 0, 0, 3, 2 ) ); /* equal shift right 8 bytes*/
504 tmpb = _mm_add_epi32( tmpb, tmpa );
505 LPC_pred_Q14 += _mm_cvtsi128_si32( tmpb );
506
507 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
508 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
509 }
510
511 LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
512
513 /* Noise shape feedback */
514 silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
515 /* Output of lowpass section */
516 tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
517 /* Output of allpass section */
518 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
519 psDD->sAR2_Q14[ 0 ] = tmp2;
520 n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 );
521 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] );
522 /* Loop over allpass sections */
523 for( j = 2; j < shapingLPCOrder; j += 2 ) {
524 /* Output of allpass section */
525 tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
526 psDD->sAR2_Q14[ j - 1 ] = tmp1;
527 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] );
528 /* Output of allpass section */
529 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
530 psDD->sAR2_Q14[ j + 0 ] = tmp2;
531 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] );
532 }
533 psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
534 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
535
536 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */
537 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */
538 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */
539
540 n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */
541 n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */
542 n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */
543
544 /* Input minus prediction plus noise feedback */
545 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
546 tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
547 tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
548 tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
549 tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
550
551 r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
552
553 /* Flip sign depending on dither */
554 if ( psDD->Seed < 0 ) {
555 r_Q10 = -r_Q10;
556 }
557 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
558
559 /* Find two quantization level candidates and measure their rate-distortion */
560 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
561 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
562 if( q1_Q0 > 0 ) {
563 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
564 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
565 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
566 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
567 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
568 } else if( q1_Q0 == 0 ) {
569 q1_Q10 = offset_Q10;
570 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
571 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
572 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
573 } else if( q1_Q0 == -1 ) {
574 q2_Q10 = offset_Q10;
575 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
576 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
577 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
578 } else { /* q1_Q0 < -1 */
579 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
580 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
581 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
582 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
583 rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
584 }
585 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
586 rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
587 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
588 rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
589
590 if( rd1_Q10 < rd2_Q10 ) {
591 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
592 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
593 psSS[ 0 ].Q_Q10 = q1_Q10;
594 psSS[ 1 ].Q_Q10 = q2_Q10;
595 } else {
596 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
597 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
598 psSS[ 0 ].Q_Q10 = q2_Q10;
599 psSS[ 1 ].Q_Q10 = q1_Q10;
600 }
601
602 /* Update states for best quantization */
603
604 /* Quantized excitation */
605 exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
606 if ( psDD->Seed < 0 ) {
607 exc_Q14 = -exc_Q14;
608 }
609
610 /* Add predictions */
611 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
612 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
613
614 /* Update states */
615 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
616 psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
617 psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
618 psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
619 psSS[ 0 ].xq_Q14 = xq_Q14;
620
621 /* Update states for second best quantization */
622
623 /* Quantized excitation */
624 exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
625 if ( psDD->Seed < 0 ) {
626 exc_Q14 = -exc_Q14;
627 }
628
629
630 /* Add predictions */
631 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
632 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
633
634 /* Update states */
635 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
636 psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
637 psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
638 psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
639 psSS[ 1 ].xq_Q14 = xq_Q14;
640 }
641 }
642 *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
643 if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
644 last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
645
646 /* Find winner */
647 RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
648 Winner_ind = 0;
649 for( k = 1; k < nStatesDelayedDecision; k++ ) {
650 if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
651 RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
652 Winner_ind = k;
653 }
654 }
655
656 /* Increase RD values of expired states */
657 Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
658 for( k = 0; k < nStatesDelayedDecision; k++ ) {
659 if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
660 psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
661 psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
662 silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
663 }
664 }
665
666 /* Find worst in first set and best in second set */
667 RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
668 RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
669 RDmax_ind = 0;
670 RDmin_ind = 0;
671 for( k = 1; k < nStatesDelayedDecision; k++ ) {
672 /* find worst in first set */
673 if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
674 RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
675 RDmax_ind = k;
676 }
677 /* find best in second set */
678 if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
679 RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
680 RDmin_ind = k;
681 }
682 }
683
684 /* Replace a state if best from second set outperforms worst in first set */
685 if( RDmin_Q10 < RDmax_Q10 ) {
686 silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
687 ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
688 silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
689 }
690
691 /* Write samples from winner to output and long-term filter states */
692 psDD = &psDelDec[ Winner_ind ];
693 if( subfr > 0 || i >= decisionDelay ) {
694 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
695 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
696 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
697 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
698 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ];
699 }
700 NSQ->sLTP_shp_buf_idx++;
701 NSQ->sLTP_buf_idx++;
702
703 /* Update states */
704 for( k = 0; k < nStatesDelayedDecision; k++ ) {
705 psDD = &psDelDec[ k ];
706 psSS = &psSampleState[ k ][ 0 ];
707 psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
708 psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
709 psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
710 psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
711 psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
712 psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14;
713 psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
714 psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
715 psDD->RD_Q10 = psSS->RD_Q10;
716 }
717 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
718 }
719 /* Update LPC states */
720 for( k = 0; k < nStatesDelayedDecision; k++ ) {
721 psDD = &psDelDec[ k ];
722 silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
723 }
724 RESTORE_STACK;
725}
726
727static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1(
728 const silk_encoder_state *psEncC, /* I Encoder State */
729 silk_nsq_state *NSQ, /* I/O NSQ state */
730 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
731 const opus_int32 x_Q3[], /* I Input in Q3 */
732 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
733 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
734 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
735 opus_int subfr, /* I Subframe number */
736 opus_int nStatesDelayedDecision, /* I Number of del dec states */
737 const opus_int LTP_scale_Q14, /* I LTP state scaling */
738 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
739 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
740 const opus_int signal_type, /* I Signal type */
741 const opus_int decisionDelay /* I Decision delay */
742)
743{
744 opus_int i, k, lag;
745 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
746 NSQ_del_dec_struct *psDD;
747 __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1;
748
749 lag = pitchL[ subfr ];
750 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
751
752 silk_assert( inv_gain_Q31 != 0 );
753
754 /* Calculate gain adjustment factor */
755 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
756 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
757 } else {
758 gain_adj_Q16 = (opus_int32)1 << 16;
759 }
760
761 /* Scale input */
762 inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
763
764 /* prepare inv_gain_Q23 in packed 4 32-bits */
765 xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23);
766
767 for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) {
768 xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) );
769 /* equal shift right 4 bytes*/
770 xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
771
772 xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 );
773 xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 );
774
775 xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 );
776 xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 );
777
778 xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC );
779
780 _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ])), xmm_x_Q3_x2x0 );
781 }
782
783 for( ; i < psEncC->subfr_length; i++ ) {
784 x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
785 }
786
787 /* Save inverse gain */
788 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
789
790 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
791 if( NSQ->rewhite_flag ) {
792 if( subfr == 0 ) {
793 /* Do LTP downscaling */
794 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
795 }
796 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
797 silk_assert( i < MAX_FRAME_LENGTH );
798 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
799 }
800 }
801
802 /* Adjust for changing gain */
803 if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
804 /* Scale long-term shaping state */
805 {
806 __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1;
807
808 /* prepare gain_adj_Q16 in packed 4 32-bits */
809 xmm_gain_adj_Q16 = _mm_set1_epi32( gain_adj_Q16 );
810
811 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 3; i += 4 )
812 {
813 xmm_sLTP_shp_Q14_x2x0 = _mm_loadu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ) );
814 /* equal shift right 4 bytes*/
815 xmm_sLTP_shp_Q14_x3x1 = _mm_shuffle_epi32( xmm_sLTP_shp_Q14_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
816
817 xmm_sLTP_shp_Q14_x2x0 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x2x0, xmm_gain_adj_Q16 );
818 xmm_sLTP_shp_Q14_x3x1 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x3x1, xmm_gain_adj_Q16 );
819
820 xmm_sLTP_shp_Q14_x2x0 = _mm_srli_epi64( xmm_sLTP_shp_Q14_x2x0, 16 );
821 xmm_sLTP_shp_Q14_x3x1 = _mm_slli_epi64( xmm_sLTP_shp_Q14_x3x1, 16 );
822
823 xmm_sLTP_shp_Q14_x2x0 = _mm_blend_epi16( xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1, 0xCC );
824
825 _mm_storeu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ), xmm_sLTP_shp_Q14_x2x0 );
826 }
827
828 for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
829 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
830 }
831
832 /* Scale long-term prediction state */
833 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
834 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
835 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
836 }
837 }
838
839 for( k = 0; k < nStatesDelayedDecision; k++ ) {
840 psDD = &psDelDec[ k ];
841
842 /* Scale scalar states */
843 psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );
844
845 /* Scale short-term prediction and shaping states */
846 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
847 psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
848 }
849 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
850 psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
851 }
852 for( i = 0; i < DECISION_DELAY; i++ ) {
853 psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] );
854 psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );
855 }
856 }
857 }
858 }
859}
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c
new file mode 100644
index 0000000000..b0315e35fc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c
@@ -0,0 +1,719 @@
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#include "stack_alloc.h"
38
39static OPUS_INLINE void silk_nsq_scale_states_sse4_1(
40 const silk_encoder_state *psEncC, /* I Encoder State */
41 silk_nsq_state *NSQ, /* I/O NSQ state */
42 const opus_int32 x_Q3[], /* I input in Q3 */
43 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
44 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
45 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
46 opus_int subfr, /* I subframe number */
47 const opus_int LTP_scale_Q14, /* I */
48 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
49 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
50 const opus_int signal_type /* I Signal type */
51);
52
53static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1(
54 silk_nsq_state *NSQ, /* I/O NSQ state */
55 opus_int signalType, /* I Signal type */
56 const opus_int32 x_sc_Q10[], /* I */
57 opus_int8 pulses[], /* O */
58 opus_int16 xq[], /* O */
59 opus_int32 sLTP_Q15[], /* I/O LTP state */
60 const opus_int16 a_Q12[], /* I Short term prediction coefs */
61 const opus_int16 b_Q14[], /* I Long term prediction coefs */
62 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
63 opus_int lag, /* I Pitch lag */
64 opus_int32 HarmShapeFIRPacked_Q14, /* I */
65 opus_int Tilt_Q14, /* I Spectral tilt */
66 opus_int32 LF_shp_Q14, /* I */
67 opus_int32 Gain_Q16, /* I */
68 opus_int offset_Q10, /* I */
69 opus_int length, /* I Input length */
70 opus_int32 table[][4] /* I */
71);
72
73void silk_NSQ_sse4_1(
74 const silk_encoder_state *psEncC, /* I Encoder State */
75 silk_nsq_state *NSQ, /* I/O NSQ state */
76 SideInfoIndices *psIndices, /* I/O Quantization Indices */
77 const opus_int32 x_Q3[], /* I Prefiltered input signal */
78 opus_int8 pulses[], /* O Quantized pulse signal */
79 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
80 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
81 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
82 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
83 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
84 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
85 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
86 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
87 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
88 const opus_int LTP_scale_Q14 /* I LTP state scaling */
89)
90{
91 opus_int k, lag, start_idx, LSF_interpolation_flag;
92 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
93 opus_int16 *pxq;
94 VARDECL( opus_int32, sLTP_Q15 );
95 VARDECL( opus_int16, sLTP );
96 opus_int32 HarmShapeFIRPacked_Q14;
97 opus_int offset_Q10;
98 VARDECL( opus_int32, x_sc_Q10 );
99
100 opus_int32 table[ 64 ][ 4 ];
101 opus_int32 tmp1;
102 opus_int32 q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;
103
104 SAVE_STACK;
105
106 NSQ->rand_seed = psIndices->Seed;
107
108 /* Set unvoiced lag to the previous one, overwrite later for voiced */
109 lag = NSQ->lagPrev;
110
111 silk_assert( NSQ->prev_gain_Q16 != 0 );
112
113 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
114
115 /* 0 */
116 q1_Q10 = offset_Q10;
117 q2_Q10 = offset_Q10 + ( 1024 - QUANT_LEVEL_ADJUST_Q10 );
118 rd1_Q20 = q1_Q10 * Lambda_Q10;
119 rd2_Q20 = q2_Q10 * Lambda_Q10;
120
121 table[ 32 ][ 0 ] = q1_Q10;
122 table[ 32 ][ 1 ] = q2_Q10;
123 table[ 32 ][ 2 ] = 2 * (q1_Q10 - q2_Q10);
124 table[ 32 ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);
125
126 /* -1 */
127 q1_Q10 = offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 );
128 q2_Q10 = offset_Q10;
129 rd1_Q20 = - q1_Q10 * Lambda_Q10;
130 rd2_Q20 = q2_Q10 * Lambda_Q10;
131
132 table[ 31 ][ 0 ] = q1_Q10;
133 table[ 31 ][ 1 ] = q2_Q10;
134 table[ 31 ][ 2 ] = 2 * (q1_Q10 - q2_Q10);
135 table[ 31 ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);
136
137 /* > 0 */
138 for (k = 1; k <= 31; k++)
139 {
140 tmp1 = offset_Q10 + silk_LSHIFT( k, 10 );
141
142 q1_Q10 = tmp1 - QUANT_LEVEL_ADJUST_Q10;
143 q2_Q10 = tmp1 - QUANT_LEVEL_ADJUST_Q10 + 1024;
144 rd1_Q20 = q1_Q10 * Lambda_Q10;
145 rd2_Q20 = q2_Q10 * Lambda_Q10;
146
147 table[ 32 + k ][ 0 ] = q1_Q10;
148 table[ 32 + k ][ 1 ] = q2_Q10;
149 table[ 32 + k ][ 2 ] = 2 * (q1_Q10 - q2_Q10);
150 table[ 32 + k ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);
151 }
152
153 /* < -1 */
154 for (k = -32; k <= -2; k++)
155 {
156 tmp1 = offset_Q10 + silk_LSHIFT( k, 10 );
157
158 q1_Q10 = tmp1 + QUANT_LEVEL_ADJUST_Q10;
159 q2_Q10 = tmp1 + QUANT_LEVEL_ADJUST_Q10 + 1024;
160 rd1_Q20 = - q1_Q10 * Lambda_Q10;
161 rd2_Q20 = - q2_Q10 * Lambda_Q10;
162
163 table[ 32 + k ][ 0 ] = q1_Q10;
164 table[ 32 + k ][ 1 ] = q2_Q10;
165 table[ 32 + k ][ 2 ] = 2 * (q1_Q10 - q2_Q10);
166 table[ 32 + k ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);
167 }
168
169 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
170 LSF_interpolation_flag = 0;
171 } else {
172 LSF_interpolation_flag = 1;
173 }
174
175 ALLOC( sLTP_Q15,
176 psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
177 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
178 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
179 /* Set up pointers to start of sub frame */
180 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
181 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
182 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
183 for( k = 0; k < psEncC->nb_subfr; k++ ) {
184 A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
185 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
186 AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
187
188 /* Noise shape parameters */
189 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
190 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
191 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
192
193 NSQ->rewhite_flag = 0;
194 if( psIndices->signalType == TYPE_VOICED ) {
195 /* Voiced */
196 lag = pitchL[ k ];
197
198 /* Re-whitening */
199 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
200 /* Rewhiten with new A coefs */
201 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
202 celt_assert( start_idx > 0 );
203
204 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
205 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
206
207 NSQ->rewhite_flag = 1;
208 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
209 }
210 }
211
212 silk_nsq_scale_states_sse4_1( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
213
214 if ( opus_likely( ( 10 == psEncC->shapingLPCOrder ) && ( 16 == psEncC->predictLPCOrder) ) )
215 {
216 silk_noise_shape_quantizer_10_16_sse4_1( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
217 AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ],
218 offset_Q10, psEncC->subfr_length, &(table[32]) );
219 }
220 else
221 {
222 silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
223 AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
224 offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch );
225 }
226
227 x_Q3 += psEncC->subfr_length;
228 pulses += psEncC->subfr_length;
229 pxq += psEncC->subfr_length;
230 }
231
232 /* Update lagPrev for next frame */
233 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
234
235 /* Save quantized speech and noise shaping signals */
236 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
237 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
238 RESTORE_STACK;
239}
240
241/***********************************/
242/* silk_noise_shape_quantizer_10_16 */
243/***********************************/
244static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1(
245 silk_nsq_state *NSQ, /* I/O NSQ state */
246 opus_int signalType, /* I Signal type */
247 const opus_int32 x_sc_Q10[], /* I */
248 opus_int8 pulses[], /* O */
249 opus_int16 xq[], /* O */
250 opus_int32 sLTP_Q15[], /* I/O LTP state */
251 const opus_int16 a_Q12[], /* I Short term prediction coefs */
252 const opus_int16 b_Q14[], /* I Long term prediction coefs */
253 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
254 opus_int lag, /* I Pitch lag */
255 opus_int32 HarmShapeFIRPacked_Q14, /* I */
256 opus_int Tilt_Q14, /* I Spectral tilt */
257 opus_int32 LF_shp_Q14, /* I */
258 opus_int32 Gain_Q16, /* I */
259 opus_int offset_Q10, /* I */
260 opus_int length, /* I Input length */
261 opus_int32 table[][4] /* I */
262)
263{
264 opus_int i;
265 opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;
266 opus_int32 n_LF_Q12, r_Q10, q1_Q0, q1_Q10, q2_Q10;
267 opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
268 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
269 opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
270
271 __m128i xmm_tempa, xmm_tempb;
272
273 __m128i xmm_one;
274
275 __m128i psLPC_Q14_hi_01234567, psLPC_Q14_hi_89ABCDEF;
276 __m128i psLPC_Q14_lo_01234567, psLPC_Q14_lo_89ABCDEF;
277 __m128i a_Q12_01234567, a_Q12_89ABCDEF;
278
279 __m128i sAR2_Q14_hi_76543210, sAR2_Q14_lo_76543210;
280 __m128i AR_shp_Q13_76543210;
281
282 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
283 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
284 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
285
286 /* Set up short term AR state */
287 psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
288
289 sLF_AR_shp_Q14 = NSQ->sLF_AR_shp_Q14;
290 xq_Q14 = psLPC_Q14[ 0 ];
291 LTP_pred_Q13 = 0;
292
293 /* load a_Q12 */
294 xmm_one = _mm_set_epi8( 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14 );
295
296 /* load a_Q12[0] - a_Q12[7] */
297 a_Q12_01234567 = _mm_loadu_si128( (__m128i *)(&a_Q12[ 0 ] ) );
298 /* load a_Q12[ 8 ] - a_Q12[ 15 ] */
299 a_Q12_89ABCDEF = _mm_loadu_si128( (__m128i *)(&a_Q12[ 8 ] ) );
300
301 a_Q12_01234567 = _mm_shuffle_epi8( a_Q12_01234567, xmm_one );
302 a_Q12_89ABCDEF = _mm_shuffle_epi8( a_Q12_89ABCDEF, xmm_one );
303
304 /* load AR_shp_Q13 */
305 AR_shp_Q13_76543210 = _mm_loadu_si128( (__m128i *)(&AR_shp_Q13[0] ) );
306
307 /* load psLPC_Q14 */
308 xmm_one = _mm_set_epi8(15, 14, 11, 10, 7, 6, 3, 2, 13, 12, 9, 8, 5, 4, 1, 0 );
309
310 xmm_tempa = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[-16]) );
311 xmm_tempb = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[-12]) );
312
313 xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one );
314 xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one );
315
316 psLPC_Q14_hi_89ABCDEF = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb );
317 psLPC_Q14_lo_89ABCDEF = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb );
318
319 xmm_tempa = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -8 ]) );
320 xmm_tempb = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -4 ]) );
321
322 xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one );
323 xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one );
324
325 psLPC_Q14_hi_01234567 = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb );
326 psLPC_Q14_lo_01234567 = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb );
327
328 /* load sAR2_Q14 */
329 xmm_tempa = _mm_loadu_si128( (__m128i *)(&(NSQ->sAR2_Q14[ 0 ]) ) );
330 xmm_tempb = _mm_loadu_si128( (__m128i *)(&(NSQ->sAR2_Q14[ 4 ]) ) );
331
332 xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one );
333 xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one );
334
335 sAR2_Q14_hi_76543210 = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb );
336 sAR2_Q14_lo_76543210 = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb );
337
338 /* prepare 1 in 8 * 16bit */
339 xmm_one = _mm_set1_epi16(1);
340
341 for( i = 0; i < length; i++ )
342 {
343 /* Short-term prediction */
344 __m128i xmm_hi_07, xmm_hi_8F, xmm_lo_07, xmm_lo_8F;
345
346 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
347 LPC_pred_Q10 = 8; /* silk_RSHIFT( predictLPCOrder, 1 ); */
348
349 /* shift psLPC_Q14 */
350 psLPC_Q14_hi_89ABCDEF = _mm_alignr_epi8( psLPC_Q14_hi_01234567, psLPC_Q14_hi_89ABCDEF, 2 );
351 psLPC_Q14_lo_89ABCDEF = _mm_alignr_epi8( psLPC_Q14_lo_01234567, psLPC_Q14_lo_89ABCDEF, 2 );
352
353 psLPC_Q14_hi_01234567 = _mm_srli_si128( psLPC_Q14_hi_01234567, 2 );
354 psLPC_Q14_lo_01234567 = _mm_srli_si128( psLPC_Q14_lo_01234567, 2 );
355
356 psLPC_Q14_hi_01234567 = _mm_insert_epi16( psLPC_Q14_hi_01234567, (xq_Q14 >> 16), 7 );
357 psLPC_Q14_lo_01234567 = _mm_insert_epi16( psLPC_Q14_lo_01234567, (xq_Q14), 7 );
358
359 /* high part, use pmaddwd, results in 4 32-bit */
360 xmm_hi_07 = _mm_madd_epi16( psLPC_Q14_hi_01234567, a_Q12_01234567 );
361 xmm_hi_8F = _mm_madd_epi16( psLPC_Q14_hi_89ABCDEF, a_Q12_89ABCDEF );
362
363 /* low part, use pmulhw, results in 8 16-bit, note we need simulate unsigned * signed, _mm_srai_epi16(psLPC_Q14_lo_01234567, 15) */
364 xmm_tempa = _mm_cmpgt_epi16( _mm_setzero_si128(), psLPC_Q14_lo_01234567 );
365 xmm_tempb = _mm_cmpgt_epi16( _mm_setzero_si128(), psLPC_Q14_lo_89ABCDEF );
366
367 xmm_tempa = _mm_and_si128( xmm_tempa, a_Q12_01234567 );
368 xmm_tempb = _mm_and_si128( xmm_tempb, a_Q12_89ABCDEF );
369
370 xmm_lo_07 = _mm_mulhi_epi16( psLPC_Q14_lo_01234567, a_Q12_01234567 );
371 xmm_lo_8F = _mm_mulhi_epi16( psLPC_Q14_lo_89ABCDEF, a_Q12_89ABCDEF );
372
373 xmm_lo_07 = _mm_add_epi16( xmm_lo_07, xmm_tempa );
374 xmm_lo_8F = _mm_add_epi16( xmm_lo_8F, xmm_tempb );
375
376 xmm_lo_07 = _mm_madd_epi16( xmm_lo_07, xmm_one );
377 xmm_lo_8F = _mm_madd_epi16( xmm_lo_8F, xmm_one );
378
379 /* accumulate */
380 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_hi_8F );
381 xmm_lo_07 = _mm_add_epi32( xmm_lo_07, xmm_lo_8F );
382
383 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_lo_07 );
384
385 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_unpackhi_epi64(xmm_hi_07, xmm_hi_07 ) );
386 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_shufflelo_epi16(xmm_hi_07, 0x0E ) );
387
388 LPC_pred_Q10 += _mm_cvtsi128_si32( xmm_hi_07 );
389
390 /* Long-term prediction */
391 if ( opus_likely( signalType == TYPE_VOICED ) ) {
392 /* Unrolled loop */
393 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
394 LTP_pred_Q13 = 2;
395 {
396 __m128i b_Q14_3210, b_Q14_0123, pred_lag_ptr_0123;
397
398 b_Q14_3210 = OP_CVTEPI16_EPI32_M64( b_Q14 );
399 b_Q14_0123 = _mm_shuffle_epi32( b_Q14_3210, 0x1B );
400
401 /* loaded: [0] [-1] [-2] [-3] */
402 pred_lag_ptr_0123 = _mm_loadu_si128( (__m128i *)(&pred_lag_ptr[ -3 ] ) );
403 /* shuffle to [-3] [-2] [-1] [0] and to new xmm */
404 xmm_tempa = _mm_shuffle_epi32( pred_lag_ptr_0123, 0x1B );
405 /*64-bit multiply, a[2] * b[-2], a[0] * b[0] */
406 xmm_tempa = _mm_mul_epi32( xmm_tempa, b_Q14_3210 );
407 /* right shift 2 bytes (16 bits), zero extended */
408 xmm_tempa = _mm_srli_si128( xmm_tempa, 2 );
409
410 /* a[1] * b[-1], a[3] * b[-3] */
411 pred_lag_ptr_0123 = _mm_mul_epi32( pred_lag_ptr_0123, b_Q14_0123 );
412 pred_lag_ptr_0123 = _mm_srli_si128( pred_lag_ptr_0123, 2 );
413
414 pred_lag_ptr_0123 = _mm_add_epi32( pred_lag_ptr_0123, xmm_tempa );
415 /* equal shift right 8 bytes*/
416 xmm_tempa = _mm_shuffle_epi32( pred_lag_ptr_0123, _MM_SHUFFLE( 0, 0, 3, 2 ) );
417 xmm_tempa = _mm_add_epi32( xmm_tempa, pred_lag_ptr_0123 );
418
419 LTP_pred_Q13 += _mm_cvtsi128_si32( xmm_tempa );
420
421 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
422 pred_lag_ptr++;
423 }
424 }
425
426 /* Noise shape feedback */
427 NSQ->sAR2_Q14[ 9 ] = NSQ->sAR2_Q14[ 8 ];
428 NSQ->sAR2_Q14[ 8 ] = _mm_cvtsi128_si32( _mm_srli_si128(_mm_unpackhi_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 ), 12 ) );
429
430 sAR2_Q14_hi_76543210 = _mm_slli_si128( sAR2_Q14_hi_76543210, 2 );
431 sAR2_Q14_lo_76543210 = _mm_slli_si128( sAR2_Q14_lo_76543210, 2 );
432
433 sAR2_Q14_hi_76543210 = _mm_insert_epi16( sAR2_Q14_hi_76543210, (xq_Q14 >> 16), 0 );
434 sAR2_Q14_lo_76543210 = _mm_insert_epi16( sAR2_Q14_lo_76543210, (xq_Q14), 0 );
435
436 /* high part, use pmaddwd, results in 4 32-bit */
437 xmm_hi_07 = _mm_madd_epi16( sAR2_Q14_hi_76543210, AR_shp_Q13_76543210 );
438
439 /* low part, use pmulhw, results in 8 16-bit, note we need simulate unsigned * signed,_mm_srai_epi16(sAR2_Q14_lo_76543210, 15) */
440 xmm_tempa = _mm_cmpgt_epi16( _mm_setzero_si128(), sAR2_Q14_lo_76543210 );
441 xmm_tempa = _mm_and_si128( xmm_tempa, AR_shp_Q13_76543210 );
442
443 xmm_lo_07 = _mm_mulhi_epi16( sAR2_Q14_lo_76543210, AR_shp_Q13_76543210 );
444 xmm_lo_07 = _mm_add_epi16( xmm_lo_07, xmm_tempa );
445
446 xmm_lo_07 = _mm_madd_epi16( xmm_lo_07, xmm_one );
447
448 /* accumulate */
449 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_lo_07 );
450
451 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_unpackhi_epi64(xmm_hi_07, xmm_hi_07 ) );
452 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_shufflelo_epi16(xmm_hi_07, 0x0E ) );
453
454 n_AR_Q12 = 5 + _mm_cvtsi128_si32( xmm_hi_07 );
455
456 n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sAR2_Q14[ 8 ], AR_shp_Q13[ 8 ] );
457 n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sAR2_Q14[ 9 ], AR_shp_Q13[ 9 ] );
458
459 n_AR_Q12 = silk_LSHIFT32( n_AR_Q12, 1 ); /* Q11 -> Q12 */
460 n_AR_Q12 = silk_SMLAWB( n_AR_Q12, sLF_AR_shp_Q14, Tilt_Q14 );
461
462 n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
463 n_LF_Q12 = silk_SMLAWT( n_LF_Q12, sLF_AR_shp_Q14, LF_shp_Q14 );
464
465 silk_assert( lag > 0 || signalType != TYPE_VOICED );
466
467 /* Combine prediction and noise shaping signals */
468 tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */
469 tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */
470 if( lag > 0 ) {
471 /* Symmetric, packed FIR coefficients */
472 n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
473 n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
474 n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 );
475 shp_lag_ptr++;
476
477 tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */
478 tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */
479 tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */
480 } else {
481 tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */
482 }
483
484 r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */
485
486 /* Generate dither */
487 NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
488
489 /* Flip sign depending on dither */
490 tmp2 = -r_Q10;
491 if ( NSQ->rand_seed < 0 ) r_Q10 = tmp2;
492
493 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
494
495 /* Find two quantization level candidates and measure their rate-distortion */
496 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
497 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
498
499 q1_Q10 = table[q1_Q0][0];
500 q2_Q10 = table[q1_Q0][1];
501
502 if (r_Q10 * table[q1_Q0][2] - table[q1_Q0][3] < 0)
503 {
504 q1_Q10 = q2_Q10;
505 }
506
507 pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );
508
509 /* Excitation */
510 exc_Q14 = silk_LSHIFT( q1_Q10, 4 );
511
512 tmp2 = -exc_Q14;
513 if ( NSQ->rand_seed < 0 ) exc_Q14 = tmp2;
514
515 /* Add predictions */
516 LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );
517 xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 );
518
519 /* Update states */
520 psLPC_Q14++;
521 *psLPC_Q14 = xq_Q14;
522 sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 );
523
524 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );
525 sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 );
526 NSQ->sLTP_shp_buf_idx++;
527 NSQ->sLTP_buf_idx++;
528
529 /* Make dither dependent on quantized signal */
530 NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] );
531 }
532
533 NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;
534
535 /* Scale XQ back to normal level before saving */
536 psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH ];
537
538 /* write back sAR2_Q14 */
539 xmm_tempa = _mm_unpackhi_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 );
540 xmm_tempb = _mm_unpacklo_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 );
541 _mm_storeu_si128( (__m128i *)(&NSQ->sAR2_Q14[ 4 ]), xmm_tempa );
542 _mm_storeu_si128( (__m128i *)(&NSQ->sAR2_Q14[ 0 ]), xmm_tempb );
543
544 /* xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psLPC_Q14[ i ], Gain_Q10 ), 8 ) ); */
545 {
546 __m128i xmm_Gain_Q10;
547 __m128i xmm_xq_Q14_3210, xmm_xq_Q14_x3x1, xmm_xq_Q14_7654, xmm_xq_Q14_x7x5;
548
549 /* prepare (1 << 7) in packed 4 32-bits */
550 xmm_tempa = _mm_set1_epi32( (1 << 7) );
551
552 /* prepare Gain_Q10 in packed 4 32-bits */
553 xmm_Gain_Q10 = _mm_set1_epi32( Gain_Q10 );
554
555 /* process xq */
556 for (i = 0; i < length - 7; i += 8)
557 {
558 xmm_xq_Q14_3210 = _mm_loadu_si128( (__m128i *)(&(psLPC_Q14[ i + 0 ] ) ) );
559 xmm_xq_Q14_7654 = _mm_loadu_si128( (__m128i *)(&(psLPC_Q14[ i + 4 ] ) ) );
560
561 /* equal shift right 4 bytes*/
562 xmm_xq_Q14_x3x1 = _mm_shuffle_epi32( xmm_xq_Q14_3210, _MM_SHUFFLE( 0, 3, 2, 1 ) );
563 /* equal shift right 4 bytes*/
564 xmm_xq_Q14_x7x5 = _mm_shuffle_epi32( xmm_xq_Q14_7654, _MM_SHUFFLE( 0, 3, 2, 1 ) );
565
566 xmm_xq_Q14_3210 = _mm_mul_epi32( xmm_xq_Q14_3210, xmm_Gain_Q10 );
567 xmm_xq_Q14_x3x1 = _mm_mul_epi32( xmm_xq_Q14_x3x1, xmm_Gain_Q10 );
568 xmm_xq_Q14_7654 = _mm_mul_epi32( xmm_xq_Q14_7654, xmm_Gain_Q10 );
569 xmm_xq_Q14_x7x5 = _mm_mul_epi32( xmm_xq_Q14_x7x5, xmm_Gain_Q10 );
570
571 xmm_xq_Q14_3210 = _mm_srli_epi64( xmm_xq_Q14_3210, 16 );
572 xmm_xq_Q14_x3x1 = _mm_slli_epi64( xmm_xq_Q14_x3x1, 16 );
573 xmm_xq_Q14_7654 = _mm_srli_epi64( xmm_xq_Q14_7654, 16 );
574 xmm_xq_Q14_x7x5 = _mm_slli_epi64( xmm_xq_Q14_x7x5, 16 );
575
576 xmm_xq_Q14_3210 = _mm_blend_epi16( xmm_xq_Q14_3210, xmm_xq_Q14_x3x1, 0xCC );
577 xmm_xq_Q14_7654 = _mm_blend_epi16( xmm_xq_Q14_7654, xmm_xq_Q14_x7x5, 0xCC );
578
579 /* silk_RSHIFT_ROUND(xq, 8) */
580 xmm_xq_Q14_3210 = _mm_add_epi32( xmm_xq_Q14_3210, xmm_tempa );
581 xmm_xq_Q14_7654 = _mm_add_epi32( xmm_xq_Q14_7654, xmm_tempa );
582
583 xmm_xq_Q14_3210 = _mm_srai_epi32( xmm_xq_Q14_3210, 8 );
584 xmm_xq_Q14_7654 = _mm_srai_epi32( xmm_xq_Q14_7654, 8 );
585
586 /* silk_SAT16 */
587 xmm_xq_Q14_3210 = _mm_packs_epi32( xmm_xq_Q14_3210, xmm_xq_Q14_7654 );
588
589 /* save to xq */
590 _mm_storeu_si128( (__m128i *)(&xq[ i ] ), xmm_xq_Q14_3210 );
591 }
592 }
593 for ( ; i < length; i++)
594 {
595 xq[i] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psLPC_Q14[ i ], Gain_Q10 ), 8 ) );
596 }
597
598 /* Update LPC synth buffer */
599 silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
600}
601
602static OPUS_INLINE void silk_nsq_scale_states_sse4_1(
603 const silk_encoder_state *psEncC, /* I Encoder State */
604 silk_nsq_state *NSQ, /* I/O NSQ state */
605 const opus_int32 x_Q3[], /* I input in Q3 */
606 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
607 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
608 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
609 opus_int subfr, /* I subframe number */
610 const opus_int LTP_scale_Q14, /* I */
611 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
612 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
613 const opus_int signal_type /* I Signal type */
614)
615{
616 opus_int i, lag;
617 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
618 __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1;
619
620 lag = pitchL[ subfr ];
621 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
622 silk_assert( inv_gain_Q31 != 0 );
623
624 /* Calculate gain adjustment factor */
625 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
626 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
627 } else {
628 gain_adj_Q16 = (opus_int32)1 << 16;
629 }
630
631 /* Scale input */
632 inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
633
634 /* prepare inv_gain_Q23 in packed 4 32-bits */
635 xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23);
636
637 for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) {
638 xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) );
639
640 /* equal shift right 4 bytes*/
641 xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
642
643 xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 );
644 xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 );
645
646 xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 );
647 xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 );
648
649 xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC );
650
651 _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ] ) ), xmm_x_Q3_x2x0 );
652 }
653
654 for( ; i < psEncC->subfr_length; i++ ) {
655 x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
656 }
657
658 /* Save inverse gain */
659 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
660
661 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
662 if( NSQ->rewhite_flag ) {
663 if( subfr == 0 ) {
664 /* Do LTP downscaling */
665 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
666 }
667 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
668 silk_assert( i < MAX_FRAME_LENGTH );
669 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
670 }
671 }
672
673 /* Adjust for changing gain */
674 if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
675 /* Scale long-term shaping state */
676 __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1;
677
678 /* prepare gain_adj_Q16 in packed 4 32-bits */
679 xmm_gain_adj_Q16 = _mm_set1_epi32(gain_adj_Q16);
680
681 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 3; i += 4 )
682 {
683 xmm_sLTP_shp_Q14_x2x0 = _mm_loadu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ) );
684 /* equal shift right 4 bytes*/
685 xmm_sLTP_shp_Q14_x3x1 = _mm_shuffle_epi32( xmm_sLTP_shp_Q14_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
686
687 xmm_sLTP_shp_Q14_x2x0 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x2x0, xmm_gain_adj_Q16 );
688 xmm_sLTP_shp_Q14_x3x1 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x3x1, xmm_gain_adj_Q16 );
689
690 xmm_sLTP_shp_Q14_x2x0 = _mm_srli_epi64( xmm_sLTP_shp_Q14_x2x0, 16 );
691 xmm_sLTP_shp_Q14_x3x1 = _mm_slli_epi64( xmm_sLTP_shp_Q14_x3x1, 16 );
692
693 xmm_sLTP_shp_Q14_x2x0 = _mm_blend_epi16( xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1, 0xCC );
694
695 _mm_storeu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ), xmm_sLTP_shp_Q14_x2x0 );
696 }
697
698 for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
699 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
700 }
701
702 /* Scale long-term prediction state */
703 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
704 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
705 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
706 }
707 }
708
709 NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );
710
711 /* Scale short-term prediction and shaping states */
712 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
713 NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
714 }
715 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
716 NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
717 }
718 }
719}
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h b/lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h
new file mode 100644
index 0000000000..61efa8da41
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h
@@ -0,0 +1,94 @@
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#ifndef SIGPROC_FIX_SSE_H
29#define SIGPROC_FIX_SSE_H
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#if defined(OPUS_X86_MAY_HAVE_SSE4_1)
36void silk_burg_modified_sse4_1(
37 opus_int32 *res_nrg, /* O Residual energy */
38 opus_int *res_nrg_Q, /* O Residual energy Q value */
39 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
40 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
41 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
42 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
43 const opus_int nb_subfr, /* I Number of subframes stacked in x */
44 const opus_int D, /* I Order */
45 int arch /* I Run-time architecture */
46);
47
48#if defined(OPUS_X86_PRESUME_SSE4_1)
49#define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \
50 ((void)(arch), silk_burg_modified_sse4_1(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch))
51
52#else
53
54extern void (*const SILK_BURG_MODIFIED_IMPL[OPUS_ARCHMASK + 1])(
55 opus_int32 *res_nrg, /* O Residual energy */
56 opus_int *res_nrg_Q, /* O Residual energy Q value */
57 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
58 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
59 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
60 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
61 const opus_int nb_subfr, /* I Number of subframes stacked in x */
62 const opus_int D, /* I Order */
63 int arch /* I Run-time architecture */);
64
65# define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \
66 ((*SILK_BURG_MODIFIED_IMPL[(arch) & OPUS_ARCHMASK])(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch))
67
68#endif
69
70opus_int64 silk_inner_prod16_aligned_64_sse4_1(
71 const opus_int16 *inVec1,
72 const opus_int16 *inVec2,
73 const opus_int len
74);
75
76
77#if defined(OPUS_X86_PRESUME_SSE4_1)
78
79#define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \
80 ((void)(arch),silk_inner_prod16_aligned_64_sse4_1(inVec1, inVec2, len))
81
82#else
83
84extern opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[OPUS_ARCHMASK + 1])(
85 const opus_int16 *inVec1,
86 const opus_int16 *inVec2,
87 const opus_int len);
88
89# define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \
90 ((*SILK_INNER_PROD16_ALIGNED_64_IMPL[(arch) & OPUS_ARCHMASK])(inVec1, inVec2, len))
91
92#endif
93#endif
94#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c
new file mode 100644
index 0000000000..d02ddf4ad0
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c
@@ -0,0 +1,277 @@
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 "main.h"
37#include "stack_alloc.h"
38
39/* Weighting factors for tilt measure */
40static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };
41
42/***************************************/
43/* Get the speech activity level in Q8 */
44/***************************************/
45opus_int silk_VAD_GetSA_Q8_sse4_1( /* O Return value, 0 if success */
46 silk_encoder_state *psEncC, /* I/O Encoder state */
47 const opus_int16 pIn[] /* I PCM input */
48)
49{
50 opus_int SA_Q15, pSNR_dB_Q7, input_tilt;
51 opus_int decimated_framelength1, decimated_framelength2;
52 opus_int decimated_framelength;
53 opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
54 opus_int32 sumSquared, smooth_coef_Q16;
55 opus_int16 HPstateTmp;
56 VARDECL( opus_int16, X );
57 opus_int32 Xnrg[ VAD_N_BANDS ];
58 opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
59 opus_int32 speech_nrg, x_tmp;
60 opus_int X_offset[ VAD_N_BANDS ];
61 opus_int ret = 0;
62 silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
63
64 SAVE_STACK;
65
66 /* Safety checks */
67 silk_assert( VAD_N_BANDS == 4 );
68 celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
69 celt_assert( psEncC->frame_length <= 512 );
70 celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
71
72 /***********************/
73 /* Filter and Decimate */
74 /***********************/
75 decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
76 decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
77 decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
78 /* Decimate into 4 bands:
79 0 L 3L L 3L 5L
80 - -- - -- --
81 8 8 2 4 4
82
83 [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz |
84
85 They're arranged to allow the minimal ( frame_length / 4 ) extra
86 scratch space during the downsampling process */
87 X_offset[ 0 ] = 0;
88 X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
89 X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
90 X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
91 ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
92
93 /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
94 silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ],
95 X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
96
97 /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
98 silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
99 X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
100
101 /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
102 silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
103 X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
104
105 /*********************************************/
106 /* HP filter on lowest band (differentiator) */
107 /*********************************************/
108 X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
109 HPstateTmp = X[ decimated_framelength - 1 ];
110 for( i = decimated_framelength - 1; i > 0; i-- ) {
111 X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 );
112 X[ i ] -= X[ i - 1 ];
113 }
114 X[ 0 ] -= psSilk_VAD->HPstate;
115 psSilk_VAD->HPstate = HPstateTmp;
116
117 /*************************************/
118 /* Calculate the energy in each band */
119 /*************************************/
120 for( b = 0; b < VAD_N_BANDS; b++ ) {
121 /* Find the decimated framelength in the non-uniformly divided bands */
122 decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
123
124 /* Split length into subframe lengths */
125 dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
126 dec_subframe_offset = 0;
127
128 /* Compute energy per sub-frame */
129 /* initialize with summed energy of last subframe */
130 Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
131 for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
132 __m128i xmm_X, xmm_acc;
133 sumSquared = 0;
134
135 xmm_acc = _mm_setzero_si128();
136
137 for( i = 0; i < dec_subframe_length - 7; i += 8 )
138 {
139 xmm_X = _mm_loadu_si128( (__m128i *)&(X[ X_offset[ b ] + i + dec_subframe_offset ] ) );
140 xmm_X = _mm_srai_epi16( xmm_X, 3 );
141 xmm_X = _mm_madd_epi16( xmm_X, xmm_X );
142 xmm_acc = _mm_add_epi32( xmm_acc, xmm_X );
143 }
144
145 xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) );
146 xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) );
147
148 sumSquared += _mm_cvtsi128_si32( xmm_acc );
149
150 for( ; i < dec_subframe_length; i++ ) {
151 /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */
152 /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */
153 x_tmp = silk_RSHIFT(
154 X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
155 sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
156
157 /* Safety check */
158 silk_assert( sumSquared >= 0 );
159 }
160
161 /* Add/saturate summed energy of current subframe */
162 if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
163 Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
164 } else {
165 /* Look-ahead subframe */
166 Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
167 }
168
169 dec_subframe_offset += dec_subframe_length;
170 }
171 psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
172 }
173
174 /********************/
175 /* Noise estimation */
176 /********************/
177 silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
178
179 /***********************************************/
180 /* Signal-plus-noise to noise ratio estimation */
181 /***********************************************/
182 sumSquared = 0;
183 input_tilt = 0;
184 for( b = 0; b < VAD_N_BANDS; b++ ) {
185 speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
186 if( speech_nrg > 0 ) {
187 /* Divide, with sufficient resolution */
188 if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
189 NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
190 } else {
191 NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
192 }
193
194 /* Convert to log domain */
195 SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
196
197 /* Sum-of-squares */
198 sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */
199
200 /* Tilt measure */
201 if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
202 /* Scale down SNR value for small subband speech energies */
203 SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
204 }
205 input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
206 } else {
207 NrgToNoiseRatio_Q8[ b ] = 256;
208 }
209 }
210
211 /* Mean-of-squares */
212 sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
213
214 /* Root-mean-square approximation, scale to dBs, and write to output pointer */
215 pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
216
217 /*********************************/
218 /* Speech Probability Estimation */
219 /*********************************/
220 SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
221
222 /**************************/
223 /* Frequency Tilt Measure */
224 /**************************/
225 psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );
226
227 /**************************************************/
228 /* Scale the sigmoid output based on power levels */
229 /**************************************************/
230 speech_nrg = 0;
231 for( b = 0; b < VAD_N_BANDS; b++ ) {
232 /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
233 speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
234 }
235
236 /* Power scaling */
237 if( speech_nrg <= 0 ) {
238 SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
239 } else if( speech_nrg < 32768 ) {
240 if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
241 speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 );
242 } else {
243 speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 );
244 }
245
246 /* square-root */
247 speech_nrg = silk_SQRT_APPROX( speech_nrg );
248 SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );
249 }
250
251 /* Copy the resulting speech activity in Q8 */
252 psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );
253
254 /***********************************/
255 /* Energy Level and SNR estimation */
256 /***********************************/
257 /* Smoothing coefficient */
258 smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
259
260 if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
261 smooth_coef_Q16 >>= 1;
262 }
263
264 for( b = 0; b < VAD_N_BANDS; b++ ) {
265 /* compute smoothed energy-to-noise ratio per band */
266 psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
267 NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
268
269 /* signal to noise ratio in dB per band */
270 SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
271 /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
272 psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
273 }
274
275 RESTORE_STACK;
276 return( ret );
277}
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c
new file mode 100644
index 0000000000..74d6c6d0ec
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c
@@ -0,0 +1,142 @@
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
38/* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */
39void silk_VQ_WMat_EC_sse4_1(
40 opus_int8 *ind, /* O index of best codebook vector */
41 opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
42 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
43 const opus_int16 *in_Q14, /* I input vector to be quantized */
44 const opus_int32 *W_Q18, /* I weighting matrix */
45 const opus_int8 *cb_Q7, /* I codebook */
46 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
47 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
48 const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
49 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
50 opus_int L /* I number of vectors in codebook */
51)
52{
53 opus_int k, gain_tmp_Q7;
54 const opus_int8 *cb_row_Q7;
55 opus_int16 diff_Q14[ 5 ];
56 opus_int32 sum1_Q14, sum2_Q16;
57
58 __m128i C_tmp1, C_tmp2, C_tmp3, C_tmp4, C_tmp5;
59 /* Loop over codebook */
60 *rate_dist_Q14 = silk_int32_MAX;
61 cb_row_Q7 = cb_Q7;
62 for( k = 0; k < L; k++ ) {
63 gain_tmp_Q7 = cb_gain_Q7[k];
64
65 diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 );
66
67 C_tmp1 = OP_CVTEPI16_EPI32_M64( &in_Q14[ 1 ] );
68 C_tmp2 = OP_CVTEPI8_EPI32_M32( &cb_row_Q7[ 1 ] );
69 C_tmp2 = _mm_slli_epi32( C_tmp2, 7 );
70 C_tmp1 = _mm_sub_epi32( C_tmp1, C_tmp2 );
71
72 diff_Q14[ 1 ] = _mm_extract_epi16( C_tmp1, 0 );
73 diff_Q14[ 2 ] = _mm_extract_epi16( C_tmp1, 2 );
74 diff_Q14[ 3 ] = _mm_extract_epi16( C_tmp1, 4 );
75 diff_Q14[ 4 ] = _mm_extract_epi16( C_tmp1, 6 );
76
77 /* Weighted rate */
78 sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] );
79
80 /* Penalty for too large gain */
81 sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 );
82
83 silk_assert( sum1_Q14 >= 0 );
84
85 /* first row of W_Q18 */
86 C_tmp3 = _mm_loadu_si128( (__m128i *)(&W_Q18[ 1 ] ) );
87 C_tmp4 = _mm_mul_epi32( C_tmp3, C_tmp1 );
88 C_tmp4 = _mm_srli_si128( C_tmp4, 2 );
89
90 C_tmp1 = _mm_shuffle_epi32( C_tmp1, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */
91 C_tmp3 = _mm_shuffle_epi32( C_tmp3, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */
92
93 C_tmp5 = _mm_mul_epi32( C_tmp3, C_tmp1 );
94 C_tmp5 = _mm_srli_si128( C_tmp5, 2 );
95
96 C_tmp5 = _mm_add_epi32( C_tmp4, C_tmp5 );
97 C_tmp5 = _mm_slli_epi32( C_tmp5, 1 );
98
99 C_tmp5 = _mm_add_epi32( C_tmp5, _mm_shuffle_epi32( C_tmp5, _MM_SHUFFLE( 0, 0, 0, 2 ) ) );
100 sum2_Q16 = _mm_cvtsi128_si32( C_tmp5 );
101
102 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] );
103 sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] );
104
105 /* second row of W_Q18 */
106 sum2_Q16 = silk_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] );
107 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] );
108 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] );
109 sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
110 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] );
111 sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] );
112
113 /* third row of W_Q18 */
114 sum2_Q16 = silk_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] );
115 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] );
116 sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
117 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] );
118 sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] );
119
120 /* fourth row of W_Q18 */
121 sum2_Q16 = silk_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] );
122 sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
123 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] );
124 sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] );
125
126 /* last row of W_Q18 */
127 sum2_Q16 = silk_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] );
128 sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] );
129
130 silk_assert( sum1_Q14 >= 0 );
131
132 /* find best */
133 if( sum1_Q14 < *rate_dist_Q14 ) {
134 *rate_dist_Q14 = sum1_Q14;
135 *ind = (opus_int8)k;
136 *gain_Q7 = gain_tmp_Q7;
137 }
138
139 /* Go to next cbk vector */
140 cb_row_Q7 += LTP_ORDER;
141 }
142}
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/main_sse.h b/lib/rbcodec/codecs/libopus/silk/x86/main_sse.h
new file mode 100644
index 0000000000..2f15d44869
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/main_sse.h
@@ -0,0 +1,248 @@
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#ifndef MAIN_SSE_H
29#define MAIN_SSE_H
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35# if defined(OPUS_X86_MAY_HAVE_SSE4_1)
36
37#if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */
38# define OVERRIDE_silk_VQ_WMat_EC
39
40void silk_VQ_WMat_EC_sse4_1(
41 opus_int8 *ind, /* O index of best codebook vector */
42 opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
43 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
44 const opus_int16 *in_Q14, /* I input vector to be quantized */
45 const opus_int32 *W_Q18, /* I weighting matrix */
46 const opus_int8 *cb_Q7, /* I codebook */
47 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
48 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
49 const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
50 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
51 opus_int L /* I number of vectors in codebook */
52);
53
54#if defined OPUS_X86_PRESUME_SSE4_1
55
56#define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
57 mu_Q9, max_gain_Q7, L, arch) \
58 ((void)(arch),silk_VQ_WMat_EC_sse4_1(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
59 mu_Q9, max_gain_Q7, L))
60
61#else
62
63extern void (*const SILK_VQ_WMAT_EC_IMPL[OPUS_ARCHMASK + 1])(
64 opus_int8 *ind, /* O index of best codebook vector */
65 opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
66 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
67 const opus_int16 *in_Q14, /* I input vector to be quantized */
68 const opus_int32 *W_Q18, /* I weighting matrix */
69 const opus_int8 *cb_Q7, /* I codebook */
70 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
71 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
72 const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
73 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
74 opus_int L /* I number of vectors in codebook */
75);
76
77# define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
78 mu_Q9, max_gain_Q7, L, arch) \
79 ((*SILK_VQ_WMAT_EC_IMPL[(arch) & OPUS_ARCHMASK])(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
80 mu_Q9, max_gain_Q7, L))
81
82#endif
83#endif
84
85#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
86# define OVERRIDE_silk_NSQ
87
88void silk_NSQ_sse4_1(
89 const silk_encoder_state *psEncC, /* I Encoder State */
90 silk_nsq_state *NSQ, /* I/O NSQ state */
91 SideInfoIndices *psIndices, /* I/O Quantization Indices */
92 const opus_int32 x_Q3[], /* I Prefiltered input signal */
93 opus_int8 pulses[], /* O Quantized pulse signal */
94 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
95 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
96 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
97 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
98 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
99 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
100 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
101 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
102 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
103 const opus_int LTP_scale_Q14 /* I LTP state scaling */
104);
105
106#if defined OPUS_X86_PRESUME_SSE4_1
107
108#define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
109 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
110 ((void)(arch),silk_NSQ_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
111 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
112
113#else
114
115extern void (*const SILK_NSQ_IMPL[OPUS_ARCHMASK + 1])(
116 const silk_encoder_state *psEncC, /* I Encoder State */
117 silk_nsq_state *NSQ, /* I/O NSQ state */
118 SideInfoIndices *psIndices, /* I/O Quantization Indices */
119 const opus_int32 x_Q3[], /* I Prefiltered input signal */
120 opus_int8 pulses[], /* O Quantized pulse signal */
121 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
122 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
123 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
124 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
125 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
126 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
127 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
128 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
129 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
130 const opus_int LTP_scale_Q14 /* I LTP state scaling */
131);
132
133# define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
134 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
135 ((*SILK_NSQ_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
136 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
137
138#endif
139
140# define OVERRIDE_silk_NSQ_del_dec
141
142void silk_NSQ_del_dec_sse4_1(
143 const silk_encoder_state *psEncC, /* I Encoder State */
144 silk_nsq_state *NSQ, /* I/O NSQ state */
145 SideInfoIndices *psIndices, /* I/O Quantization Indices */
146 const opus_int32 x_Q3[], /* I Prefiltered input signal */
147 opus_int8 pulses[], /* O Quantized pulse signal */
148 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
149 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
150 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
151 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
152 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
153 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
154 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
155 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
156 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
157 const opus_int LTP_scale_Q14 /* I LTP state scaling */
158);
159
160#if defined OPUS_X86_PRESUME_SSE4_1
161
162#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
163 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
164 ((void)(arch),silk_NSQ_del_dec_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
165 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
166
167#else
168
169extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
170 const silk_encoder_state *psEncC, /* I Encoder State */
171 silk_nsq_state *NSQ, /* I/O NSQ state */
172 SideInfoIndices *psIndices, /* I/O Quantization Indices */
173 const opus_int32 x_Q3[], /* I Prefiltered input signal */
174 opus_int8 pulses[], /* O Quantized pulse signal */
175 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
176 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
177 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
178 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
179 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
180 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
181 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
182 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
183 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
184 const opus_int LTP_scale_Q14 /* I LTP state scaling */
185);
186
187# define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
188 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
189 ((*SILK_NSQ_DEL_DEC_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
190 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
191
192#endif
193#endif
194
195void silk_noise_shape_quantizer(
196 silk_nsq_state *NSQ, /* I/O NSQ state */
197 opus_int signalType, /* I Signal type */
198 const opus_int32 x_sc_Q10[], /* I */
199 opus_int8 pulses[], /* O */
200 opus_int16 xq[], /* O */
201 opus_int32 sLTP_Q15[], /* I/O LTP state */
202 const opus_int16 a_Q12[], /* I Short term prediction coefs */
203 const opus_int16 b_Q14[], /* I Long term prediction coefs */
204 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
205 opus_int lag, /* I Pitch lag */
206 opus_int32 HarmShapeFIRPacked_Q14, /* I */
207 opus_int Tilt_Q14, /* I Spectral tilt */
208 opus_int32 LF_shp_Q14, /* I */
209 opus_int32 Gain_Q16, /* I */
210 opus_int Lambda_Q10, /* I */
211 opus_int offset_Q10, /* I */
212 opus_int length, /* I Input length */
213 opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
214 opus_int predictLPCOrder, /* I Prediction filter order */
215 int arch /* I Architecture */
216);
217
218/**************************/
219/* Noise level estimation */
220/**************************/
221void silk_VAD_GetNoiseLevels(
222 const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */
223 silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
224);
225
226# define OVERRIDE_silk_VAD_GetSA_Q8
227
228opus_int silk_VAD_GetSA_Q8_sse4_1(
229 silk_encoder_state *psEnC,
230 const opus_int16 pIn[]
231);
232
233#if defined(OPUS_X86_PRESUME_SSE4_1)
234#define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_sse4_1(psEnC, pIn))
235
236#else
237
238# define silk_VAD_GetSA_Q8(psEnC, pIn, arch) \
239 ((*SILK_VAD_GETSA_Q8_IMPL[(arch) & OPUS_ARCHMASK])(psEnC, pIn))
240
241extern opus_int (*const SILK_VAD_GETSA_Q8_IMPL[OPUS_ARCHMASK + 1])(
242 silk_encoder_state *psEnC,
243 const opus_int16 pIn[]);
244
245#endif
246
247# endif
248#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c b/lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c
new file mode 100644
index 0000000000..32dcc3cab7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c
@@ -0,0 +1,164 @@
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#if defined(HAVE_CONFIG_H)
29#include "config.h"
30#endif
31
32#include "celt/x86/x86cpu.h"
33#include "structs.h"
34#include "SigProc_FIX.h"
35#include "pitch.h"
36#include "main.h"
37
38#if !defined(OPUS_X86_PRESUME_SSE4_1)
39
40#if defined(FIXED_POINT)
41
42#include "fixed/main_FIX.h"
43
44opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[ OPUS_ARCHMASK + 1 ] )(
45 const opus_int16 *inVec1,
46 const opus_int16 *inVec2,
47 const opus_int len
48) = {
49 silk_inner_prod16_aligned_64_c, /* non-sse */
50 silk_inner_prod16_aligned_64_c,
51 silk_inner_prod16_aligned_64_c,
52 MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ), /* sse4.1 */
53 MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ) /* avx */
54};
55
56#endif
57
58opus_int (*const SILK_VAD_GETSA_Q8_IMPL[ OPUS_ARCHMASK + 1 ] )(
59 silk_encoder_state *psEncC,
60 const opus_int16 pIn[]
61) = {
62 silk_VAD_GetSA_Q8_c, /* non-sse */
63 silk_VAD_GetSA_Q8_c,
64 silk_VAD_GetSA_Q8_c,
65 MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ), /* sse4.1 */
66 MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ) /* avx */
67};
68
69#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
70void (*const SILK_NSQ_IMPL[ OPUS_ARCHMASK + 1 ] )(
71 const silk_encoder_state *psEncC, /* I Encoder State */
72 silk_nsq_state *NSQ, /* I/O NSQ state */
73 SideInfoIndices *psIndices, /* I/O Quantization Indices */
74 const opus_int32 x_Q3[], /* I Prefiltered input signal */
75 opus_int8 pulses[], /* O Quantized pulse signal */
76 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
77 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
78 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
79 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
80 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
81 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
82 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
83 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
84 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
85 const opus_int LTP_scale_Q14 /* I LTP state scaling */
86) = {
87 silk_NSQ_c, /* non-sse */
88 silk_NSQ_c,
89 silk_NSQ_c,
90 MAY_HAVE_SSE4_1( silk_NSQ ), /* sse4.1 */
91 MAY_HAVE_SSE4_1( silk_NSQ ) /* avx */
92};
93#endif
94
95#if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */
96void (*const SILK_VQ_WMAT_EC_IMPL[ OPUS_ARCHMASK + 1 ] )(
97 opus_int8 *ind, /* O index of best codebook vector */
98 opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
99 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
100 const opus_int16 *in_Q14, /* I input vector to be quantized */
101 const opus_int32 *W_Q18, /* I weighting matrix */
102 const opus_int8 *cb_Q7, /* I codebook */
103 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
104 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
105 const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
106 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
107 opus_int L /* I number of vectors in codebook */
108) = {
109 silk_VQ_WMat_EC_c, /* non-sse */
110 silk_VQ_WMat_EC_c,
111 silk_VQ_WMat_EC_c,
112 MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ), /* sse4.1 */
113 MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ) /* avx */
114};
115#endif
116
117#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
118void (*const SILK_NSQ_DEL_DEC_IMPL[ OPUS_ARCHMASK + 1 ] )(
119 const silk_encoder_state *psEncC, /* I Encoder State */
120 silk_nsq_state *NSQ, /* I/O NSQ state */
121 SideInfoIndices *psIndices, /* I/O Quantization Indices */
122 const opus_int32 x_Q3[], /* I Prefiltered input signal */
123 opus_int8 pulses[], /* O Quantized pulse signal */
124 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
125 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
126 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
127 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
128 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
129 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
130 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
131 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
132 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
133 const opus_int LTP_scale_Q14 /* I LTP state scaling */
134) = {
135 silk_NSQ_del_dec_c, /* non-sse */
136 silk_NSQ_del_dec_c,
137 silk_NSQ_del_dec_c,
138 MAY_HAVE_SSE4_1( silk_NSQ_del_dec ), /* sse4.1 */
139 MAY_HAVE_SSE4_1( silk_NSQ_del_dec ) /* avx */
140};
141#endif
142
143#if defined(FIXED_POINT)
144
145void (*const SILK_BURG_MODIFIED_IMPL[ OPUS_ARCHMASK + 1 ] )(
146 opus_int32 *res_nrg, /* O Residual energy */
147 opus_int *res_nrg_Q, /* O Residual energy Q value */
148 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
149 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
150 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
151 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
152 const opus_int nb_subfr, /* I Number of subframes stacked in x */
153 const opus_int D, /* I Order */
154 int arch /* I Run-time architecture */
155) = {
156 silk_burg_modified_c, /* non-sse */
157 silk_burg_modified_c,
158 silk_burg_modified_c,
159 MAY_HAVE_SSE4_1( silk_burg_modified ), /* sse4.1 */
160 MAY_HAVE_SSE4_1( silk_burg_modified ) /* avx */
161};
162
163#endif
164#endif