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"
35 : #include "prot.h"
36 : #include "ivas_prot.h"
37 : #include "ivas_rom_com.h"
38 : #ifdef DEBUGGING
39 : #include "debug.h"
40 : #endif
41 : #include "ivas_stat_com.h"
42 : #include "wmc_auto.h"
43 :
44 :
45 : /*------------------------------------------------------------------------------------------*
46 : * Local constants
47 : *------------------------------------------------------------------------------------------*/
48 :
49 : #define IVAS_MDCT_SCALING_GAIN_48k 1.9699011974118126e-06f
50 : #define IVAS_MDCT_SCALING_GAIN_32k 2.9548517961177197e-06f
51 : #define IVAS_MDCT_SCALING_GAIN_16k 5.909703592235439e-06f
52 :
53 : #define IVAS_IMDCT_SCALING_GAIN 2115.165304808f
54 :
55 :
56 : /*-----------------------------------------------------------------------------------------*
57 : * Function ivas_tda()
58 : *
59 : * Time domain aliasing
60 : *-----------------------------------------------------------------------------------------*/
61 :
62 1320 : void ivas_tda(
63 : const float *pIn, /* i : time domain buffer of size 2*length */
64 : float *pOut, /* o : time domain buffer of size length */
65 : const int16_t length /* i : length of time alised signal buffer */
66 : )
67 : {
68 : int16_t i;
69 1320 : int16_t len_by_2 = length >> 1;
70 :
71 316200 : for ( i = 0; i < len_by_2; i++ )
72 : {
73 314880 : pOut[i] = -pIn[len_by_2 - i - 1] + pIn[len_by_2 + i];
74 314880 : pOut[len_by_2 + i] = pIn[length * 2 - i - 1] + pIn[length + i];
75 : }
76 :
77 1320 : return;
78 : }
79 :
80 :
81 : /*-----------------------------------------------------------------------------------------*
82 : * Function ivas_dct_windowing()
83 : *
84 : * Windowing block, input is passed through Fielder window
85 : *-----------------------------------------------------------------------------------------*/
86 :
87 55160 : void ivas_dct_windowing(
88 : const int16_t fade_len,
89 : const int16_t full_len,
90 : const int16_t dct_len,
91 : const int16_t zero_pad_len,
92 : const float *pWindow_coeffs,
93 : const int16_t frame_len,
94 : float *pOut_buf,
95 : float *pBuffer_prev,
96 : float *pTemp_lfe )
97 : {
98 : int16_t i;
99 55160 : int16_t rem_len = 0;
100 :
101 55160 : mvr2r( pBuffer_prev, pOut_buf + zero_pad_len, fade_len );
102 :
103 55160 : mvr2r( pTemp_lfe, ( pOut_buf + fade_len + zero_pad_len ), dct_len );
104 :
105 2687736 : for ( i = 0; i < zero_pad_len; i++ )
106 : {
107 2632576 : pOut_buf[i] = 0.0f;
108 : }
109 :
110 55160 : mvr2r( ( pOut_buf + full_len - fade_len ), pBuffer_prev, fade_len );
111 :
112 21115768 : for ( i = 0; i < fade_len; i++ )
113 : {
114 21060608 : pOut_buf[zero_pad_len + i] = pOut_buf[zero_pad_len + i] * pWindow_coeffs[i];
115 : }
116 :
117 55160 : rem_len = full_len - ( zero_pad_len * 3 + fade_len );
118 :
119 21115768 : for ( i = 0; i < rem_len; i++ )
120 : {
121 21060608 : pOut_buf[zero_pad_len * 3 + fade_len + i] = pOut_buf[zero_pad_len * 3 + fade_len + i] * pWindow_coeffs[fade_len - i - 1];
122 : }
123 :
124 2687736 : for ( i = 0; i < frame_len - full_len; i++ )
125 : {
126 2632576 : pOut_buf[full_len + i] = 0.0f;
127 : }
128 :
129 55160 : return;
130 : }
131 :
132 :
133 : /*-----------------------------------------------------------------------------------------*
134 : * Function ivas_mdct()
135 : *
136 : * MDCT implementation
137 : *-----------------------------------------------------------------------------------------*/
138 :
139 53840 : void ivas_mdct(
140 : const float *pIn,
141 : float *pOut,
142 : const int16_t length )
143 : {
144 : const float *pTwid_re, *pTwid_im;
145 : int16_t i, len_by_2;
146 : float re[IVAS_480_PT_LEN], im[IVAS_480_PT_LEN];
147 : float ivas_mdct_scaling_gain;
148 :
149 53840 : len_by_2 = length >> 1;
150 53840 : ivas_mdct_scaling_gain = ivas_get_mdct_scaling_gain( len_by_2 );
151 :
152 53840 : ivas_get_twid_factors( length, &pTwid_re, &pTwid_im );
153 :
154 12901840 : for ( i = 0; i < len_by_2; i++ )
155 : {
156 12848000 : pOut[i] = -pIn[len_by_2 - i - 1] + pIn[len_by_2 + i];
157 12848000 : pOut[len_by_2 + i] = pIn[length * 2 - i - 1] + pIn[length + i];
158 : }
159 :
160 12901840 : for ( i = 0; i < len_by_2; i++ )
161 : {
162 12848000 : re[i] = -( pOut[2 * i] * pTwid_re[i] + pOut[length - 1 - 2 * i] * pTwid_im[i] );
163 12848000 : im[i] = pOut[length - 1 - 2 * i] * pTwid_re[i] - pOut[2 * i] * pTwid_im[i];
164 : }
165 :
166 53840 : DoFFT( &re[0], &im[0], len_by_2 );
167 :
168 12901840 : for ( i = 0; i < len_by_2; i++ )
169 : {
170 12848000 : re[i] = re[i] * ivas_mdct_scaling_gain;
171 12848000 : im[i] = im[i] * ivas_mdct_scaling_gain;
172 : }
173 :
174 12901840 : for ( i = 0; i < len_by_2; i++ )
175 : {
176 : float tmp;
177 12848000 : tmp = re[i] * pTwid_re[i] - im[i] * pTwid_im[i];
178 12848000 : im[i] = im[i] * pTwid_re[i] + re[i] * pTwid_im[i];
179 12848000 : re[i] = tmp;
180 : }
181 :
182 12901840 : for ( i = 0; i < len_by_2; i++ )
183 : {
184 12848000 : pOut[length - 2 * i - 1] = re[i];
185 12848000 : pOut[2 * i] = im[i];
186 : }
187 :
188 53840 : return;
189 : }
190 :
191 :
192 : /*-----------------------------------------------------------------------------------------*
193 : * Function ivas_ifft_cplx()
194 : *
195 : * Complex IFFT implementation using DoFFT
196 : *-----------------------------------------------------------------------------------------*/
197 :
198 160236 : static void ivas_ifft_cplx(
199 : float *re,
200 : float *im,
201 : const int16_t length )
202 : {
203 : int16_t i;
204 160236 : float ivas_imdct_one_by_powergain = IVAS_IMDCT_SCALING_GAIN;
205 : /*re-arrange inputs to use fft as ifft */
206 160236 : re[0] = re[0] * ivas_imdct_one_by_powergain;
207 160236 : im[0] = im[0] * ivas_imdct_one_by_powergain;
208 :
209 18411996 : for ( i = 1; i <= length >> 1; i++ )
210 : {
211 18251760 : float tmp = re[length - i] * ivas_imdct_one_by_powergain;
212 18251760 : re[length - i] = re[i] * ivas_imdct_one_by_powergain;
213 18251760 : re[i] = tmp;
214 :
215 18251760 : tmp = im[length - i] * ivas_imdct_one_by_powergain;
216 18251760 : im[length - i] = im[i] * ivas_imdct_one_by_powergain;
217 18251760 : im[i] = tmp;
218 : }
219 :
220 160236 : DoFFT( re, im, (int16_t) length );
221 :
222 160236 : return;
223 : }
224 :
225 :
226 : /*-----------------------------------------------------------------------------------------*
227 : * Function ivas_itda()
228 : *
229 : * Inverse time domain alias implementation
230 : *-----------------------------------------------------------------------------------------*/
231 :
232 1320 : void ivas_itda(
233 : const float *re, /* i : time alised signal after IDCT */
234 : float *pOut, /* o : time domain buffer of size 2*length */
235 : const int16_t length /* i : length of time alised signal buffer */
236 : )
237 : {
238 : int16_t i;
239 1320 : int16_t len_by_2 = length >> 1;
240 :
241 316200 : for ( i = 0; i < len_by_2; i++ )
242 : {
243 314880 : pOut[i] = -re[len_by_2 - i - 1];
244 314880 : pOut[len_by_2 + i] = re[i];
245 314880 : pOut[length + i] = re[len_by_2 + i];
246 314880 : pOut[3 * len_by_2 + i] = re[length - i - 1];
247 : }
248 :
249 1320 : return;
250 : }
251 :
252 :
253 : /*-----------------------------------------------------------------------------------------*
254 : * Function ivas_imdct()
255 : *
256 : * IMDCT implementation
257 : *-----------------------------------------------------------------------------------------*/
258 :
259 160236 : void ivas_imdct(
260 : const float *pIn,
261 : float *pOut,
262 : const int16_t length )
263 : {
264 : const float *pTwid_re, *pTwid_im;
265 160236 : int16_t len_by_2 = length >> 1;
266 : int16_t i;
267 : float re[IVAS_480_PT_LEN];
268 : float im[IVAS_480_PT_LEN];
269 :
270 160236 : ivas_get_twid_factors( length, &pTwid_re, &pTwid_im );
271 :
272 36663756 : for ( i = 0; i < len_by_2; i++ )
273 : {
274 36503520 : re[i] = pIn[length - 2 * i - 1] * pTwid_re[i] + pIn[2 * i] * pTwid_im[i]; /*stl_arr_index*/
275 36503520 : im[i] = -pIn[length - 2 * i - 1] * pTwid_im[i] + pIn[2 * i] * pTwid_re[i]; /*stl_arr_index*/
276 : }
277 :
278 160236 : ivas_ifft_cplx( &re[0], &im[0], len_by_2 );
279 :
280 36663756 : for ( i = 0; i < len_by_2; i++ )
281 : {
282 : float tmp;
283 36503520 : tmp = re[i] * pTwid_re[i] + im[i] * pTwid_im[i];
284 36503520 : im[i] = -re[i] * pTwid_im[i] + im[i] * pTwid_re[i];
285 36503520 : re[i] = tmp;
286 : }
287 :
288 36663756 : for ( i = ( len_by_2 - 1 ); i >= 0; i-- )
289 : {
290 36503520 : re[2 * i + 1] = im[( len_by_2 - 1 ) - i];
291 36503520 : re[2 * i] = -re[i];
292 : }
293 :
294 36663756 : for ( i = 0; i < len_by_2; i++ )
295 : {
296 36503520 : pOut[i] = -re[len_by_2 - i - 1];
297 36503520 : pOut[len_by_2 + i] = re[i];
298 36503520 : pOut[length + i] = re[len_by_2 + i];
299 36503520 : pOut[3 * len_by_2 + i] = re[length - i - 1];
300 : }
301 :
302 160236 : return;
303 : }
304 :
305 :
306 : /*-----------------------------------------------------------------------------------------*
307 : * Function ivas_get_twid_factors()
308 : *
309 : * Sets/Maps the fft twiddle tables based on fft length
310 : *-----------------------------------------------------------------------------------------*/
311 :
312 214076 : void ivas_get_twid_factors(
313 : const int16_t length,
314 : const float **pTwid_re,
315 : const float **pTwid_im )
316 : {
317 214076 : if ( length == 480 )
318 : {
319 200022 : *pTwid_re = &ivas_cos_twiddle_480[0];
320 200022 : *pTwid_im = &ivas_sin_twiddle_480[0];
321 : }
322 14054 : else if ( length == 320 )
323 : {
324 2774 : *pTwid_re = &ivas_cos_twiddle_320[0];
325 2774 : *pTwid_im = &ivas_sin_twiddle_320[0];
326 : }
327 11280 : else if ( length == 160 )
328 : {
329 11280 : *pTwid_re = &ivas_cos_twiddle_160[0];
330 11280 : *pTwid_im = &ivas_sin_twiddle_160[0];
331 : }
332 0 : else if ( length == 80 )
333 : {
334 0 : *pTwid_re = &ivas_cos_twiddle_80[0];
335 0 : *pTwid_im = &ivas_sin_twiddle_80[0];
336 : }
337 : else
338 : {
339 0 : assert( !"Not supported FFT length!" );
340 : }
341 :
342 214076 : return;
343 : }
344 :
345 :
346 : /*-----------------------------------------------------------------------------------------*
347 : * Function ivas_get_mdct_scaling_gain()
348 : *
349 : * Get scaling gain for MDCT functions
350 : *-----------------------------------------------------------------------------------------*/
351 :
352 53840 : float ivas_get_mdct_scaling_gain(
353 : const int16_t dct_len_by_2 )
354 : {
355 53840 : float gain = 0.0f;
356 :
357 53840 : switch ( dct_len_by_2 )
358 : {
359 52920 : case L_FRAME48k >> 2:
360 : {
361 52920 : gain = IVAS_MDCT_SCALING_GAIN_48k;
362 52920 : break;
363 : }
364 920 : case L_FRAME32k >> 2:
365 : {
366 920 : gain = IVAS_MDCT_SCALING_GAIN_32k;
367 920 : break;
368 : }
369 0 : case L_FRAME16k >> 2:
370 : {
371 0 : gain = IVAS_MDCT_SCALING_GAIN_16k;
372 0 : break;
373 : }
374 0 : default:
375 : {
376 0 : assert( !"Unsupported frame length!" );
377 : break;
378 : }
379 : }
380 :
381 53840 : return gain;
382 : }
|