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