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 "prot_fx.h"
36 : #include <assert.h>
37 : #include "ivas_cnst.h"
38 : #include "wmc_auto.h"
39 : #include "math.h"
40 : #include "ivas_prot_fx.h"
41 :
42 : /*-----------------------------------------------------------------------*
43 : * Local function definitions
44 : *-----------------------------------------------------------------------*/
45 :
46 12 : static Word32 ivas_bitstream_read_int32_fx(
47 : Decoder_State *st0,
48 : const Word16 bits /*Q0*/
49 : )
50 : {
51 : Word32 val;
52 :
53 : /* MSB */
54 12 : val = L_shl( get_next_indice_fx( st0, sub( bits, 16 ) ), 16 ); /*Q0*/
55 :
56 : /* + LSB */
57 12 : val = L_add( val, get_next_indice_fx( st0, 16 ) ); /*Q0*/
58 :
59 12 : return val;
60 : }
61 :
62 9965 : static void pca_dec_reset_dquat_fx(
63 : Word16 *ql_fx, /*Q15*/
64 : Word16 *qr_fx /*Q15*/
65 : )
66 : {
67 9965 : set16_fx( ql_fx, 0, IVAS_PCA_INTERP );
68 9965 : ql_fx[0] = MAX_16;
69 9965 : move16();
70 9965 : set16_fx( qr_fx, 0, IVAS_PCA_INTERP );
71 9965 : qr_fx[0] = MAX_16;
72 9965 : move16();
73 9965 : return;
74 : }
75 :
76 :
77 9440 : static void pca_dec_reset_mem_eigvec_fx(
78 : PCA_DEC_STATE *hPCA )
79 : {
80 : Word16 i;
81 :
82 613600 : FOR( i = 0; i < ( IVAS_PCA_LEN_INTERP_EIG_DEC >> 4 ); i++ )
83 : {
84 604160 : eye_matrix_fx( &hPCA->mem_eigVec_interp_fx[( 16 * i )], FOA_CHANNELS, MAX_16 );
85 : }
86 :
87 9440 : return;
88 : }
89 :
90 :
91 46880 : static void pca_inv_transform_sub_fx(
92 : Word16 *eigVec, /*Q15*/
93 : Word32 *transformed_data[], /* i : input/transformed audio channels Q11*/
94 : const Word16 start, /*Q0*/
95 : const Word16 len, /*Q0*/
96 : const Word16 n_channels /*Q0*/
97 : )
98 : {
99 : Word16 i, j, k;
100 : Word32 temp, temp2;
101 : Word32 buffer_data[FOA_CHANNELS];
102 :
103 829280 : FOR( j = 0; j < len; j++ )
104 : {
105 3912000 : FOR( k = 0; k < n_channels; k++ )
106 : {
107 3129600 : buffer_data[k] = transformed_data[k][( j + start )]; /*Q11*/
108 3129600 : move32();
109 : }
110 :
111 3912000 : FOR( k = 0; k < n_channels; k++ )
112 : {
113 3129600 : temp = 0;
114 3129600 : move32();
115 15648000 : FOR( i = 0; i < n_channels; i++ )
116 : {
117 12518400 : temp2 = Mpy_32_16_1( buffer_data[i], eigVec[( k * IVAS_PCA_INTERP + i )] ); /*Q11*/
118 12518400 : temp = L_add( temp, temp2 );
119 : }
120 3129600 : transformed_data[k][( j + start )] = temp; /*Q11*/
121 3129600 : move32();
122 : }
123 : }
124 :
125 46880 : return;
126 : }
127 :
128 :
129 1172 : static void pca_dec_inv_transform_fx(
130 : PCA_DEC_STATE *hPCA,
131 : Word16 *ql_fx, /*Q15*/
132 : Word16 *qr_fx, /*Q15*/
133 : const Word16 n_samples, /*Q0*/
134 : const Word16 n_channels, /*Q0*/
135 : Word32 *decoded_data[] /*Q11*/
136 : )
137 : {
138 : Word16 j;
139 : Word16 slot_len;
140 : Word16 ql_interp_fx[IVAS_PCA_LEN_INTERP_Q], qr_interp_fx[IVAS_PCA_LEN_INTERP_Q];
141 : // todo : updtate prev buffer, find Q
142 1172 : quat_shortestpath_fx( hPCA->prev_ql_fx, ql_fx, hPCA->prev_qr_fx, qr_fx );
143 :
144 1172 : pca_interp_preproc_fx( hPCA->prev_ql_fx, hPCA->prev_qr_fx, ql_fx, qr_fx, IVAS_PCA_N_SLOTS, ql_interp_fx, qr_interp_fx );
145 :
146 1172 : slot_len = idiv1616( n_samples, IVAS_PCA_N_SLOTS ); /*Q0*/
147 :
148 48052 : FOR( j = 0; j < IVAS_PCA_N_SLOTS; j++ )
149 : {
150 : /* convert from double quaternion to 4D matrix */
151 46880 : dquat2mat_fx( &ql_interp_fx[4 * j], &qr_interp_fx[4 * j], &hPCA->mem_eigVec_interp_fx[( 16 * j + IVAS_PCA_DELAY_CMP * 16 )] );
152 :
153 46880 : pca_inv_transform_sub_fx( &hPCA->mem_eigVec_interp_fx[16 * j], decoded_data, slot_len * j, slot_len, n_channels );
154 : }
155 :
156 1172 : return;
157 : }
158 :
159 10580 : static void pca_dec_update_dquat_fx(
160 : PCA_DEC_STATE *hPCA,
161 : const Word16 *ql_fx, /*Q15*/
162 : const Word16 *qr_fx /*Q15*/
163 : )
164 : {
165 : /* update state for next frame */
166 10580 : Copy( qr_fx, hPCA->prev_qr_fx, IVAS_PCA_INTERP ); /*Q15*/
167 10580 : Copy( ql_fx, hPCA->prev_ql_fx, IVAS_PCA_INTERP ); /*Q15*/
168 :
169 10580 : return;
170 : }
171 :
172 :
173 : /*-------------------------------------------------------------------------
174 : * ivas_pca_dec_init_fx()
175 : *
176 : * Initialize PCA decoder
177 : *------------------------------------------------------------------------*/
178 :
179 :
180 32 : void ivas_pca_dec_init_fx(
181 : PCA_DEC_STATE *hPCA /* i/o: PCA decoder structure */
182 : )
183 : {
184 32 : pca_dec_reset_dquat_fx( hPCA->prev_ql_fx, hPCA->prev_qr_fx );
185 32 : pca_dec_reset_mem_eigvec_fx( hPCA );
186 :
187 : /* set counter saturated to 2 frames */
188 32 : hPCA->prev_pca_bypass = 2;
189 32 : move16();
190 32 : return;
191 : }
192 : /*-------------------------------------------------------------------------
193 : * ivas_pca_read_bits_fx()
194 : *
195 : * Decode PCA indexes
196 : *------------------------------------------------------------------------*/
197 :
198 9840 : void ivas_pca_read_bits_fx(
199 : Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/
200 : PCA_DEC_STATE *hPCA )
201 : {
202 : /*first bit in the PCA payload (first bit after 3 header bits) signals bypass/active*/
203 9840 : hPCA->pca_bypass = get_next_indice_fx( st0, 1 ); /*Q0*/
204 9840 : move16();
205 9840 : IF( EQ_16( hPCA->pca_bypass, PCA_MODE_INACTIVE ) )
206 : {
207 9834 : return;
208 : }
209 :
210 6 : hPCA->index[0] = ivas_bitstream_read_int32_fx( st0, IVAS_PCA_QBITS - 1 ); /*Q0*/
211 6 : move32();
212 6 : hPCA->index[1] = ivas_bitstream_read_int32_fx( st0, IVAS_PCA_QBITS ); /*Q0*/
213 6 : move32();
214 :
215 6 : return;
216 : }
217 :
218 : /*-------------------------------------------------------------------------
219 : * ivas_pca_dec_fx()
220 : *
221 : * PCA decoder
222 : *------------------------------------------------------------------------*/
223 :
224 10580 : void ivas_pca_dec_fx(
225 : PCA_DEC_STATE *hPCA, /* i/o: PCA decoder structure */
226 : const Word16 output_frame, /* i : output frame length Q0*/
227 : const Word16 n_channels, /* i : number of channels Q0*/
228 : const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/
229 : const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/
230 : const Word16 bfi, /* i : bad frame indicator Q0*/
231 : Word32 *pcm_out_fx[] /* o : output audio channels Q11*/
232 : )
233 : {
234 : Word16 ql_fx[IVAS_PCA_INTERP], qr_fx[IVAS_PCA_INTERP]; /*Q15*/
235 : Word16 pca_bypass;
236 : // todo : check if mem_eigVec_interp_fx values are being updated / add loop to update
237 10580 : Copy( &hPCA->mem_eigVec_interp_fx[IVAS_PCA_N_SLOTS * 16], hPCA->mem_eigVec_interp_fx, IVAS_PCA_DELAY_CMP * 16 ); /*Q15*/
238 :
239 : /* @@@TODO: check how ivas_total_brate is set if bfi == 1 */ // ToDo: and what happens in DTX where "ivas_total_brate" can be close to zero?
240 :
241 : /* handle bit rate switching */
242 10580 : test();
243 10580 : test();
244 10580 : IF( NE_32( ivas_total_brate, PCA_BRATE ) || ( EQ_32( ivas_total_brate, PCA_BRATE ) && GT_16( n_channels, FOA_CHANNELS ) ) )
245 : {
246 : /* set PCA by-pass mode in current frame and interpolate transform as previous frame used PCA */
247 0 : pca_dec_reset_dquat_fx( ql_fx, qr_fx );
248 :
249 0 : test();
250 0 : test();
251 0 : IF( ( NE_32( last_ivas_total_brate, PCA_BRATE ) ) || ( EQ_32( last_ivas_total_brate, PCA_BRATE ) && GT_16( hPCA->prev_pca_bypass, 1 ) ) )
252 : {
253 0 : pca_dec_reset_mem_eigvec_fx( hPCA );
254 : }
255 : ELSE
256 : {
257 0 : pca_dec_inv_transform_fx( hPCA, ql_fx, qr_fx, output_frame, n_channels, pcm_out_fx );
258 : }
259 :
260 0 : pca_dec_update_dquat_fx( hPCA, ql_fx, qr_fx );
261 0 : hPCA->prev_pca_bypass = add( hPCA->prev_pca_bypass, 1 ); /*Q0*/
262 0 : move16();
263 :
264 0 : if ( GT_16( hPCA->prev_pca_bypass, 2 ) )
265 : {
266 0 : hPCA->prev_pca_bypass = 2; /*Q0*/
267 0 : move16();
268 : }
269 :
270 0 : return;
271 : }
272 :
273 10580 : IF( bfi == 0 )
274 : {
275 : /* set PCA by-pass mode indicator */
276 9840 : pca_bypass = hPCA->pca_bypass; /*Q0*/
277 9840 : move16();
278 : }
279 : ELSE
280 : {
281 740 : pca_bypass = hPCA->prev_pca_bypass; /*Q0*/
282 740 : move16();
283 : }
284 :
285 10580 : IF( EQ_16( pca_bypass, PCA_MODE_INACTIVE ) )
286 : {
287 9933 : pca_dec_reset_dquat_fx( ql_fx, qr_fx );
288 :
289 9933 : IF( GT_16( hPCA->prev_pca_bypass, 1 ) ) //&& (hPCA->pca_off_hangover == 0))
290 : {
291 : /* copy input data into output directly as previous frame was already in by-pass mode */
292 9408 : pca_dec_reset_mem_eigvec_fx( hPCA );
293 : }
294 : ELSE
295 : {
296 525 : pca_dec_inv_transform_fx( hPCA, ql_fx, qr_fx, output_frame, n_channels, pcm_out_fx );
297 : }
298 :
299 9933 : pca_dec_update_dquat_fx( hPCA, ql_fx, qr_fx );
300 :
301 9933 : hPCA->prev_pca_bypass = add( hPCA->prev_pca_bypass, 1 ); /*Q0*/
302 9933 : move16();
303 9933 : hPCA->prev_pca_bypass = s_min( hPCA->prev_pca_bypass, 2 ); /*Q0*/
304 9933 : move16();
305 9933 : return; // exit happens here
306 : }
307 :
308 647 : IF( bfi == 0 )
309 : {
310 6 : pca_dec_s3_fx( hPCA->index[0], ql_fx );
311 6 : pca_dec_s3_fx( hPCA->index[1], qr_fx );
312 : }
313 : ELSE
314 : {
315 : /* freeze */
316 : // todo : check if update of prev_ql_fx is required
317 641 : Copy( hPCA->prev_ql_fx, ql_fx, IVAS_PCA_INTERP ); /*Q15*/
318 641 : Copy( hPCA->prev_qr_fx, qr_fx, IVAS_PCA_INTERP ); /*Q15*/
319 : }
320 647 : pca_dec_inv_transform_fx( hPCA, ql_fx, qr_fx, output_frame, n_channels, pcm_out_fx );
321 :
322 : /* update for next frame */
323 647 : pca_dec_update_dquat_fx( hPCA, ql_fx, qr_fx );
324 :
325 647 : hPCA->prev_pca_bypass = 0;
326 647 : move16();
327 647 : return;
328 : }
|