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 : * Local constants
48 : *--------------------------------------------------------------------------*/
49 :
50 : #define ENV_STAB_SMO_HO 10 /* number of hangover frames when switching from music to speech state */
51 :
52 :
53 : /*--------------------------------------------------------------------------*/
54 : /* Function env_stability() */
55 : /* ~~~~~~~~~~~~~~~~~~~~~~~~~ */
56 : /* */
57 : /* Envelope stability measure */
58 : /*--------------------------------------------------------------------------*/
59 :
60 6499 : Word16 env_stability_fx( /* in Q15 */
61 : const Word16 *ynrm, /*i: Norm vector for current frame */
62 : const Word16 nb_sfm, /*i: Number of sub-bands */
63 : Word16 *mem_norm, /*i/o: Norm vector memory from past frame */
64 : Word16 *mem_env_delta, /*i/o: Envelope stability memory for smoothing in Q12 */
65 : const Word16 core_switching_flag /* i : Core switching flag */
66 : )
67 : {
68 : Word16 env_delta;
69 : Word16 env_stab;
70 : Word16 tmp, tmp_stab;
71 : Word16 i;
72 :
73 : Word16 exp, exp2;
74 : Word32 L_tmp, L_env_delta;
75 : Word16 inv_nb_sfm;
76 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
77 6499 : Flag Overflow = 0;
78 6499 : move32();
79 : #endif
80 :
81 6499 : IF( core_switching_flag )
82 : {
83 5058 : FOR( i = 0; i < nb_sfm; i++ )
84 : {
85 4873 : mem_norm[i] = ynrm[i];
86 4873 : move16();
87 : }
88 185 : Overflow = 0;
89 185 : move16();
90 185 : env_delta = shl_o( *mem_env_delta, 1, &Overflow );
91 : }
92 : ELSE
93 : {
94 : /* Calculate envelope stability parameter */
95 6314 : L_env_delta = L_deposit_l( 0 );
96 171782 : FOR( i = 0; i < nb_sfm; i++ )
97 : {
98 165468 : tmp = sub( mem_norm[i], ynrm[i] );
99 165468 : L_env_delta = L_mac0( L_env_delta, tmp, tmp );
100 165468 : mem_norm[i] = ynrm[i];
101 165468 : move16();
102 : }
103 :
104 6314 : inv_nb_sfm = 19418; /* Q19 */
105 6314 : move16();
106 6314 : if ( nb_sfm == 26 )
107 : {
108 5010 : inv_nb_sfm = 20165; /* Q19 */
109 5010 : move16();
110 : }
111 6314 : exp = norm_l( L_env_delta );
112 6314 : L_env_delta = Mult_32_16( L_shl( L_env_delta, exp ), inv_nb_sfm ); /* 0+exp+19-15 */
113 :
114 6314 : L_tmp = Sqrt_l( L_env_delta, &exp2 ); /* exp+4+31+exp2 */
115 :
116 6314 : exp = add( 35, add( exp, exp2 ) );
117 6314 : if ( EQ_16( s_and( exp, 1 ), 1 ) )
118 : {
119 3073 : L_tmp = Mult_32_16( L_tmp, 23170 ); /* 1/sqrt(2) in Q15 */
120 : }
121 6314 : exp = shr( exp, 1 );
122 :
123 6314 : env_delta = round_fx_sat( L_shl_sat( L_tmp, sub( 26, exp ) ) ); /* Q10 */
124 :
125 6314 : L_tmp = L_mult0( 26214, env_delta ); /* 26214 is 0.1 in Q18. Q28 */
126 6314 : L_tmp = L_mac_sat( L_tmp, 29491, *mem_env_delta ); /* 29491 is 0.9 in Q15. Q28 */
127 :
128 6314 : *mem_env_delta = round_fx_sat( L_tmp ); /* Q12 */
129 6314 : Overflow = 0;
130 6314 : move16();
131 6314 : env_delta = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /* Q13 */
132 : }
133 6499 : IF( Overflow != 0 ) /* Saturated due to the above up-shifting operation. */
134 : {
135 31 : return stab_trans_fx[L_STAB_TBL - 1]; /* The highest quantized index. */
136 : }
137 :
138 : /* If tmp_stab > (D_STAB_TBL*L_STAB_TBL + M_STAB_TBL), i.e., 0.103138*10+2.51757=3.603137,
139 : * the quantized index is equal to 9. Hence, we only need to worry about any tmpStab < 4.
140 : * In this case, Q13 is good enough.
141 : */
142 6468 : tmp_stab = sub( env_delta, M_STAB_TBL_FX ); /* in Q13 */
143 6468 : tmp_stab = abs_s( tmp_stab );
144 :
145 : /* Table lookup for smooth transitions
146 : * First, find the quantization level, i, of tmpStab. */
147 : #if L_STAB_TBL > 10
148 : #error env_stability_fx: Use more efficient usquant()
149 : #endif
150 6468 : tmp_stab = sub( tmp_stab, HALF_D_STAB_TBL_FX ); /* in Q13 */
151 46972 : FOR( i = 0; i < L_STAB_TBL - 1; i++ )
152 : {
153 44341 : IF( tmp_stab < 0 )
154 : {
155 3837 : BREAK;
156 : }
157 : ELSE
158 : {
159 40504 : tmp_stab = sub( tmp_stab, D_STAB_TBL_FX ); /* in Q13 */
160 : }
161 : }
162 :
163 6468 : env_stab = stab_trans_fx[i];
164 6468 : move16();
165 6468 : if ( LT_16( env_delta, M_STAB_TBL_FX ) )
166 : {
167 5755 : env_stab = sub( 0x7FFF, stab_trans_fx[i] );
168 : }
169 :
170 6468 : return env_stab;
171 : }
172 :
173 : /*--------------------------------------------------------------------------*
174 : * env_stab_smo_fx()
175 : *
176 : *
177 : *--------------------------------------------------------------------------*/
178 :
179 : /*! r: New speech/music state */
180 7728 : Word16 env_stab_smo_fx( /* Q0 */
181 : Word16 env_stab, /*i : env_stab value Q15 */
182 : Word16 *env_stab_state_p, /*i/o: env_stab state probabilities Q15 */
183 : Word16 *ho_cnt /*i/o: hangover counter for speech state */
184 : )
185 : {
186 : Word16 state, prev_state;
187 : Word16 maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
188 : Word16 i;
189 : Word16 tmp, sum, exp;
190 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
191 7728 : Flag Overflow = 0;
192 7728 : move32();
193 : #endif
194 : /* get previous state */
195 7728 : prev_state = maximum_fx( env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval );
196 :
197 : /* assume two states: speech(0), music(1) */
198 : /* set a posteriori likelihoods for the two states according to env_stab */
199 : /* re-scale. Unclear if needed */
200 : /* env_stab = (env_stab - stab_trans_fx[L_STAB_TBL-1])/(1-2*stab_trans_fx[L_STAB_TBL-1]); */
201 7728 : tmp = sub( env_stab, stab_trans_fx[L_STAB_TBL - 1] );
202 7728 : tmp = round_fx( L_shl( L_mult( tmp, INV_STAB_TRANS_FX ), 1 ) ); /* Q15 */
203 :
204 7728 : pp[0] = sub( 32767, tmp );
205 7728 : move16(); /* 1 in Q15 */
206 7728 : pp[1] = tmp;
207 7728 : move16();
208 :
209 : /* calculate a priori likelihoods */
210 7728 : pa[0] = round_fx( Dot_product( env_stab_tp_fx[0], env_stab_state_p, NUM_ENV_STAB_PLC_STATES ) ); /* Q15*/
211 7728 : pa[1] = round_fx( Dot_product( env_stab_tp_fx[1], env_stab_state_p, NUM_ENV_STAB_PLC_STATES ) );
212 :
213 : /* multiply elementwise with a posteriori likelihoods */
214 7728 : sum = 0;
215 7728 : move16();
216 23184 : FOR( i = 0; i < NUM_ENV_STAB_PLC_STATES; i++ )
217 : {
218 15456 : env_stab_state_p[i] = mult_r( pa[i], pp[i] );
219 15456 : move16(); /* Q15 */
220 15456 : sum = add( sum, env_stab_state_p[i] );
221 : }
222 :
223 : /* renormalize state probabilities */
224 7728 : exp = norm_s( sum );
225 7728 : tmp = div_s( 16384, shl( sum, exp ) ); /* Q(14-exp) */
226 : /*tmp = shl(tmp, add(exp, 1));*/ /* Q15 */
227 23184 : FOR( i = 0; i < NUM_ENV_STAB_PLC_STATES; i++ )
228 : {
229 15456 : 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 */
230 15456 : move16();
231 : }
232 :
233 : /* find maximum index as return value */
234 7728 : state = maximum_fx( env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval );
235 :
236 : /* apply some hangover for speech */
237 7728 : test();
238 7728 : if ( state == 0 && EQ_16( prev_state, 1 ) )
239 : {
240 143 : *ho_cnt = ENV_STAB_SMO_HO;
241 143 : move16();
242 : }
243 :
244 7728 : IF( *ho_cnt > 0 )
245 : {
246 1246 : *ho_cnt = sub( *ho_cnt, 1 );
247 1246 : move16();
248 : }
249 :
250 7728 : return state;
251 : }
|