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 : #ifdef DEBUGGING
41 : #include "debug.h"
42 : #endif
43 : #include "prot.h"
44 : #include "rom_enc.h"
45 : #include "wmc_auto.h"
46 :
47 :
48 : /* Iterations: nb_pos_ix*16 */
49 6250629 : static void E_ACELP_2pulse_searchx(
50 : const int16_t nb_pos_ix,
51 : const int16_t track_x,
52 : const int16_t track_y,
53 : float *R,
54 : float *ps,
55 : float *alp,
56 : int16_t *ix,
57 : int16_t *iy,
58 : float dn[],
59 : int16_t *dn2,
60 : float cor[],
61 : float sign[] )
62 : {
63 : int16_t i;
64 6250629 : int16_t x, y, *pos_x, x_save = 0, y_save = 0;
65 : float ps0, alp0, alp1, ps1, alp2, ps2, sq, s, sqk, alpk, *pR, sgnx, *pRx, *pRy, sign_x, sign_y;
66 :
67 : /* x_save=y_save=0 */
68 : /* eight dn2 max positions per track */
69 6250629 : pos_x = &dn2[track_x << 3];
70 : /* save these to limit memory searches */
71 6250629 : ps0 = *ps;
72 6250629 : alp0 = *alp + 2.0f * R[0];
73 :
74 6250629 : sqk = -1.0F;
75 6250629 : alpk = 1.0F;
76 :
77 6250629 : x = pos_x[0];
78 6250629 : sgnx = sign[track_y];
79 6250629 : if ( sign[x] < 0 )
80 : {
81 3045056 : sgnx = -sgnx;
82 : }
83 6250629 : if ( ( alp0 + ( cor[x] * sign[x] ) + ( cor[track_y] * sign[track_y] ) + ( R[track_y - x] * sgnx ) ) < 0.0F )
84 : {
85 0 : sqk = 1.0F;
86 : }
87 :
88 : /* loop track 1 */
89 45588378 : for ( i = 0; i < nb_pos_ix; i++ )
90 : {
91 39337749 : x = pos_x[i];
92 39337749 : sgnx = sign[x];
93 : /* dn[x] has only nb_pos_ix positions saved */
94 39337749 : ps1 = ps0 + dn[x];
95 39337749 : alp1 = alp0 + 2 * sgnx * cor[x];
96 39337749 : pR = R - x;
97 :
98 668741733 : for ( y = track_y; y < L_SUBFR; y += 4 )
99 : {
100 629403984 : ps2 = ps1 + dn[y];
101 629403984 : alp2 = alp1 + 2.0f * sign[y] * ( cor[y] + sgnx * pR[y] );
102 629403984 : sq = ps2 * ps2;
103 :
104 629403984 : s = ( alpk * sq ) - ( sqk * alp2 );
105 629403984 : if ( s > 0.0F )
106 : {
107 35969571 : sqk = sq;
108 35969571 : alpk = alp2;
109 35969571 : y_save = y;
110 35969571 : x_save = x;
111 : }
112 : }
113 : }
114 : /* Update numerator */
115 6250629 : *ps = ps0 + dn[x_save] + dn[y_save];
116 : /* Update denominator */
117 6250629 : *alp = alpk;
118 :
119 : /* Update product of autocorrelation and already fixed pulses. with the
120 : * two newly found ones */
121 6250629 : pRx = R - x_save;
122 6250629 : pRy = R - y_save;
123 6250629 : sign_x = sign[x_save];
124 6250629 : sign_y = sign[y_save];
125 :
126 406290885 : for ( i = 0; i < L_SUBFR; i++ )
127 : {
128 400040256 : cor[i] += pRx[i] * sign_x + pRy[i] * sign_y;
129 : }
130 :
131 6250629 : *ix = x_save;
132 6250629 : *iy = y_save;
133 6250629 : if ( ( ( x_save & 3 ) != track_x ) || ( ( y_save & 3 ) != track_y ) )
134 : {
135 : /* sanity check */
136 0 : assert( 0 );
137 : }
138 :
139 6250629 : return;
140 : }
141 :
142 611156 : static void E_ACELP_1pulse_searchx(
143 : int16_t track_x,
144 : int16_t track_y,
145 : float *R,
146 : float *ps,
147 : float *alp,
148 : int16_t *ix,
149 : float dn[],
150 : float cor[],
151 : float sign[] )
152 : {
153 611156 : int16_t x, x_save = 0;
154 : float ps0, alp0;
155 : float ps1, sq, sqk;
156 : float alp1, alpk;
157 : float s;
158 :
159 : /* save these to limit memory searches */
160 611156 : ps0 = *ps;
161 611156 : alp0 = *alp + R[0];
162 611156 : sqk = -1.0F;
163 611156 : alpk = 1.0F;
164 :
165 611156 : if ( ( alp0 + ( cor[track_x] * sign[track_x] ) ) < 0 )
166 : {
167 0 : sqk = 1.0F;
168 : }
169 :
170 611156 : x_save = track_x;
171 10389652 : for ( x = track_x; x < L_SUBFR; x += 4 )
172 : {
173 9778496 : ps1 = ps0 + dn[x];
174 9778496 : alp1 = alp0 + 2 * sign[x] * cor[x];
175 9778496 : sq = ps1 * ps1;
176 9778496 : s = ( alpk * sq ) - ( sqk * alp1 );
177 9778496 : if ( s > 0.0F )
178 : {
179 2121807 : sqk = sq;
180 2121807 : alpk = alp1;
181 2121807 : x_save = x;
182 : }
183 : }
184 :
185 611156 : if ( track_y != track_x )
186 : {
187 2719609 : for ( x = track_y; x < L_SUBFR; x += 4 )
188 : {
189 2559632 : ps1 = ps0 + dn[x];
190 2559632 : alp1 = alp0 + 2 * sign[x] * cor[x];
191 2559632 : sq = ps1 * ps1;
192 2559632 : s = ( alpk * sq ) - ( sqk * alp1 );
193 2559632 : if ( s > 0.0F )
194 : {
195 102044 : sqk = sq;
196 102044 : alpk = alp1;
197 102044 : x_save = x;
198 : }
199 : }
200 : }
201 :
202 611156 : *ps = ps0 + dn[x_save];
203 611156 : *alp = alpk;
204 611156 : *ix = x_save;
205 :
206 611156 : return;
207 : }
208 :
209 :
210 : /* Autocorrelation method for searching pulse positions effectively
211 : * Algorithm is identical to traditional covariance method. */
212 395563 : void E_ACELP_4tsearchx(
213 : float dn[],
214 : const float cn[],
215 : float Rw[],
216 : float code[],
217 : PulseConfig *config,
218 : int16_t ind[] )
219 : {
220 : float sign[L_SUBFR], vec[L_SUBFR];
221 : float cor[L_SUBFR];
222 : float R_buf[2 * L_SUBFR - 1], *R;
223 : float dn2[L_SUBFR];
224 395563 : float psk = 0.0F, ps2k, ps, ps2, alpk, alp = 0.0F;
225 : int16_t codvec[NB_PULSE_MAX];
226 : int16_t pos_max[4];
227 : int16_t dn2_pos[8 * 4];
228 : int16_t ipos[NB_PULSE_MAX];
229 : float *p0;
230 395563 : int16_t i, j, k, l, st, pos = 0, index, track;
231 : int16_t iPulse;
232 : float val;
233 : float s;
234 : int16_t restpulses;
235 :
236 395563 : alp = config->alp;
237 5377458 : for ( k = 0; k < config->nb_pulse; k++ )
238 : {
239 4981895 : codvec[k] = ( k & 3 );
240 : }
241 :
242 395563 : set_f( cor, 0.0f, L_SUBFR );
243 :
244 : /* Set up autocorrelation vector */
245 395563 : R = R_buf + L_SUBFR - 1;
246 395563 : R[0] = Rw[0];
247 25316032 : for ( k = 1; k < L_SUBFR; k++ )
248 : {
249 24920469 : R[k] = R[-k] = Rw[k];
250 : }
251 :
252 : /* Find sign for each pulse position. */
253 395563 : acelp_pulsesign( cn, dn, dn2, sign, vec, alp );
254 :
255 : /* Select the most important 8 position per track according to dn2[]. */
256 395563 : acelp_findcandidates( dn2, dn2_pos, pos_max, L_SUBFR, NB_TRACK_FCB_4T );
257 :
258 : /*
259 : * Deep first search:
260 : * ------------------
261 : * 20 bits (4p): 4 iter x ((4x16)+(8x16)) = 768 tests
262 : * 36 bits (8p): 4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests
263 : * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16)
264 : * +(8x16)+(8x16)) = 1248 tests
265 : * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16)
266 : * +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests
267 : */
268 395563 : ps2k = -1.0;
269 395563 : alpk = 1000.0;
270 : /*Number of iterations*/
271 1801170 : for ( k = 0; k < config->nbiter; k++ )
272 : {
273 : /* copy search order from hash-table */
274 18441727 : for ( l = 0; l < config->nb_pulse; l++ )
275 : {
276 17036120 : ipos[l] = tipos[( k * 4 ) + l];
277 : }
278 :
279 : /* if all tracks do not have equal number of pulses */
280 1405607 : restpulses = config->nb_pulse & 3;
281 1405607 : if ( restpulses )
282 : {
283 1004486 : switch ( config->codetrackpos )
284 : {
285 681364 : case TRACKPOS_FIXED_FIRST: /* fixed track positions, starting from left */
286 : /* add tracks from left */
287 2036727 : for ( iPulse = 0; iPulse < restpulses; iPulse++ )
288 : {
289 1355363 : ipos[config->nb_pulse - restpulses + iPulse] = iPulse;
290 : }
291 : /* Put the same track on the next position, because the 1-pulse search
292 : * will access it to determine if this could be in any track. */
293 681364 : ipos[config->nb_pulse] = ipos[config->nb_pulse - 1];
294 681364 : break;
295 0 : case TRACKPOS_FIXED_EVEN: /* fixed track positions, odd tracks */
296 : /* odd tracks, switch order for every iteration */
297 0 : ipos[config->nb_pulse - restpulses] = ( k << 1 ) & 2; /* 0 for even k, 2 for odd*/
298 0 : ipos[config->nb_pulse - restpulses + 1] = ipos[config->nb_pulse - restpulses] ^ 2; /* 2 for even k, 0 for odd*/
299 0 : break;
300 163145 : case TRACKPOS_FIXED_TWO: /* two tracks instead of four */
301 : /* Put the next track on the next position, because the 1-pulse search
302 : * will access it to determine if this could be in any track. */
303 163145 : ipos[config->nb_pulse] = ( ipos[config->nb_pulse - 1] + 1 ) & 3;
304 163145 : break;
305 159977 : default: /* one or three free track positions */
306 : /* copy an extra position from table - 1pulse search will access this */
307 159977 : ipos[config->nb_pulse] = tipos[( k * 4 ) + config->nb_pulse];
308 159977 : break;
309 : }
310 401121 : }
311 1405607 : if ( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */
312 : {
313 106990 : pos = 0;
314 106990 : ps = 0.0F;
315 106990 : alp = 0.0F;
316 6954350 : for ( i = 0; i < L_SUBFR; i++ )
317 : {
318 6847360 : cor[i] = 0;
319 : }
320 : }
321 1298617 : else if ( config->fixedpulses == 2 ) /* 2222 and 3322 */
322 : {
323 : /* --- first stage: fix 2 pulses --- */
324 : /* index to first non-fixed position */
325 635381 : pos = 2;
326 :
327 : /* set fixed positions */
328 635381 : ind[0] = pos_max[ipos[0]];
329 635381 : ind[1] = pos_max[ipos[1]];
330 :
331 : /* correlation of fixed part with residual */
332 635381 : ps = dn[ind[0]] + dn[ind[1]];
333 :
334 : /* multiplication of autocorrelation with signed fixed pulses */
335 : /* first pulse */
336 635381 : p0 = R - ind[0];
337 635381 : if ( sign[ind[0]] > 0 )
338 : {
339 21061690 : for ( i = 0; i < L_SUBFR; i++ )
340 : {
341 20737664 : cor[i] = *p0;
342 20737664 : p0++;
343 : }
344 : }
345 : else
346 : {
347 20238075 : for ( i = 0; i < L_SUBFR; i++ )
348 : {
349 19926720 : cor[i] = -*p0;
350 19926720 : p0++;
351 : }
352 : }
353 : /* second pulse */
354 635381 : p0 = R - ind[1];
355 635381 : if ( sign[ind[1]] > 0 )
356 : {
357 21060520 : for ( i = 0; i < L_SUBFR; i++ )
358 : {
359 20736512 : cor[i] += *p0;
360 20736512 : p0++;
361 : }
362 : }
363 : else
364 : {
365 20239245 : for ( i = 0; i < L_SUBFR; i++ )
366 : {
367 19927872 : cor[i] -= *p0;
368 19927872 : p0++;
369 : }
370 : }
371 :
372 : /* normalisation contribution of fixed part */
373 635381 : alp = sign[ind[0]] * cor[ind[0]] + sign[ind[1]] * cor[ind[1]];
374 : }
375 : else /* if (config->fixedpulses == 4) */ /* 3333 and above */
376 : {
377 : /* first stage: fix 4 pulses */
378 663236 : pos = 4;
379 :
380 663236 : ind[0] = pos_max[ipos[0]];
381 663236 : ind[1] = pos_max[ipos[1]];
382 663236 : ind[2] = pos_max[ipos[2]];
383 663236 : ind[3] = pos_max[ipos[3]];
384 :
385 : /* correlation of fixed part with residual */
386 663236 : ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];
387 :
388 : /* multiplication of autocorrelation with signed fixed pulses */
389 : /* first pulse */
390 663236 : p0 = R - ind[0];
391 663236 : if ( sign[ind[0]] > 0 )
392 : {
393 22137310 : for ( i = 0; i < L_SUBFR; i++ )
394 : {
395 21796736 : cor[i] = *p0;
396 21796736 : p0++;
397 : }
398 : }
399 : else
400 : {
401 20973030 : for ( i = 0; i < L_SUBFR; i++ )
402 : {
403 20650368 : cor[i] = -*p0;
404 20650368 : p0++;
405 : }
406 : }
407 : /* pulses 1..3 */
408 2652944 : for ( j = 1; j < 4; j++ )
409 : {
410 1989708 : p0 = R - ind[j];
411 1989708 : if ( sign[ind[j]] > 0 )
412 : {
413 66468805 : for ( i = 0; i < L_SUBFR; i++ )
414 : {
415 65446208 : cor[i] += *p0;
416 65446208 : p0++;
417 : }
418 : }
419 : else
420 : {
421 62862215 : for ( i = 0; i < L_SUBFR; i++ )
422 : {
423 61895104 : cor[i] -= *p0;
424 61895104 : p0++;
425 : }
426 : }
427 : }
428 :
429 : /* normalisation contribution of fixed part */
430 663236 : alp = sign[ind[0]] * cor[ind[0]] + sign[ind[1]] * cor[ind[1]] + sign[ind[2]] * cor[ind[2]] + sign[ind[3]] * cor[ind[3]];
431 : }
432 :
433 : /* other stages of 2 pulses */
434 8267392 : for ( j = pos, st = 0; j < config->nb_pulse; j += 2, st++ )
435 : {
436 6861785 : if ( ( config->nb_pulse - j ) >= 2 )
437 : {
438 : /*pair-wise search*/
439 :
440 : /* Calculate correlation of all possible positions
441 : * of the next 2 pulses with previous fixed pulses.
442 : * Each pulse can have 16 possible positions. */
443 :
444 6250629 : E_ACELP_2pulse_searchx( config->nbpos[st], ipos[j], ipos[j + 1], R, &ps, &alp, &ind[j], &ind[j + 1], dn, dn2_pos, cor, sign );
445 : }
446 : else
447 : {
448 : /*single pulse search*/
449 611156 : E_ACELP_1pulse_searchx( ipos[j], ipos[j + 1], R, &ps, &alp, &ind[j], dn, cor, sign );
450 : }
451 : }
452 :
453 : /* memorise the best codevector */
454 1405607 : ps2 = ps * ps;
455 1405607 : s = ( alpk * ps2 ) - ( ps2k * alp );
456 1405607 : if ( s > 0.0F )
457 : {
458 772904 : ps2k = ps2;
459 772904 : psk = ps;
460 772904 : alpk = alp;
461 10326837 : for ( i = 0; i < config->nb_pulse; i++ )
462 : {
463 9553933 : codvec[i] = ind[i];
464 : }
465 : }
466 : }
467 :
468 : /* Store weighted energy of code, build the codeword and index of codevector. */
469 395563 : set_f( code, 0, L_SUBFR );
470 395563 : set_s( ind, -1, NPMAXPT * 4 );
471 :
472 5377458 : for ( k = 0; k < config->nb_pulse; k++ )
473 : {
474 4981895 : i = codvec[k]; /* read pulse position */
475 4981895 : val = sign[i]; /* read sign */
476 :
477 4981895 : index = i / 4; /* pos of pulse (0..15) */
478 4981895 : track = i % 4;
479 4981895 : if ( val * psk > 0 )
480 : {
481 2483089 : code[i] += 1.0f;
482 2483089 : codvec[k] += ( 2 * L_SUBFR );
483 : }
484 : else
485 : {
486 2498806 : code[i] -= 1.0f;
487 2498806 : index += 16;
488 : }
489 :
490 4981895 : i = track * NPMAXPT;
491 11630541 : while ( ind[i] >= 0 )
492 : {
493 6648646 : i++;
494 : }
495 :
496 4981895 : ind[i] = index;
497 : }
498 :
499 395563 : return;
500 : }
|