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 : #include <stdint.h>
34 : #include "options.h"
35 : #include <math.h>
36 : #include "prot_fx.h"
37 : #include "ivas_prot_rend_fx.h"
38 : #include "wmc_auto.h"
39 : #include "ivas_prot_fx.h"
40 :
41 :
42 : /*-------------------------------------------------------------------*
43 : * TDREND_SPATIAL_VecInit()
44 : *
45 : * Initialize 3-dim vector
46 : *-------------------------------------------------------------------*/
47 :
48 4557 : void TDREND_SPATIAL_VecInit_fx(
49 : Word32 *Pos_p, /* o : Output vector */
50 : const Word32 PosX, /* i : X value */
51 : const Word32 PosY, /* i : Y value */
52 : const Word32 PosZ /* i : Z value */
53 : )
54 : {
55 4557 : Pos_p[0] = PosX;
56 4557 : Pos_p[1] = PosY;
57 4557 : Pos_p[2] = PosZ;
58 4557 : move32();
59 4557 : move32();
60 4557 : move32();
61 4557 : return;
62 : }
63 :
64 :
65 : /*-------------------------------------------------------------------*
66 : * TDREND_SPATIAL_VecNorm()
67 : *
68 : * Compute Euclidian norm of vector
69 : *-------------------------------------------------------------------*/
70 :
71 : /*! r: Euclidian norm value */
72 :
73 1804632 : Word32 TDREND_SPATIAL_VecNorm_fx(
74 : const Word32 *Vec_p, /* i : Vector for norm calculation */
75 : const Word16 in_exp, /* i : Input exp */
76 : Word16 *out_exp /* o : Output exp */
77 : )
78 : {
79 : Word32 tmp;
80 : Word16 tmp_e;
81 1804632 : tmp = L_add( L_add( Mpy_32_32( Vec_p[0], Vec_p[0] ), Mpy_32_32( Vec_p[1], Vec_p[1] ) ), Mpy_32_32( Vec_p[2], Vec_p[2] ) );
82 1804632 : tmp_e = shl( in_exp, 1 ); // 2 * in_exp
83 1804632 : tmp = Sqrt32( tmp, &tmp_e );
84 1804632 : *out_exp = tmp_e;
85 1804632 : move16();
86 :
87 1804632 : return tmp;
88 : }
89 :
90 2390485 : void TDREND_SPATIAL_VecNormalize_fx(
91 : const Word32 *Vec_p_fx, /* i : Input vector q */
92 : Word16 q, /* i : Input vector Q-factor */
93 : Word32 *VecNorm_p_fx /* o : Normalised output vector Q30 */
94 : )
95 : {
96 : Word32 scaler_fx;
97 : Word32 sqrd_sum;
98 : Word16 exp, shift;
99 :
100 2390485 : sqrd_sum = L_add( Mpy_32_32( Vec_p_fx[0], Vec_p_fx[0] ), L_add( Mpy_32_32( Vec_p_fx[1], Vec_p_fx[1] ), Mpy_32_32( Vec_p_fx[2], Vec_p_fx[2] ) ) );
101 2390485 : exp = shl( sub( 31, q ), 1 );
102 2390485 : scaler_fx = ISqrt32( sqrd_sum, &exp );
103 :
104 2390485 : VecNorm_p_fx[0] = Mpy_32_32( scaler_fx, Vec_p_fx[0] ); // Q: ( q + ( 31 - exp ) ) - 31
105 2390485 : move32();
106 2390485 : VecNorm_p_fx[1] = Mpy_32_32( scaler_fx, Vec_p_fx[1] ); // Q: ( q + ( 31 - exp ) ) - 31
107 2390485 : move32();
108 2390485 : VecNorm_p_fx[2] = Mpy_32_32( scaler_fx, Vec_p_fx[2] ); // Q: ( q + ( 31 - exp ) ) - 31
109 2390485 : move32();
110 2390485 : exp = add( exp, sub( 31, q ) );
111 :
112 : // Since vector is normalised, all values will be <= 1. Hence making all values in Q30
113 2390485 : shift = sub( exp, 1 );
114 2390485 : VecNorm_p_fx[0] = L_shl( VecNorm_p_fx[0], shift ); // Q30
115 2390485 : move32();
116 2390485 : VecNorm_p_fx[1] = L_shl( VecNorm_p_fx[1], shift ); // Q30
117 2390485 : move32();
118 2390485 : VecNorm_p_fx[2] = L_shl( VecNorm_p_fx[2], shift ); // Q30
119 2390485 : move32();
120 :
121 2390485 : return;
122 : }
123 :
124 :
125 : /*-------------------------------------------------------------------*
126 : * TDREND_SPATIAL_VecMapToNewCoordSystem()
127 : *
128 : * Transform vector to new coordinate system
129 : *-------------------------------------------------------------------*/
130 :
131 902316 : void TDREND_SPATIAL_VecMapToNewCoordSystem_fx(
132 : const Word32 *Vec_p, /* i : Input vector Qx */
133 : const Word32 *TranslVec_p, /* i : Translation vector Qx */
134 : const Word32 *DirVec_p, /* i : Direction vector Qy */
135 : const Word32 *UpVec_p, /* i : Up vector Qy */
136 : const Word32 *RightVec_p, /* i : Right vector Qy */
137 : Word32 *MappedVec_p, /* o : Transformed vector Qx+Qy-31 */
138 : Word32 *LisRelPosAbs /* o : Transformed vector ignoring orientation Qy */
139 : )
140 : {
141 902316 : v_sub_32( Vec_p, TranslVec_p, LisRelPosAbs, 3 );
142 : /* Evalute the relative Vec in the coordinates of the Orientation vectors, */
143 : /* which form an orthonormal basis */
144 902316 : MappedVec_p[0] = dotp_fixed( LisRelPosAbs, DirVec_p, 3 ); // Q: Qy + Qy - Q31
145 902316 : move32();
146 902316 : MappedVec_p[1] = dotp_fixed( LisRelPosAbs, RightVec_p, 3 ); // Q: Qy + Qy - Q31
147 902316 : move32();
148 902316 : MappedVec_p[2] = dotp_fixed( LisRelPosAbs, UpVec_p, 3 ); // Q: Qy + Qy - Q31
149 902316 : move32();
150 902316 : return;
151 : }
152 :
153 : /*-------------------------------------------------------------------*
154 : * TDREND_SPATIAL_EvalOrthonormOrient()
155 : *
156 : * Evaluate the normalized orientation vectors
157 : *-------------------------------------------------------------------*/
158 :
159 : /*! r: Flag if the orientation has been updated */
160 :
161 664495 : Word16 TDREND_SPATIAL_EvalOrthonormOrient_fx(
162 : Word32 *FrontVecON_p_fx, /* i/o: Normalized front vector Q30 */
163 : Word32 *UpVecON_p_fx, /* i/o: Normalized up vector Q30 */
164 : Word32 *RightVecON_p_fx, /* i/o: Normalized right vector Q30 */
165 : const Word32 *FrontVec_p_fx, /* i : Input front vector Qx */
166 : const Word32 *UpVec_p_fx, /* i : Input up vector orient_q */
167 : const Word16 orient_q /* i : Input up Q-factor */
168 : )
169 : {
170 : Word32 tmp_fx[9]; // Q30
171 : Word16 orientation_updated;
172 :
173 664495 : orientation_updated = FALSE;
174 664495 : move16();
175 :
176 : /* Store current state to detect change */
177 : // Q30
178 664495 : Copy32( FrontVecON_p_fx, tmp_fx, 3 );
179 664495 : Copy32( RightVecON_p_fx, tmp_fx + 3, 3 );
180 664495 : Copy32( UpVecON_p_fx, tmp_fx + 6, 3 );
181 :
182 : /* Evaluate the normalized front vector */
183 664495 : TDREND_SPATIAL_VecNormalize_fx( FrontVec_p_fx, orient_q, FrontVecON_p_fx ); // FrontVecON_p_fx -> Q30
184 :
185 : /* Evaluate the orthonormal right vector */
186 : /* through the cross product of the front and the up vectors */
187 664495 : RightVecON_p_fx[0] = L_shl_sat( L_sub( Mpy_32_32( FrontVecON_p_fx[1], UpVec_p_fx[2] ), Mpy_32_32( FrontVecON_p_fx[2], UpVec_p_fx[1] ) ), 1 ); // Q: ( Q30 + Q30 - Q31 ) + Q1 -> Q30
188 664495 : move32();
189 664495 : RightVecON_p_fx[1] = L_shl_sat( L_sub( Mpy_32_32( FrontVecON_p_fx[2], UpVec_p_fx[0] ), Mpy_32_32( FrontVecON_p_fx[0], UpVec_p_fx[2] ) ), 1 ); // Q: ( Q30 + Q30 - Q31 ) + Q1 -> Q30
190 664495 : move32();
191 664495 : RightVecON_p_fx[2] = L_shl_sat( L_sub( Mpy_32_32( FrontVecON_p_fx[0], UpVec_p_fx[1] ), Mpy_32_32( FrontVecON_p_fx[1], UpVec_p_fx[0] ) ), 1 ); // Q: ( Q30 + Q30 - Q31 ) + Q1 -> Q30
192 664495 : move32();
193 :
194 664495 : TDREND_SPATIAL_VecNormalize_fx( RightVecON_p_fx, orient_q, RightVecON_p_fx ); // RightVecON_p_fx -> Q30
195 :
196 : /* Evaluate the orthonormal up vector */
197 : /* through the cross product of the front and the right vectors */
198 664495 : UpVecON_p_fx[0] = L_shl_sat( L_sub( Mpy_32_32( RightVecON_p_fx[1], FrontVecON_p_fx[2] ), Mpy_32_32( RightVecON_p_fx[2], FrontVecON_p_fx[1] ) ), 1 ); // Q: ( Q30 + Q30 - Q31 ) + Q1 -> Q30
199 664495 : move32();
200 664495 : UpVecON_p_fx[1] = L_shl_sat( L_sub( Mpy_32_32( RightVecON_p_fx[2], FrontVecON_p_fx[0] ), Mpy_32_32( RightVecON_p_fx[0], FrontVecON_p_fx[2] ) ), 1 ); // Q: ( Q30 + Q30 - Q31 ) + Q1 -> Q30
201 664495 : move32();
202 664495 : UpVecON_p_fx[2] = L_shl_sat( L_sub( Mpy_32_32( RightVecON_p_fx[0], FrontVecON_p_fx[1] ), Mpy_32_32( RightVecON_p_fx[1], FrontVecON_p_fx[0] ) ), 1 ); // Q: ( Q30 + Q30 - Q31 ) + Q1 -> Q30
203 664495 : move32();
204 :
205 664495 : TDREND_SPATIAL_VecNormalize_fx( UpVecON_p_fx, orient_q, UpVecON_p_fx ); // UpVecON_p_fx -> Q30
206 :
207 : /* Check if vectors have been changed */
208 664495 : test();
209 664495 : test();
210 664495 : test();
211 664495 : test();
212 664495 : test();
213 664495 : test();
214 664495 : test();
215 664495 : test();
216 989245 : if ( NE_32( FrontVecON_p_fx[0], tmp_fx[0] ) || NE_32( FrontVecON_p_fx[1], tmp_fx[1] ) || NE_32( FrontVecON_p_fx[2], tmp_fx[2] ) ||
217 974250 : NE_32( RightVecON_p_fx[0], tmp_fx[3] ) || NE_32( RightVecON_p_fx[1], tmp_fx[4] ) || NE_32( RightVecON_p_fx[2], tmp_fx[5] ) ||
218 649500 : NE_32( UpVecON_p_fx[0], tmp_fx[6] ) || NE_32( UpVecON_p_fx[1], tmp_fx[7] ) || NE_32( UpVecON_p_fx[2], tmp_fx[8] ) )
219 : {
220 339745 : orientation_updated = TRUE;
221 339745 : move16();
222 : }
223 :
224 664495 : return orientation_updated;
225 : }
|