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 <stdint.h>
38 : #include "options.h"
39 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include "cnst.h"
43 : #include "prot.h"
44 : #include "rom_com.h"
45 : #include <assert.h>
46 : #include "wmc_auto.h"
47 : #ifdef DEBUG_PLOT
48 : #include "deb_out.h"
49 : #endif
50 :
51 : /*--------------------------------------------------------------------------*
52 : * mvr2r_inv()
53 : *
54 : *
55 : *--------------------------------------------------------------------------*/
56 :
57 163197 : static void mvr2r_inv(
58 : const float *in, /* i : input vector */
59 : float *out, /* o : output vector */
60 : const int16_t L, /* i : length */
61 : const int16_t decimate /* i : decimation flag [-1,1] */
62 : )
63 : {
64 : int16_t i;
65 :
66 163197 : in = in + (int16_t) ( ( decimate - 1 ) / 2 );
67 163197 : out = out + L - 1;
68 :
69 15144125 : for ( i = 0; i < L; i++ )
70 : {
71 14980928 : *out = *in;
72 14980928 : in += decimate;
73 14980928 : out--;
74 : }
75 :
76 163197 : return;
77 : }
78 :
79 : /*--------------------------------------------------------------------------*
80 : * mvr2r_dec()
81 : *
82 : *
83 : *--------------------------------------------------------------------------*/
84 :
85 149817 : static void mvr2r_dec(
86 : const float *in, /* i : input vector */
87 : float *out, /* o : output vector */
88 : int16_t L, /* i : length */
89 : int16_t decimate /* i : decimation flag [-1,1] */
90 : )
91 : {
92 : int16_t i;
93 149817 : in = in + (int16_t) ( ( decimate - 1 ) / 2 );
94 14449817 : for ( i = 0; i < L; i++ )
95 : {
96 14300000 : *out = *in;
97 14300000 : in += decimate;
98 14300000 : out++;
99 : }
100 :
101 149817 : return;
102 : }
103 :
104 : /*--------------------------------------------------------------------------*
105 : * copy_win()
106 : *
107 : *
108 : *--------------------------------------------------------------------------*/
109 :
110 313014 : static void copy_win(
111 : float *out_win, /* o : output window buffer */
112 : const int16_t nb_zero, /* i : length of zero padding */
113 : const float *in_win, /* i : input window */
114 : const int16_t win_lenght, /* i : length */
115 : const int16_t nb_one, /* i : length of flat section (ones) */
116 : const int16_t decimate /* i : input window */
117 : )
118 : {
119 313014 : if ( decimate < 0 )
120 : {
121 163197 : set_f( out_win, 1, nb_one );
122 163197 : mvr2r_inv( in_win, out_win + nb_one, win_lenght, -decimate );
123 163197 : set_f( out_win + win_lenght + nb_one, 0, nb_zero );
124 : }
125 : else
126 : {
127 149817 : set_f( out_win, 0, nb_zero );
128 149817 : mvr2r_dec( in_win, out_win + nb_zero, win_lenght, decimate );
129 149817 : set_f( out_win + nb_zero + win_lenght, 1, nb_one );
130 : }
131 :
132 313014 : return;
133 : }
134 :
135 : /*--------------------------------------------------------------------------*
136 : * tcx_get_windows_mode1()
137 : *
138 : *
139 : *--------------------------------------------------------------------------*/
140 :
141 6973048 : void tcx_get_windows_mode1(
142 : const int16_t left_mode, /* i : overlap mode of left window half */
143 : const int16_t right_mode, /* i : overlap mode of right window half */
144 : float *left_win, /* o : left overlap window */
145 : float *right_win, /* o : right overlap window */
146 : float *left_win_int, /* o : left overlap window */
147 : float *right_win_int, /* o : right overlap window */
148 : const int16_t L /* i : length */
149 : )
150 : {
151 : /* Left part */
152 6973048 : if ( left_mode == MIN_OVERLAP || left_mode == TRANSITION_OVERLAP )
153 : {
154 23176 : if ( L == 256 || L == 512 )
155 : {
156 3119 : copy_win( left_win, R1_25 - 4 * R2_25 / 7, small_overlap_25, R2_25 / 7, 3 * R2_25 / 7, 1 );
157 : }
158 : else
159 : {
160 20057 : copy_win( left_win, R1_48 - 4 * R2_48 / 7, small_overlap_48, R2_48 / 7, 3 * R2_48 / 7, 1 );
161 20057 : copy_win( left_win_int, R1_16 - 4 * R2_16 / 7, small_overlap_int, R2_16 / 7, 3 * R2_16 / 7, 1 );
162 : }
163 : }
164 6949872 : else if ( left_mode == HALF_OVERLAP )
165 : {
166 57343 : if ( L == 256 || L == 512 )
167 : {
168 8102 : copy_win( left_win, R1_25 - 5 * R2_25 / 7, half_overlap_25, 3 * R2_25 / 7, 2 * R2_25 / 7, 1 );
169 : }
170 : else
171 : {
172 49241 : copy_win( left_win, R1_48 - 5 * R2_48 / 7, half_overlap_48, 3 * R2_48 / 7, 2 * R2_48 / 7, 1 );
173 49241 : copy_win( left_win_int, R1_16 - 5 * R2_16 / 7, half_overlap_int, 3 * R2_16 / 7, 2 * R2_16 / 7, 1 );
174 : }
175 : }
176 6892529 : else if ( left_mode == ALDO_WINDOW )
177 : {
178 : /* ALDO */
179 6892529 : if ( L == 256 || L == 512 )
180 : {
181 951601 : mvr2r( window_256kHz, left_win, R1_25 );
182 : }
183 : else
184 : {
185 5940928 : mvr2r( window_48kHz, left_win, R1_48 );
186 5940928 : mvr2r( window_8_16_32kHz, left_win_int, R1_16 );
187 : }
188 : }
189 : else
190 : {
191 0 : assert( !"Window not supported" );
192 : }
193 :
194 : /* Right part */
195 6973048 : if ( right_mode == MIN_OVERLAP || right_mode == TRANSITION_OVERLAP )
196 : {
197 :
198 29647 : if ( L == 256 || L == 512 )
199 : {
200 4722 : copy_win( right_win, 3 * R2_25 / 7, small_overlap_25, R2_25 / 7, 3 * R2_25 / 7, -1 );
201 : }
202 : else
203 : {
204 24925 : copy_win( right_win, 3 * R2_48 / 7, small_overlap_48, R2_48 / 7, 3 * R2_48 / 7, -1 );
205 24925 : copy_win( right_win_int, 3 * R2_16 / 7, small_overlap_int, R2_16 / 7, 3 * R2_16 / 7, -1 );
206 : }
207 : }
208 6943401 : else if ( right_mode == HALF_OVERLAP )
209 : {
210 :
211 58462 : if ( L == 256 || L == 512 )
212 : {
213 8299 : copy_win( right_win, 2 * R2_25 / 7, half_overlap_25, 3 * R2_25 / 7, 2 * R2_25 / 7, -1 );
214 : }
215 : else
216 : {
217 50163 : copy_win( right_win, 2 * R2_48 / 7, half_overlap_48, 3 * R2_48 / 7, 2 * R2_48 / 7, -1 );
218 50163 : copy_win( right_win_int, 2 * R2_16 / 7, half_overlap_int, 3 * R2_16 / 7, 2 * R2_16 / 7, -1 );
219 : }
220 : }
221 6884939 : else if ( right_mode == ALDO_WINDOW )
222 : {
223 6884939 : if ( L == 256 || L == 512 )
224 : {
225 949801 : mvr2r( window_256kHz + R1_25, right_win, R2_25 );
226 : }
227 : else
228 : {
229 5935138 : mvr2r( window_48kHz + R1_48, right_win, R2_48 );
230 5935138 : mvr2r( window_8_16_32kHz + R1_16, right_win_int, R2_16 );
231 : }
232 : }
233 : else
234 : {
235 0 : assert( !"Window not supported" );
236 : }
237 :
238 6973048 : return;
239 : }
240 :
241 :
242 : /*--------------------------------------------------------------------------*
243 : * wtda()
244 : *
245 : * Windowing and time-domain aliasing
246 : *--------------------------------------------------------------------------*/
247 :
248 955152 : void wtda(
249 : const float *new_audio, /* i : input audio */
250 : float *wtda_audio, /* o : windowed audio */
251 : float *old_wtda, /* i/o: windowed audio from previous frame */
252 : const int16_t left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */
253 : const int16_t right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */
254 : const int16_t L /* i : length */
255 : )
256 : {
257 : int16_t i, decimate, decay;
258 : int16_t n, windecay48, windecay16;
259 : const float *allsig_l, *allsig_r;
260 : float win_right[R2_48];
261 : float win_int_left[R1_16];
262 : float win_left[R1_48];
263 : float win_int_right[R2_16];
264 :
265 955152 : tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
266 :
267 955152 : decimate = 1; /* L_FRAME 48k */
268 955152 : decay = 0;
269 955152 : windecay48 = (int16_t) ( 2 * ( (float) L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_48;
270 :
271 955152 : if ( L == L_FRAME32k || L == L_FRAME16k )
272 : {
273 241184 : decimate = 3;
274 241184 : decay = 1;
275 : }
276 713968 : else if ( L == L_FRAME8k )
277 : {
278 0 : decimate = 6;
279 0 : decay = 2;
280 : }
281 :
282 955152 : n = (int16_t) ( (float) L * N_ZERO_MDCT_NS / FRAME_SIZE_NS );
283 :
284 955152 : windecay16 = (int16_t) ( 2 * ( (float) L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_16;
285 :
286 : /* algorithmic delay reduction */
287 955152 : i = 0;
288 :
289 955152 : if ( old_wtda == NULL )
290 : {
291 865546 : allsig_r = new_audio + n;
292 865546 : allsig_l = new_audio + n - L;
293 : #ifdef DEBUG_PLOT
294 : sendDebout( "tcx_mdct", 2 * L, 1, "mdct_sig", MTV_FLOAT, allsig_l );
295 : #endif
296 : }
297 : else
298 : {
299 89606 : allsig_r = new_audio + n;
300 89606 : allsig_l = old_wtda + n;
301 : }
302 :
303 955152 : if ( L == L_FRAME32k )
304 : {
305 13118315 : for ( i = 0; i < L / 2 - n; i += 2 )
306 : {
307 12933550 : wtda_audio[i] = -allsig_r[L / 2 - i - 1] * win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] - allsig_r[L / 2 + i] * win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16];
308 12933550 : wtda_audio[i + 1] = -allsig_r[L / 2 - ( i + 1 ) - 1] * win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] - allsig_r[L / 2 + i + 1] * win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48];
309 : }
310 :
311 16813615 : for ( i = L / 2 - n; i < L / 2; i += 2 )
312 : {
313 16628850 : wtda_audio[i] = -allsig_r[L / 2 - i - 1];
314 16628850 : wtda_audio[i + 1] = -allsig_r[L / 2 - ( i + 1 ) - 1];
315 : }
316 16813615 : for ( i = 0; i < n; i += 2 )
317 : {
318 16628850 : wtda_audio[i + L / 2] = allsig_l[i] * win_left[( i / 2 ) * decimate + decay] - new_audio[n - i - 1];
319 16628850 : wtda_audio[i + L / 2 + 1] = allsig_l[i + 1] * win_int_left[i / 2] - new_audio[n - ( i + 1 ) - 1];
320 : }
321 :
322 13118315 : for ( i = n; i < L / 2; i += 2 )
323 : {
324 12933550 : wtda_audio[i + L / 2] = allsig_l[i] * win_left[( i / 2 ) * decimate + decay] - allsig_l[L - i - 1] * win_left[( L / 2 - i / 2 ) * decimate - 1 - decay];
325 12933550 : wtda_audio[i + L / 2 + 1] = allsig_l[i + 1] * win_int_left[i / 2] - allsig_l[L - ( i + 1 ) - 1] * win_int_left[L / 2 - i / 2 - 1];
326 : }
327 : }
328 : else
329 : {
330 154652997 : for ( i = 0; i < L / 2 - n; i++ )
331 : {
332 153882610 : wtda_audio[i] = -allsig_r[L / 2 - i - 1] * win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] - allsig_r[L / 2 + i] * win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48];
333 : }
334 :
335 198619457 : for ( i = L / 2 - n; i < L / 2; i++ )
336 : {
337 197849070 : wtda_audio[i] = -allsig_r[L / 2 - i - 1];
338 : }
339 :
340 198619457 : for ( i = 0; i < n; i++ )
341 : {
342 197849070 : wtda_audio[i + L / 2] = allsig_l[i] * win_left[i * decimate + decay] - new_audio[n - i - 1];
343 : }
344 :
345 154652997 : for ( i = n; i < L / 2; i++ )
346 : {
347 153882610 : wtda_audio[i + L / 2] = allsig_l[i] * win_left[i * decimate + decay] - allsig_l[L - i - 1] * win_left[L * decimate - i * decimate - 1 - decay];
348 : }
349 : }
350 :
351 955152 : if ( old_wtda != NULL )
352 : {
353 89606 : mvr2r( new_audio, old_wtda, L );
354 : }
355 :
356 955152 : return;
357 : }
358 :
359 631362 : void wtda_ext(
360 : const float *new_audio, /* i : input audio */
361 : float *wtda_audio, /* o : windowed audio */
362 : const int16_t left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */
363 : const int16_t right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */
364 : const int16_t L, /* i : length */
365 : const uint16_t kernel_type /* i : transform kernel type (0 - 3) */
366 : )
367 : {
368 631362 : const float sign_left = ( kernel_type >= 2 ? -1.f : 1.f );
369 631362 : const float sign_right = ( kernel_type & 1 ? 1.f : -1.f );
370 : int16_t i, decimate, decay;
371 : int16_t n, windecay48, windecay16;
372 : const float *allsig_l, *allsig_r;
373 : float win_right[R2_48];
374 : float win_int_left[R1_16];
375 : float win_left[R1_48];
376 : float win_int_right[R2_16];
377 :
378 631362 : tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
379 :
380 631362 : decimate = 1; /* L_FRAME 48k */
381 631362 : decay = 0;
382 631362 : windecay48 = (int16_t) ( 2 * ( (float) L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_48;
383 :
384 631362 : if ( L == L_FRAME32k || L == L_FRAME16k )
385 : {
386 195837 : decimate = 3;
387 195837 : decay = 1;
388 : }
389 435525 : else if ( L == L_FRAME8k )
390 : {
391 0 : decimate = 6;
392 0 : decay = 2;
393 : }
394 :
395 631362 : n = (int16_t) ( (float) L * N_ZERO_MDCT_NS / FRAME_SIZE_NS );
396 :
397 631362 : windecay16 = (int16_t) ( 2 * ( (float) L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_16;
398 :
399 631362 : allsig_r = new_audio + n;
400 631362 : allsig_l = new_audio + n - L;
401 :
402 631362 : if ( L == L_FRAME32k )
403 : {
404 11026939 : for ( i = 0; i < L / 2 - n; i += 2 )
405 : {
406 10871630 : wtda_audio[i] = -allsig_r[L / 2 - i - 1] * win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] + sign_right * allsig_r[L / 2 + i] * win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16];
407 10871630 : wtda_audio[i + 1] = -allsig_r[L / 2 - ( i + 1 ) - 1] * win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] + sign_right * allsig_r[L / 2 + i + 1] * win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48];
408 : }
409 :
410 14133119 : for ( i = L / 2 - n; i < L / 2; i += 2 )
411 : {
412 13977810 : wtda_audio[i] = -allsig_r[L / 2 - i - 1];
413 13977810 : wtda_audio[i + 1] = -allsig_r[L / 2 - ( i + 1 ) - 1];
414 : }
415 14133119 : for ( i = 0; i < n; i += 2 )
416 : {
417 13977810 : wtda_audio[i + L / 2] = sign_left * allsig_l[i] * win_left[( i / 2 ) * decimate + decay] - new_audio[n - i - 1];
418 13977810 : wtda_audio[i + L / 2 + 1] = sign_left * allsig_l[i + 1] * win_int_left[i / 2] - new_audio[n - ( i + 1 ) - 1];
419 : }
420 :
421 11026939 : for ( i = n; i < L / 2; i += 2 )
422 : {
423 10871630 : wtda_audio[i + L / 2] = sign_left * allsig_l[i] * win_left[( i / 2 ) * decimate + decay] - allsig_l[L - i - 1] * win_left[( L / 2 - i / 2 ) * decimate - 1 - decay];
424 10871630 : wtda_audio[i + L / 2 + 1] = sign_left * allsig_l[i + 1] * win_int_left[i / 2] - allsig_l[L - ( i + 1 ) - 1] * win_int_left[L / 2 - i / 2 - 1];
425 : }
426 : }
427 : else
428 : {
429 94773263 : for ( i = 0; i < L / 2 - n; i++ )
430 : {
431 94297210 : wtda_audio[i] = -allsig_r[L / 2 - i - 1] * win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] + sign_right * allsig_r[L / 2 + i] * win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48];
432 : }
433 :
434 121715323 : for ( i = L / 2 - n; i < L / 2; i++ )
435 : {
436 121239270 : wtda_audio[i] = -allsig_r[L / 2 - i - 1];
437 : }
438 :
439 121715323 : for ( i = 0; i < n; i++ )
440 : {
441 121239270 : wtda_audio[i + L / 2] = sign_left * allsig_l[i] * win_left[i * decimate + decay] - new_audio[n - i - 1];
442 : }
443 :
444 94773263 : for ( i = n; i < L / 2; i++ )
445 : {
446 94297210 : wtda_audio[i + L / 2] = sign_left * allsig_l[i] * win_left[i * decimate + decay] - allsig_l[L - i - 1] * win_left[L * decimate - i * decimate - 1 - decay];
447 : }
448 : }
449 :
450 631362 : return;
451 : }
|