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 : #include <stdint.h>
38 : #include "options.h"
39 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include <math.h>
43 : #include "cnst.h"
44 : #include "prot.h"
45 : #include "rom_com.h"
46 : #include "wmc_auto.h"
47 : #include "stl.h"
48 : #ifdef DEBUGGING
49 : #include "assert.h"
50 : #endif
51 :
52 : /*--------------------------------------------------------------------------*
53 : * Local constants
54 : *--------------------------------------------------------------------------*/
55 :
56 : #define ENV_STAB_SMO_HO 10 /* number of hangover frames when switching from music to speech state */
57 :
58 :
59 : /*--------------------------------------------------------------------------*/
60 : /* Function env_stability() */
61 : /* ~~~~~~~~~~~~~~~~~~~~~~~~~ */
62 : /* */
63 : /* Envelope stability measure */
64 : /*--------------------------------------------------------------------------*/
65 :
66 20838 : float env_stability(
67 : const int16_t *ynrm, /* i : Norm vector for current frame */
68 : const int16_t nb_sfm, /* i : Number of sub-bands */
69 : int16_t *mem_norm, /* i/o: Norm vector memory from past frame */
70 : int16_t *mem_env_delta, /* i/o: Envelope stability memory for smoothing*/
71 : const int16_t core_switching_flag /* i : Core switching flag */
72 : )
73 : {
74 : Word16 env_delta;
75 : Word16 env_stab;
76 : Word16 tmp, tmp_stab;
77 : Word16 i;
78 :
79 : Word16 exp, exp2;
80 : Word32 L_tmp, L_env_delta;
81 : Word16 inv_nb_sfm;
82 : float env_stab_f;
83 : #ifdef BASOP_NOGLOB
84 : Flag Overflow;
85 : #endif /* BASOP_NOGLOB */
86 :
87 20838 : if ( core_switching_flag )
88 : {
89 16065 : for ( i = 0; i < nb_sfm; i++ )
90 : {
91 15477 : mem_norm[i] = ynrm[i];
92 : }
93 : #ifdef BASOP_NOGLOB
94 588 : Overflow = 0;
95 588 : env_delta = shl_o( *mem_env_delta, 1, &Overflow );
96 : #else
97 : env_delta = shl( *mem_env_delta, 1 );
98 : #endif
99 : }
100 : else
101 : {
102 : /* Calculate envelope stability parameter */
103 20250 : L_env_delta = L_deposit_l( 0 );
104 550788 : for ( i = 0; i < nb_sfm; i++ )
105 : {
106 530538 : tmp = sub( mem_norm[i], ynrm[i] );
107 530538 : L_env_delta = L_mac0( L_env_delta, tmp, tmp );
108 530538 : mem_norm[i] = ynrm[i];
109 : }
110 :
111 : #ifdef DEBUGGING
112 : assert( nb_sfm == 27 || nb_sfm == 26 );
113 : #endif
114 20250 : inv_nb_sfm = 19418; /* Q19 */
115 20250 : if ( nb_sfm == 26 )
116 : {
117 16212 : inv_nb_sfm = 20165; /* Q19 */
118 : }
119 20250 : exp = norm_l( L_env_delta );
120 20250 : L_env_delta = Mult_32_16( L_shl( L_env_delta, exp ), inv_nb_sfm ); /* 0+exp+19-15 */
121 :
122 20250 : L_tmp = Sqrt_l( L_env_delta, &exp2 ); /* exp+4+31+exp2 */
123 :
124 20250 : exp = add( 35, add( exp, exp2 ) );
125 20250 : if ( sub( s_and( exp, 1 ), 1 ) == 0 )
126 : {
127 9906 : L_tmp = Mult_32_16( L_tmp, 23170 ); /* 1/sqrt(2) in Q15 */
128 : }
129 20250 : exp = shr( exp, 1 );
130 :
131 : #ifndef BASOP_NOGLOB
132 : env_delta = round_fx( L_shl( L_tmp, sub( 26, exp ) ) ); /* Q10 */
133 : L_tmp = L_mult0( 26214, env_delta ); /* 26214 is 0.1 in Q18. Q28 */
134 : L_tmp = L_mac( L_tmp, 29491, *mem_env_delta ); /* 29491 is 0.9 in Q15. Q28 */
135 : *mem_env_delta = round_fx( L_tmp ); /* Q12 */
136 : #else /* BASOP_NOGLOB */
137 20250 : env_delta = round_fx_o( L_shl_o( L_tmp, sub( 26, exp ), &Overflow ), &Overflow ); /* Q10 */
138 20250 : L_tmp = L_mult0( 26214, env_delta ); /* 26214 is 0.1 in Q18. Q28 */
139 20250 : L_tmp = L_mac_o( L_tmp, 29491, *mem_env_delta, &Overflow ); /* 29491 is 0.9 in Q15. Q28 */
140 20250 : *mem_env_delta = round_fx_o( L_tmp, &Overflow ); /* Q12 */
141 : #endif /* BASOP_NOGLOB */
142 20250 : Overflow = 0;
143 : #ifndef BASOP_NOGLOB
144 : env_delta = round_fx( L_shl( L_tmp, 1 ) ); /* Q13 */
145 : #else /* BASOP_NOGLOB */
146 20250 : env_delta = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /* Q13 */
147 : #endif /* BASOP_NOGLOB */
148 : }
149 20838 : if ( Overflow != 0 ) /* Saturated due to the above up-shifting operation. */
150 : {
151 102 : env_stab = stab_trans_fx[L_STAB_TBL - 1]; /* The highest quantized index. */
152 102 : env_stab_f = ( (float) env_stab ) / PCM16_TO_FLT_FAC; /* Convert env_stab(Q15) to float */
153 102 : return env_stab_f;
154 : }
155 :
156 : /* If tmp_stab > (D_STAB_TBL*L_STAB_TBL + M_STAB_TBL), i.e., 0.103138*10+2.51757=3.603137,
157 : * the quantized index is equal to 9. Hence, we only need to worry about any tmpStab < 4.
158 : * In this case, Q13 is good enough.
159 : */
160 20736 : tmp_stab = sub( env_delta, M_STAB_TBL_FX ); /* in Q13 */
161 20736 : tmp_stab = abs_s( tmp_stab );
162 :
163 : /* Table lookup for smooth transitions
164 : * First, find the quantization level, i, of tmpStab. */
165 : #if L_STAB_TBL > 10
166 : #error env_stability_fx: Use more efficient usquant()
167 : #endif
168 20736 : tmp_stab = sub( tmp_stab, HALF_D_STAB_TBL_FX ); /* in Q13 */
169 150189 : for ( i = 0; i < L_STAB_TBL - 1; i++ )
170 : {
171 141873 : if ( tmp_stab < 0 )
172 : {
173 12420 : break;
174 : }
175 : else
176 : {
177 129453 : tmp_stab = sub( tmp_stab, D_STAB_TBL_FX ); /* in Q13 */
178 : }
179 : }
180 :
181 20736 : env_stab = stab_trans_fx[i];
182 20736 : if ( sub( env_delta, M_STAB_TBL_FX ) < 0 )
183 : {
184 18366 : env_stab = sub( 0x7FFF, stab_trans_fx[i] );
185 : }
186 :
187 20736 : env_stab_f = ( (float) env_stab ) / PCM16_TO_FLT_FAC; /* Convert env_stab(Q15) to float */
188 :
189 20736 : return env_stab_f;
190 : }
191 :
192 : /*--------------------------------------------------------------------------*
193 : * env_stab_smo_fx()
194 : *
195 : *
196 : *--------------------------------------------------------------------------*/
197 :
198 : /*! r: New speech/music state */
199 24705 : float env_stab_smo(
200 : float env_stab, /* i : env_stab value */
201 : float *env_stab_state_p, /* i/o: env_stab state probabilities */
202 : int16_t *ho_cnt /* i/o: hangover counter for speech state */
203 : )
204 : {
205 : int16_t state, prev_state;
206 : float maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
207 : /* get previous state */
208 24705 : prev_state = maximum( env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval );
209 :
210 : /* assume two states: speech(0), music(1) */
211 : /* set a posteriori likelihoods for the two states according to env_stab */
212 24705 : env_stab = ( env_stab - stab_trans[L_STAB_TBL - 1] ) / ( 1 - 2 * stab_trans[L_STAB_TBL - 1] );
213 24705 : pp[0] = 1.0f - env_stab;
214 24705 : pp[1] = env_stab;
215 :
216 : /* calculate a priori likelihoods */
217 24705 : pa[0] = dotp( env_stab_tp[0], env_stab_state_p, NUM_ENV_STAB_PLC_STATES );
218 24705 : pa[1] = dotp( env_stab_tp[1], env_stab_state_p, NUM_ENV_STAB_PLC_STATES );
219 :
220 : /* multiply elementwise with a posteriori likelihoods */
221 24705 : v_mult( pa, pp, env_stab_state_p, NUM_ENV_STAB_PLC_STATES );
222 :
223 : /* renormalize state probabilities */
224 24705 : v_multc( env_stab_state_p, 1.0f / sum_f( env_stab_state_p, NUM_ENV_STAB_PLC_STATES ), env_stab_state_p, NUM_ENV_STAB_PLC_STATES );
225 :
226 : /* find maximum index as return value */
227 24705 : state = maximum( env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval );
228 :
229 : /* apply some hangover for speech */
230 24705 : if ( state == 0 && prev_state == 1 )
231 : {
232 435 : *ho_cnt = ENV_STAB_SMO_HO;
233 : }
234 24705 : if ( *ho_cnt > 0 )
235 : {
236 3804 : pp[0] = 1;
237 3804 : pp[1] = 0;
238 3804 : ( *ho_cnt )--;
239 : }
240 :
241 24705 : return state;
242 : }
|