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 : #include <math.h>
41 : #include "cnst.h"
42 : #include "prot_fx.h"
43 : #include "rom_com.h"
44 : #include "wmc_auto.h"
45 :
46 :
47 : const PWord16 *getSineWindowTable( Word16 length );
48 :
49 :
50 151527 : void mdct_window_sine_IVAS_updated(
51 : PWord16 *window, /* Qx */
52 : const Word32 Fs, /* Q0 */
53 : const Word16 n, /* Q0 */
54 : const Word16 window_type, /* Q0 */
55 : const Word16 element_mode /* Q0 */
56 : )
57 : {
58 151527 : IF( element_mode == EVS_MONO )
59 : {
60 : const PWord16 *table;
61 0 : table = getSineWindowTable( n );
62 0 : FOR( Word32 i = 0; i < n / 2; i++ )
63 : {
64 0 : window[i].v.re = table[i].v.re; /* Qx */
65 0 : move16();
66 0 : window[i].v.im = table[i].v.im; /* Qx */
67 0 : move16();
68 : }
69 : // PMT("getSineWindowTable needs to be updated for IVAS")
70 : }
71 : ELSE
72 : {
73 151527 : const Word16 *window_table = 0;
74 151527 : Word16 buf_in_size = 0;
75 151527 : move16();
76 : Word16 temp[420];
77 151527 : set16_fx( temp, 0, 420 );
78 151527 : SWITCH( window_type )
79 : {
80 50509 : case FULL_OVERLAP:
81 50509 : window_table = tcx_mdct_window_48_fx; /* Q15 */
82 50509 : buf_in_size = 420;
83 50509 : move16();
84 50509 : BREAK;
85 50509 : case HALF_OVERLAP:
86 50509 : window_table = tcx_mdct_window_half_48_fx; /* Q15 */
87 50509 : buf_in_size = 180;
88 50509 : BREAK;
89 50509 : case TRANSITION_OVERLAP:
90 : case MIN_OVERLAP:
91 50509 : window_table = tcx_mdct_window_trans_48_fx; /* Q15 */
92 50509 : buf_in_size = 60;
93 50509 : move16();
94 50509 : BREAK;
95 :
96 0 : default:
97 0 : assert( 0 && "Unsupported window type" );
98 : BREAK;
99 : }
100 :
101 151527 : IF( EQ_32( Fs, 48000 ) )
102 : {
103 56013 : Copy( window_table, temp, n ); /* Q15 */
104 : }
105 : ELSE
106 : {
107 95514 : lerp( window_table, temp, n, buf_in_size );
108 : }
109 :
110 11245511 : FOR( Word32 i = 0; i < n / 2; i++ )
111 : {
112 11093984 : window[i].v.re = temp[n - 1 - i]; /* Qx */
113 11093984 : move16();
114 11093984 : window[i].v.im = temp[i]; /* Qx */
115 11093984 : move16();
116 : }
117 : }
118 151527 : }
119 :
120 : ////Use mdct_window_sine_IVAS_updated for IVAS (EVS path covered as well)
121 328 : void mdct_window_sine(
122 : PWord16 *window, /* Qx */
123 : Word16 n /* Q0 */
124 : )
125 : {
126 : {
127 : const PWord16 *table;
128 328 : table = getSineWindowTable( n );
129 16360 : FOR( Word32 i = 0; i < n / 2; i++ )
130 : {
131 16032 : window[i].v.re = table[i].v.re; /* Qx */
132 16032 : move16();
133 16032 : window[i].v.im = table[i].v.im; /* Qx */
134 16032 : move16();
135 : }
136 : // PMT("getSineWindowTable needs to be updated for IVAS")
137 : }
138 328 : }
139 :
140 :
141 52398 : void mdct_window_aldo(
142 : Word16 *window1, /* Q15 */
143 : PWord16 *window1_trunc, /* Q15 */
144 : PWord16 *window2, /* Q15 */
145 : Word16 n /* Q0 */
146 : )
147 : {
148 : Word16 i, n0, n1, n2, d, tmp;
149 : const Word16 *p1, *p2;
150 :
151 : /* set table pointers and decimation factor */
152 52398 : SWITCH( n )
153 : {
154 0 : case 320 / 2:
155 0 : p1 = window_48kHz_fx + 2; /* Q15 */
156 0 : p2 = window_48kHz_fx + 1110 - 3; /* Q15 */
157 0 : d = 6;
158 0 : move16();
159 0 : BREAK;
160 6457 : case 512 / 2:
161 6457 : p1 = window_256kHz; /* Q15 */
162 6457 : p2 = window_256kHz + 592 - 1; /* Q15 */
163 6457 : d = 2;
164 6457 : move16();
165 6457 : BREAK;
166 8763 : case 640 / 2:
167 8763 : p1 = window_48kHz_fx + 1; /* Q15 */
168 8763 : p2 = window_48kHz_fx + 1110 - 2; /* Q15 */
169 8763 : d = 3;
170 8763 : move16();
171 8763 : BREAK;
172 7539 : case 1024 / 2:
173 7539 : p1 = window_256kHz; /* Q15 */
174 7539 : p2 = window_256kHz + 592 - 1; /* Q15 */
175 7539 : d = 1;
176 7539 : move16();
177 7539 : BREAK;
178 10952 : case 1280 / 2:
179 10952 : p1 = window_48kHz_fx + 1; /* Q15 */
180 10952 : p2 = window_48kHz_fx + 1110 - 2; /* Q15 */
181 10952 : d = 3;
182 10952 : move16();
183 10952 : BREAK;
184 18687 : case 1920 / 2:
185 18687 : p1 = window_48kHz_fx; /* Q15 */
186 18687 : p2 = window_48kHz_fx + 1110 - 1; /* Q15 */
187 18687 : d = 1;
188 18687 : move16();
189 18687 : BREAK;
190 0 : default:
191 0 : assert( 0 );
192 : return;
193 : }
194 :
195 : /* set lengths */
196 52398 : n0 = shr( imult1616( n, 9 ), 5 );
197 52398 : n1 = shr( imult1616( n, 23 ), 5 ); /* left slope length */
198 52398 : n2 = shr( imult1616( n, 14 ), 5 ); /* right slope length */
199 :
200 : /* first part (long slope) */
201 52398 : IF( NE_16( n, 1280 / 2 ) )
202 : {
203 7426126 : FOR( i = 0; i < n0; i++ )
204 : {
205 7384680 : *window1 = *p1; /* Q15 */
206 7384680 : move16();
207 7384680 : window1++;
208 7384680 : p1 += d;
209 : }
210 :
211 41446 : tmp = shr( n, 1 );
212 5785086 : FOR( ; i < tmp; i++ )
213 : {
214 5743640 : window1_trunc->v.im = *p1; /* Q15 */
215 5743640 : move16();
216 5743640 : window1_trunc++;
217 5743640 : p1 += d;
218 : }
219 :
220 41446 : test();
221 41446 : if ( EQ_16( n, 512 / 2 ) || EQ_16( n, 320 / 2 ) )
222 6457 : p1++;
223 :
224 5785086 : FOR( ; i < n1; i++ )
225 : {
226 5743640 : window1_trunc--;
227 5743640 : window1_trunc->v.re = *p1; /* Q15 */
228 5743640 : move16();
229 5743640 : p1 += d;
230 : }
231 : }
232 : ELSE
233 : {
234 10952 : const Word16 *pi = window_8_16_32kHz_fx;
235 :
236 996632 : FOR( i = 0; i < n0; i += 2 )
237 : {
238 985680 : *window1 = *p1; /* Q15 */
239 985680 : move16();
240 985680 : window1++;
241 985680 : p1 += d;
242 :
243 985680 : *window1 = *pi; /* Q15 */
244 985680 : move16();
245 985680 : window1++;
246 985680 : pi++;
247 : }
248 :
249 10952 : tmp = shr( n, 1 );
250 777592 : FOR( ; i < tmp; i += 2 )
251 : {
252 766640 : window1_trunc->v.im = *p1; /* Q15 */
253 766640 : move16();
254 766640 : window1_trunc++;
255 766640 : p1 += d;
256 :
257 766640 : window1_trunc->v.im = *pi; /* Q15 */
258 766640 : move16();
259 766640 : window1_trunc++;
260 766640 : pi++;
261 : }
262 :
263 777592 : FOR( ; i < n1; i += 2 )
264 : {
265 766640 : window1_trunc--;
266 766640 : window1_trunc->v.re = *pi; /* Q15 */
267 766640 : move16();
268 766640 : pi++;
269 :
270 766640 : window1_trunc--;
271 766640 : window1_trunc->v.re = *p1; /* Q15 */
272 766640 : move16();
273 766640 : p1 += d;
274 : }
275 : }
276 :
277 : /* second part (short slope) */
278 52398 : IF( NE_16( n, 1280 / 2 ) )
279 : {
280 41446 : tmp = shr( n2, 1 );
281 5785086 : FOR( i = 0; i < tmp; i++ )
282 : {
283 5743640 : window2->v.im = *p2; /* Q15 */
284 5743640 : move16();
285 5743640 : window2++;
286 5743640 : p2 -= d;
287 : }
288 :
289 41446 : test();
290 41446 : if ( EQ_16( n, 512 / 2 ) || EQ_16( n, 320 / 2 ) )
291 6457 : p2--;
292 :
293 5785086 : FOR( ; i < n2; i++ )
294 : {
295 5743640 : window2--;
296 5743640 : window2->v.re = *p2; /* Q15 */
297 5743640 : move16();
298 5743640 : p2 -= d;
299 : }
300 : }
301 : ELSE
302 : {
303 10952 : const Word16 *pi = window_8_16_32kHz_fx + 370 - 1;
304 :
305 10952 : tmp = shr( n2, 1 );
306 777592 : FOR( i = 0; i < tmp; i += 2 )
307 : {
308 766640 : window2->v.im = *p2; /* Q15 */
309 766640 : move16();
310 766640 : window2++;
311 766640 : p2 -= d;
312 :
313 766640 : window2->v.im = *pi; /* Q15 */
314 766640 : move16();
315 766640 : window2++;
316 766640 : pi--;
317 : }
318 :
319 777592 : FOR( ; i < n2; i += 2 )
320 : {
321 766640 : window2--;
322 766640 : window2->v.re = *pi; /* Q15 */
323 766640 : move16();
324 766640 : pi--;
325 :
326 766640 : window2--;
327 766640 : window2->v.re = *p2; /* Q15 */
328 766640 : move16();
329 766640 : p2 -= d;
330 : }
331 : }
332 52398 : }
|