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 : #include <stdint.h>
34 : #include "options.h" /* Compilation switches */
35 : #include "prot_fx.h" /* Function prototypes */
36 : #include "rom_com.h" /* Static table prototypes */
37 : #include "cnst.h" /* Common constants */
38 : #include <math.h>
39 : /*--------------------------------------------------------------------------*
40 : * Local constants
41 : *--------------------------------------------------------------------------*/
42 :
43 : #define THREN2POW 1518500250L
44 :
45 : /*--------------------------------------------------------------------------*
46 : * logqnorm_fx
47 : *
48 : * Log quantization for norms of sub-vectors
49 : *--------------------------------------------------------------------------*/
50 257249 : void logqnorm_ivas_fx(
51 : const Word32 *x_fx, /* i : coefficient vector Qq*/
52 : const Word16 q, /* i : q of coefficient vector */
53 : Word16 *k_fx, /* o : index (Q0)*/
54 : const Word16 L, /* i : codebook length */
55 : const Word16 N, /* i : sub-vector size */
56 : const Word32 *thre_fxn /* i : quantization thresholds Q14*/
57 : )
58 : {
59 : Word16 i, j, j1, j2;
60 : Word64 temp_fx;
61 : Word32 temp32_fx;
62 : Word32 power_fx;
63 : Word64 thren0_sqr, threnL2_sqr;
64 : Word32 thren0_sqr32, threnL2_sqr32;
65 : Word16 thren0_sqr32_e, threnL2_sqr32_e;
66 257249 : temp_fx = 0;
67 257249 : move64();
68 : Word32 result1, result2;
69 : Word16 result1_e, result2_e;
70 257249 : Word16 gd_bits = find_guarded_bits_fx( N );
71 4599815 : FOR( i = 0; i < N; i++ )
72 : {
73 4342566 : temp_fx = W_add( W_shr( W_mult0_32_32( x_fx[i], x_fx[i] ), gd_bits ), temp_fx ); // 2*qin-gd_bits
74 : }
75 257249 : Word16 l_shift = W_norm( temp_fx );
76 257249 : temp32_fx = W_extract_h( W_shl( temp_fx, l_shift ) ); // 2*qin-gd_bits + l_shift -32
77 257249 : Word16 temp_e = sub( 31, ( sub( add( sub( shl( q, 1 ), gd_bits ), l_shift ), 32 ) ) );
78 : /* sqrt will be done later */
79 : // temp *= inv_tbl[N];
80 257249 : temp32_fx = Mpy_32_16_1( temp32_fx, inv_tbl_fx[N] ); // temp_e
81 257249 : thren0_sqr = W_mult0_32_32( thre_fxn[0], thre_fxn[0] ); // Q28
82 257249 : threnL2_sqr = W_mult0_32_32( thre_fxn[L - 2], thre_fxn[L - 2] ); // Q28
83 257249 : l_shift = W_norm( thren0_sqr );
84 257249 : thren0_sqr32 = W_extract_h( W_shl( thren0_sqr, l_shift ) ); // Q28 + l_shift - 32
85 257249 : thren0_sqr32_e = sub( 31, sub( add( Q28, l_shift ), 32 ) );
86 257249 : l_shift = W_norm( threnL2_sqr );
87 257249 : threnL2_sqr32 = W_extract_h( W_shl( threnL2_sqr, l_shift ) ); // Q28 + l_shift - 32
88 257249 : threnL2_sqr32_e = sub( 31, sub( add( Q28, l_shift ), 32 ) );
89 257249 : result1 = BASOP_Util_Add_Mant32Exp( thren0_sqr32, thren0_sqr32_e, L_negate( temp32_fx ), temp_e, &result1_e );
90 257249 : result2 = BASOP_Util_Add_Mant32Exp( threnL2_sqr32, threnL2_sqr32_e, L_negate( temp32_fx ), temp_e, &result2_e );
91 :
92 257249 : IF( result1 <= 0 )
93 : {
94 0 : *k_fx = 0;
95 0 : move16();
96 : }
97 257249 : ELSE IF( result2 > 0 )
98 : {
99 1164 : *k_fx = sub( L, 1 );
100 1164 : move16();
101 : }
102 : ELSE
103 : {
104 256085 : Word16 e = 0;
105 256085 : move16();
106 256085 : power_fx = Sqrt32( ONE_IN_Q31, &e );
107 256085 : power_fx = Sqrt32( temp32_fx, &temp_e ); // Q31-temp_e
108 : // power_fx = L_shr( power_fx , Q14-(31-temp_e));
109 256085 : j1 = 0;
110 256085 : move16();
111 256085 : j2 = sub( L, 1 );
112 256085 : move16();
113 1635941 : WHILE( GT_16( sub( j2, j1 ), 1 ) )
114 : {
115 1379856 : j = shr( add( j1, j2 ), 1 );
116 1379856 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( power_fx, temp_e, thre_fxn[j], Q31 - Q14 );
117 1379856 : IF( flag >= 0 )
118 : {
119 602935 : j2 = j;
120 602935 : move16();
121 : }
122 : ELSE
123 : {
124 776921 : j1 = j;
125 776921 : move16();
126 : }
127 : }
128 :
129 256085 : *k_fx = j2;
130 256085 : move16();
131 : }
132 257249 : return;
133 : }
134 139692 : void logqnorm_fx(
135 : const Word32 *L_x, /* i : coefficient vector Qx */
136 : const Word16 qx, /* i : Q value of input */
137 : Word16 *k, /* o : index Q0 */
138 : const Word16 L, /* i : codebook length Q0 */
139 : const Word16 N, /* i : sub-vector size Q0 */
140 : const Word16 hvq_flag /* i : HVQ flag Q0 */
141 : )
142 : {
143 : Word16 i, m;
144 : Word16 coefs_shift, power_shift, temp_shift;
145 : Word32 L_temp, L_temp1, L_temp2;
146 : Word16 coefs16[MAX_SFM_LEN_FX];
147 : UWord16 lsb;
148 :
149 139692 : Word16 offset = add( 3, shl( qx, 1 ) ); /* 3 + 2*qx */
150 :
151 139692 : lsb = 0U; /* to avoid compilation warnings */
152 139692 : move16();
153 :
154 139692 : L_temp1 = L_deposit_l( 1 );
155 2565833 : FOR( i = 0; i < N; i++ )
156 : {
157 2426141 : L_temp2 = L_abs( L_x[i] );
158 2426141 : L_temp1 = L_max( L_temp1, L_temp2 );
159 : }
160 139692 : coefs_shift = sub( norm_l( L_temp1 ), sqac_headroom_fx[N] );
161 139692 : L_temp = L_deposit_l( 0 );
162 :
163 2565833 : FOR( i = 0; i < N; i++ )
164 : {
165 2426141 : coefs16[i] = extract_h( L_shl( L_x[i], coefs_shift ) ); // Qx + coefs_shift - 16
166 2426141 : move16();
167 2426141 : L_temp = L_mac0( L_temp, coefs16[i], coefs16[i] ); // 2*(Qx + coefs_shift - 16)
168 : }
169 :
170 139692 : IF( GT_16( N, 1 ) )
171 : {
172 136847 : Mpy_32_16_ss( L_temp, inv_tbl_fx[N], &L_temp, &lsb ); // 2*(Qx + coefs_shift - 16)
173 : }
174 139692 : power_shift = shl( sub( coefs_shift, 16 ), 1 );
175 :
176 139692 : temp_shift = norm_l( L_temp );
177 139692 : m = add( temp_shift, power_shift );
178 :
179 139692 : L_temp1 = L_add( L_shl( L_temp, temp_shift ), L_shr( lsb, sub( 16, temp_shift ) ) ); // 2*(Qx + coefs_shift - 16)+ temp_shift
180 :
181 139692 : m = add( offset, m );
182 139692 : test();
183 139692 : IF( LT_16( m, 5 ) && hvq_flag )
184 : {
185 0 : m = shl( m, 1 );
186 0 : IF( LT_32( L_temp1, 1276901417L /* 2^0.25 Q30 */ ) )
187 : {
188 0 : m = add( m, 2 );
189 : }
190 0 : ELSE IF( LT_32( L_temp1, 1805811301L /* 2^0.75 Q30 */ ) )
191 : {
192 0 : m = add( m, 1 );
193 : }
194 : }
195 : ELSE
196 : {
197 139692 : if ( LT_32( L_temp1, THREN2POW /* 2^0.5 Q30 */ ) )
198 : {
199 69564 : m = add( m, 1 );
200 : }
201 139692 : if ( hvq_flag )
202 : {
203 0 : m = add( m, 5 ); /* offset, 5 extra levels in HVQ codebook */
204 : }
205 : }
206 139692 : *k = s_max( m, 0 );
207 139692 : move16();
208 139692 : i = sub( L, 1 );
209 139692 : *k = s_min( *k, i );
210 139692 : move16();
211 :
212 139692 : return;
213 : }
214 :
215 5626 : void logqnorm_2_fx(
216 : const Word32 *env_fl, /* o, Q10 : index */
217 : const Word16 L, /* i : codebook length */
218 : const Word16 n_env_band, /* i : sub-vector size */
219 : const Word16 nb_sfm, /* i : sub-vector size */
220 : Word16 *ynrm, /* o : norm indices Q0*/
221 : Word16 *normqlg2, /* o : quantized norm values Q0*/
222 : const Word32 *thren /* i, Q10 : quantization thresholds */
223 : )
224 : {
225 : Word16 i, j, j1, j2;
226 : Word32 temp, power;
227 :
228 94513 : FOR( i = n_env_band; i < nb_sfm; i++ )
229 : {
230 88887 : temp = env_fl[sub( i, n_env_band )];
231 88887 : IF( LE_32( thren[0], temp ) )
232 : {
233 0 : *ynrm = 0;
234 0 : move16();
235 : }
236 88887 : ELSE IF( GT_32( thren[sub( L, 2 )], temp ) )
237 : {
238 8833 : *ynrm = sub( L, 1 );
239 8833 : move16();
240 : }
241 : ELSE
242 : {
243 80054 : power = temp;
244 80054 : move16();
245 80054 : j1 = 0;
246 80054 : move16();
247 80054 : j2 = sub( L, 1 );
248 511060 : WHILE( GT_16( sub( j2, j1 ), 1 ) )
249 : {
250 431006 : j = shr( add( j1, j2 ), 1 );
251 431006 : IF( GE_32( power, thren[j] ) )
252 : {
253 166551 : j2 = j;
254 166551 : move16();
255 : }
256 : ELSE
257 : {
258 264455 : j1 = j;
259 264455 : move16();
260 : }
261 : }
262 80054 : *ynrm = j2;
263 80054 : move16();
264 : }
265 88887 : *normqlg2 = dicnlg2[*ynrm];
266 88887 : move16();
267 88887 : normqlg2++;
268 88887 : ynrm++;
269 : }
270 :
271 5626 : return;
272 : }
273 :
274 : /*--------------------------------------------------------------------------
275 : * calc_norm_fx()
276 : *
277 : * Calculate the norms for the spectral envelope
278 : *--------------------------------------------------------------------------*/
279 7815 : void calc_norm_ivas_fx(
280 : const Word32 *x_fx, /* i : Input vector.(Qin) */
281 : Word16 *norm, /* o : Quantization indices for norms Q0 */
282 : Word16 *normlg, /* o : Quantized norms in log2 Q0 */
283 : const Word16 start_band, /* i : Indice of band to start coding */
284 : const Word16 num_bands, /* i : Number of bands */
285 : const Word16 *band_len, /* i : Length of bands */
286 : const Word16 *band_start /* i : Start of bands */
287 : )
288 : {
289 : Word16 nrm;
290 : Word16 band;
291 : Word16 tmp;
292 :
293 7815 : set16_fx( norm, 0, start_band );
294 7815 : logqnorm_ivas_fx( &x_fx[band_start[start_band]], 12, &nrm, 32, band_len[start_band], thren_HQ_fx );
295 7815 : norm[start_band] = nrm;
296 7815 : move16();
297 7815 : normlg[start_band] = dicnlg2[nrm];
298 7815 : move16();
299 :
300 7815 : tmp = add( start_band, num_bands );
301 226494 : FOR( band = add( start_band, 1 ); band < tmp; band++ )
302 : {
303 218679 : logqnorm_ivas_fx( &x_fx[band_start[band]], 12, &nrm, 40, band_len[band], thren_HQ_fx );
304 218679 : norm[band] = nrm;
305 218679 : move16();
306 218679 : normlg[band] = dicnlg2[nrm]; // Q0
307 218679 : move16();
308 : }
309 :
310 7815 : return;
311 : }
312 :
313 3207 : void calc_norm_fx(
314 : const Word32 *L_x, /* i : Input vector. Qx */
315 : const Word16 qx, /* i : Q value of input */
316 : Word16 *norm, /* o : Quantization indices for norms Q0 */
317 : Word16 *normlg, /* o : Quantized norms in log2 Q0 */
318 : const Word16 start_band, /* i : Indice of band to start coding Q0 */
319 : const Word16 num_bands, /* i : Number of bands Q0 */
320 : const Word16 *band_len, /* i : Length of bands Q0 */
321 : const Word16 *band_start /* i : Start of bands Q0 */
322 : )
323 : {
324 : Word16 nrm;
325 : Word16 band;
326 : Word16 tmp;
327 :
328 3207 : set16_fx( norm, 0, start_band );
329 3207 : logqnorm_fx( &L_x[band_start[start_band]], qx, &nrm, 32, band_len[start_band], 0 );
330 3207 : norm[start_band] = nrm;
331 3207 : move16();
332 3207 : normlg[start_band] = dicnlg2[nrm];
333 3207 : move16();
334 :
335 3207 : tmp = add( start_band, num_bands );
336 135618 : FOR( band = add( start_band, 1 ); band < tmp; band++ )
337 : {
338 132411 : logqnorm_fx( &L_x[band_start[band]], qx, &nrm, 40, band_len[band], 0 );
339 :
340 132411 : norm[band] = nrm;
341 132411 : move16();
342 132411 : normlg[band] = dicnlg2[nrm];
343 132411 : move16();
344 : }
345 :
346 3207 : return;
347 : }
|