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 10044449 : static void ivas_get_mdft_twid_factors(
64 : const int16_t length,
65 : const float **ppTwid )
66 : {
67 10044449 : switch ( length )
68 : {
69 97323 : case L_FRAME48k:
70 97323 : *ppTwid = &ivas_mdft_coeff_cos_twid_960[0];
71 97323 : break;
72 63787 : case L_FRAME32k:
73 63787 : *ppTwid = &ivas_mdft_coeff_cos_twid_640[0];
74 :
75 63787 : break;
76 12168 : case L_FRAME16k:
77 12168 : *ppTwid = &ivas_mdft_coeff_cos_twid_320[0];
78 12168 : break;
79 8872318 : case IVAS_240_PT_LEN:
80 8872318 : *ppTwid = &ivas_mdft_coeff_cos_twid_240[0];
81 8872318 : break;
82 624955 : case IVAS_160_PT_LEN:
83 624955 : *ppTwid = &ivas_mdft_coeff_cos_twid_160[0];
84 624955 : break;
85 206276 : case IVAS_120_PT_LEN:
86 206276 : *ppTwid = &ivas_mdft_coeff_cos_twid_120[0];
87 206276 : break;
88 167622 : case IVAS_80_PT_LEN:
89 167622 : *ppTwid = &ivas_mdft_coeff_cos_twid_80[0];
90 167622 : 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 10044449 : return;
101 : }
102 :
103 :
104 : /*-----------------------------------------------------------------------------------------*
105 : * Function ivas_get_imdft_twid_factors()
106 : *
107 : * get twiddle tables for IMDFT
108 : *-----------------------------------------------------------------------------------------*/
109 :
110 1742957 : static void ivas_get_imdft_twid_factors(
111 : const int16_t length,
112 : const float **ppTwid )
113 : {
114 1742957 : switch ( length )
115 : {
116 260278 : case L_FRAME48k:
117 260278 : *ppTwid = ivas_mdft_coeff_cos_twid_960;
118 260278 : break;
119 108087 : case L_FRAME32k:
120 108087 : *ppTwid = ivas_mdft_coeff_cos_twid_640;
121 108087 : break;
122 23168 : case L_FRAME16k:
123 23168 : *ppTwid = ivas_mdft_coeff_cos_twid_320;
124 23168 : break;
125 1330814 : case 240:
126 1330814 : *ppTwid = ivas_mdft_coeff_cos_twid_240;
127 1330814 : break;
128 7250 : case 160:
129 7250 : *ppTwid = ivas_mdft_coeff_cos_twid_160;
130 7250 : break;
131 13360 : case 80:
132 13360 : *ppTwid = ivas_mdft_coeff_cos_twid_80;
133 13360 : break;
134 0 : default:
135 0 : assert( !"Not supported FFT length!" );
136 : }
137 :
138 1742957 : return;
139 : }
140 :
141 :
142 1742957 : static void get_one_by_length(
143 : float *one_by_length,
144 : const int16_t length )
145 : {
146 1742957 : if ( length == L_FRAME48k )
147 : {
148 260278 : *one_by_length = IVAS_ONE_BY_960;
149 : }
150 1482679 : else if ( length == L_FRAME32k )
151 : {
152 108087 : *one_by_length = IVAS_ONE_BY_640;
153 : }
154 1374592 : else if ( length == L_FRAME16k )
155 : {
156 23168 : *one_by_length = IVAS_ONE_BY_320;
157 : }
158 1351424 : else if ( length == IVAS_240_PT_LEN )
159 : {
160 1330814 : *one_by_length = IVAS_ONE_BY_240;
161 : }
162 20610 : else if ( length == IVAS_160_PT_LEN )
163 : {
164 7250 : *one_by_length = IVAS_ONE_BY_160;
165 : }
166 13360 : else if ( length == IVAS_80_PT_LEN )
167 : {
168 13360 : *one_by_length = IVAS_ONE_BY_80;
169 : }
170 : else
171 : {
172 0 : assert( !"Not supported FFT length!" );
173 : }
174 :
175 1742957 : return;
176 : }
177 :
178 :
179 : /*-----------------------------------------------------------------------------------------*
180 : * Function ivas_ifft_cplx1()
181 : *
182 : * Complex IFFT implementation using fft()
183 : *-----------------------------------------------------------------------------------------*/
184 :
185 1742957 : 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 1742957 : get_one_by_length( &one_by_length, length );
194 :
195 : /* re-arrange inputs to use fft as ifft */
196 1742957 : re[0] = re[0] * one_by_length;
197 1742957 : im[0] = im[0] * one_by_length;
198 :
199 325783197 : for ( i = 1; i <= length >> 1; i++ )
200 : {
201 324040240 : tmp = re[length - i] * one_by_length; /*stl_arr_index*/
202 324040240 : re[length - i] = re[i] * one_by_length; /*stl_arr_index*/
203 324040240 : re[i] = tmp;
204 :
205 324040240 : tmp = im[length - i] * one_by_length; /*stl_arr_index*/
206 324040240 : im[length - i] = im[i] * one_by_length; /*stl_arr_index*/
207 324040240 : im[i] = tmp;
208 : }
209 :
210 1742957 : fft( re, im, length, 1 );
211 :
212 1742957 : return;
213 : }
214 :
215 :
216 : /*-----------------------------------------------------------------------------------------*
217 : * Function ivas_mdft()
218 :
219 : * MDFT implementation
220 : *-----------------------------------------------------------------------------------------*/
221 :
222 10044449 : 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 10044449 : len_by_2 = mdft_length >> 1;
236 :
237 10044449 : ivas_get_mdft_twid_factors( mdft_length, &pTwid );
238 :
239 10044449 : if ( mdft_length == input_length )
240 : {
241 1731389833 : for ( j = 0; j < mdft_length; j++ )
242 : {
243 1724168320 : re[j] = pIn[j] * pTwid[j];
244 1724168320 : im[j] = -pIn[j] * pTwid[mdft_length - j];
245 : }
246 : }
247 : else
248 : {
249 684314136 : for ( j = 0; j < mdft_length; j++ )
250 : {
251 681491200 : re[j] = pIn[j] * pTwid[j] - pIn[j + mdft_length] * pTwid[mdft_length - j];
252 681491200 : im[j] = -pIn[j] * pTwid[mdft_length - j] - pIn[j + mdft_length] * pTwid[j];
253 : }
254 : }
255 :
256 10044449 : fft( re, im, mdft_length, 1 );
257 :
258 1212874209 : for ( j = 0; j < len_by_2; j++ )
259 : {
260 1202829760 : pOut_re[2 * j] = re[j];
261 1202829760 : pOut_re[2 * j + 1] = re[mdft_length - j - 1];
262 :
263 1202829760 : pOut_im[2 * j] = im[j];
264 1202829760 : pOut_im[2 * j + 1] = -im[mdft_length - j - 1];
265 : }
266 :
267 10044449 : 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 1742957 : 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 1742957 : float *re_tmp = pOut;
286 1742957 : float *im_tmp = pOut + length;
287 : float tmp;
288 : int16_t j;
289 1742957 : int16_t len_by_2 = length >> 1;
290 : const float *pTwid;
291 :
292 1742957 : ivas_get_imdft_twid_factors( length, &pTwid );
293 :
294 325783197 : for ( j = 0; j < len_by_2; j++ )
295 : {
296 324040240 : re_tmp[j] = pRe[2 * j];
297 324040240 : re_tmp[j + len_by_2] = pRe[length - 2 * j - 1];
298 :
299 324040240 : im_tmp[j] = pIm[2 * j];
300 324040240 : im_tmp[j + len_by_2] = -pIm[length - 2 * j - 1];
301 : }
302 :
303 1742957 : ivas_ifft_cplx1( re_tmp, im_tmp, length );
304 :
305 649823437 : for ( j = 0; j < length; j++ )
306 : {
307 648080480 : tmp = re_tmp[j] * pTwid[j] - im_tmp[j] * pTwid[length - j];
308 648080480 : im_tmp[j] = -( re_tmp[j] * pTwid[length - j] + im_tmp[j] * pTwid[j] );
309 648080480 : re_tmp[j] = tmp;
310 : }
311 :
312 1742957 : return;
313 : }
|