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 "cnst.h"
43 : #include "prot.h"
44 : #include "wmc_auto.h"
45 : #include "wmc_auto.h"
46 :
47 : /*-------------------------------------------------------------------*
48 : * Local function prototypes
49 : *-------------------------------------------------------------------*/
50 :
51 : static void nearest_neighbor_2D8( const float x[], int16_t y[] );
52 :
53 : /*--------------------------------------------------------------*
54 : * re8_PPV()
55 : *
56 : * Nearest neighbor search in infinite lattice RE8
57 : * the algorithm is based on the definition of RE8 as
58 : * RE8 = (2D8) U (2D8+[1,1,1,1,1,1,1,1])
59 : * it applies the coset decoding of Sloane and Conway
60 : * --------------------------------------------------------------*/
61 :
62 2416271 : void re8_PPV(
63 : const float x[], /* i : point in R^8 */
64 : int16_t y[] /* o : point in RE8 (8-dimensional integer vector) */
65 : )
66 : {
67 : int16_t i, y0[8], y1[8];
68 : float e0, e1, x1[8], tmp;
69 :
70 : /*--------------------------------------------------------------*
71 : * find the nearest neighbor y0 of x in 2D8
72 : *--------------------------------------------------------------*/
73 :
74 2416271 : nearest_neighbor_2D8( x, y0 );
75 :
76 : /*--------------------------------------------------------------*
77 : * find the nearest neighbor y1 of x in 2D8+(1,...,1) (by coset decoding)
78 : *--------------------------------------------------------------*/
79 :
80 21746439 : for ( i = 0; i < 8; i++ )
81 : {
82 19330168 : x1[i] = x[i] - 1.0f;
83 : }
84 :
85 2416271 : nearest_neighbor_2D8( x1, y1 );
86 :
87 21746439 : for ( i = 0; i < 8; i++ )
88 : {
89 19330168 : y1[i] += 1;
90 : }
91 :
92 : /*--------------------------------------------------------------*
93 : * compute e0=||x-y0||^2 and e1=||x-y1||^2
94 : *--------------------------------------------------------------*/
95 :
96 2416271 : e0 = e1 = 0.0;
97 21746439 : for ( i = 0; i < 8; i++ )
98 : {
99 19330168 : tmp = x[i] - y0[i];
100 19330168 : e0 += tmp * tmp;
101 19330168 : tmp = x[i] - y1[i];
102 19330168 : e1 += tmp * tmp;
103 : }
104 :
105 : /*--------------------------------------------------------------*
106 : * select best candidate y0 or y1 to minimize distortion
107 : *--------------------------------------------------------------*/
108 :
109 2416271 : if ( e0 < e1 )
110 : {
111 12153654 : for ( i = 0; i < 8; i++ )
112 : {
113 10803248 : y[i] = y0[i];
114 : }
115 : }
116 : else
117 : {
118 9592785 : for ( i = 0; i < 8; i++ )
119 : {
120 8526920 : y[i] = y1[i];
121 : }
122 : }
123 :
124 2416271 : return;
125 : }
126 :
127 : /*--------------------------------------------------------------*
128 : * nearest_neighbor_2D8()
129 : *
130 : * Nearest neighbor search in infinite lattice 2D8
131 : * algorithm: nn_2D8(x) = 2*nn_D8(x/2)
132 : * nn_D8 = decoding of Z^8 with Wagner rule
133 : * (see Conway and Sloane's paper in IT-82)
134 : --------------------------------------------------------------*/
135 :
136 4832542 : static void nearest_neighbor_2D8(
137 : const float x[], /* i : point in R^8 */
138 : int16_t y[] /* o : point in 2D8 (8-dimensional integer vector) */
139 : )
140 : {
141 : int16_t i, j, sum;
142 : float s, e[8], em;
143 :
144 : /*--------------------------------------------------------------*
145 : * round x into 2Z^8 i.e. compute y=(y1,...,y8) such that yi = 2[xi/2]
146 : * where [.] is the nearest integer operator
147 : * in the mean time, compute sum = y1+...+y8
148 : *--------------------------------------------------------------*/
149 :
150 4832542 : sum = 0;
151 43492878 : for ( i = 0; i < 8; i++ )
152 : {
153 : /* round to ..., -2, 0, 2, ... ([-1..1[ --> 0) */
154 38660336 : if ( x[i] < 0 )
155 : {
156 23045018 : y[i] = -2 * ( ( (int16_t) ( 1.0 - x[i] ) ) >> 1 );
157 : }
158 : else
159 : {
160 15615318 : y[i] = 2 * ( ( (int16_t) ( 1.0 + x[i] ) ) >> 1 );
161 : }
162 38660336 : sum += y[i];
163 : }
164 :
165 : /*--------------------------------------------------------------*
166 : * check if y1+...+y8 is a multiple of 4
167 : * if not, y is not round xj in the wrong way where j is defined by
168 : * j = arg max_i | xi -yi|
169 : * (this is called the Wagner rule)
170 : *--------------------------------------------------------------*/
171 :
172 4832542 : if ( sum % 4 )
173 : {
174 : /* find j = arg max_i | xi -yi| */
175 2471489 : em = 0;
176 2471489 : j = 0;
177 22243401 : for ( i = 0; i < 8; i++ )
178 : {
179 : /* compute ei = xi-yi */
180 19771912 : e[i] = x[i] - y[i];
181 : }
182 :
183 22243401 : for ( i = 0; i < 8; i++ )
184 : {
185 : /* compute |ei| = | xi-yi | */
186 19771912 : if ( e[i] < 0 )
187 : {
188 8804953 : s = -e[i];
189 : }
190 : else
191 : {
192 10966959 : s = e[i];
193 : }
194 : /* check if |ei| is maximal, if so, set j=i */
195 19771912 : if ( em < s )
196 : {
197 5681480 : em = s;
198 5681480 : j = i;
199 : }
200 : }
201 :
202 : /* round xj in the "wrong way" */
203 2471489 : if ( e[j] < 0 )
204 : {
205 1210801 : y[j] -= 2;
206 : }
207 : else
208 : {
209 1260688 : y[j] += 2;
210 : }
211 : }
212 :
213 4832542 : return;
214 : }
|