Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 :
38 : #include <stdint.h>
39 : #include "options.h"
40 : #include <math.h>
41 : #include "cnst.h"
42 : #include "prot_fx.h"
43 : #include "rom_com.h"
44 : #include "wmc_auto.h"
45 : #include "stl.h"
46 :
47 : /*--------------------------------------------------------------------------*
48 : * Local constants
49 : *--------------------------------------------------------------------------*/
50 :
51 : #define ENV_STAB_SMO_HO 10 /* number of hangover frames when switching from music to speech state */
52 :
53 :
54 : /*--------------------------------------------------------------------------*/
55 : /* Function env_stability() */
56 : /* ~~~~~~~~~~~~~~~~~~~~~~~~~ */
57 : /* */
58 : /* Envelope stability measure */
59 : /*--------------------------------------------------------------------------*/
60 :
61 6607 : Word16 env_stability_fx( /* in Q15 */
62 : const Word16 *ynrm, /*i: Norm vector for current frame */
63 : const Word16 nb_sfm, /*i: Number of sub-bands */
64 : Word16 *mem_norm, /*i/o: Norm vector memory from past frame */
65 : Word16 *mem_env_delta, /*i/o: Envelope stability memory for smoothing in Q12 */
66 : const Word16 core_switching_flag /* i : Core switching flag */
67 : )
68 : {
69 : Word16 env_delta;
70 : Word16 env_stab;
71 : Word16 tmp, tmp_stab;
72 : Word16 i;
73 :
74 : Word16 exp, exp2;
75 : Word32 L_tmp, L_env_delta;
76 : Word16 inv_nb_sfm;
77 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
78 6607 : Flag Overflow = 0;
79 6607 : move32();
80 : #endif
81 :
82 6607 : IF( core_switching_flag )
83 : {
84 5193 : FOR( i = 0; i < nb_sfm; i++ )
85 : {
86 5003 : mem_norm[i] = ynrm[i];
87 5003 : move16();
88 : }
89 190 : Overflow = 0;
90 190 : move16();
91 190 : env_delta = shl_o( *mem_env_delta, 1, &Overflow );
92 : }
93 : ELSE
94 : {
95 : /* Calculate envelope stability parameter */
96 6417 : L_env_delta = L_deposit_l( 0 );
97 174599 : FOR( i = 0; i < nb_sfm; i++ )
98 : {
99 168182 : tmp = sub( mem_norm[i], ynrm[i] );
100 168182 : L_env_delta = L_mac0( L_env_delta, tmp, tmp );
101 168182 : mem_norm[i] = ynrm[i];
102 168182 : move16();
103 : }
104 :
105 6417 : inv_nb_sfm = 19418; /* Q19 */
106 6417 : move16();
107 6417 : if ( nb_sfm == 26 )
108 : {
109 5077 : inv_nb_sfm = 20165; /* Q19 */
110 5077 : move16();
111 : }
112 6417 : exp = norm_l( L_env_delta );
113 6417 : L_env_delta = Mult_32_16( L_shl( L_env_delta, exp ), inv_nb_sfm ); /* 0+exp+19-15 */
114 :
115 6417 : L_tmp = Sqrt_l( L_env_delta, &exp2 ); /* exp+4+31+exp2 */
116 :
117 6417 : exp = add( 35, add( exp, exp2 ) );
118 6417 : if ( EQ_16( s_and( exp, 1 ), 1 ) )
119 : {
120 3120 : L_tmp = Mult_32_16( L_tmp, 23170 ); /* 1/sqrt(2) in Q15 */
121 : }
122 6417 : exp = shr( exp, 1 );
123 :
124 6417 : env_delta = round_fx_sat( L_shl_sat( L_tmp, sub( 26, exp ) ) ); /* Q10 */
125 :
126 6417 : L_tmp = L_mult0( 26214, env_delta ); /* 26214 is 0.1 in Q18. Q28 */
127 6417 : L_tmp = L_mac_sat( L_tmp, 29491, *mem_env_delta ); /* 29491 is 0.9 in Q15. Q28 */
128 :
129 6417 : *mem_env_delta = round_fx_sat( L_tmp ); /* Q12 */
130 6417 : Overflow = 0;
131 6417 : move16();
132 6417 : env_delta = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /* Q13 */
133 : }
134 6607 : IF( Overflow != 0 ) /* Saturated due to the above up-shifting operation. */
135 : {
136 32 : return stab_trans_fx[L_STAB_TBL - 1]; /* The highest quantized index. */
137 : }
138 :
139 : /* If tmp_stab > (D_STAB_TBL*L_STAB_TBL + M_STAB_TBL), i.e., 0.103138*10+2.51757=3.603137,
140 : * the quantized index is equal to 9. Hence, we only need to worry about any tmpStab < 4.
141 : * In this case, Q13 is good enough.
142 : */
143 6575 : tmp_stab = sub( env_delta, M_STAB_TBL_FX ); /* in Q13 */
144 6575 : tmp_stab = abs_s( tmp_stab );
145 :
146 : /* Table lookup for smooth transitions
147 : * First, find the quantization level, i, of tmpStab. */
148 : #if L_STAB_TBL > 10
149 : #error env_stability_fx: Use more efficient usquant()
150 : #endif
151 6575 : tmp_stab = sub( tmp_stab, HALF_D_STAB_TBL_FX ); /* in Q13 */
152 47623 : FOR( i = 0; i < L_STAB_TBL - 1; i++ )
153 : {
154 44975 : IF( tmp_stab < 0 )
155 : {
156 3927 : BREAK;
157 : }
158 : ELSE
159 : {
160 41048 : tmp_stab = sub( tmp_stab, D_STAB_TBL_FX ); /* in Q13 */
161 : }
162 : }
163 :
164 6575 : env_stab = stab_trans_fx[i];
165 6575 : move16();
166 6575 : if ( LT_16( env_delta, M_STAB_TBL_FX ) )
167 : {
168 5826 : env_stab = sub( 0x7FFF, stab_trans_fx[i] );
169 : }
170 :
171 6575 : return env_stab;
172 : }
173 :
174 : /*--------------------------------------------------------------------------*
175 : * env_stab_smo_fx()
176 : *
177 : *
178 : *--------------------------------------------------------------------------*/
179 :
180 : /*! r: New speech/music state */
181 7838 : Word16 env_stab_smo_fx( /* Q0 */
182 : Word16 env_stab, /*i : env_stab value Q15 */
183 : Word16 *env_stab_state_p, /*i/o: env_stab state probabilities Q15 */
184 : Word16 *ho_cnt /*i/o: hangover counter for speech state */
185 : )
186 : {
187 : Word16 state, prev_state;
188 : Word16 maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
189 : Word16 i;
190 : Word16 tmp, sum, exp;
191 : #ifndef ISSUE_1836_replace_overflow_libcom
192 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
193 : Flag Overflow = 0;
194 : move32();
195 : #endif
196 : #endif
197 : /* get previous state */
198 7838 : prev_state = maximum_fx( env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval );
199 :
200 : /* assume two states: speech(0), music(1) */
201 : /* set a posteriori likelihoods for the two states according to env_stab */
202 : /* re-scale. Unclear if needed */
203 : /* env_stab = (env_stab - stab_trans_fx[L_STAB_TBL-1])/(1-2*stab_trans_fx[L_STAB_TBL-1]); */
204 7838 : tmp = sub( env_stab, stab_trans_fx[L_STAB_TBL - 1] );
205 7838 : tmp = round_fx( L_shl( L_mult( tmp, INV_STAB_TRANS_FX ), 1 ) ); /* Q15 */
206 :
207 7838 : pp[0] = sub( 32767, tmp );
208 7838 : move16(); /* 1 in Q15 */
209 7838 : pp[1] = tmp;
210 7838 : move16();
211 :
212 : /* calculate a priori likelihoods */
213 7838 : pa[0] = round_fx( Dot_product( env_stab_tp_fx[0], env_stab_state_p, NUM_ENV_STAB_PLC_STATES ) ); /* Q15*/
214 7838 : pa[1] = round_fx( Dot_product( env_stab_tp_fx[1], env_stab_state_p, NUM_ENV_STAB_PLC_STATES ) );
215 :
216 : /* multiply elementwise with a posteriori likelihoods */
217 7838 : sum = 0;
218 7838 : move16();
219 23514 : FOR( i = 0; i < NUM_ENV_STAB_PLC_STATES; i++ )
220 : {
221 15676 : env_stab_state_p[i] = mult_r( pa[i], pp[i] );
222 15676 : move16(); /* Q15 */
223 15676 : sum = add( sum, env_stab_state_p[i] );
224 : }
225 :
226 : /* renormalize state probabilities */
227 7838 : exp = norm_s( sum );
228 7838 : tmp = div_s( 16384, shl( sum, exp ) ); /* Q(14-exp) */
229 : /*tmp = shl(tmp, add(exp, 1));*/ /* Q15 */
230 23514 : FOR( i = 0; i < NUM_ENV_STAB_PLC_STATES; i++ )
231 : {
232 : #ifdef ISSUE_1836_replace_overflow_libcom
233 15676 : env_stab_state_p[i] = round_fx_sat( L_shl_sat( L_mult_sat( env_stab_state_p[i], tmp ), add( exp, 1 ) ) ); /* Q15 */
234 : #else
235 : env_stab_state_p[i] = round_fx_o( L_shl_o( L_mult_o( env_stab_state_p[i], tmp, &Overflow ), add( exp, 1 ), &Overflow ), &Overflow ); /* Q15 */
236 : #endif
237 15676 : move16();
238 : }
239 :
240 : /* find maximum index as return value */
241 7838 : state = maximum_fx( env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval );
242 :
243 : /* apply some hangover for speech */
244 7838 : test();
245 7838 : if ( state == 0 && EQ_16( prev_state, 1 ) )
246 : {
247 144 : *ho_cnt = ENV_STAB_SMO_HO;
248 144 : move16();
249 : }
250 :
251 7838 : IF( *ho_cnt > 0 )
252 : {
253 1257 : *ho_cnt = sub( *ho_cnt, 1 );
254 1257 : move16();
255 : }
256 :
257 7838 : return state;
258 : }
|