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 <assert.h>
38 : #include <stdint.h>
39 : #include "options.h"
40 : #ifdef DEBUGGING
41 : #include "debug.h"
42 : #endif
43 : #include "cnst.h"
44 : #include "basop_proto_func.h"
45 : #include "stl.h"
46 : #include "prot.h"
47 : #include "rom_com.h"
48 :
49 : #define WMC_TOOL_SKIP
50 :
51 : /* compare two positive normalized 16 bit mantissa/exponent values */
52 : /* return value: positive if first value greater, negative if second value greater, zero if equal */
53 19080154 : static Word16 compMantExp16Unorm( Word16 m1, Word16 e1, Word16 m2, Word16 e2 )
54 : {
55 : Word16 tmp;
56 :
57 19080154 : assert( ( m1 >= 0x4000 ) && ( m2 >= 0x4000 ) ); /* comparisons below work only for normalized mantissas */
58 :
59 19080154 : tmp = sub( e1, e2 );
60 19080154 : if ( tmp == 0 )
61 12825338 : tmp = sub( m1, m2 );
62 :
63 19080154 : return tmp;
64 : }
65 :
66 2244724 : void basop_lpc2mdct( Word16 *lpcCoeffs, Word16 lpcOrder, Word16 *mdct_gains, Word16 *mdct_gains_exp, Word16 *mdct_inv_gains, Word16 *mdct_inv_gains_exp )
67 : {
68 : Word32 RealData[FDNS_NPTS];
69 : Word32 ImagData[FDNS_NPTS];
70 : Word16 i, j, k, step, scale, s, tmp16;
71 : Word16 g, g_e, ig, ig_e;
72 : Word32 tmp32;
73 : const PWord16 *ptwiddle;
74 :
75 :
76 : /* short-cut, to avoid calling of BASOP_getTables() */
77 2244724 : ptwiddle = SineTable512_fx;
78 2244724 : step = 8;
79 :
80 : /*ODFT*/
81 2244724 : assert( lpcOrder < FDNS_NPTS );
82 :
83 : /* pre-twiddle */
84 41527394 : FOR( i = 0; i <= lpcOrder; i++ )
85 : {
86 39282670 : RealData[i] = L_mult( lpcCoeffs[i], ptwiddle->v.re );
87 39282670 : move32();
88 39282670 : ImagData[i] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) );
89 39282670 : move32();
90 39282670 : ptwiddle += step;
91 : }
92 :
93 : /* zero padding */
94 106624390 : FOR( ; i < FDNS_NPTS; i++ )
95 : {
96 104379666 : RealData[i] = 0;
97 104379666 : move32();
98 104379666 : ImagData[i] = 0;
99 104379666 : move32();
100 : }
101 :
102 : /* half length FFT */
103 2244724 : scale = add( norm_s( lpcCoeffs[0] ), 1 );
104 2244724 : move16();
105 2244724 : BASOP_cfft( RealData, ImagData, 1, &scale ); /* sizeOfFft == FDNS_NPTS == 8 */
106 :
107 :
108 : /*Get amplitude*/
109 2244724 : j = FDNS_NPTS - 1;
110 2244724 : k = 0;
111 2244724 : move16();
112 :
113 74075892 : FOR( i = 0; i < FDNS_NPTS / 2; i++ )
114 : {
115 71831168 : s = sub( norm_l( L_max( L_abs( RealData[i] ), L_abs( ImagData[i] ) ) ), 1 );
116 :
117 71831168 : tmp16 = extract_h( L_shl( RealData[i], s ) );
118 71831168 : tmp32 = L_mult( tmp16, tmp16 );
119 :
120 71831168 : tmp16 = extract_h( L_shl( ImagData[i], s ) );
121 71831168 : tmp16 = mac_r( tmp32, tmp16, tmp16 );
122 :
123 71831168 : s = shl( sub( scale, s ), 1 );
124 :
125 71831168 : if ( tmp16 == 0 )
126 : {
127 0 : s = -16;
128 0 : move16();
129 : }
130 71831168 : if ( tmp16 == 0 )
131 : {
132 0 : tmp16 = 1;
133 0 : move16();
134 : }
135 :
136 71831168 : BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
137 :
138 71831168 : if ( mdct_gains != NULL )
139 : {
140 35915584 : mdct_gains[k] = g;
141 35915584 : move16();
142 : }
143 :
144 71831168 : if ( mdct_gains_exp != NULL )
145 : {
146 35915584 : mdct_gains_exp[k] = g_e;
147 35915584 : move16();
148 : }
149 :
150 71831168 : if ( mdct_inv_gains != NULL )
151 : {
152 35915584 : mdct_inv_gains[k] = ig;
153 35915584 : move16();
154 : }
155 :
156 71831168 : if ( mdct_inv_gains_exp != NULL )
157 : {
158 35915584 : mdct_inv_gains_exp[k] = ig_e;
159 35915584 : move16();
160 : }
161 :
162 71831168 : k = add( k, 1 );
163 :
164 :
165 71831168 : s = sub( norm_l( L_max( L_abs( RealData[j] ), L_abs( ImagData[j] ) ) ), 1 );
166 :
167 71831168 : tmp16 = extract_h( L_shl( RealData[j], s ) );
168 71831168 : tmp32 = L_mult( tmp16, tmp16 );
169 :
170 71831168 : tmp16 = extract_h( L_shl( ImagData[j], s ) );
171 71831168 : tmp16 = mac_r( tmp32, tmp16, tmp16 );
172 :
173 71831168 : s = shl( sub( scale, s ), 1 );
174 :
175 71831168 : if ( tmp16 == 0 )
176 : {
177 0 : s = -16;
178 0 : move16();
179 : }
180 71831168 : if ( tmp16 == 0 )
181 : {
182 0 : tmp16 = 1;
183 0 : move16();
184 : }
185 :
186 71831168 : BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
187 :
188 71831168 : if ( mdct_gains != NULL )
189 : {
190 35915584 : mdct_gains[k] = g;
191 35915584 : move16();
192 : }
193 :
194 71831168 : if ( mdct_gains_exp != NULL )
195 : {
196 35915584 : mdct_gains_exp[k] = g_e;
197 35915584 : move16();
198 : }
199 :
200 71831168 : if ( mdct_inv_gains != NULL )
201 : {
202 35915584 : mdct_inv_gains[k] = ig;
203 35915584 : move16();
204 : }
205 :
206 71831168 : if ( mdct_inv_gains_exp != NULL )
207 : {
208 35915584 : mdct_inv_gains_exp[k] = ig_e;
209 35915584 : move16();
210 : }
211 :
212 71831168 : j = sub( j, 1 );
213 71831168 : k = add( k, 1 );
214 : }
215 2244724 : }
216 :
217 :
218 1122362 : void basop_mdct_noiseShaping_interp( Word32 x[], Word16 lg, Word16 gains[], Word16 gains_exp[] )
219 : {
220 : Word16 i, j, jp, jn, k, l;
221 : Word16 g, pg, ng, e, tmp;
222 :
223 :
224 1122362 : assert( lg % FDNS_NPTS == 0 );
225 1122362 : k = shr( lg, 6 ); /* FDNS_NPTS = 64 */
226 :
227 1122362 : IF( gains != NULL )
228 : {
229 : /* Linear interpolation */
230 1122362 : IF( sub( k, 4 ) == 0 )
231 : {
232 1049970 : jp = 0;
233 1049970 : move16();
234 1049970 : j = 0;
235 1049970 : move16();
236 1049970 : jn = 1;
237 1049970 : move16();
238 :
239 68248050 : FOR( i = 0; i < lg; i += 4 )
240 : {
241 67198080 : pg = gains[jp];
242 67198080 : move16();
243 67198080 : g = gains[j];
244 67198080 : move16();
245 67198080 : ng = gains[jn];
246 67198080 : move16();
247 :
248 : /* common exponent for pg and g */
249 67198080 : tmp = sub( gains_exp[j], gains_exp[jp] );
250 67198080 : if ( tmp > 0 )
251 7228347 : pg = shr( pg, tmp );
252 67198080 : if ( tmp < 0 )
253 4409625 : g = shl( g, tmp );
254 67198080 : e = s_max( gains_exp[j], gains_exp[jp] );
255 :
256 67198080 : tmp = mac_r( L_mult( pg, FL2WORD16( 0.375f ) ), g, FL2WORD16( 0.625f ) );
257 67198080 : x[i] = L_shl( Mpy_32_16( x[i], tmp ), e );
258 67198080 : move32();
259 :
260 67198080 : tmp = mac_r( L_mult( pg, FL2WORD16( 0.125f ) ), g, FL2WORD16( 0.875f ) );
261 67198080 : x[i + 1] = L_shl( Mpy_32_16( x[i + 1], tmp ), e );
262 67198080 : move32();
263 :
264 : /* common exponent for g and ng */
265 67198080 : g = gains[j];
266 67198080 : move16();
267 67198080 : tmp = sub( gains_exp[j], gains_exp[jn] );
268 67198080 : if ( tmp > 0 )
269 4409625 : ng = shr( ng, tmp );
270 67198080 : if ( tmp < 0 )
271 7228347 : g = shl( g, tmp );
272 67198080 : e = s_max( gains_exp[j], gains_exp[jn] );
273 :
274 67198080 : tmp = mac_r( L_mult( g, FL2WORD16( 0.875f ) ), ng, FL2WORD16( 0.125f ) );
275 67198080 : x[i + 2] = L_shl( Mpy_32_16( x[i + 2], tmp ), e );
276 67198080 : move32();
277 :
278 67198080 : tmp = mac_r( L_mult( g, FL2WORD16( 0.625f ) ), ng, FL2WORD16( 0.375f ) );
279 67198080 : x[i + 3] = L_shl( Mpy_32_16( x[i + 3], tmp ), e );
280 67198080 : move32();
281 :
282 67198080 : jp = j;
283 67198080 : move16();
284 67198080 : j = jn;
285 67198080 : move16();
286 67198080 : jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
287 : }
288 : }
289 72392 : ELSE IF( sub( k, 5 ) == 0 )
290 : {
291 72392 : jp = 0;
292 72392 : move16();
293 72392 : j = 0;
294 72392 : move16();
295 72392 : jn = 1;
296 72392 : move16();
297 :
298 4705480 : FOR( i = 0; i < lg; i += 5 )
299 : {
300 4633088 : pg = gains[jp];
301 4633088 : move16();
302 4633088 : g = gains[j];
303 4633088 : move16();
304 4633088 : ng = gains[jn];
305 4633088 : move16();
306 :
307 : /* common exponent for pg and g */
308 4633088 : tmp = sub( gains_exp[j], gains_exp[jp] );
309 4633088 : if ( tmp > 0 )
310 482509 : pg = shr( pg, tmp );
311 4633088 : if ( tmp < 0 )
312 281807 : g = shl( g, tmp );
313 4633088 : e = s_max( gains_exp[j], gains_exp[jp] );
314 :
315 4633088 : tmp = mac_r( L_mult( pg, FL2WORD16( 0.40f ) ), g, FL2WORD16( 0.60f ) );
316 4633088 : x[i] = L_shl( Mpy_32_16( x[i], tmp ), e );
317 4633088 : move32();
318 :
319 4633088 : tmp = mac_r( L_mult( pg, FL2WORD16( 0.20f ) ), g, FL2WORD16( 0.80f ) );
320 4633088 : x[i + 1] = L_shl( Mpy_32_16( x[i + 1], tmp ), e );
321 4633088 : move32();
322 :
323 :
324 4633088 : x[i + 2] = L_shl( Mpy_32_16( x[i + 2], gains[j] ), gains_exp[j] );
325 4633088 : move32();
326 :
327 : /* common exponent for g and ng */
328 4633088 : g = gains[j];
329 4633088 : move16();
330 4633088 : tmp = sub( gains_exp[j], gains_exp[jn] );
331 4633088 : if ( tmp > 0 )
332 281807 : ng = shr( ng, tmp );
333 4633088 : if ( tmp < 0 )
334 482509 : g = shl( g, tmp );
335 4633088 : e = s_max( gains_exp[j], gains_exp[jn] );
336 :
337 4633088 : tmp = mac_r( L_mult( g, FL2WORD16( 0.80f ) ), ng, FL2WORD16( 0.20f ) );
338 4633088 : x[i + 3] = L_shl( Mpy_32_16( x[i + 3], tmp ), e );
339 4633088 : move32();
340 :
341 4633088 : tmp = mac_r( L_mult( g, FL2WORD16( 0.60f ) ), ng, FL2WORD16( 0.40f ) );
342 4633088 : x[i + 4] = L_shl( Mpy_32_16( x[i + 4], tmp ), e );
343 4633088 : move32();
344 :
345 4633088 : jp = j;
346 4633088 : move16();
347 4633088 : j = jn;
348 4633088 : move16();
349 4633088 : jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
350 : }
351 : }
352 : ELSE /* no interpolation */
353 : {
354 0 : FOR( i = 0; i < FDNS_NPTS; i++ )
355 : {
356 0 : FOR( l = 0; l < k; l++ )
357 : {
358 0 : *x = L_shl( Mpy_32_16( *x, *gains ), *gains_exp );
359 0 : move32();
360 0 : x++;
361 : }
362 :
363 0 : gains++;
364 0 : gains_exp++;
365 : }
366 : }
367 : }
368 1122362 : }
369 :
370 :
371 1122362 : void basop_PsychAdaptLowFreqDeemph( Word32 x[], const Word16 lpcGains[], const Word16 lpcGains_e[], Word16 lf_deemph_factors[] )
372 : {
373 : Word16 i;
374 : Word16 max_val, max_e, fac, min_val, min_e, tmp, tmp_e;
375 : Word32 L_tmp;
376 :
377 :
378 1122362 : assert( lpcGains[0] >= 0x4000 );
379 :
380 1122362 : max_val = lpcGains[0];
381 1122362 : move16();
382 1122362 : max_e = lpcGains_e[0];
383 1122362 : move16();
384 1122362 : min_val = lpcGains[0];
385 1122362 : move16();
386 1122362 : min_e = lpcGains_e[0];
387 1122362 : move16();
388 :
389 : /* find minimum (min) and maximum (max) of LPC gains in low frequencies */
390 10101258 : FOR( i = 1; i < 9; i++ )
391 : {
392 8978896 : IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], min_val, min_e ) < 0 )
393 : {
394 4920346 : min_val = lpcGains[i];
395 4920346 : move16();
396 4920346 : min_e = lpcGains_e[i];
397 4920346 : move16();
398 : }
399 :
400 8978896 : IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], max_val, max_e ) > 0 )
401 : {
402 2883189 : max_val = lpcGains[i];
403 2883189 : move16();
404 2883189 : max_e = lpcGains_e[i];
405 2883189 : move16();
406 : }
407 : }
408 :
409 1122362 : min_e = add( min_e, 5 ); /* min *= 32.0f; */
410 :
411 1122362 : test();
412 1122362 : IF( ( compMantExp16Unorm( max_val, max_e, min_val, min_e ) < 0 ) && ( min_val > 0 ) )
413 : {
414 : /* fac = tmp = (float)pow(max / min, 0.0078125f); */
415 1122362 : tmp_e = min_e;
416 1122362 : move16();
417 1122362 : tmp = Inv16( min_val, &tmp_e );
418 1122362 : L_tmp = L_shl( L_mult( tmp, max_val ), add( tmp_e, max_e ) ); /* Q31 */
419 1122362 : L_tmp = BASOP_Util_Log2( L_tmp ); /* Q25 */
420 1122362 : L_tmp = L_shr( L_tmp, 7 ); /* 0.0078125f = 1.f/(1<<7) */
421 1122362 : L_tmp = BASOP_Util_InvLog2( L_tmp ); /* Q31 */
422 1122362 : tmp = round_fx( L_tmp ); /* Q15 */
423 1122362 : fac = tmp; /* Q15 */
424 1122362 : move16();
425 :
426 : /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
427 37037946 : FOR( i = 31; i >= 0; i-- )
428 : {
429 35915584 : x[i] = Mpy_32_16( x[i], fac );
430 35915584 : move32();
431 35915584 : if ( lf_deemph_factors != NULL )
432 : {
433 0 : lf_deemph_factors[i] = mult_r( lf_deemph_factors[i], fac );
434 0 : move16();
435 : }
436 35915584 : fac = mult_r( fac, tmp );
437 : }
438 : }
439 1122362 : }
440 :
441 : #undef WMC_TOOL_SKIP
|