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 <math.h> /* for ldexp() */
43 : #include "cnst.h"
44 : #include "rom_com.h"
45 : #include "prot.h"
46 : #include "wmc_auto.h"
47 :
48 :
49 : /*-------------------------------------------------------------------*
50 : * Local function prototypes
51 : *-------------------------------------------------------------------*/
52 :
53 : static int16_t re8_identify_absolute_leader( const int16_t y[] );
54 :
55 : static void re8_coord( const int16_t y[], int16_t k[] );
56 :
57 :
58 : /*----------------------------------------------------------------*
59 : * re8_vor()
60 : *
61 : * Multi-rate RE8 indexing by Voronoi extension
62 : *----------------------------------------------------------------*/
63 :
64 1960406 : void re8_vor(
65 : int16_t y[], /* i : point in RE8 (8-dimensional integer vector) */
66 : int16_t *n, /* o : codebook number n=0,2,3,4,... (scalar integer) */
67 : int16_t k[], /* o : Voronoi index (integer vector of dimension 8) used only if n>4 */
68 : int16_t c[], /* o : codevector in Q0, Q2, Q3, or Q4 if n<=4, y=c */
69 : int16_t *ka /* o : identifier of absolute leader (needed to index c)*/
70 : )
71 : {
72 : int16_t v[8];
73 : int16_t k_mod[8], c_tmp[8];
74 : int16_t i, r, m, k_tmp[8], iter, ka_tmp, n_tmp, mask;
75 : float sphere;
76 :
77 : /*----------------------------------------------------------------*
78 : * verify if y is in Q0, Q2, Q3 or Q4
79 : * (a fast search is used here:
80 : * the codebooks Q0, Q2, Q3 or Q4 are specified in terms of RE8 absolute leaders
81 : * (see FORinstance Xie and Adoul's paper in ICASSP 96)
82 : * - a unique code identifying the absolute leader related to y is computed
83 : * in re8_identify_absolute_leader()
84 : * this code is searched FORin a pre-defined list which specifies Q0, Q2, Q3 or Q4)
85 : * the absolute leader is identified by ka
86 : * - a translation table maps ka to the codebook number n)
87 : *----------------------------------------------------------------*/
88 :
89 1960406 : *ka = re8_identify_absolute_leader( y );
90 :
91 : /*----------------------------------------------------------------*
92 : * compute codebook number n of Qn (by table look-up)
93 : * at this stage, n=0,2,3,4 or out=100
94 : *----------------------------------------------------------------*/
95 :
96 1960406 : *n = Da_nq[*ka];
97 :
98 : /*----------------------------------------------------------------*
99 : * decompose y into :
100 : * (if n<=4:)
101 : * y = c where c is in Q0, Q2, Q3 or Q4
102 : * or
103 : * (if n>4:)
104 : * y = m c + v where c is in Q3 or Q4, v is a Voronoi codevector
105 : * m=2^r (r integer >=2)
106 : *
107 : * in the latter case (if n>4), as a side-product, compute the (Voronoi) index k[] of v
108 : * and replace n by n = n' + 2r where n' = 3 or 4 (c is in Qn') and r is defined above
109 : *----------------------------------------------------------------*/
110 :
111 1960406 : if ( *n <= 4 )
112 : {
113 16771689 : for ( i = 0; i < 8; i++ )
114 : {
115 14908168 : c[i] = y[i];
116 : }
117 : }
118 : else
119 : {
120 : /*------------------------------------------------------------*
121 : * initialize r and m=2^r based on || y ||^2/8
122 : *------------------------------------------------------------*/
123 :
124 96885 : sphere = 0.0;
125 871965 : for ( i = 0; i < 8; i++ )
126 : {
127 775080 : sphere += (float) y[i] * (float) y[i];
128 : }
129 96885 : sphere *= 0.125;
130 96885 : r = 1;
131 96885 : sphere *= 0.25; /* not counted, merge 0.125*0.25 */
132 97282 : while ( sphere > 11.0 )
133 : {
134 397 : r++;
135 397 : sphere *= 0.25;
136 : }
137 : /*------------------------------------------------------------*
138 : * compute the coordinates of y in the RE8 basis
139 : *------------------------------------------------------------*/
140 :
141 96885 : re8_coord( y, k_mod );
142 :
143 : /*------------------------------------------------------------*
144 : * compute m and the mask needed for modulo m (for Voronoi coding)
145 : *------------------------------------------------------------*/
146 :
147 96885 : m = 1 << r;
148 96885 : mask = m - 1; /* 0x0..011...1 */
149 :
150 : /*------------------------------------------------------------*
151 : * find the minimal value of r (or equivalently of m) in 2 iterations
152 : *------------------------------------------------------------*/
153 :
154 290655 : for ( iter = 0; iter < 2; iter++ )
155 : {
156 : /*--------------------------------------------------------*
157 : * compute v such that y is in m RE_8 +v (by Voronoi coding)
158 : *--------------------------------------------------------*/
159 :
160 1743930 : for ( i = 0; i < 8; i++ )
161 : {
162 1550160 : k_tmp[i] = k_mod[i] & mask;
163 : }
164 :
165 193770 : re8_k2y( k_tmp, m, v );
166 :
167 : /*--------------------------------------------------------*
168 : * compute c = (y-v)/m
169 : * (y is in RE8, c is also in RE8 by definition of v)
170 : *--------------------------------------------------------*/
171 :
172 1743930 : for ( i = 0; i < 8; i++ )
173 : {
174 1550160 : c_tmp[i] = ( y[i] - v[i] ) / m;
175 : /* M IS A FACTOR OF 2 */
176 : }
177 :
178 : /*--------------------------------------------------------*
179 : * verify if c_tmp is in Q2, Q3 or Q4
180 : *--------------------------------------------------------*/
181 :
182 193770 : ka_tmp = re8_identify_absolute_leader( c_tmp );
183 :
184 : /*--------------------------------------------------------*
185 : * at this stage, n_tmp=2,3,4 or out = 100 -- n=0 is not possible
186 : *--------------------------------------------------------*/
187 :
188 193770 : n_tmp = Da_nq[ka_tmp];
189 :
190 193770 : if ( n_tmp > 4 )
191 : {
192 : /*--------------------------------------------------------*
193 : * if c is not in Q2, Q3, or Q4 (i.e. n_tmp>4), use m = 2^(r+1) instead of 2^r
194 : *--------------------------------------------------------*/
195 :
196 96883 : r++;
197 96883 : m = m << 1;
198 96883 : mask = ( ( mask << 1 ) + 1 ); /* mask = m-1; <- this is less complex */
199 : }
200 : else
201 : {
202 : /*--------------------------------------------------------*
203 : * c is in Q2, Q3, or Q4 -> the decomposition of y as y = m c + v is valid
204 : *
205 : * since Q2 is a subset of Q3, indicate n=3 instead of n=2 (this is because
206 : * for n>4, n=n'+2r with n'=3 or 4, so n'=2 is not valid)
207 : *--------------------------------------------------------*/
208 :
209 96887 : if ( n_tmp < 3 )
210 : {
211 9886 : n_tmp = 3;
212 : }
213 :
214 : /*--------------------------------------------------------*
215 : * save current values into ka, n, k and c
216 : *--------------------------------------------------------*/
217 :
218 96887 : *ka = ka_tmp;
219 96887 : *n = n_tmp + 2 * r;
220 871983 : for ( i = 0; i < 8; i++ )
221 : {
222 775096 : k[i] = k_tmp[i];
223 775096 : c[i] = c_tmp[i];
224 : }
225 :
226 : /*--------------------------------------------------------*
227 : * try m = 2^(r-1) instead of 2^r to be sure that m is minimal
228 : *--------------------------------------------------------*/
229 :
230 96887 : r--;
231 96887 : m = m >> 1;
232 96887 : mask = mask >> 1;
233 : }
234 : }
235 : }
236 :
237 1960406 : return;
238 : }
239 :
240 : /*-----------------------------------------------------------------------*
241 : * re8_identify_absolute_leader()
242 : *
243 : * Identify the absolute leader related to y using a pre-defined table which
244 : * specifies the codebooks Q0, Q2, Q3 and Q4
245 : -----------------------------------------------------------------------*/
246 :
247 : /*! r: integer indicating if y if in Q0, Q2, Q3 or Q4 (or if y is an outlier) */
248 2154176 : static int16_t re8_identify_absolute_leader(
249 : const int16_t y[] /* i : point in RE8 (8-dimensional integer vector) */
250 : )
251 : {
252 : int16_t i, id, nb, pos, ka;
253 : int32_t s, C[8], tmp;
254 :
255 : /*-----------------------------------------------------------------------*
256 : * compute the RE8 shell number s = (y1^2+...+y8^2)/8 and C=(y1^2, ..., y8^2)
257 : *-----------------------------------------------------------------------*/
258 :
259 2154176 : s = 0;
260 19387584 : for ( i = 0; i < 8; i++ )
261 : {
262 17233408 : C[i] = y[i] * y[i];
263 17233408 : s += C[i];
264 : }
265 2154176 : s >>= 3;
266 :
267 : /*-----------------------------------------------------------------------*
268 : * compute the index 0 <= ka <= NB_LEADER+1 which identifies an absolute leader of Q0, Q2, Q3 or Q4
269 : *
270 : * by default, ka=index of last element of the table (to indicate an outlier)
271 : *-----------------------------------------------------------------------*/
272 :
273 2154176 : ka = NB_LEADER + 1;
274 2154176 : if ( s == 0 )
275 : {
276 : /*-------------------------------------------------------------------*
277 : * if s=0, y=0 i.e. y is in Q0 -> ka=index of element indicating Q0
278 : *-------------------------------------------------------------------*/
279 :
280 212396 : ka = NB_LEADER;
281 : }
282 : else
283 : {
284 : /*-------------------------------------------------------------------*
285 : * the maximal value of s for y in Q0, Q2, Q3 or Q4 is NB_SPHERE
286 : * if s> NB_SPHERE, y is an outlier (the value of ka is set correctly)
287 : *-------------------------------------------------------------------*/
288 :
289 1941780 : if ( s <= NB_SPHERE )
290 : {
291 : /*---------------------------------------------------------------*
292 : * compute the unique identifier id of the absolute leader related to y:
293 : * s = (y1^4 + ... + y8^4)/8
294 : *---------------------------------------------------------------*/
295 :
296 1941135 : tmp = 0;
297 17470215 : for ( i = 0; i < 8; i++ )
298 : {
299 15529080 : tmp += C[i] * C[i];
300 : }
301 1941135 : id = (int16_t) ( tmp >> 3 );
302 :
303 : /*---------------------------------------------------------------*
304 : * search for id in table Da_id
305 : * (containing all possible values of id if y is in Q2, Q3 or Q4)
306 : * this search is focused based on the shell number s so that
307 : * only the id's related to the shell of number s are checked
308 : *---------------------------------------------------------------*/
309 :
310 1941135 : nb = Da_nb[s - 1]; /* get the number of absolute leaders used on the shell of number s */
311 1941135 : pos = Da_pos[s - 1]; /* get the position of the first absolute leader of shell s in Da_id */
312 3378912 : for ( i = 0; i < nb; i++ )
313 : {
314 3185789 : if ( id == Da_id[pos] )
315 : {
316 1748012 : ka = pos; /* get ka */
317 1748012 : break;
318 : }
319 1437777 : pos++;
320 : }
321 : }
322 : }
323 :
324 2154176 : return ( ka );
325 : }
326 :
327 : /*-------------------------------------------------------------------------
328 : * re8_coord()
329 : *
330 : * COMPUTATION OF RE8 COORDINATES
331 : -----------------------------------------------------------------------*/
332 :
333 96885 : static void re8_coord(
334 : const int16_t *y, /* i : 8-dimensional point y[0..7] in RE8 */
335 : int16_t *k /* o : coordinates k[0..7] */
336 : )
337 : {
338 : int16_t i, tmp, sum;
339 :
340 : /*---------------------------------------------------------------*
341 : * compute k = y M^-1
342 : * M = 1/4 [ 1 ]
343 : * [-1 2 ]
344 : * [ | \ ]
345 : * [-1 2 ]
346 : * [ 5 -2 _ -2 4]
347 : *
348 : *---------------------------------------------------------------*/
349 :
350 96885 : k[7] = y[7];
351 96885 : tmp = y[7];
352 96885 : sum = 5 * y[7];
353 678195 : for ( i = 6; i >= 1; i-- )
354 : {
355 : /* apply factor 2/4 from M^-1 */
356 581310 : k[i] = ( y[i] - tmp ) >> 1;
357 581310 : sum -= y[i];
358 : }
359 :
360 : /* apply factor 1/4 from M^-1 */
361 96885 : k[0] = ( y[0] + sum ) >> 2;
362 :
363 96885 : return;
364 : }
365 :
366 :
367 : /*-------------------------------------------------------------------------
368 : * re8_k2y()
369 : *
370 : * Voronoi indexing (index decoding) k -> y
371 : -----------------------------------------------------------------------*/
372 :
373 455865 : void re8_k2y(
374 : const int16_t *k, /* i : Voronoi index k[0..7] */
375 : const int16_t m, /* i : Voronoi modulo (m = 2^r = 1<<r, where r is integer >=2) */
376 : int16_t *y /* o : 8-dimensional point y[0..7] in RE8 */
377 : )
378 : {
379 : int16_t i, lm, v[8], tmp, sum, *ptr1, *ptr2;
380 : float z[8];
381 :
382 : /*---------------------------------------------------------------*
383 : * compute y = k M and z=(y-a)/m, where
384 : * M = [4 ]
385 : * [2 2 ]
386 : * [| \ ]
387 : * [2 2 ]
388 : * [1 1 _ 1 1]
389 : * a=(2,0,...,0)
390 : *---------------------------------------------------------------*/
391 :
392 4102785 : for ( i = 0; i < 8; i++ )
393 : {
394 3646920 : y[i] = k[7];
395 : }
396 :
397 455865 : sum = 0;
398 3191055 : for ( i = 6; i >= 1; i-- )
399 : {
400 2735190 : tmp = 2 * k[i];
401 2735190 : sum += tmp;
402 2735190 : y[i] += tmp;
403 : }
404 455865 : y[0] += ( 4 * k[0] + sum );
405 :
406 : /* find log2(m) */
407 825730 : for ( lm = 0; lm < 31; lm++ )
408 : {
409 825730 : if ( ( m >> lm ) & 0x0001 )
410 : {
411 455865 : break;
412 : }
413 : }
414 :
415 455865 : z[0] = (float) ldexp( y[0] - 2, -lm );
416 3646920 : for ( i = 1; i < 8; i++ )
417 : {
418 3191055 : z[i] = (float) ldexp( y[i], -lm );
419 : }
420 :
421 : /*---------------------------------------------------------------*
422 : * find nearest neighbor v of z in infinite RE8
423 : *---------------------------------------------------------------*/
424 :
425 455865 : re8_PPV( z, v );
426 :
427 : /*---------------------------------------------------------------*
428 : * compute y -= m v
429 : *---------------------------------------------------------------*/
430 :
431 455865 : ptr1 = y;
432 455865 : ptr2 = v;
433 4102785 : for ( i = 0; i < 8; i++ )
434 : {
435 3646920 : *ptr1++ -= m * *ptr2++;
436 : }
437 :
438 455865 : return;
439 : }
|