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_rend.h"
37 : #ifdef DEBUGGING
38 : #include "debug.h"
39 : #endif
40 : #include <math.h>
41 : #include "wmc_auto.h"
42 :
43 :
44 : /*------------------------------------------------------------------------------------------*
45 : * Static functions declarations
46 : *------------------------------------------------------------------------------------------*/
47 :
48 : static void fft_wrapper_2ch( float *buffer_L, float *buffer_R, const int16_t fft_size );
49 :
50 : static void ifft_wrapper_2ch( float *buffer_L, float *buffer_R, const int16_t fft_size );
51 :
52 :
53 : /*-----------------------------------------------------------------------------------------*
54 : * Function int_log2()
55 : *
56 : * takes integer log2 of power_of_2 input value. e.g. int_log2(1024) = 10
57 : * powerOf2 must be a power of two between 2^0 and 2^15
58 : * NOT valid for integers thar are NOT a power of 2
59 : *-----------------------------------------------------------------------------------------*/
60 :
61 : /*! r: integer log2 */
62 58660 : uint16_t int_log2(
63 : uint32_t powerOf2 )
64 : {
65 58660 : int16_t l2 = 15;
66 :
67 58660 : if ( powerOf2 & 0x00FF )
68 : {
69 0 : l2 -= 8;
70 : }
71 :
72 58660 : if ( powerOf2 & 0x0F0F )
73 : {
74 58660 : l2 -= 4;
75 : }
76 :
77 58660 : if ( powerOf2 & 0x3333 )
78 : {
79 58660 : l2 -= 2;
80 : }
81 :
82 58660 : if ( powerOf2 & 0x5555 )
83 : {
84 21393 : l2 -= 1;
85 : }
86 :
87 58660 : return l2;
88 : }
89 :
90 :
91 : /*-----------------------------------------------------------------------------------------*
92 : * Function fft_wrapper_2ch()
93 : *
94 : * Wrapper uses complex FFT to perform real-input FFT on 2 channels simultaneously
95 : *-----------------------------------------------------------------------------------------*/
96 :
97 7814825 : static void fft_wrapper_2ch(
98 : float *buffer_L,
99 : float *buffer_R,
100 : const int16_t fft_size )
101 : {
102 7814825 : const int16_t half_sz = fft_size >> 1;
103 : int16_t k, mirror_k;
104 : float left_re, left_im, right_re, right_im;
105 :
106 7814825 : DoRTFTn( buffer_L, buffer_R, fft_size );
107 :
108 : /* separating left and right channel spectra */
109 1690355456 : for ( k = 1; k < half_sz; k++ )
110 : {
111 1682540631 : mirror_k = fft_size - k;
112 :
113 1682540631 : left_re = 0.5f * ( buffer_L[k] + buffer_L[mirror_k] );
114 1682540631 : left_im = 0.5f * ( buffer_R[k] - buffer_R[mirror_k] );
115 :
116 1682540631 : right_re = 0.5f * ( buffer_R[k] + buffer_R[mirror_k] );
117 1682540631 : right_im = -0.5f * ( buffer_L[k] - buffer_L[mirror_k] );
118 :
119 1682540631 : buffer_L[k] = left_re;
120 1682540631 : buffer_R[k] = right_re;
121 1682540631 : buffer_L[mirror_k] = left_im;
122 1682540631 : buffer_R[mirror_k] = right_im;
123 : }
124 :
125 7814825 : return;
126 : }
127 :
128 : /*-----------------------------------------------------------------------------------------*
129 : * Function ifft_wrapper_2ch()
130 : *
131 : * Wrapper uses complex FFT to perform real-output IFFT on 2 channels simultaneously
132 : *-----------------------------------------------------------------------------------------*/
133 :
134 7814825 : static void ifft_wrapper_2ch(
135 : float *buffer_L,
136 : float *buffer_R,
137 : const int16_t fft_size )
138 : {
139 : float buffer_L_re, buffer_L_im, buffer_R_re, buffer_R_im;
140 7814825 : const int16_t half_sz = fft_size >> 1;
141 7814825 : const float inv_sz = 1.0f / (float) fft_size;
142 : int16_t k, mirror_k;
143 :
144 : /* Re-arranging and adding spectra in order to obtain L/R signals as re/im ifft outputs */
145 1690355456 : for ( k = 1; k < half_sz; k++ )
146 : {
147 1682540631 : mirror_k = fft_size - k;
148 :
149 1682540631 : buffer_L_re = buffer_L[k];
150 1682540631 : buffer_L_im = buffer_L[mirror_k];
151 1682540631 : buffer_R_re = buffer_R[k];
152 1682540631 : buffer_R_im = buffer_R[mirror_k];
153 :
154 1682540631 : buffer_L[k] = buffer_L_re + buffer_R_im;
155 1682540631 : buffer_L[mirror_k] = buffer_L_re - buffer_R_im;
156 1682540631 : buffer_R[k] = buffer_R_re - buffer_L_im;
157 1682540631 : buffer_R[mirror_k] = buffer_R_re + buffer_L_im;
158 : }
159 :
160 7814825 : DoRTFTn( buffer_L, buffer_R, fft_size );
161 :
162 : /* Apply (1/length) scaling for inverse FFT */
163 3388525737 : for ( k = 0; k < fft_size; k++ )
164 : {
165 3380710912 : buffer_L[k] *= inv_sz;
166 3380710912 : buffer_R[k] *= inv_sz;
167 : }
168 :
169 7814825 : return;
170 : }
171 :
172 :
173 : /*-----------------------------------------------------------------------------------------*
174 : * Function ivas_reverb_t2f_f2t_init()
175 : *
176 : * Initializes t2t_f2t struct and clears history
177 : *-----------------------------------------------------------------------------------------*/
178 :
179 5804 : int16_t ivas_reverb_t2f_f2t_init(
180 : ivas_reverb_t2f_f2t_t *t2f_f2t,
181 : const int16_t fft_size,
182 : const int16_t block_size )
183 : {
184 5804 : if ( fft_size > RV_FILTER_MAX_FFT_SIZE )
185 : {
186 0 : return 1;
187 : }
188 :
189 5804 : if ( ( block_size > fft_size ) || ( fft_size - block_size > RV_FILTER_MAX_HISTORY ) )
190 : {
191 0 : return 2;
192 : }
193 :
194 5804 : t2f_f2t->log2_fft_size = int_log2( fft_size );
195 :
196 5804 : if ( ( 1 << t2f_f2t->log2_fft_size ) != fft_size )
197 : {
198 0 : return 3; /* fft_size not a power of 2 */
199 : }
200 5804 : t2f_f2t->fft_size = fft_size;
201 5804 : t2f_f2t->block_size = block_size;
202 5804 : t2f_f2t->hist_size = t2f_f2t->fft_size - t2f_f2t->block_size;
203 :
204 5804 : if ( t2f_f2t->hist_size > RV_FILTER_MAX_HISTORY )
205 : {
206 0 : t2f_f2t->hist_size = RV_FILTER_MAX_HISTORY;
207 : }
208 :
209 5804 : ivas_reverb_t2f_f2t_ClearHistory( t2f_f2t );
210 :
211 5804 : return 0;
212 : }
213 :
214 :
215 : /*-----------------------------------------------------------------------------------------*
216 : * Function ivas_reverb_t2f_f2t_ClearHistory()
217 : *
218 : * Clears the history for the overlap length (fft_size - block_size)
219 : *-----------------------------------------------------------------------------------------*/
220 :
221 11608 : void ivas_reverb_t2f_f2t_ClearHistory(
222 : ivas_reverb_t2f_f2t_t *t2f_f2t )
223 : {
224 : int16_t i;
225 11608 : float *hist_L = t2f_f2t->fft_history_L;
226 11608 : float *hist_R = t2f_f2t->fft_history_R;
227 :
228 2986680 : for ( i = 0; i < t2f_f2t->hist_size; i++ )
229 : {
230 2975072 : hist_L[i] = 0.0f;
231 2975072 : hist_R[i] = 0.0f;
232 : }
233 :
234 11608 : return;
235 : }
236 :
237 :
238 : /*-----------------------------------------------------------------------------------------*
239 : * Function ivas_reverb_t2f_f2t_in()
240 : *
241 : * Input of block data, history is copied, fft is taken for both L/R channels
242 : *-----------------------------------------------------------------------------------------*/
243 :
244 7814825 : void ivas_reverb_t2f_f2t_in(
245 : ivas_reverb_t2f_f2t_t *t2f_f2t,
246 : float *input_L,
247 : float *input_R,
248 : float *buffer_L,
249 : float *buffer_R )
250 : {
251 : int16_t i;
252 7814825 : int16_t hlen = t2f_f2t->hist_size;
253 7814825 : int16_t bsiz = t2f_f2t->block_size;
254 7814825 : float *hist_L = t2f_f2t->fft_history_L;
255 7814825 : float *hist_R = t2f_f2t->fft_history_R;
256 : float *pL, *pR;
257 :
258 : /* copy history to buffer */
259 2092334057 : for ( i = 0; i < hlen; i++ )
260 : {
261 2084519232 : buffer_L[i] = hist_L[i];
262 2084519232 : buffer_R[i] = hist_R[i];
263 : }
264 :
265 : /* copy input to buffer */
266 7814825 : pL = &buffer_L[hlen];
267 7814825 : pR = &buffer_R[hlen];
268 1304006505 : for ( i = 0; i < bsiz; i++ )
269 : {
270 1296191680 : pL[i] = input_L[i];
271 1296191680 : pR[i] = input_R[i];
272 : }
273 :
274 : /* copy buffer to history */
275 7814825 : pL = &buffer_L[bsiz];
276 7814825 : pR = &buffer_R[bsiz];
277 2092334057 : for ( i = 0; i < hlen; i++ )
278 : {
279 2084519232 : hist_L[i] = pL[i];
280 2084519232 : hist_R[i] = pR[i];
281 : }
282 :
283 : /* do FFT */
284 7814825 : fft_wrapper_2ch( buffer_L, buffer_R, t2f_f2t->fft_size );
285 :
286 7814825 : return;
287 : }
288 :
289 :
290 : /*-----------------------------------------------------------------------------------------*
291 : * Function ivas_reverb_t2f_f2t_out()
292 : *
293 : * Input of frequency domain data, IFFT, copied to output (both L & R channels)
294 : *-----------------------------------------------------------------------------------------*/
295 :
296 7814825 : void ivas_reverb_t2f_f2t_out(
297 : ivas_reverb_t2f_f2t_t *t2f_f2t,
298 : float *buffer_L,
299 : float *buffer_R,
300 : float *output_L,
301 : float *output_R )
302 : {
303 : int16_t i;
304 7814825 : float *pL = &buffer_L[t2f_f2t->hist_size];
305 7814825 : float *pR = &buffer_R[t2f_f2t->hist_size];
306 :
307 7814825 : ifft_wrapper_2ch( buffer_L, buffer_R, t2f_f2t->fft_size );
308 :
309 1304006505 : for ( i = 0; i < t2f_f2t->block_size; i++ )
310 : {
311 1296191680 : output_L[i] = pL[i];
312 1296191680 : output_R[i] = pR[i];
313 : }
314 :
315 7814825 : return;
316 : }
317 :
318 :
319 : /*-----------------------------------------------------------------------------------------*
320 : * Function ivas_reverb_fft_filter_init()
321 : *
322 : * Initializes filter struct
323 : *-----------------------------------------------------------------------------------------*/
324 :
325 23216 : int16_t ivas_reverb_fft_filter_init(
326 : ivas_reverb_fft_filter_t *fft_filter,
327 : const int16_t fft_size )
328 : {
329 23216 : if ( fft_size > RV_FILTER_MAX_FFT_SIZE )
330 : {
331 0 : return 1;
332 : }
333 :
334 23216 : fft_filter->fft_size = fft_size;
335 :
336 23216 : return 0;
337 : }
338 :
339 :
340 : /*-----------------------------------------------------------------------------------------*
341 : * Function ivas_reverb_fft_filter_ComplexMul()
342 : *
343 : * Buffer is complex multiplied with fft_filter internal coefficients
344 : *-----------------------------------------------------------------------------------------*/
345 :
346 31259300 : void ivas_reverb_fft_filter_ComplexMul(
347 : ivas_reverb_fft_filter_t *fft_filter,
348 : float *buffer )
349 : {
350 : int16_t f_spec, h, i, j;
351 : float *spec;
352 : float t;
353 :
354 31259300 : f_spec = fft_filter->fft_size;
355 31259300 : h = f_spec >> 1;
356 31259300 : spec = fft_filter->fft_spectrum;
357 :
358 31259300 : buffer[0] *= spec[0]; /* real multiply f0 DC */
359 31259300 : buffer[h] *= spec[h]; /* real multiply f_spec Nyquist */
360 31259300 : j = f_spec - 1;
361 6761421824 : for ( i = 1; i < h; i++ ) /*actual complex multiply in loop */
362 : {
363 6730162524 : t = buffer[i];
364 6730162524 : buffer[i] = t * spec[i] - buffer[j] * spec[j];
365 6730162524 : buffer[j] = t * spec[j] + buffer[j] * spec[i];
366 6730162524 : j--;
367 : }
368 :
369 31259300 : return;
370 : }
371 :
372 :
373 : /*-----------------------------------------------------------------------------------------*
374 : * Function ivas_reverb_fft_filter_ConvertFFTWF_2_FFTR()
375 : *
376 : * Convert the FFTWF formatted spectrum to fft_real formatted spectrum
377 : *-----------------------------------------------------------------------------------------*/
378 :
379 26428 : void ivas_reverb_fft_filter_ConvertFFTWF_2_FFTR(
380 : rv_fftwf_type_complex *spectrum,
381 : float *fft_real,
382 : const int16_t fft_size )
383 : {
384 : int16_t i, h;
385 :
386 26428 : h = fft_size >> 1;
387 26428 : fft_real[0] = spectrum[0][0];
388 26428 : fft_real[h] = spectrum[h][0];
389 5548544 : for ( i = 1; i < h; i++ )
390 : {
391 5522116 : fft_real[i] = spectrum[i][0];
392 5522116 : fft_real[fft_size - i] = spectrum[i][1];
393 : }
394 :
395 26428 : return;
396 : }
397 :
398 :
399 : /*-----------------------------------------------------------------------------------------*
400 : * Function ivas_reverb_fft_filter_CrossMix()
401 : *
402 : * buffer0 and 1 are cross mixed
403 : *-----------------------------------------------------------------------------------------*/
404 :
405 7814825 : void ivas_reverb_fft_filter_CrossMix(
406 : float *buffer0,
407 : float *buffer1,
408 : const int16_t fft_size )
409 : {
410 : float t;
411 : int16_t i;
412 :
413 3388525737 : for ( i = 0; i < fft_size; i++ )
414 : {
415 3380710912 : t = buffer0[i];
416 3380710912 : buffer0[i] = t + buffer1[i];
417 3380710912 : buffer1[i] = t - buffer1[i];
418 : }
419 :
420 7814825 : return;
421 : }
|