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 : #ifdef DEBUGGING
38 : #include "debug.h"
39 : #endif
40 : #include "ivas_rom_com.h"
41 : #include <assert.h>
42 : #include "wmc_auto.h"
43 :
44 :
45 : /*-----------------------------------------------------------------------------------------*
46 : * Local constants
47 : *-----------------------------------------------------------------------------------------*/
48 :
49 : #define IVAS_ONE_BY_960 0.001041666666666666f
50 : #define IVAS_ONE_BY_640 0.0015625f
51 : #define IVAS_ONE_BY_320 0.003125f
52 : #define IVAS_ONE_BY_240 0.004166666666666667f
53 : #define IVAS_ONE_BY_160 0.00625f
54 : #define IVAS_ONE_BY_80 0.0125f
55 :
56 :
57 : /*-----------------------------------------------------------------------------------------*
58 : * Function ivas_get_mdft_twid_factors()
59 : *
60 : * get twiddle tables for MDFT
61 : *-----------------------------------------------------------------------------------------*/
62 :
63 16792281 : static void ivas_get_mdft_twid_factors(
64 : const int16_t length,
65 : const float **ppTwid )
66 : {
67 16792281 : switch ( length )
68 : {
69 127223 : case L_FRAME48k:
70 127223 : *ppTwid = &ivas_mdft_coeff_cos_twid_960[0];
71 127223 : break;
72 139407 : case L_FRAME32k:
73 139407 : *ppTwid = &ivas_mdft_coeff_cos_twid_640[0];
74 :
75 139407 : break;
76 27486 : case L_FRAME16k:
77 27486 : *ppTwid = &ivas_mdft_coeff_cos_twid_320[0];
78 27486 : break;
79 14371328 : case IVAS_240_PT_LEN:
80 14371328 : *ppTwid = &ivas_mdft_coeff_cos_twid_240[0];
81 14371328 : break;
82 1312705 : case IVAS_160_PT_LEN:
83 1312705 : *ppTwid = &ivas_mdft_coeff_cos_twid_160[0];
84 1312705 : break;
85 477950 : case IVAS_120_PT_LEN:
86 477950 : *ppTwid = &ivas_mdft_coeff_cos_twid_120[0];
87 477950 : break;
88 336182 : case IVAS_80_PT_LEN:
89 336182 : *ppTwid = &ivas_mdft_coeff_cos_twid_80[0];
90 336182 : break;
91 0 : case IVAS_40_PT_LEN:
92 0 : *ppTwid = &ivas_mdft_coeff_cos_twid_40[0];
93 0 : break;
94 :
95 0 : default:
96 0 : assert( !"Not supported FFT length!" );
97 : break;
98 : }
99 :
100 16792281 : return;
101 : }
102 :
103 :
104 : /*-----------------------------------------------------------------------------------------*
105 : * Function ivas_get_imdft_twid_factors()
106 : *
107 : * get twiddle tables for IMDFT
108 : *-----------------------------------------------------------------------------------------*/
109 :
110 3071081 : static void ivas_get_imdft_twid_factors(
111 : const int16_t length,
112 : const float **ppTwid )
113 : {
114 3071081 : switch ( length )
115 : {
116 303578 : case L_FRAME48k:
117 303578 : *ppTwid = ivas_mdft_coeff_cos_twid_960;
118 303578 : break;
119 207457 : case L_FRAME32k:
120 207457 : *ppTwid = ivas_mdft_coeff_cos_twid_640;
121 207457 : break;
122 39986 : case L_FRAME16k:
123 39986 : *ppTwid = ivas_mdft_coeff_cos_twid_320;
124 39986 : break;
125 2458230 : case 240:
126 2458230 : *ppTwid = ivas_mdft_coeff_cos_twid_240;
127 2458230 : break;
128 21750 : case 160:
129 21750 : *ppTwid = ivas_mdft_coeff_cos_twid_160;
130 21750 : break;
131 40080 : case 80:
132 40080 : *ppTwid = ivas_mdft_coeff_cos_twid_80;
133 40080 : break;
134 0 : default:
135 0 : assert( !"Not supported FFT length!" );
136 : }
137 :
138 3071081 : return;
139 : }
140 :
141 :
142 3071081 : static void get_one_by_length(
143 : float *one_by_length,
144 : const int16_t length )
145 : {
146 3071081 : if ( length == L_FRAME48k )
147 : {
148 303578 : *one_by_length = IVAS_ONE_BY_960;
149 : }
150 2767503 : else if ( length == L_FRAME32k )
151 : {
152 207457 : *one_by_length = IVAS_ONE_BY_640;
153 : }
154 2560046 : else if ( length == L_FRAME16k )
155 : {
156 39986 : *one_by_length = IVAS_ONE_BY_320;
157 : }
158 2520060 : else if ( length == IVAS_240_PT_LEN )
159 : {
160 2458230 : *one_by_length = IVAS_ONE_BY_240;
161 : }
162 61830 : else if ( length == IVAS_160_PT_LEN )
163 : {
164 21750 : *one_by_length = IVAS_ONE_BY_160;
165 : }
166 40080 : else if ( length == IVAS_80_PT_LEN )
167 : {
168 40080 : *one_by_length = IVAS_ONE_BY_80;
169 : }
170 : else
171 : {
172 0 : assert( !"Not supported FFT length!" );
173 : }
174 :
175 3071081 : return;
176 : }
177 :
178 :
179 : /*-----------------------------------------------------------------------------------------*
180 : * Function ivas_ifft_cplx1()
181 : *
182 : * Complex IFFT implementation using fft()
183 : *-----------------------------------------------------------------------------------------*/
184 :
185 3071081 : static void ivas_ifft_cplx1(
186 : float *re,
187 : float *im,
188 : const int16_t length )
189 : {
190 : int16_t i;
191 : float one_by_length, tmp;
192 :
193 3071081 : get_one_by_length( &one_by_length, length );
194 :
195 : /* re-arrange inputs to use fft as ifft */
196 3071081 : re[0] = re[0] * one_by_length;
197 3071081 : im[0] = im[0] * one_by_length;
198 :
199 519903321 : for ( i = 1; i <= length >> 1; i++ )
200 : {
201 516832240 : tmp = re[length - i] * one_by_length; /*stl_arr_index*/
202 516832240 : re[length - i] = re[i] * one_by_length; /*stl_arr_index*/
203 516832240 : re[i] = tmp;
204 :
205 516832240 : tmp = im[length - i] * one_by_length; /*stl_arr_index*/
206 516832240 : im[length - i] = im[i] * one_by_length; /*stl_arr_index*/
207 516832240 : im[i] = tmp;
208 : }
209 :
210 3071081 : fft( re, im, length, 1 );
211 :
212 3071081 : return;
213 : }
214 :
215 :
216 : /*-----------------------------------------------------------------------------------------*
217 : * Function ivas_mdft()
218 :
219 : * MDFT implementation
220 : *-----------------------------------------------------------------------------------------*/
221 :
222 16792281 : void ivas_mdft(
223 : const float *pIn, /* i : input time-domain signal */
224 : float *pOut_re, /* o : Real part of MDFT signal */
225 : float *pOut_im, /* o : Imag. part of MDFT signal */
226 : const int16_t input_length, /* i : signal length */
227 : const int16_t mdft_length /* i : MDFT length */
228 : )
229 : {
230 : float re[L_FRAME48k];
231 : float im[L_FRAME48k];
232 : int16_t j, len_by_2;
233 : const float *pTwid;
234 :
235 16792281 : len_by_2 = mdft_length >> 1;
236 :
237 16792281 : ivas_get_mdft_twid_factors( mdft_length, &pTwid );
238 :
239 16792281 : if ( mdft_length == input_length )
240 : {
241 2928078793 : for ( j = 0; j < mdft_length; j++ )
242 : {
243 2915817120 : re[j] = pIn[j] * pTwid[j];
244 2915817120 : im[j] = -pIn[j] * pTwid[mdft_length - j];
245 : }
246 : }
247 : else
248 : {
249 1052263648 : for ( j = 0; j < mdft_length; j++ )
250 : {
251 1047733040 : re[j] = pIn[j] * pTwid[j] - pIn[j + mdft_length] * pTwid[mdft_length - j];
252 1047733040 : im[j] = -pIn[j] * pTwid[mdft_length - j] - pIn[j + mdft_length] * pTwid[j];
253 : }
254 : }
255 :
256 16792281 : fft( re, im, mdft_length, 1 );
257 :
258 1998567361 : for ( j = 0; j < len_by_2; j++ )
259 : {
260 1981775080 : pOut_re[2 * j] = re[j];
261 1981775080 : pOut_re[2 * j + 1] = re[mdft_length - j - 1];
262 :
263 1981775080 : pOut_im[2 * j] = im[j];
264 1981775080 : pOut_im[2 * j + 1] = -im[mdft_length - j - 1];
265 : }
266 :
267 16792281 : return;
268 : }
269 :
270 :
271 : /*-----------------------------------------------------------------------------------------*
272 : * Function ivas_imdft()
273 : *
274 : * iMDFT implementation
275 : * out buffer needs to have 2*length worth memory
276 : *-----------------------------------------------------------------------------------------*/
277 :
278 3071081 : void ivas_imdft(
279 : const float *pRe, /* i : Real part of MDFT signal */
280 : const float *pIm, /* i : Imag. part of MDFT signal */
281 : float *pOut, /* o : output time-domain signal */
282 : const int16_t length /* i : signal length */
283 : )
284 : {
285 3071081 : float *re_tmp = pOut;
286 3071081 : float *im_tmp = pOut + length;
287 : float tmp;
288 : int16_t j;
289 3071081 : int16_t len_by_2 = length >> 1;
290 : const float *pTwid;
291 :
292 3071081 : ivas_get_imdft_twid_factors( length, &pTwid );
293 :
294 519903321 : for ( j = 0; j < len_by_2; j++ )
295 : {
296 516832240 : re_tmp[j] = pRe[2 * j];
297 516832240 : re_tmp[j + len_by_2] = pRe[length - 2 * j - 1];
298 :
299 516832240 : im_tmp[j] = pIm[2 * j];
300 516832240 : im_tmp[j + len_by_2] = -pIm[length - 2 * j - 1];
301 : }
302 :
303 3071081 : ivas_ifft_cplx1( re_tmp, im_tmp, length );
304 :
305 1036735561 : for ( j = 0; j < length; j++ )
306 : {
307 1033664480 : tmp = re_tmp[j] * pTwid[j] - im_tmp[j] * pTwid[length - j];
308 1033664480 : im_tmp[j] = -( re_tmp[j] * pTwid[length - j] + im_tmp[j] * pTwid[j] );
309 1033664480 : re_tmp[j] = tmp;
310 : }
311 :
312 3071081 : return;
313 : }
|