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 64629829 : 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 64629829 : 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 64629829 : pos_x = &dn2[track_x << 3];
70 : /* save these to limit memory searches */
71 64629829 : ps0 = *ps;
72 64629829 : alp0 = *alp + 2.0f * R[0];
73 :
74 64629829 : sqk = -1.0F;
75 64629829 : alpk = 1.0F;
76 :
77 64629829 : x = pos_x[0];
78 64629829 : sgnx = sign[track_y];
79 64629829 : if ( sign[x] < 0 )
80 : {
81 31440686 : sgnx = -sgnx;
82 : }
83 64629829 : 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 466627977 : for ( i = 0; i < nb_pos_ix; i++ )
90 : {
91 401998148 : x = pos_x[i];
92 401998148 : sgnx = sign[x];
93 : /* dn[x] has only nb_pos_ix positions saved */
94 401998148 : ps1 = ps0 + dn[x];
95 401998148 : alp1 = alp0 + 2 * sgnx * cor[x];
96 401998148 : pR = R - x;
97 :
98 6833968516 : for ( y = track_y; y < L_SUBFR; y += 4 )
99 : {
100 6431970368 : ps2 = ps1 + dn[y];
101 6431970368 : alp2 = alp1 + 2.0f * sign[y] * ( cor[y] + sgnx * pR[y] );
102 6431970368 : sq = ps2 * ps2;
103 :
104 6431970368 : s = ( alpk * sq ) - ( sqk * alp2 );
105 6431970368 : if ( s > 0.0F )
106 : {
107 373852605 : sqk = sq;
108 373852605 : alpk = alp2;
109 373852605 : y_save = y;
110 373852605 : x_save = x;
111 : }
112 : }
113 : }
114 : /* Update numerator */
115 64629829 : *ps = ps0 + dn[x_save] + dn[y_save];
116 : /* Update denominator */
117 64629829 : *alp = alpk;
118 :
119 : /* Update product of autocorrelation and already fixed pulses. with the
120 : * two newly found ones */
121 64629829 : pRx = R - x_save;
122 64629829 : pRy = R - y_save;
123 64629829 : sign_x = sign[x_save];
124 64629829 : sign_y = sign[y_save];
125 :
126 4200938885 : for ( i = 0; i < L_SUBFR; i++ )
127 : {
128 4136309056 : cor[i] += pRx[i] * sign_x + pRy[i] * sign_y;
129 : }
130 :
131 64629829 : *ix = x_save;
132 64629829 : *iy = y_save;
133 64629829 : if ( ( ( x_save & 3 ) != track_x ) || ( ( y_save & 3 ) != track_y ) )
134 : {
135 : /* sanity check */
136 0 : assert( 0 );
137 : }
138 :
139 64629829 : return;
140 : }
141 :
142 6418766 : 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 6418766 : 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 6418766 : ps0 = *ps;
161 6418766 : alp0 = *alp + R[0];
162 6418766 : sqk = -1.0F;
163 6418766 : alpk = 1.0F;
164 :
165 6418766 : if ( ( alp0 + ( cor[track_x] * sign[track_x] ) ) < 0 )
166 : {
167 0 : sqk = 1.0F;
168 : }
169 :
170 6418766 : x_save = track_x;
171 109119022 : for ( x = track_x; x < L_SUBFR; x += 4 )
172 : {
173 102700256 : ps1 = ps0 + dn[x];
174 102700256 : alp1 = alp0 + 2 * sign[x] * cor[x];
175 102700256 : sq = ps1 * ps1;
176 102700256 : s = ( alpk * sq ) - ( sqk * alp1 );
177 102700256 : if ( s > 0.0F )
178 : {
179 22100156 : sqk = sq;
180 22100156 : alpk = alp1;
181 22100156 : x_save = x;
182 : }
183 : }
184 :
185 6418766 : if ( track_y != track_x )
186 : {
187 29708809 : for ( x = track_y; x < L_SUBFR; x += 4 )
188 : {
189 27961232 : ps1 = ps0 + dn[x];
190 27961232 : alp1 = alp0 + 2 * sign[x] * cor[x];
191 27961232 : sq = ps1 * ps1;
192 27961232 : s = ( alpk * sq ) - ( sqk * alp1 );
193 27961232 : if ( s > 0.0F )
194 : {
195 1128450 : sqk = sq;
196 1128450 : alpk = alp1;
197 1128450 : x_save = x;
198 : }
199 : }
200 : }
201 :
202 6418766 : *ps = ps0 + dn[x_save];
203 6418766 : *alp = alpk;
204 6418766 : *ix = x_save;
205 :
206 6418766 : return;
207 : }
208 :
209 :
210 : /* Autocorrelation method for searching pulse positions effectively
211 : * Algorithm is identical to traditional covariance method. */
212 3922797 : 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 3922797 : 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 3922797 : 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 3922797 : alp = config->alp;
237 55422609 : for ( k = 0; k < config->nb_pulse; k++ )
238 : {
239 51499812 : codvec[k] = ( k & 3 );
240 : }
241 :
242 3922797 : set_f( cor, 0.0f, L_SUBFR );
243 :
244 : /* Set up autocorrelation vector */
245 3922797 : R = R_buf + L_SUBFR - 1;
246 3922797 : R[0] = Rw[0];
247 251059008 : for ( k = 1; k < L_SUBFR; k++ )
248 : {
249 247136211 : R[k] = R[-k] = Rw[k];
250 : }
251 :
252 : /* Find sign for each pulse position. */
253 3922797 : acelp_pulsesign( cn, dn, dn2, sign, vec, alp );
254 :
255 : /* Select the most important 8 position per track according to dn2[]. */
256 3922797 : 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 3922797 : ps2k = -1.0;
269 3922797 : alpk = 1000.0;
270 : /*Number of iterations*/
271 17858679 : for ( k = 0; k < config->nbiter; k++ )
272 : {
273 : /* copy search order from hash-table */
274 191946702 : for ( l = 0; l < config->nb_pulse; l++ )
275 : {
276 178010820 : ipos[l] = tipos[( k * 4 ) + l];
277 : }
278 :
279 : /* if all tracks do not have equal number of pulses */
280 13935882 : restpulses = config->nb_pulse & 3;
281 13935882 : if ( restpulses )
282 : {
283 10141755 : switch ( config->codetrackpos )
284 : {
285 6998505 : case TRACKPOS_FIXED_FIRST: /* fixed track positions, starting from left */
286 : /* add tracks from left */
287 21092042 : for ( iPulse = 0; iPulse < restpulses; iPulse++ )
288 : {
289 14093537 : 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 6998505 : ipos[config->nb_pulse] = ipos[config->nb_pulse - 1];
294 6998505 : 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 1395673 : 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 1395673 : ipos[config->nb_pulse] = ( ipos[config->nb_pulse - 1] + 1 ) & 3;
304 1395673 : break;
305 1747577 : default: /* one or three free track positions */
306 : /* copy an extra position from table - 1pulse search will access this */
307 1747577 : ipos[config->nb_pulse] = tipos[( k * 4 ) + config->nb_pulse];
308 1747577 : break;
309 : }
310 3794127 : }
311 13935882 : if ( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */
312 : {
313 854249 : pos = 0;
314 854249 : ps = 0.0F;
315 854249 : alp = 0.0F;
316 55526185 : for ( i = 0; i < L_SUBFR; i++ )
317 : {
318 54671936 : cor[i] = 0;
319 : }
320 : }
321 13081633 : else if ( config->fixedpulses == 2 ) /* 2222 and 3322 */
322 : {
323 : /* --- first stage: fix 2 pulses --- */
324 : /* index to first non-fixed position */
325 4997068 : pos = 2;
326 :
327 : /* set fixed positions */
328 4997068 : ind[0] = pos_max[ipos[0]];
329 4997068 : ind[1] = pos_max[ipos[1]];
330 :
331 : /* correlation of fixed part with residual */
332 4997068 : ps = dn[ind[0]] + dn[ind[1]];
333 :
334 : /* multiplication of autocorrelation with signed fixed pulses */
335 : /* first pulse */
336 4997068 : p0 = R - ind[0];
337 4997068 : if ( sign[ind[0]] > 0 )
338 : {
339 166246015 : for ( i = 0; i < L_SUBFR; i++ )
340 : {
341 163688384 : cor[i] = *p0;
342 163688384 : p0++;
343 : }
344 : }
345 : else
346 : {
347 158563405 : for ( i = 0; i < L_SUBFR; i++ )
348 : {
349 156123968 : cor[i] = -*p0;
350 156123968 : p0++;
351 : }
352 : }
353 : /* second pulse */
354 4997068 : p0 = R - ind[1];
355 4997068 : if ( sign[ind[1]] > 0 )
356 : {
357 166233145 : for ( i = 0; i < L_SUBFR; i++ )
358 : {
359 163675712 : cor[i] += *p0;
360 163675712 : p0++;
361 : }
362 : }
363 : else
364 : {
365 158576275 : for ( i = 0; i < L_SUBFR; i++ )
366 : {
367 156136640 : cor[i] -= *p0;
368 156136640 : p0++;
369 : }
370 : }
371 :
372 : /* normalisation contribution of fixed part */
373 4997068 : 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 8084565 : pos = 4;
379 :
380 8084565 : ind[0] = pos_max[ipos[0]];
381 8084565 : ind[1] = pos_max[ipos[1]];
382 8084565 : ind[2] = pos_max[ipos[2]];
383 8084565 : ind[3] = pos_max[ipos[3]];
384 :
385 : /* correlation of fixed part with residual */
386 8084565 : 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 8084565 : p0 = R - ind[0];
391 8084565 : if ( sign[ind[0]] > 0 )
392 : {
393 270046790 : for ( i = 0; i < L_SUBFR; i++ )
394 : {
395 265892224 : cor[i] = *p0;
396 265892224 : p0++;
397 : }
398 : }
399 : else
400 : {
401 255449935 : for ( i = 0; i < L_SUBFR; i++ )
402 : {
403 251519936 : cor[i] = -*p0;
404 251519936 : p0++;
405 : }
406 : }
407 : /* pulses 1..3 */
408 32338260 : for ( j = 1; j < 4; j++ )
409 : {
410 24253695 : p0 = R - ind[j];
411 24253695 : if ( sign[ind[j]] > 0 )
412 : {
413 810609865 : for ( i = 0; i < L_SUBFR; i++ )
414 : {
415 798138944 : cor[i] += *p0;
416 798138944 : p0++;
417 : }
418 : }
419 : else
420 : {
421 765880310 : for ( i = 0; i < L_SUBFR; i++ )
422 : {
423 754097536 : cor[i] -= *p0;
424 754097536 : p0++;
425 : }
426 : }
427 : }
428 :
429 : /* normalisation contribution of fixed part */
430 8084565 : 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 84984477 : for ( j = pos, st = 0; j < config->nb_pulse; j += 2, st++ )
435 : {
436 71048595 : 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 64629829 : 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 6418766 : 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 13935882 : ps2 = ps * ps;
455 13935882 : s = ( alpk * ps2 ) - ( ps2k * alp );
456 13935882 : if ( s > 0.0F )
457 : {
458 7669241 : ps2k = ps2;
459 7669241 : psk = ps;
460 7669241 : alpk = alp;
461 107128080 : for ( i = 0; i < config->nb_pulse; i++ )
462 : {
463 99458839 : codvec[i] = ind[i];
464 : }
465 : }
466 : }
467 :
468 : /* Store weighted energy of code, build the codeword and index of codevector. */
469 3922797 : set_f( code, 0, L_SUBFR );
470 3922797 : set_s( ind, -1, NPMAXPT * 4 );
471 :
472 55422609 : for ( k = 0; k < config->nb_pulse; k++ )
473 : {
474 51499812 : i = codvec[k]; /* read pulse position */
475 51499812 : val = sign[i]; /* read sign */
476 :
477 51499812 : index = i / 4; /* pos of pulse (0..15) */
478 51499812 : track = i % 4;
479 51499812 : if ( val * psk > 0 )
480 : {
481 25621039 : code[i] += 1.0f;
482 25621039 : codvec[k] += ( 2 * L_SUBFR );
483 : }
484 : else
485 : {
486 25878773 : code[i] -= 1.0f;
487 25878773 : index += 16;
488 : }
489 :
490 51499812 : i = track * NPMAXPT;
491 121884712 : while ( ind[i] >= 0 )
492 : {
493 70384900 : i++;
494 : }
495 :
496 51499812 : ind[i] = index;
497 : }
498 :
499 3922797 : return;
500 : }
|