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 <assert.h>
34 : #include <stdint.h>
35 : #include "options.h"
36 : #include <math.h>
37 : #include "ivas_cnst.h"
38 : #include "ivas_rom_com.h"
39 : #include "ivas_rom_dec.h"
40 : #include "wmc_auto.h"
41 : #include "prot_fx.h"
42 : #include "ivas_prot_fx.h"
43 :
44 :
45 : /*-----------------------------------------------------------------------*
46 : * Local function prototypes
47 : *-----------------------------------------------------------------------*/
48 :
49 : static Word16 ivas_qmetadata_entropy_decode_diffuseness( UWord16 *bitstream, Word16 *index, IVAS_QDIRECTION *q_direction, UWord16 *diffuseness_index_max_ec_frame );
50 : static Word16 ivas_qmetadata_entropy_decode_df_ratio( UWord16 *bitstream, Word16 *index, IVAS_QDIRECTION *q_direction, Word16 *dfRatio_bits );
51 : static Word16 ivas_qmetadata_raw_decode_dir_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *index, const Word16 nbands, const Word16 start_band, const Word16 hrmasa_flag );
52 : static UWord16 ivas_qmetadata_DecodeQuasiUniform( const UWord16 *bitstream, Word16 *index, const UWord16 alphabet_size );
53 : static Word16 ivas_qmetadata_ReorderElevationDecoded( const Word16 elev_dist, const Word16 elev_avg, const Word16 elev_alph );
54 : static Word16 read_directions_fx( IVAS_QDIRECTION *q_direction, const UWord8 coding_subbands, const UWord8 masa_subframes, UWord16 *bitstream, Word16 *pbit_pos, Word16 *ind_order );
55 : static Word16 read_common_direction_fx( UWord16 *bitstream, IVAS_QDIRECTION *q_direction, const Word16 j, const Word16 no_subframes, const Word16 bits_total, Word16 *pbit_pos );
56 : static Word16 decode_azimuth_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *pbit_pos, const Word16 idx_subband, const Word16 masa_subframes );
57 : static Word16 decode_fixed_rate_fx( IVAS_QDIRECTION *q_direction, const UWord16 *bitstream, Word16 *pbit_pos, const Word16 b, const Word16 nblocks );
58 : static Word16 ivas_qmetadata_entropy_decode_diffuseness_hr_512( UWord16 *bitstream, Word16 *index, IVAS_QDIRECTION *q_direction );
59 : static Word16 ivas_qmetadata_entropy_decode_dir_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *index, const UWord16 diffuseness_index_max_ec_frame, const Word16 nbands, const Word16 start_band, const Word16 hrmasa_flag );
60 : static Word16 read_surround_coherence_hr_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData, Word64 energy_ratio[][MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] );
61 : static void set_zero_direction_fx( IVAS_QDIRECTION *q_direction, const Word16 idx_band, const Word16 len );
62 : static Word16 decode_azimuth2D_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, const Word16 coding_subbands, Word16 *pbit_pos, const Word16 no_frames );
63 : static Word16 read_truncGR_azimuth_fx( UWord16 *bitstream, IVAS_QDIRECTION *q_direction, const Word16 j, const Word16 no_subframes, Word16 *pbit_pos );
64 : static void decode_combined_index_fx( UWord64 comb_index, const Word16 *no_cv_vec, UWord16 *index, const Word16 len );
65 : static Word16 decode_elevation_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *pbit_pos, const Word16 j, const Word16 masa_subframes );
66 : static Word16 decode_fixed_rate_composed_index_coherence_fx( UWord16 *bitstream, Word16 *p_bit_pos, const Word16 no_bands, Word16 *no_cv_vec, UWord16 *decoded_index, const Word16 no_symb );
67 : static void decode_spread_coherence_fx( IVAS_QMETADATA_HANDLE hQMetaData, Word16 idx_d, const Word16 no_frames, const Word16 hrmasa_flag );
68 : static Word16 ivas_diffuseness_huff_ec_decode_fx( const UWord16 *bitstream, Word16 *index, Word16 av );
69 : static void read_stream_dct_coeffs_omasa_fx( Word16 *q_idx, Word32 *q_dct_data_fx, const Word16 len_stream, UWord16 *bit_stream, Word16 *index, const Word16 first_line );
70 : static Word16 read_coherence_data_hr_512_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData, const Word16 idx_dir, const Word16 nbits_coh );
71 : static Word16 read_coherence_data_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData, const Word16 idx_dir, const Word16 hrmasa_flag );
72 : static Word16 ivas_qmetadata_raw_decode_dir_512_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *index, const Word16 nbands, const Word16 start_band, const SPHERICAL_GRID_DATA *sph_grid16 );
73 : static Word16 read_surround_coherence( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData );
74 : static ivas_error read_huf( Word16 *num_bits_read, const UWord16 *bitstream, UWord16 *out, const Word16 start_pos, const Word16 len, const Word16 *huff_code, const Word16 max_len );
75 : const Word32 inv_dfRatio_qsteps[9] = { 0, 0, ONE_IN_Q30, 0, 357913941, 0, 0, 0, 153391689 }; // Q30
76 :
77 : /*-----------------------------------------------------------------------*
78 : * Global function definitions
79 : *-----------------------------------------------------------------------*/
80 :
81 : /*-----------------------------------------------------------------------*
82 : * ivas_qmetadata_dec_decode()
83 : *
84 : * Main function for decoding Spatial Metadata
85 : *-----------------------------------------------------------------------*/
86 : /*! r: number of bits read */
87 266402 : Word16 ivas_qmetadata_dec_decode(
88 : IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: hQMetaData handle */
89 : UWord16 *bitstream, /* i : bitstream Q0*/
90 : Word16 *index, /* i/o: bitstream position Q0*/
91 : const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode Q0*/
92 : )
93 : {
94 : Word16 d, b, m;
95 : UWord16 diffuseness_index_max_ec_frame;
96 : UWord16 diffuseness_index_max_ec_frame_pre[QMETADATA_MAX_NO_DIRECTIONS];
97 : Word16 bits_dir_raw_pre[QMETADATA_MAX_NO_DIRECTIONS];
98 : Word16 dir2band;
99 : Word16 bits_diff_sum;
100 : Word16 bits_diff, bits_coherence;
101 : Word16 bits_dir_raw;
102 : Word16 bits_dir;
103 : Word16 nbands, nblocks, start_band;
104 : IVAS_QDIRECTION *q_direction;
105 : Word16 start_index_0;
106 : Word16 total_bits_1dir;
107 : Word16 signal_bits;
108 : Word16 bits_no_dirs_coh, bits_sur_coherence;
109 : UWord16 all_coherence_zero;
110 : Word16 ec_flag;
111 : Word16 raw_flag[MASA_MAXIMUM_CODING_SUBBANDS];
112 : Word16 diff_bits;
113 : Word16 dfRatio_bits[MASA_MAXIMUM_CODING_SUBBANDS];
114 : Word16 no_TF;
115 : Word16 p[MASA_MAXIMUM_CODING_SUBBANDS], dif_p[MASA_MAXIMUM_CODING_SUBBANDS];
116 : Word16 bits_dir_target;
117 : Word16 bits_dir_used;
118 : Word16 reduce_bits;
119 : Word16 ind_order[MASA_MAXIMUM_CODING_SUBBANDS];
120 : Word32 tmp32;
121 :
122 :
123 266402 : ec_flag = 0;
124 266402 : move16();
125 266402 : start_index_0 = *index;
126 266402 : move16();
127 :
128 : /*Coherence flag decoding*/
129 266402 : bits_no_dirs_coh = 0;
130 266402 : move16();
131 266402 : all_coherence_zero = 1;
132 266402 : move16();
133 :
134 266402 : IF( hQMetaData->coherence_flag )
135 : {
136 : /* read if coherence is zero */
137 63684 : all_coherence_zero = bitstream[( *index )--]; /*Q0*/
138 63684 : move16();
139 63684 : bits_no_dirs_coh = add( bits_no_dirs_coh, 1 );
140 : }
141 :
142 266402 : hQMetaData->all_coherence_zero = (UWord8) all_coherence_zero;
143 :
144 266402 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
145 : {
146 : /* Read which bands have 2 directions */
147 32077 : hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands; /*Q0*/
148 32077 : move16();
149 32077 : set_c( (Word8 *) hQMetaData->twoDirBands, 0, hQMetaData->q_direction[0].cfg.nbands );
150 32077 : d = *index;
151 32077 : move16();
152 32077 : dif_p[0] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
153 32077 : move16();
154 32077 : p[0] = dif_p[0]; /*Q0*/
155 32077 : move16();
156 32077 : hQMetaData->twoDirBands[p[0]] = 1;
157 32077 : move16();
158 233540 : FOR( b = 1; b < hQMetaData->numTwoDirBands; b++ )
159 : {
160 201463 : dif_p[b] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
161 201463 : move16();
162 201463 : p[b] = add( add( p[b - 1], dif_p[b] ), 1 );
163 201463 : move16();
164 201463 : hQMetaData->twoDirBands[p[b]] = 1;
165 201463 : move16();
166 : }
167 32077 : bits_no_dirs_coh = add( bits_no_dirs_coh, sub( d, *index ) );
168 : }
169 :
170 266402 : bits_diff_sum = 0;
171 266402 : move16();
172 266402 : bits_diff_sum = add( bits_diff_sum, ivas_qmetadata_entropy_decode_diffuseness( bitstream, index, &( hQMetaData->q_direction[0] ), &diffuseness_index_max_ec_frame_pre[0] ) );
173 :
174 266402 : IF( hodirac_flag )
175 : {
176 16391 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
177 : {
178 : /* Calculate bits for dfRatio */
179 16391 : dir2band = 0;
180 16391 : move16();
181 196692 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
182 : {
183 180301 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
184 : {
185 180301 : dfRatio_bits[dir2band] = ivas_get_df_ratio_bits_hodirac_fx( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); /*Q0*/
186 180301 : move16();
187 180301 : dir2band = add( dir2band, 1 );
188 : }
189 : }
190 :
191 16391 : bits_diff_sum = add( bits_diff_sum, ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ) );
192 : }
193 : }
194 : ELSE
195 : {
196 250011 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
197 : {
198 : /* Calculate bits for dfRatio */
199 15686 : dir2band = 0;
200 15686 : move16();
201 180751 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
202 : {
203 165065 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
204 : {
205 53239 : dfRatio_bits[dir2band] = ivas_get_df_ratio_bits_fx( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); /*Q0*/
206 53239 : move16();
207 53239 : dir2band = add( dir2band, 1 );
208 : }
209 : }
210 :
211 15686 : bits_diff_sum = add( bits_diff_sum, ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ) ); /*Q0*/
212 : }
213 : }
214 :
215 : /* Calculate direct-to-total energy ratios for both directions from diffuse-to-total ratio and distribution factor of direct-to-total ratios */
216 266402 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
217 : {
218 32077 : dir2band = 0;
219 32077 : move16();
220 377443 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
221 : {
222 345366 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
223 : {
224 : Word32 diffRatio_fx, dir1ratio_fx, dir2ratio_fx;
225 : Word32 dfRatio_fx;
226 : Word16 dfRatio_qsteps;
227 :
228 233540 : diffRatio_fx = diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; // Q30
229 233540 : move32();
230 :
231 233540 : dfRatio_qsteps = shl( 1, dfRatio_bits[dir2band] ); /*1 << dfRatio_bits[dir2band]*/
232 : /* already encoded as total and ratios in HO-DirAC */
233 233540 : IF( hodirac_flag )
234 : {
235 180301 : dfRatio_fx = usdequant32_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], 0 /* Q15 */, inv_dfRatio_qsteps[dfRatio_qsteps] ); // Q31
236 180301 : dir1ratio_fx = L_sub( ONE_IN_Q30, diffRatio_fx );
237 180301 : dir2ratio_fx = L_shr( dfRatio_fx, 1 ); /*Q30*/
238 : }
239 : ELSE
240 : {
241 53239 : IF( EQ_16( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], sub( dfRatio_qsteps, 1 ) ) )
242 : {
243 2582 : dfRatio_fx = MAX_32; // Q31
244 2582 : move16();
245 2582 : dir1ratio_fx = L_sub( ONE_IN_Q30, diffRatio_fx ); // Q30
246 : }
247 : ELSE
248 : {
249 50657 : dfRatio_fx = usdequant32_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], L_shr( MAX_32, 1 ), L_shr( inv_dfRatio_qsteps[dfRatio_qsteps], 1 ) ); // Q31
250 50657 : dir1ratio_fx = Mpy_32_32( L_sub( ONE_IN_Q30, diffRatio_fx ), dfRatio_fx ); // Q30
251 : }
252 :
253 53239 : dir2ratio_fx = L_sub( L_sub( ONE_IN_Q30, diffRatio_fx ), dir1ratio_fx ); // Q30
254 : }
255 :
256 : /* Requantize the 1 - dirRatio separately for each direction to obtain inverted dirRatio index. These are used in further decoding. */
257 :
258 233540 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] = masa_sq_fx( L_sub( ONE_IN_Q30, dir1ratio_fx ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
259 233540 : move16();
260 233540 : IF( hodirac_flag )
261 : {
262 : Word16 tmp_fx;
263 180301 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0] = usquant_fx( extract_h( dir2ratio_fx ), &tmp_fx, 0, INV_DIRAC_DIFFUSE_LEVELS_Q13, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
264 180301 : move16();
265 : }
266 : ELSE
267 : {
268 53239 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0] = masa_sq_fx( L_sub( ONE_IN_Q30, dir2ratio_fx ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
269 53239 : move16();
270 : }
271 :
272 1088890 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
273 : {
274 855350 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = dir1ratio_fx; // Q30
275 855350 : move32();
276 855350 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
277 855350 : move16();
278 : }
279 :
280 1088890 : FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
281 : {
282 855350 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[m] = dir2ratio_fx; /*Q30*/
283 855350 : move32();
284 855350 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[m] = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0]; /*Q0*/
285 855350 : move16();
286 : }
287 :
288 233540 : dir2band = add( dir2band, 1 );
289 : }
290 : ELSE
291 : {
292 : /* 1dir band */
293 111826 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]] ); /*Q30*/
294 111826 : move32();
295 252550 : FOR( m = 1; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
296 : {
297 140724 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0]; /*Q30*/
298 140724 : move32();
299 140724 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
300 140724 : move16();
301 : }
302 : }
303 : }
304 : }
305 : ELSE
306 : {
307 : /* With 1dir band, the decoded index is directly diffuseness and we can decode to direct-to-total ratio with 1 - diff. */
308 1418611 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
309 : {
310 1184286 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]] ); /*Q30*/
311 1184286 : move32();
312 2921436 : FOR( m = 1; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
313 : {
314 1737150 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0]; /*Q30*/
315 1737150 : move32();
316 1737150 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
317 1737150 : move16();
318 : }
319 : }
320 : }
321 :
322 : /* To decode directions correctly for 2dir bands, we need to obtain the compensated direct-to-total ratios and their
323 : * corresponding inverted indices. */
324 266402 : bits_dir_raw_pre[0] = 0;
325 266402 : move16();
326 266402 : bits_dir_raw_pre[1] = 0;
327 266402 : move16();
328 266402 : dir2band = 0;
329 266402 : move16();
330 1796054 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
331 : {
332 1529652 : test();
333 1529652 : IF( EQ_32( hQMetaData->no_directions, 2 ) && EQ_16( hQMetaData->twoDirBands[b], 1 ) )
334 233540 : {
335 : Word16 index_dirRatio1Inv, index_dirRatio2Inv, index_dirRatio1Inv_mod, index_dirRatio2Inv_mod;
336 :
337 233540 : index_dirRatio1Inv = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
338 233540 : move16();
339 233540 : index_dirRatio2Inv = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0]; /*Q0*/
340 233540 : move16();
341 :
342 233540 : masa_compensate_two_dir_energy_ratio_index_fx( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod, hodirac_flag );
343 :
344 1088890 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
345 : {
346 855350 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index_mod[m] = index_dirRatio1Inv_mod; /*Q0*/
347 855350 : move16();
348 855350 : hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] = bits_direction_masa[index_dirRatio1Inv_mod]; /*Q0*/
349 855350 : move16();
350 855350 : bits_dir_raw_pre[0] = add( bits_dir_raw_pre[0], hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] );
351 855350 : move16();
352 : }
353 :
354 1088890 : FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
355 : {
356 855350 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index_mod[m] = index_dirRatio2Inv_mod; /*Q0*/
357 855350 : move16();
358 855350 : hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[m] = bits_direction_masa[index_dirRatio2Inv_mod]; /*Q0*/
359 855350 : move16();
360 855350 : bits_dir_raw_pre[1] = add( bits_dir_raw_pre[1], hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[m] );
361 855350 : move16();
362 : }
363 :
364 233540 : dir2band = add( dir2band, 1 );
365 : }
366 : ELSE
367 : {
368 4470098 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
369 : {
370 3173986 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index_mod[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
371 3173986 : move16();
372 3173986 : hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] = bits_direction_masa[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; /*Q0*/
373 3173986 : move16();
374 3173986 : bits_dir_raw_pre[0] = add( bits_dir_raw_pre[0], hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] );
375 3173986 : move16();
376 : }
377 : }
378 : }
379 :
380 266402 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
381 : {
382 32077 : no_TF = add( i_mult2( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ), i_mult2( hQMetaData->q_direction[1].cfg.nbands, hQMetaData->q_direction[1].cfg.nblocks ) ); /*Q0*/
383 32077 : tmp32 = L_sub( L_deposit_h( sub( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), bits_diff_sum ) ), L_mult0( 17612 /* 4.2998046875f in Q12 */, shl( no_TF, 4 ) ) ); /*Q16*/
384 32077 : test();
385 32077 : IF( !all_coherence_zero && GE_32( tmp32, L_deposit_h( MASA_MIN_BITS_SURR_COH ) ) )
386 : {
387 15617 : bits_sur_coherence = read_surround_coherence( bitstream, index, hQMetaData ); /*Q0*/
388 : }
389 : ELSE
390 : {
391 16460 : bits_sur_coherence = 0;
392 16460 : move16();
393 : /*Surround coherence*/
394 197579 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
395 : {
396 181119 : IF( hQMetaData->surcoh_band_data != NULL )
397 : {
398 818 : set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
399 : }
400 : }
401 : }
402 32077 : bits_no_dirs_coh = add( bits_no_dirs_coh, bits_sur_coherence );
403 32077 : total_bits_1dir = extract_l( L_mult0( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), i_mult2( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ) ) / no_TF ); /*Q0*/
404 : }
405 : ELSE
406 : {
407 234325 : no_TF = i_mult2( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ); /*Q0*/
408 234325 : tmp32 = L_sub( L_deposit_h( sub( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), bits_diff_sum ) ), L_mult0( 17612 /* 4.2998046875f in Q12 */, shl( no_TF, 4 ) ) ); /*Q16*/
409 234325 : test();
410 234325 : IF( !all_coherence_zero && GE_32( tmp32, L_deposit_h( MASA_MIN_BITS_SURR_COH ) ) )
411 : {
412 37526 : bits_sur_coherence = read_surround_coherence( bitstream, index, hQMetaData ); /*Q0*/
413 : }
414 : ELSE
415 : {
416 196799 : bits_sur_coherence = 0;
417 196799 : move16();
418 : /*Surround coherence*/
419 1015585 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
420 : {
421 818786 : IF( hQMetaData->surcoh_band_data != NULL )
422 : {
423 166467 : set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
424 : }
425 : }
426 : }
427 234325 : bits_no_dirs_coh = add( bits_no_dirs_coh, bits_sur_coherence );
428 :
429 234325 : total_bits_1dir = sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh );
430 : }
431 :
432 266402 : bits_dir_target = 0;
433 266402 : move16();
434 266402 : bits_dir_used = 0;
435 266402 : move16();
436 :
437 564881 : FOR( d = 0; d < hQMetaData->no_directions; d++ )
438 : {
439 298479 : q_direction = &hQMetaData->q_direction[d];
440 298479 : nbands = q_direction->cfg.nbands; /*Q0*/
441 298479 : move16();
442 298479 : nblocks = q_direction->cfg.nblocks; /*Q0*/
443 298479 : move16();
444 298479 : start_band = q_direction->cfg.start_band; /*Q0*/
445 298479 : move16();
446 :
447 298479 : diffuseness_index_max_ec_frame = diffuseness_index_max_ec_frame_pre[0]; /*Q0*/
448 298479 : move16();
449 298479 : IF( d == 0 )
450 : {
451 266402 : bits_diff = bits_diff_sum; /*Q0*/
452 266402 : move16();
453 : }
454 : ELSE
455 : {
456 32077 : bits_diff = 0;
457 32077 : move16();
458 : }
459 298479 : bits_dir_raw = bits_dir_raw_pre[d]; /*Q0*/
460 298479 : move16();
461 :
462 : /* Read coherence, if any */
463 298479 : bits_coherence = 0;
464 298479 : move16();
465 :
466 298479 : IF( all_coherence_zero == 0 )
467 : {
468 68925 : bits_coherence = read_coherence_data_fx( bitstream, index, hQMetaData, d, 0 ); /*Q0*/
469 : }
470 : ELSE
471 : {
472 : /*Surround coherence*/
473 1409753 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
474 : {
475 1180199 : IF( hQMetaData->surcoh_band_data != NULL )
476 : {
477 167278 : set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
478 : }
479 :
480 1180199 : IF( hQMetaData->q_direction[d].coherence_band_data != NULL )
481 : {
482 167278 : set_c( (Word8 *) hQMetaData->q_direction[d].coherence_band_data[b].spread_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
483 : }
484 : }
485 : }
486 :
487 : /* Read 2D signaling*/
488 298479 : q_direction->not_in_2D = bitstream[( *index )--]; /*Q0*/
489 298479 : move16();
490 298479 : signal_bits = 1;
491 298479 : move16();
492 :
493 : /* Read EC signaling */
494 298479 : ec_flag = 0;
495 298479 : move16();
496 298479 : IF( LE_16( add( total_bits_1dir, bits_sur_coherence ), hQMetaData->qmetadata_max_bit_req ) )
497 : {
498 230793 : ec_flag = bitstream[( *index )];
499 230793 : move16();
500 230793 : ( *index ) = sub( ( *index ), 1 );
501 230793 : move16();
502 230793 : signal_bits = add( signal_bits, 1 );
503 230793 : IF( GT_16( nblocks, 1 ) )
504 : {
505 137388 : IF( ec_flag )
506 : {
507 7969 : ec_flag = add( ec_flag, (Word16) bitstream[( *index )--] );
508 7969 : signal_bits = add( signal_bits, 1 );
509 : }
510 : }
511 : }
512 :
513 : /* Decode quantized directions frame-wise */
514 298479 : test();
515 298479 : IF( !ec_flag ) /* EC 1*/
516 : {
517 283386 : bits_dir = 0;
518 283386 : move16();
519 283386 : raw_flag[0] = bitstream[( *index )--]; /*Q0*/
520 283386 : move16();
521 283386 : bits_dir = add( bits_dir, 1 );
522 :
523 283386 : IF( !raw_flag[0] )
524 : {
525 157749 : bits_dir = add( bits_dir, ivas_qmetadata_entropy_decode_dir_fx( q_direction, bitstream, index, diffuseness_index_max_ec_frame, nbands, start_band, 0 ) );
526 : }
527 : ELSE
528 : {
529 125637 : bits_dir = add( bits_dir, ivas_qmetadata_raw_decode_dir_fx( q_direction, bitstream, index, nbands, start_band, 0 ) );
530 : }
531 : }
532 : /* Decode quantized directions band-wise */
533 15093 : ELSE IF( EQ_16( ec_flag, 1 ) && GT_16( nblocks, 1 ) ) /* EC2 */
534 : {
535 2310 : bits_dir = 0;
536 2310 : move16();
537 11597 : FOR( b = start_band; b < nbands; b++ )
538 : {
539 9287 : raw_flag[b] = bitstream[( *index )--]; /*Q0*/
540 9287 : move16();
541 9287 : bits_dir = add( bits_dir, 1 );
542 : }
543 :
544 : /* Read EC bits*/
545 2310 : diff_bits = add( bits_diff, add( bits_coherence, sub( signal_bits, total_bits_1dir ) ) );
546 :
547 11597 : FOR( b = start_band; b < nbands; b++ )
548 : {
549 9287 : IF( !raw_flag[b] )
550 : {
551 3227 : bits_dir = add( bits_dir, ivas_qmetadata_entropy_decode_dir_fx( q_direction, bitstream, index, diffuseness_index_max_ec_frame, b + 1, b, 0 ) );
552 : }
553 : ELSE
554 : {
555 6060 : diff_bits = add( diff_bits, q_direction->band_data[b].bits_sph_idx[0] * q_direction->cfg.nblocks );
556 : }
557 : }
558 2310 : diff_bits = add( diff_bits, bits_dir );
559 :
560 : /* Small requantization?*/
561 2310 : IF( q_direction->not_in_2D > 0 )
562 : {
563 : /* This is not an ideal solution but mirrors better encoder */
564 : Word16 i, j;
565 : UWord16 bits_temp[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
566 :
567 11371 : FOR( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
568 : {
569 45505 : FOR( j = 0; j < q_direction->cfg.nblocks; j++ )
570 : {
571 36404 : bits_temp[i][j] = q_direction->band_data[i].bits_sph_idx[j]; /*Q0*/
572 36404 : move16();
573 : }
574 : }
575 :
576 2270 : small_reduction_direction_fx( q_direction, bits_temp, raw_flag, &diff_bits );
577 :
578 11371 : FOR( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
579 : {
580 45505 : FOR( j = 0; j < q_direction->cfg.nblocks; j++ )
581 : {
582 36404 : q_direction->band_data[i].bits_sph_idx[j] = bits_temp[i][j]; /*Q0*/
583 36404 : move16();
584 : }
585 : }
586 : }
587 :
588 : /* Read raw-coded bits*/
589 11597 : FOR( b = start_band; b < nbands; b++ )
590 : {
591 9287 : IF( raw_flag[b] )
592 : {
593 6060 : bits_dir = add( bits_dir, ivas_qmetadata_raw_decode_dir_fx( q_direction, bitstream, index, b + 1, b, 0 ) );
594 : }
595 : }
596 : }
597 : /* Decode requantized directions */
598 : ELSE /* EC3 */
599 : {
600 : Word16 dummy;
601 12783 : ec_flag = 2;
602 12783 : move16();
603 :
604 12783 : IF( hQMetaData->is_masa_ivas_format == 0 )
605 : {
606 3599 : reduce_bits = sub( bits_dir_raw, sub( sub( sub( total_bits_1dir, bits_diff ), bits_coherence ), signal_bits ) ); /*Q0*/
607 3599 : ind_order[0] = -1;
608 3599 : move16();
609 : }
610 : ELSE
611 : {
612 9184 : ind_order[0] = 0;
613 9184 : move16();
614 9184 : reduce_bits = s_min( add( i_mult2( nbands, nblocks ), MASA_BIT_REDUCT_PARAM ), sub( bits_dir_raw, sub( sub( sub( total_bits_1dir, bits_diff ), bits_coherence ), signal_bits ) ) ); /*Q0*/
615 9184 : IF( GT_16( reduce_bits, sub( bits_dir_raw, i_mult2( nbands, nblocks ) ) ) )
616 : {
617 137 : reduce_bits = sub( bits_dir_raw, i_mult2( nbands, nblocks ) );
618 : }
619 : }
620 12783 : only_reduce_bits_direction_fx( &dummy, q_direction, reduce_bits, nbands, nblocks, ind_order );
621 :
622 : /* Read directions */
623 12783 : bits_dir = read_directions_fx( q_direction, (UWord8) nbands, (UWord8) nblocks, bitstream, index, ind_order ); /*Q0*/
624 : }
625 :
626 298479 : IF( bits_coherence > 0 )
627 : {
628 67563 : IF( GT_16( nblocks, 1 ) )
629 : {
630 42588 : decode_spread_coherence_fx( hQMetaData, d, nblocks, 0 );
631 : }
632 : }
633 : ELSE
634 : {
635 1415735 : FOR( b = start_band; b < nbands; b++ )
636 : {
637 1184819 : IF( q_direction->coherence_band_data != NULL )
638 : {
639 171898 : set_c( (Word8 *) q_direction->coherence_band_data[b].spread_coherence, 0, nblocks );
640 : }
641 : }
642 : }
643 298479 : IF( d == 0 )
644 : {
645 266402 : total_bits_1dir = sub( hQMetaData->metadata_max_bits, sub( start_index_0, *index ) ); /*Q0*/
646 : }
647 :
648 298479 : bits_dir_target = add( bits_dir_target, bits_dir_raw );
649 298479 : bits_dir_used = add( bits_dir_used, bits_dir );
650 : }
651 : /* move 2 dir data to its correct subband */
652 266402 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
653 : {
654 32077 : d = sub( hQMetaData->q_direction[1].cfg.nbands, 1 );
655 32077 : nblocks = hQMetaData->q_direction[0].cfg.nblocks;
656 32077 : move16();
657 :
658 377443 : FOR( b = hQMetaData->q_direction[0].cfg.nbands - 1; b >= 0; b-- )
659 : {
660 345366 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
661 : {
662 233540 : Copy32( hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].band_data[b].azimuth_fx, nblocks ); /*Q22*/
663 233540 : Copy32( hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].band_data[b].elevation_fx, nblocks ); /*Q22*/
664 233540 : Copy32( hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, nblocks ); /*Q30*/
665 :
666 233540 : IF( LT_32( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0], 7 ) )
667 : {
668 778994 : FOR( m = 0; m < nblocks; m++ )
669 : {
670 609712 : Word32 a1 = hQMetaData->q_direction[1].band_data[b].azimuth_fx[m]; /*Q22*/
671 609712 : move32();
672 609712 : a1 = L_shr( hQMetaData->q_direction[1].band_data[b].azimuth_fx[m], 1 ); /*Q21*/
673 609712 : Word32 b1 = hQMetaData->q_direction[0].band_data[b].azimuth_fx[m]; /*Q22*/
674 609712 : move32();
675 609712 : b1 = L_shr( hQMetaData->q_direction[0].band_data[b].azimuth_fx[m], 1 ); /*Q21*/
676 609712 : Word32 c = L_shr( DEGREE_180_Q_22, 1 ); /*Q21*/
677 609712 : a1 = L_add( a1, L_sub( b1, c ) );
678 609712 : IF( GE_32( a1, L_shr( DEGREE_180_Q_22, 1 ) ) )
679 : {
680 0 : a1 = L_sub( a1, L_shr( DEGREE_360_Q_22, 1 ) ); /*Q21*/
681 : }
682 609712 : IF( LT_32( a1, L_shr( -DEGREE_180_Q_22, 1 ) ) )
683 : {
684 81864 : a1 = L_add( a1, L_shr( DEGREE_360_Q_22, 1 ) ); /*Q21*/
685 : }
686 :
687 609712 : hQMetaData->q_direction[1].band_data[b].azimuth_fx[m] = L_shl( a1, 1 ); /*Q22*/
688 609712 : move32();
689 : }
690 : }
691 :
692 233540 : IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
693 : {
694 53239 : mvc2c( hQMetaData->q_direction[1].coherence_band_data[d].spread_coherence, hQMetaData->q_direction[1].coherence_band_data[b].spread_coherence, nblocks ); /*Q0*/
695 : }
696 233540 : d = sub( d, 1 );
697 : }
698 : ELSE
699 : {
700 111826 : set32_fx( hQMetaData->q_direction[1].band_data[b].azimuth_fx, 0, nblocks );
701 111826 : set32_fx( hQMetaData->q_direction[1].band_data[b].elevation_fx, 0, nblocks );
702 111826 : set32_fx( hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, 0, nblocks );
703 :
704 111826 : IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
705 : {
706 111826 : set_c( (Word8 *) hQMetaData->q_direction[1].coherence_band_data[b].spread_coherence, 0, nblocks );
707 : }
708 : }
709 : }
710 :
711 : /* Scale energy ratios that sum to over one */
712 32077 : IF( hodirac_flag == 0 )
713 : {
714 180751 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
715 : {
716 : Word32 ratioSum_flt_fx;
717 :
718 165065 : ratioSum_flt_fx = L_add( hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0], hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[0] ); /*Q30*/
719 :
720 165065 : IF( GT_32( ratioSum_flt_fx, ONE_IN_Q30 ) )
721 : {
722 0 : set32_fx( hQMetaData->q_direction[0].band_data[b].energy_ratio_fx, L_shl( (Word32) divide3232( hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0], ratioSum_flt_fx ), 15 ) /* Q30 */, nblocks ); /*Q30*/
723 0 : set32_fx( hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, L_shl( (Word32) divide3232( hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[0], ratioSum_flt_fx ), 15 ) /* Q30 */, nblocks ); /*Q30*/
724 : }
725 : }
726 : }
727 : }
728 :
729 : /* Store status information for renderer use */
730 266402 : hQMetaData->ec_flag = ec_flag;
731 266402 : move16();
732 :
733 266402 : IF( GT_16( bits_dir_used, bits_dir_target ) )
734 : {
735 94402 : hQMetaData->dir_comp_ratio_fx = MAX_WORD16; /*Q15*/
736 94402 : move16();
737 : }
738 : ELSE
739 : {
740 172000 : hQMetaData->dir_comp_ratio_fx = divide3232( bits_dir_used, bits_dir_target ); /*Q15*/
741 : }
742 266402 : return sub( start_index_0, *index );
743 : }
744 :
745 : /*-----------------------------------------------------------------------*
746 : * ivas_qmetadata_dec_decode_hr_384_512()
747 : *
748 : * Main function for decoding Spatial Metadata at HRs
749 : *-----------------------------------------------------------------------*/
750 :
751 : /*! r: number of bits read */
752 7033 : Word16 ivas_qmetadata_dec_decode_hr_384_512(
753 : IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: hQMetaData handle */
754 : UWord16 *bitstream, /* i : bitstream Q0*/
755 : Word16 *index, /* i/o: bitstream position Q0*/
756 : const SPHERICAL_GRID_DATA *sph_grid16, /* i : spherical grid for deindexing */
757 : const Word16 bits_sph_idx,
758 : const Word16 bits_sp_coh,
759 : const UWord8 ncoding_bands_config )
760 : {
761 : Word16 d, b, m;
762 : Word16 nbands, start_band;
763 : IVAS_QDIRECTION *q_direction;
764 : Word16 start_index_0;
765 : UWord16 all_coherence_zero;
766 : Word16 p[MASA_MAXIMUM_CODING_SUBBANDS], dif_p[MASA_MAXIMUM_CODING_SUBBANDS];
767 : Word16 codedBands, sf_nbands0, sf_nbands1;
768 7033 : sf_nbands1 = 1;
769 7033 : move16();
770 : Word64 W_nrg_ratio[2][MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
771 :
772 7033 : start_index_0 = *index;
773 7033 : move16();
774 : /* read number of higher inactive/not encoded bands */
775 7033 : IF( bitstream[( *index )--] )
776 : {
777 725 : codedBands = sub( sub( MASA_MAXIMUM_CODING_SUBBANDS, ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 1 ) ), 1 ); /*Q0*/
778 : }
779 : ELSE
780 : {
781 6308 : codedBands = MASA_MAXIMUM_CODING_SUBBANDS; /*Q0*/
782 6308 : move16();
783 : }
784 8918 : FOR( b = codedBands; b < ncoding_bands_config; b++ )
785 : {
786 9425 : FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ )
787 : {
788 :
789 7540 : hQMetaData->q_direction[0].band_data[b].azimuth_fx[m] = 0;
790 7540 : move32();
791 7540 : hQMetaData->q_direction[0].band_data[b].elevation_fx[m] = 0;
792 7540 : move32();
793 7540 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = 0;
794 7540 : move32();
795 7540 : W_nrg_ratio[0][b][m] = 0;
796 7540 : move64();
797 :
798 7540 : test();
799 7540 : IF( hQMetaData->coherence_flag && hQMetaData->q_direction[0].coherence_band_data != NULL )
800 : {
801 7540 : hQMetaData->q_direction[0].coherence_band_data[b].spread_coherence[m] = 0u;
802 7540 : move16();
803 : }
804 :
805 7540 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
806 : {
807 :
808 1140 : hQMetaData->q_direction[1].band_data[b].azimuth_fx[m] = 0;
809 1140 : move32();
810 1140 : hQMetaData->q_direction[1].band_data[b].elevation_fx[m] = 0;
811 1140 : move32();
812 1140 : hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[m] = 0;
813 1140 : move32();
814 1140 : W_nrg_ratio[1][b][m] = 0;
815 1140 : move64();
816 :
817 1140 : test();
818 1140 : IF( hQMetaData->coherence_flag && hQMetaData->q_direction[1].coherence_band_data != NULL )
819 : {
820 1140 : hQMetaData->q_direction[1].coherence_band_data[b].spread_coherence[m] = 0u;
821 1140 : move16();
822 : }
823 : }
824 :
825 7540 : test();
826 7540 : IF( hQMetaData->coherence_flag && hQMetaData->surcoh_band_data != NULL )
827 : {
828 7540 : hQMetaData->surcoh_band_data[b].surround_coherence[m] = 0u;
829 7540 : move16();
830 : }
831 : }
832 :
833 1885 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
834 : {
835 285 : hQMetaData->twoDirBands[b] = 0;
836 285 : move16();
837 : }
838 : }
839 7033 : sf_nbands0 = hQMetaData->q_direction[0].cfg.nbands; /*Q0*/
840 7033 : move16();
841 :
842 7033 : hQMetaData->q_direction[0].cfg.nbands = codedBands; /*Q0*/
843 7033 : move16();
844 :
845 : /*Coherence flag decoding*/
846 7033 : all_coherence_zero = 1;
847 7033 : move16();
848 7033 : IF( hQMetaData->coherence_flag )
849 : {
850 : /* read if coherence is zero */
851 7033 : all_coherence_zero = bitstream[( *index )--]; /*Q0*/
852 7033 : move16();
853 : }
854 :
855 7033 : hQMetaData->all_coherence_zero = (UWord8) all_coherence_zero; /*Q0*/
856 :
857 7033 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
858 : {
859 1905 : set_c( (Word8 *) hQMetaData->twoDirBands, 1, hQMetaData->q_direction[0].cfg.nbands );
860 : }
861 :
862 7033 : test();
863 7033 : IF( EQ_16( bits_sph_idx, 11 ) && EQ_32( hQMetaData->no_directions, 2 ) )
864 : {
865 : /* Read which bands have 2 directions */
866 1253 : hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands; /*Q0*/
867 1253 : move16();
868 1253 : sf_nbands1 = hQMetaData->q_direction[1].cfg.nbands; /*Q0*/
869 1253 : move16();
870 1253 : if ( GT_16( hQMetaData->q_direction[1].cfg.nbands, codedBands ) )
871 : {
872 0 : hQMetaData->q_direction[1].cfg.nbands = codedBands; /*Q0*/
873 0 : move16();
874 : }
875 1253 : set_c( (Word8 *) hQMetaData->twoDirBands, 0, hQMetaData->q_direction[0].cfg.nbands );
876 1253 : d = *index;
877 1253 : move16();
878 1253 : dif_p[0] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
879 1253 : move16();
880 1253 : p[0] = dif_p[0];
881 1253 : move16();
882 1253 : hQMetaData->twoDirBands[p[0]] = 1;
883 1253 : move16();
884 12780 : FOR( b = 1; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
885 : {
886 11527 : dif_p[b] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
887 11527 : move16();
888 11527 : p[b] = add( add( p[b - 1], dif_p[b] ), 1 );
889 11527 : move16();
890 11527 : hQMetaData->twoDirBands[p[b]] = 1;
891 11527 : move16();
892 : }
893 : }
894 :
895 7033 : test();
896 7033 : IF( EQ_16( bits_sph_idx, 16 ) && EQ_32( hQMetaData->no_directions, 2 ) )
897 : {
898 652 : sf_nbands1 = hQMetaData->q_direction[1].cfg.nbands; /*Q0*/
899 652 : move16();
900 652 : IF( GT_16( hQMetaData->q_direction[1].cfg.nbands, codedBands ) )
901 : {
902 0 : hQMetaData->q_direction[1].cfg.nbands = codedBands; /*Q0*/
903 0 : move16();
904 : }
905 : }
906 7033 : ivas_qmetadata_entropy_decode_diffuseness_hr_512( bitstream, index, &( hQMetaData->q_direction[0] ) );
907 :
908 7033 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
909 : {
910 1905 : ivas_qmetadata_entropy_decode_diffuseness_hr_512( bitstream, index, &( hQMetaData->q_direction[1] ) );
911 : }
912 :
913 :
914 173895 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
915 : {
916 595804 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
917 : {
918 428942 : W_nrg_ratio[0][b][m] = W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m]] ); /*Q62*/
919 428942 : move64();
920 : }
921 : }
922 7033 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
923 : {
924 : Word32 ratioSum;
925 1905 : IF( EQ_16( bits_sph_idx, 16 ) )
926 : {
927 16300 : FOR( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
928 : {
929 56856 : FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
930 : {
931 41208 : W_nrg_ratio[1][b][m] = W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[hQMetaData->q_direction[1].band_data[b].energy_ratio_index[m]] ); /*Q62*/
932 41208 : move64();
933 :
934 : /* Scale energy ratios that sum to over one */
935 41208 : ratioSum = W_round64_L( W_add( W_nrg_ratio[0][b][m], W_nrg_ratio[1][b][m] ) ); /*Q30*/
936 :
937 41208 : IF( GT_32( ratioSum, ONE_IN_Q30 ) )
938 : {
939 444 : W_nrg_ratio[0][b][m] = W_shl( (Word64) ( W_nrg_ratio[0][b][m] / ratioSum ), 30 ); // Q62
940 444 : move64();
941 444 : W_nrg_ratio[1][b][m] = W_shl( (Word64) ( W_nrg_ratio[1][b][m] / ratioSum ), 30 ); // Q62
942 444 : move64();
943 : }
944 : }
945 : }
946 : }
947 : ELSE
948 : {
949 : Word16 pos_2dir_band[MASA_MAXIMUM_CODING_SUBBANDS];
950 1253 : d = 0;
951 1253 : move16();
952 31040 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
953 : {
954 29787 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
955 : {
956 12780 : pos_2dir_band[d] = b; /*Q0*/
957 12780 : move16();
958 12780 : d = add( d, 1 );
959 : }
960 : ELSE
961 : {
962 17007 : pos_2dir_band[d] = 0;
963 17007 : move16();
964 : }
965 : }
966 14033 : FOR( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
967 : {
968 45864 : FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
969 : {
970 :
971 33084 : W_nrg_ratio[1][b][m] = W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[hQMetaData->q_direction[1].band_data[b].energy_ratio_index[m]] ); /*Q62*/
972 33084 : move64();
973 :
974 33084 : ratioSum = W_round64_L( W_add( W_nrg_ratio[0][pos_2dir_band[b]][m], W_nrg_ratio[1][b][m] ) ); /*Q30*/
975 :
976 33084 : IF( GT_32( ratioSum, ONE_IN_Q30 ) )
977 : {
978 135 : W_nrg_ratio[0][pos_2dir_band[b]][m] = W_shl( (Word64) ( W_nrg_ratio[0][pos_2dir_band[b]][m] / ratioSum ), 30 ); /*Q62*/
979 135 : move64();
980 135 : W_nrg_ratio[1][b][m] = W_shl( (Word64) ( W_nrg_ratio[1][b][m] / ratioSum ), 30 ); /*Q62*/
981 135 : move64();
982 : }
983 : }
984 : }
985 : }
986 : }
987 :
988 7033 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
989 : {
990 30333 : FOR( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
991 : {
992 102720 : FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
993 : {
994 74292 : hQMetaData->q_direction[1].band_data[b].energy_ratio_index_mod[m] = hQMetaData->q_direction[1].band_data[b].energy_ratio_index[m]; /*Q0*/
995 74292 : move16();
996 74292 : hQMetaData->q_direction[1].band_data[b].bits_sph_idx[m] = bits_sph_idx; /*Q0*/
997 74292 : move16();
998 : }
999 : }
1000 : }
1001 :
1002 173895 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1003 : {
1004 595804 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
1005 : {
1006 428942 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index_mod[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
1007 428942 : move16();
1008 428942 : hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] = bits_sph_idx; /*Q0*/
1009 428942 : move16();
1010 : }
1011 : }
1012 :
1013 7033 : IF( !all_coherence_zero )
1014 : {
1015 5640 : read_surround_coherence_hr_fx( bitstream, index, hQMetaData, W_nrg_ratio );
1016 : }
1017 : ELSE
1018 : {
1019 : /*Surround coherence*/
1020 34400 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1021 : {
1022 33007 : IF( hQMetaData->surcoh_band_data != NULL )
1023 : {
1024 33007 : set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
1025 : }
1026 : }
1027 : }
1028 :
1029 15971 : FOR( d = 0; d < hQMetaData->no_directions; d++ )
1030 : {
1031 8938 : q_direction = &hQMetaData->q_direction[d];
1032 8938 : nbands = q_direction->cfg.nbands;
1033 8938 : move16();
1034 8938 : start_band = q_direction->cfg.start_band;
1035 8938 : move16();
1036 :
1037 : /* Read coherence, IF any */
1038 8938 : IF( !all_coherence_zero )
1039 : {
1040 7540 : read_coherence_data_hr_512_fx( bitstream, index, hQMetaData, d, bits_sp_coh );
1041 : }
1042 : ELSE
1043 : {
1044 : /*Surround coherence*/
1045 34525 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1046 : {
1047 33127 : IF( hQMetaData->surcoh_band_data != NULL )
1048 : {
1049 33127 : set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
1050 : }
1051 :
1052 33127 : IF( hQMetaData->q_direction[d].coherence_band_data != NULL )
1053 : {
1054 33127 : set_c( (Word8 *) hQMetaData->q_direction[d].coherence_band_data[b].spread_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
1055 : }
1056 : }
1057 : }
1058 :
1059 : /* Decode quantized directions frame-wise */
1060 :
1061 8938 : ivas_qmetadata_raw_decode_dir_512_fx( q_direction, bitstream, index, nbands, start_band, sph_grid16 );
1062 : }
1063 :
1064 7033 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
1065 : {
1066 : /* move 2 dir data to its correct subband */
1067 1905 : IF( EQ_16( bits_sph_idx, 11 ) )
1068 : {
1069 : Word16 nblocks;
1070 1253 : d = sub( hQMetaData->q_direction[1].cfg.nbands, 1 );
1071 1253 : nblocks = hQMetaData->q_direction[0].cfg.nblocks;
1072 1253 : move16();
1073 :
1074 31040 : FOR( b = hQMetaData->q_direction[0].cfg.nbands - 1; b >= 0; b-- )
1075 : {
1076 29787 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
1077 : {
1078 :
1079 12780 : Copy32( hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].band_data[b].azimuth_fx, nblocks ); /*Q22*/
1080 12780 : Copy32( hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].band_data[b].elevation_fx, nblocks ); /*Q22*/
1081 12780 : Copy32( hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, nblocks ); /*Q30*/
1082 12780 : Copy64( W_nrg_ratio[1][d], W_nrg_ratio[1][b], nblocks );
1083 :
1084 12780 : IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
1085 : {
1086 12780 : mvc2c( hQMetaData->q_direction[1].coherence_band_data[d].spread_coherence, hQMetaData->q_direction[1].coherence_band_data[b].spread_coherence, nblocks ); /*Q0*/
1087 : }
1088 12780 : d = sub( d, 1 );
1089 : }
1090 : ELSE
1091 : {
1092 17007 : set32_fx( hQMetaData->q_direction[1].band_data[b].azimuth_fx, 0, nblocks );
1093 17007 : set32_fx( hQMetaData->q_direction[1].band_data[b].elevation_fx, 0, nblocks );
1094 17007 : set32_fx( hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, 0, nblocks );
1095 17007 : set64_fx( W_nrg_ratio[1][b], 0, nblocks );
1096 :
1097 17007 : IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
1098 : {
1099 17007 : set_c( (Word8 *) hQMetaData->q_direction[1].coherence_band_data[b].spread_coherence, 0, nblocks );
1100 : }
1101 : }
1102 : }
1103 : }
1104 :
1105 : /* Scale energy ratios that sum to over one */
1106 47340 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1107 : {
1108 170142 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
1109 : {
1110 : Word32 ratioSum;
1111 124707 : ratioSum = W_round64_L( W_add( W_nrg_ratio[0][b][m], W_nrg_ratio[1][b][m] ) ); /*Q30*/
1112 124707 : IF( GT_32( ratioSum, ONE_IN_Q30 ) )
1113 : {
1114 0 : W_nrg_ratio[0][b][m] = W_shl( (Word64) ( W_nrg_ratio[0][b][m] / ratioSum ), 30 ); /*Q62*/
1115 0 : move64();
1116 0 : W_nrg_ratio[1][b][m] = W_shl( (Word64) ( W_nrg_ratio[1][b][m] / ratioSum ), 30 ); /*Q62*/
1117 0 : move64();
1118 : }
1119 : }
1120 : }
1121 : }
1122 :
1123 173895 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1124 : {
1125 595804 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
1126 : {
1127 428942 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[0][b][m] ); /*Q30*/
1128 428942 : move32();
1129 : }
1130 : }
1131 7033 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
1132 : {
1133 47340 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1134 : {
1135 170142 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
1136 : {
1137 124707 : hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[1][b][m] ); /*Q30*/
1138 124707 : move32();
1139 : }
1140 : }
1141 : }
1142 : /* Store status information for renderer use */
1143 7033 : hQMetaData->ec_flag = 0;
1144 7033 : move16();
1145 7033 : hQMetaData->dir_comp_ratio_fx = MAX_WORD16; /*Q15*/
1146 7033 : move16();
1147 :
1148 :
1149 7033 : hQMetaData->q_direction[0].cfg.nbands = sf_nbands0; /*Q0*/
1150 7033 : move16();
1151 7033 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
1152 : {
1153 1905 : hQMetaData->q_direction[1].cfg.nbands = sf_nbands1; /*Q0*/
1154 1905 : move16();
1155 : }
1156 :
1157 7033 : return sub( start_index_0, *index );
1158 : }
1159 :
1160 :
1161 : /*-----------------------------------------------------------------------*
1162 : * ivas_qmetadata_dec_sid_decode()
1163 : *
1164 : * Main function for decoding SID for Spatial Metadata
1165 : *-----------------------------------------------------------------------*/
1166 :
1167 : /*! r: number of bits written */
1168 1062 : Word16 ivas_qmetadata_dec_sid_decode(
1169 : IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */
1170 : UWord16 *bitstream, /* i : bitstream Q0*/
1171 : Word16 *index, /* i/o: bitstream position Q0*/
1172 : const Word16 nchan_transport, /* i : number of transport channels Q0*/
1173 : Word16 *element_mode, /* o : element mode Q0*/
1174 : const Word16 ivas_format /* i : IVAS format Q0*/
1175 : )
1176 : {
1177 : Word16 b, m, i;
1178 : UWord16 value;
1179 : UWord16 diffuseness_index[DIRAC_MAX_NBANDS];
1180 : Word16 nbands, nblocks, start_band;
1181 : IVAS_QDIRECTION *q_direction;
1182 : Word16 start_index;
1183 : Word32 avg_elevation_fx, avg_azimuth_fx;
1184 : Word32 avg_direction_vector_fx[3];
1185 : Word32 direction_vector_fx[3];
1186 : Word16 metadata_sid_bits; /* bits allocated to SID for metadata */
1187 : Word16 bits_delta, bits_dir;
1188 : Word16 sba_spar_bitlen;
1189 :
1190 1062 : IF( EQ_16( ivas_format, SBA_FORMAT ) )
1191 : {
1192 868 : sba_spar_bitlen = ivas_sba_spar_sid_bitlen_fx( nchan_transport );
1193 868 : metadata_sid_bits = (Word16) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - SBA_ORDER_BITS - SBA_PLANAR_BITS - 1; /* -1 for inactive mode header bit*/
1194 868 : metadata_sid_bits = sub( metadata_sid_bits, sba_spar_bitlen );
1195 : }
1196 : ELSE
1197 : {
1198 194 : metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS;
1199 194 : move16();
1200 : }
1201 :
1202 1062 : start_index = *index;
1203 1062 : move16();
1204 :
1205 : /* read MASA SID descriptor */
1206 1062 : test();
1207 1062 : IF( EQ_16( ivas_format, MASA_FORMAT ) && EQ_16( nchan_transport, 2 ) )
1208 : {
1209 74 : b = bitstream[( *index )--]; /*Q0*/
1210 74 : move16();
1211 74 : IF( b )
1212 : {
1213 0 : *element_mode = IVAS_CPE_MDCT;
1214 0 : move16();
1215 : }
1216 : ELSE
1217 : {
1218 74 : *element_mode = IVAS_CPE_DFT;
1219 74 : move16();
1220 : }
1221 : }
1222 :
1223 : /* Fix configuration for SID */
1224 1062 : q_direction = &hQMetaData->q_direction[0]; /* only 1 direction */
1225 1062 : IF( EQ_16( ivas_format, SBA_FORMAT ) )
1226 : {
1227 868 : nbands = DIRAC_DTX_BANDS; /* only 2 bands transmitted */
1228 868 : move16();
1229 : }
1230 : ELSE
1231 : {
1232 194 : nbands = 5; /* only 5 bands transmitted */
1233 194 : move16();
1234 : }
1235 :
1236 1062 : nblocks = q_direction->cfg.nblocks; /* only 1 block transmitted but up to 4 blocks re-generated Q0*/
1237 1062 : move16();
1238 1062 : start_band = 0; /* start from band 0 */
1239 1062 : move16();
1240 :
1241 : /* Read 2D signaling*/
1242 1062 : IF( NE_16( ivas_format, SBA_FORMAT ) )
1243 : {
1244 194 : q_direction->not_in_2D = bitstream[( *index )--]; /*Q0*/
1245 194 : move16();
1246 : }
1247 : ELSE
1248 : {
1249 868 : q_direction->not_in_2D = 1;
1250 868 : move16();
1251 : }
1252 :
1253 1062 : bits_dir = 0;
1254 1062 : move16();
1255 1062 : IF( NE_16( ivas_format, SBA_FORMAT ) )
1256 : {
1257 : /* Decode diffuseness*/
1258 1164 : FOR( b = start_band; b < nbands; b++ )
1259 : {
1260 970 : diffuseness_index[b] = (UWord16) L_add( ivas_qmetadata_DecodeQuasiUniform( bitstream, index, sub( DIRAC_DIFFUSE_LEVELS, 4 ) ), 4 ); /*Q0*/
1261 970 : move16();
1262 970 : q_direction->band_data[b].energy_ratio_index[0] = diffuseness_index[b]; /*Q0*/
1263 970 : move16();
1264 970 : q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[diffuseness_index[b]]; /*Q0*/
1265 970 : move16();
1266 970 : bits_dir = extract_l( L_add( bits_dir, q_direction->band_data[b].bits_sph_idx[0] ) ); /*Q0*/
1267 970 : q_direction->band_data[b].azimuth_m_alphabet[0] = no_phi_masa[q_direction->band_data[b].bits_sph_idx[0] - 1][0]; /*Q0*/
1268 970 : move16();
1269 : }
1270 :
1271 194 : bits_delta = sub( sub( metadata_sid_bits, sub( start_index, *index ) ), bits_dir ); /* bit_diff is already read */
1272 :
1273 194 : IF( bits_delta > 0 )
1274 : {
1275 921 : WHILE( bits_delta > 0 )
1276 : {
1277 3954 : FOR( b = start_band; b < nbands && ( bits_delta > 0 ); b++ )
1278 : {
1279 3227 : IF( LT_32( q_direction->band_data[b].bits_sph_idx[0], 11 ) )
1280 : {
1281 3227 : bits_delta = sub( bits_delta, 1 );
1282 3227 : q_direction->band_data[b].bits_sph_idx[0] = add( q_direction->band_data[b].bits_sph_idx[0], 1 );
1283 3227 : move16();
1284 : }
1285 : }
1286 : }
1287 :
1288 194 : IF( q_direction->not_in_2D == 0 )
1289 : {
1290 0 : FOR( b = start_band; b < nbands; b++ )
1291 : {
1292 0 : q_direction->band_data[b].azimuth_m_alphabet[0] = shl( 1, extract_l( L_min( 8, q_direction->band_data[b].bits_sph_idx[0] ) ) );
1293 0 : move16();
1294 : }
1295 : }
1296 : }
1297 : ELSE
1298 : {
1299 0 : WHILE( bits_delta < 0 )
1300 : {
1301 0 : FOR( b = nbands - 1; b >= start_band && ( bits_delta < 0 ); b-- )
1302 : {
1303 0 : IF( GE_32( q_direction->band_data[b].bits_sph_idx[0], 4 ) )
1304 : {
1305 0 : bits_delta = add( bits_delta, 1 );
1306 0 : q_direction->band_data[b].bits_sph_idx[0] = sub( q_direction->band_data[b].bits_sph_idx[0], 1 );
1307 0 : move16();
1308 : }
1309 : }
1310 :
1311 0 : IF( q_direction->not_in_2D == 0 )
1312 : {
1313 0 : FOR( b = start_band; b < nbands; b++ )
1314 : {
1315 0 : q_direction->band_data[b].azimuth_m_alphabet[0] = shl( 1, extract_l( L_min( 8, q_direction->band_data[b].bits_sph_idx[0] ) ) );
1316 0 : move16();
1317 : }
1318 : }
1319 : }
1320 : }
1321 : }
1322 : ELSE
1323 : {
1324 : /* Decode diffuseness*/
1325 2604 : FOR( b = start_band; b < nbands; b++ )
1326 : {
1327 1736 : diffuseness_index[b] = (UWord16) L_add( ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS - 4 ), 4 ); /*Q0*/
1328 1736 : move16();
1329 1736 : q_direction->band_data[b].energy_ratio_index[0] = diffuseness_index[b];
1330 1736 : move16();
1331 1736 : q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[diffuseness_index[b]];
1332 1736 : move16();
1333 1736 : q_direction->band_data[b].azimuth_m_alphabet[0] = no_phi_masa[q_direction->band_data[b].bits_sph_idx[0] - 1][0];
1334 1736 : move16();
1335 : }
1336 : }
1337 :
1338 3768 : FOR( b = start_band; b < nbands; b++ )
1339 : {
1340 2706 : q_direction->band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[diffuseness_index[b]] ); /*Q30*/
1341 2706 : move32();
1342 13320 : FOR( i = 0; i < nblocks; i++ )
1343 : {
1344 10614 : q_direction->band_data[b].energy_ratio_fx[i] = q_direction->band_data[b].energy_ratio_fx[0]; /*Q30*/
1345 10614 : move32();
1346 : }
1347 : }
1348 :
1349 : /* Decoder DOAs*/
1350 1062 : IF( q_direction->not_in_2D > 0 )
1351 : {
1352 3768 : FOR( b = start_band; b < nbands; b++ )
1353 : {
1354 2706 : value = 0;
1355 2706 : move16();
1356 16121 : FOR( i = 0; i < q_direction->band_data[b].bits_sph_idx[0]; i++ )
1357 : {
1358 13415 : value = (UWord16) L_add( L_shl( value, 1 ), bitstream[( *index )--] );
1359 : }
1360 13320 : FOR( i = 0; i < nblocks; i++ )
1361 : {
1362 10614 : q_direction->band_data[b].spherical_index[i] = value;
1363 10614 : move16();
1364 : }
1365 :
1366 2706 : deindex_spherical_component_fx( q_direction->band_data[b].spherical_index[0], &avg_azimuth_fx, &avg_elevation_fx, &q_direction->band_data[b].azimuth_index[0], &q_direction->band_data[b].elevation_index[0], q_direction->band_data[b].bits_sph_idx[0], q_direction->cfg.mc_ls_setup );
1367 :
1368 2706 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( avg_azimuth_fx, avg_elevation_fx, avg_direction_vector_fx );
1369 2706 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[b].azimuth_fx[nblocks - 1], q_direction->band_data[b].elevation_fx[nblocks - 1], direction_vector_fx );
1370 :
1371 2706 : v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 ); /*Q25*/
1372 2706 : v_shr_32( avg_direction_vector_fx, avg_direction_vector_fx, 3, 5 ); /*Q25*/
1373 10614 : FOR( m = 0; m < nblocks - 1; m++ )
1374 : {
1375 7908 : v_add_32( direction_vector_fx, avg_direction_vector_fx, direction_vector_fx, 3 ); /*Q25*/
1376 7908 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( direction_vector_fx, sub( 30, 5 ), &q_direction->band_data[b].azimuth_fx[m], &q_direction->band_data[b].elevation_fx[m] );
1377 : }
1378 2706 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_fx, sub( 30, 5 ), &q_direction->band_data[b].azimuth_fx[nblocks - 1], &q_direction->band_data[b].elevation_fx[nblocks - 1] );
1379 : }
1380 : }
1381 : ELSE
1382 : {
1383 0 : FOR( b = start_band; b < nbands; b++ )
1384 : {
1385 : Word32 temp_result;
1386 0 : IF( EQ_16( ivas_format, SBA_FORMAT ) )
1387 : {
1388 0 : q_direction->band_data[b].azimuth_m_alphabet[0] = shl( 1, extract_l( L_min( 5, q_direction->band_data[b].bits_sph_idx[0] ) ) );
1389 0 : move16();
1390 : }
1391 0 : q_direction->band_data[b].azimuth_index[0] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, q_direction->band_data[b].azimuth_m_alphabet[0] ); /*Q0*/
1392 0 : move16();
1393 0 : q_direction->band_data[b].azimuth_index[0] = add( ivas_qmetadata_dereorder_generic_fx( q_direction->band_data[b].azimuth_index[0] ), shr( q_direction->band_data[b].azimuth_m_alphabet[0], 1 ) ); /*Q0*/
1394 0 : move16();
1395 :
1396 0 : temp_result = div_s( ( shl( q_direction->band_data[b].azimuth_index[0], 6 ) ), ( shl( q_direction->band_data[b].azimuth_m_alphabet[0], 6 ) ) ); /*Q15*/
1397 0 : temp_result = Mpy_32_16_1( DEGREE_360_Q_22, (Word16) temp_result ); /*Q22*/
1398 0 : avg_azimuth_fx = L_sub( temp_result, DEGREE_180_Q_22 ); /*Q22*/
1399 :
1400 0 : avg_elevation_fx = 0;
1401 0 : move32();
1402 :
1403 0 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( avg_azimuth_fx, avg_elevation_fx, avg_direction_vector_fx );
1404 0 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[b].azimuth_fx[nblocks - 1], q_direction->band_data[b].elevation_fx[nblocks - 1], direction_vector_fx );
1405 :
1406 0 : v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 ); /*Q25*/
1407 0 : v_shr_32( avg_direction_vector_fx, avg_direction_vector_fx, 3, 5 ); /*Q25*/
1408 0 : FOR( m = 0; m < nblocks - 1; m++ )
1409 : {
1410 0 : v_add_32( direction_vector_fx, avg_direction_vector_fx, direction_vector_fx, 3 ); /*Q25*/
1411 0 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( direction_vector_fx, 30 - 5, &q_direction->band_data[b].azimuth_fx[m], &q_direction->band_data[b].elevation_fx[m] );
1412 : }
1413 0 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_fx, 30 - 5, &q_direction->band_data[b].azimuth_fx[nblocks - 1], &q_direction->band_data[b].elevation_fx[nblocks - 1] );
1414 :
1415 0 : FOR( i = 0; i < nblocks; i++ )
1416 : {
1417 0 : q_direction->band_data[b].spherical_index[i] = q_direction->band_data[b].azimuth_index[0];
1418 0 : move16();
1419 : }
1420 : }
1421 : }
1422 :
1423 :
1424 : /*Read filling bits*/
1425 4765 : WHILE( LT_16( sub( start_index, *index ), metadata_sid_bits ) )
1426 : {
1427 3703 : b = bitstream[( *index )--];
1428 3703 : move16();
1429 : }
1430 :
1431 1062 : return sub( start_index, *index );
1432 : }
1433 :
1434 : /*-----------------------------------------------------------------------*
1435 : * Local function definitions for diffuseness/energy ratios
1436 : *-----------------------------------------------------------------------*/
1437 :
1438 644992 : static Word16 ivas_diffuseness_huff_ec_decode_fx(
1439 : const UWord16 *bitstream, /*Q0*/
1440 : Word16 *index, /*Q0*/
1441 : Word16 av /*Q0*/ )
1442 : {
1443 : Word16 val;
1444 :
1445 644992 : val = 0;
1446 644992 : move16();
1447 1124737 : WHILE( LE_16( val, DIFF_EC_HUFF_GR0_LIMIT ) )
1448 : {
1449 1124276 : IF( EQ_16( bitstream[( *index )--], 1 ) )
1450 : {
1451 479745 : val = add( val, 1 );
1452 : }
1453 : ELSE
1454 : {
1455 644531 : BREAK;
1456 : }
1457 : }
1458 :
1459 644992 : IF( EQ_16( val, DIFF_EC_HUFF_GR0_LIMIT + 1 ) )
1460 : {
1461 461 : val = add( val, shl( bitstream[( *index )--], 1 ) );
1462 461 : val = add( val, bitstream[( *index )--] );
1463 : }
1464 :
1465 644992 : IF( val % 2 == 0 )
1466 : {
1467 496950 : return add( negate( shr( val, 1 ) ), av );
1468 : }
1469 : ELSE
1470 : {
1471 148042 : return add( shr( add( val, 1 ), 1 ), av );
1472 : }
1473 : }
1474 :
1475 : /*-------------------------------------------------------------------*
1476 : * ivas_qmetadata_entropy_decode_diffuseness()
1477 : *
1478 : *
1479 : *-------------------------------------------------------------------*/
1480 266402 : static Word16 ivas_qmetadata_entropy_decode_diffuseness(
1481 : UWord16 *bitstream, /* i : bitstream Q0*/
1482 : Word16 *index, /*Q0*/
1483 : IVAS_QDIRECTION *q_direction,
1484 : UWord16 *diffuseness_index_max_ec_frame /*Q0*/ )
1485 : {
1486 : Word16 b;
1487 : UWord16 dif_min;
1488 : Word16 index_start;
1489 : Word16 nbands;
1490 : Word16 start_band;
1491 :
1492 266402 : index_start = *index;
1493 266402 : move16();
1494 266402 : nbands = q_direction->cfg.nbands;
1495 266402 : move16();
1496 266402 : start_band = q_direction->cfg.start_band;
1497 266402 : move16();
1498 :
1499 : /* diffuseness decoding */
1500 : /* Handle one band as special case*/
1501 266402 : IF( EQ_16( nbands, 1 ) )
1502 : {
1503 6126 : q_direction->band_data[0].energy_ratio_index[0] = 0;
1504 6126 : move16();
1505 24504 : FOR( b = 0; b < MASA_BITS_ER; b++ )
1506 : {
1507 18378 : q_direction->band_data[0].energy_ratio_index[0] = (UWord16) L_add( L_shl( q_direction->band_data[0].energy_ratio_index[0], 1 ), bitstream[( *index )--] ); /*Q0*/
1508 18378 : move16();
1509 : }
1510 6126 : *diffuseness_index_max_ec_frame = 5;
1511 6126 : move16();
1512 :
1513 6126 : return MASA_BITS_ER;
1514 : }
1515 :
1516 260276 : IF( bitstream[( *index )--] == 0 ) /* dif_use_raw_coding */
1517 : {
1518 : /* Decode with similarity strategy with low band count. On higher band counts, decode with Huffman-coding strategy. */
1519 151211 : IF( LT_16( nbands, DIFF_EC_HUFF_BAND_LIMIT ) )
1520 : {
1521 104499 : IF( bitstream[( *index )--] ) /* dif_have_unique_value */
1522 : {
1523 61174 : dif_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS ); /* dif_unique_value Q0*/
1524 :
1525 260834 : FOR( b = start_band; b < nbands; b++ )
1526 : {
1527 199660 : q_direction->band_data[b].energy_ratio_index[0] = dif_min; /*Q0*/
1528 199660 : move16();
1529 : }
1530 : }
1531 : ELSE /* all diffuseness values are dif_min_value or dif_min_value + 1 */
1532 : {
1533 43325 : dif_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS - 1 ); /* dif_min_value Q0*/
1534 :
1535 196814 : FOR( b = start_band; b < nbands; b++ )
1536 : {
1537 153489 : q_direction->band_data[b].energy_ratio_index[0] = (UWord16) L_add( dif_min, bitstream[( *index )--] ); /* dif_bit_offset_values Q0*/
1538 153489 : move16();
1539 : }
1540 : }
1541 : }
1542 : ELSE
1543 : {
1544 : Word16 av;
1545 :
1546 : /* read average on 3 bits*/
1547 46712 : av = 0;
1548 46712 : move16();
1549 186848 : FOR( b = 0; b < MASA_BITS_ER; b++ )
1550 : {
1551 140136 : av = add( av, i_mult( (Word16) bitstream[( *index )--], shl( 1, sub( sub( MASA_BITS_ER, 1 ), b ) ) ) ); /*Q0*/
1552 : }
1553 :
1554 46712 : dif_min = DIRAC_DIFFUSE_LEVELS;
1555 46712 : move16();
1556 : /* read average removed data (average is added inside)*/
1557 691704 : FOR( b = start_band; b < nbands; b++ )
1558 : {
1559 644992 : q_direction->band_data[b].energy_ratio_index[0] = ivas_diffuseness_huff_ec_decode_fx( bitstream, index, av ); /*Q0*/
1560 644992 : move16();
1561 644992 : dif_min = (UWord16) L_min( dif_min, q_direction->band_data[b].energy_ratio_index[0] );
1562 644992 : move16();
1563 : }
1564 : }
1565 : }
1566 : ELSE /* different values for diffuseness */
1567 : {
1568 109065 : dif_min = DIRAC_DIFFUSE_LEVELS;
1569 109065 : move16();
1570 :
1571 634450 : FOR( b = start_band; b < nbands; b++ )
1572 : {
1573 525385 : q_direction->band_data[b].energy_ratio_index[0] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
1574 525385 : move16();
1575 525385 : dif_min = (UWord16) L_min( dif_min, q_direction->band_data[b].energy_ratio_index[0] );
1576 525385 : move16();
1577 : }
1578 : }
1579 :
1580 260276 : *diffuseness_index_max_ec_frame = 5;
1581 260276 : move16();
1582 : /* adaptively select the diffuseness_index_max_ec threshold */
1583 260276 : if ( GT_32( dif_min, 5 ) )
1584 : {
1585 96870 : *diffuseness_index_max_ec_frame = (UWord16) DIRAC_DIFFUSE_LEVELS - 1;
1586 96870 : move16();
1587 : }
1588 :
1589 260276 : return sub( index_start, *index );
1590 : }
1591 :
1592 : /*-------------------------------------------------------------------*
1593 : * ivas_qmetadata_entropy_decode_diffuseness_hr_512()
1594 : *
1595 : *
1596 : *-------------------------------------------------------------------*/
1597 :
1598 8938 : static Word16 ivas_qmetadata_entropy_decode_diffuseness_hr_512(
1599 : UWord16 *bitstream, /* i : bitstream Q0*/
1600 : Word16 *index, /*Q0*/
1601 : IVAS_QDIRECTION *q_direction )
1602 : {
1603 : Word16 b, k;
1604 :
1605 : Word16 index_start;
1606 : Word16 nbands, nblocks;
1607 : Word16 start_band;
1608 :
1609 8938 : index_start = *index;
1610 8938 : move16();
1611 8938 : nbands = q_direction->cfg.nbands;
1612 8938 : move16();
1613 8938 : nblocks = q_direction->cfg.nblocks;
1614 8938 : move16();
1615 8938 : start_band = q_direction->cfg.start_band;
1616 8938 : move16();
1617 :
1618 : /* diffuseness decoding */
1619 : /* Handle one band as special case*/
1620 8938 : IF( EQ_16( nbands, 1 ) )
1621 : {
1622 0 : q_direction->band_data[0].energy_ratio_index[0] = 0;
1623 0 : move16();
1624 0 : FOR( b = 0; b < MASA_BITS_ER_HR; b++ )
1625 : {
1626 0 : q_direction->band_data[0].energy_ratio_index[0] = (UWord16) L_add( (UWord16) L_shl( q_direction->band_data[0].energy_ratio_index[0], 1 ), bitstream[( *index )--] ); /*Q0*/
1627 0 : move16();
1628 : }
1629 :
1630 0 : return MASA_BITS_ER_HR;
1631 : }
1632 :
1633 204228 : FOR( b = start_band; b < nbands; b++ )
1634 : {
1635 698524 : FOR( k = 0; k < nblocks; k++ )
1636 : {
1637 503234 : q_direction->band_data[b].energy_ratio_index[k] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, HR_MASA_ER_LEVELS ); /*Q0*/
1638 503234 : move16();
1639 : }
1640 : }
1641 :
1642 8938 : return sub( index_start, *index );
1643 : }
1644 :
1645 :
1646 : /*-------------------------------------------------------------------*
1647 : * ivas_qmetadata_entropy_decode_df_ratio()
1648 : *
1649 : *
1650 : *-------------------------------------------------------------------*/
1651 32077 : static Word16 ivas_qmetadata_entropy_decode_df_ratio(
1652 : UWord16 *bitstream, /*Q0*/
1653 : Word16 *index, /*Q0*/
1654 : IVAS_QDIRECTION *q_direction,
1655 : Word16 *dfRatio_bits /*Q0*/ )
1656 : {
1657 : Word16 b;
1658 : Word16 bits_raw;
1659 : Word16 max_dfRatio_bits;
1660 : UWord16 ratio_min;
1661 : Word16 index_start;
1662 : Word16 nbands;
1663 : Word16 start_band;
1664 : Word16 ec_mode;
1665 : Word16 dec_mode;
1666 : Word16 max_alphabet_size;
1667 :
1668 32077 : index_start = *index;
1669 32077 : move16();
1670 32077 : nbands = q_direction->cfg.nbands;
1671 32077 : move16();
1672 32077 : start_band = q_direction->cfg.start_band;
1673 32077 : move16();
1674 :
1675 : /* Handle one band as special case*/
1676 32077 : IF( EQ_16( nbands, 1 ) )
1677 : {
1678 4720 : q_direction->band_data[0].energy_ratio_index[0] = 0;
1679 4720 : move16();
1680 14544 : FOR( b = 0; b < dfRatio_bits[0]; b++ )
1681 : {
1682 : // q_direction->band_data[0].energy_ratio_index[0] = ( q_direction->band_data[0].energy_ratio_index[0] << 1 ) + bitstream[( *index )--];
1683 9824 : q_direction->band_data[0].energy_ratio_index[0] = (UWord16) L_add( L_shl( q_direction->band_data[0].energy_ratio_index[0], 1 ), bitstream[( *index )--] ); /*Q0*/
1684 9824 : move16();
1685 : }
1686 4720 : return dfRatio_bits[0];
1687 : }
1688 :
1689 : /* Calculate raw coding bits and decide what modes are possible */
1690 27357 : bits_raw = 0;
1691 27357 : move16();
1692 27357 : max_dfRatio_bits = 0;
1693 27357 : move16();
1694 256177 : FOR( b = start_band; b < nbands; b++ )
1695 : {
1696 : // bits_raw += dfRatio_bits[b];
1697 228820 : bits_raw = add( bits_raw, dfRatio_bits[b] );
1698 228820 : max_dfRatio_bits = s_max( max_dfRatio_bits, dfRatio_bits[b] );
1699 : }
1700 :
1701 : /* Decide what modes are possible */
1702 27357 : IF( GE_16( bits_raw, add( add( max_dfRatio_bits, 2 ), nbands ) ) )
1703 : {
1704 15841 : ec_mode = 2;
1705 15841 : move16();
1706 : }
1707 11516 : ELSE IF( GE_16( bits_raw, add( max_dfRatio_bits, 1 ) ) )
1708 : {
1709 11516 : ec_mode = 1;
1710 11516 : move16();
1711 : }
1712 : ELSE
1713 : {
1714 0 : ec_mode = 0;
1715 0 : move16();
1716 : }
1717 27357 : max_alphabet_size = shl( 1, max_dfRatio_bits ); /* 1 << max_dfRatio_bits */
1718 :
1719 27357 : dec_mode = 2; /* Default to raw decoding */
1720 27357 : move16();
1721 27357 : IF( EQ_16( ec_mode, 1 ) )
1722 : {
1723 11516 : if ( bitstream[( *index )--] == 0 )
1724 : {
1725 2416 : dec_mode = 1; /* Switch to one value EC coding */
1726 2416 : move16();
1727 : }
1728 : }
1729 15841 : ELSE IF( EQ_16( ec_mode, 2 ) )
1730 : {
1731 15841 : IF( bitstream[( *index )--] == 0 )
1732 : {
1733 4014 : IF( bitstream[( *index )--] == 0 )
1734 : {
1735 970 : dec_mode = 1; /* Switch to one value EC coding */
1736 970 : move16();
1737 : }
1738 : ELSE
1739 : {
1740 3044 : dec_mode = 0; /* Use one-bit diff bandwise mode */
1741 3044 : move16();
1742 : }
1743 : }
1744 : }
1745 :
1746 27357 : IF( EQ_16( dec_mode, 2 ) ) /* Raw decoding */
1747 : {
1748 215075 : FOR( b = start_band; b < nbands; b++ )
1749 : {
1750 194148 : q_direction->band_data[b].energy_ratio_index[0] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, (UWord16) L_shl( 1, dfRatio_bits[b] ) ); /*Q0*/
1751 194148 : move16();
1752 : }
1753 : }
1754 6430 : ELSE IF( EQ_16( dec_mode, 1 ) ) /* One value decoding */
1755 : {
1756 3386 : ratio_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, max_alphabet_size ); /* dif_unique_value Q0*/
1757 :
1758 15764 : FOR( b = start_band; b < nbands; b++ )
1759 : {
1760 12378 : q_direction->band_data[b].energy_ratio_index[0] = ratio_min; /*Q0*/
1761 12378 : move16();
1762 : }
1763 : }
1764 : ELSE /* Bandwise 1-bit diff decoding */
1765 : {
1766 3044 : ratio_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, max_alphabet_size - 1 ); /* dif_min_value Q0*/
1767 :
1768 25338 : FOR( b = start_band; b < nbands; b++ )
1769 : {
1770 22294 : q_direction->band_data[b].energy_ratio_index[0] = (UWord16) L_add( ratio_min, bitstream[( *index )--] ); /* dif_bit_offset_values Q0*/
1771 22294 : move16();
1772 : }
1773 : }
1774 :
1775 27357 : return sub( index_start, *index );
1776 : }
1777 :
1778 :
1779 : /*-----------------------------------------------------------------------*
1780 : * Local functions (EC1)
1781 : *-----------------------------------------------------------------------*/
1782 :
1783 : /*-------------------------------------------------------------------------
1784 : * ivas_qmetadata_entropy_decode_dir_fx()
1785 : *
1786 : * Main function for entropy decoding of the directions
1787 : *------------------------------------------------------------------------*/
1788 160976 : static Word16 ivas_qmetadata_entropy_decode_dir_fx(
1789 : IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */
1790 : UWord16 *bitstream, /* i : bitstream Q0*/
1791 : Word16 *index, /*Q0*/
1792 : const UWord16 diffuseness_index_max_ec_frame, /*Q0*/
1793 : const Word16 nbands, /*Q0*/
1794 : const Word16 start_band, /*Q0*/
1795 : const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding Q0*/
1796 : )
1797 : {
1798 : Word16 b, m;
1799 : Word16 diff_idx;
1800 : Word16 diff_idx_min;
1801 : Word16 nblocks;
1802 : Word16 index_start;
1803 :
1804 : UWord16 gr_param_elev, gr_param_azith;
1805 : Word16 bands_entropic[MASA_MAXIMUM_CODING_SUBBANDS];
1806 : Word16 elev_alph[MASA_MAXIMUM_CODING_SUBBANDS];
1807 : Word16 azith_alph[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
1808 :
1809 : Word16 avg_elevation_alphabet, avg_azimuth_alphabet;
1810 : Word16 avg_elevation_idx, avg_azimuth_index;
1811 : Word16 avg_elevation_index_projected, avg_azimuth_index_projected;
1812 : Word32 direction_vector_fx[3], avg_direction_vector_fx[3], avg_azimuth_fx, avg_elevation_fx;
1813 : Word16 use_adapt_avg, idx;
1814 :
1815 160976 : index_start = *index;
1816 160976 : move16();
1817 160976 : nblocks = q_direction->cfg.nblocks;
1818 160976 : move16();
1819 :
1820 160976 : diff_idx_min = DIRAC_DIFFUSE_LEVELS;
1821 160976 : move16();
1822 :
1823 : /*Raw coding for high diffuseness*/
1824 1228913 : FOR( b = start_band; b < nbands; b++ )
1825 : {
1826 1067937 : IF( hrmasa_flag )
1827 : {
1828 0 : diff_idx = 0;
1829 0 : move16();
1830 : }
1831 : ELSE
1832 : {
1833 1067937 : diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
1834 1067937 : move16();
1835 : }
1836 :
1837 1067937 : diff_idx_min = s_min( diff_idx_min, diff_idx );
1838 1067937 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
1839 : {
1840 31864 : elev_alph[b] = no_theta_masa[( bits_direction_masa[diff_idx] - 3 )]; /*Q0*/
1841 31864 : move16();
1842 : }
1843 : ELSE
1844 : {
1845 1036073 : elev_alph[b] = sub( shl( no_theta_masa[( bits_direction_masa[diff_idx] - 3 )], 1 ), 1 ); /*Q0*/
1846 1036073 : move16();
1847 : }
1848 :
1849 1067937 : IF( GT_32( q_direction->band_data[b].energy_ratio_index_mod[0], diffuseness_index_max_ec_frame ) )
1850 : {
1851 274859 : bands_entropic[b] = 0;
1852 274859 : move16();
1853 :
1854 274859 : IF( q_direction->not_in_2D > 0 )
1855 : {
1856 198797 : decode_fixed_rate_fx( q_direction, bitstream, index, b, nblocks );
1857 : }
1858 : ELSE
1859 : {
1860 : /* in 2D */
1861 313629 : FOR( m = 0; m < nblocks; m++ )
1862 : {
1863 237567 : q_direction->band_data[b].elevation_fx[m] = 0;
1864 237567 : move32();
1865 237567 : q_direction->band_data[b].elevation_index[m] = 0;
1866 237567 : move16();
1867 :
1868 237567 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][0]; /*Q0*/
1869 237567 : move16();
1870 237567 : q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, azith_alph[b][m] ); /*Q0*/
1871 237567 : move16();
1872 237567 : q_direction->band_data[b].azimuth_fx[m] = deindex_azimuth_fx( q_direction->band_data[b].azimuth_index[m], q_direction->band_data[b].bits_sph_idx[m], 0, 1, q_direction->cfg.mc_ls_setup ); /*Q22*/
1873 237567 : move32();
1874 : }
1875 : }
1876 : }
1877 : ELSE
1878 : {
1879 793078 : bands_entropic[b] = 1;
1880 793078 : move16();
1881 : }
1882 : }
1883 :
1884 : /*EC for the low diffuseness*/
1885 :
1886 : /*Elevation only if not 2D */
1887 160976 : IF( q_direction->not_in_2D > 0 )
1888 : {
1889 114225 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
1890 : {
1891 1057 : avg_elevation_alphabet = no_theta_masa[( bits_direction_masa[diff_idx_min] - 3 )]; /*Q0*/
1892 1057 : move16();
1893 1057 : avg_elevation_idx = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, avg_elevation_alphabet ); /*Q0*/
1894 : }
1895 : ELSE
1896 : {
1897 113168 : avg_elevation_alphabet = sub( shl( no_theta_masa[( bits_direction_masa[diff_idx_min] - 3 )], 1 ), 1 ); /*Q0*/
1898 113168 : avg_elevation_idx = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, avg_elevation_alphabet );
1899 113168 : avg_elevation_idx = add( ivas_qmetadata_dereorder_generic_fx( avg_elevation_idx ), shr( avg_elevation_alphabet, 1 ) ); /*Q0*/
1900 : }
1901 :
1902 114225 : gr_param_elev = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, 4 + 1 );
1903 114225 : move16();
1904 114225 : IF( EQ_32( gr_param_elev, 4 ) ) /* all the elevation distances are zero */
1905 : {
1906 109207 : FOR( b = start_band; b < nbands; b++ )
1907 : {
1908 90045 : IF( bands_entropic[b] )
1909 : {
1910 : Word16 tmp_index;
1911 43363 : IF( hrmasa_flag )
1912 : {
1913 0 : diff_idx = 0;
1914 0 : move16();
1915 : }
1916 : ELSE
1917 : {
1918 43363 : diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
1919 43363 : move16();
1920 : }
1921 :
1922 43363 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
1923 : {
1924 703 : avg_elevation_index_projected = ivas_chan_project_elevation_index_fx( avg_elevation_idx, avg_elevation_alphabet, elev_alph[b] ); /*Q0*/
1925 : }
1926 : ELSE
1927 : {
1928 42660 : avg_elevation_index_projected = ivas_dirac_project_elevation_index_fx( avg_elevation_idx, avg_elevation_alphabet, elev_alph[b] ); /*Q0*/
1929 :
1930 : /*reorder elevation indexing*/
1931 42660 : tmp_index = sub( avg_elevation_index_projected, shr( elev_alph[b], 1 ) ); /*Q0*/
1932 42660 : IF( tmp_index < 0 )
1933 : {
1934 14158 : tmp_index = negate( imult1616( tmp_index, 2 ) );
1935 : }
1936 28502 : ELSE IF( tmp_index > 0 )
1937 : {
1938 11063 : tmp_index = sub( imult1616( tmp_index, 2 ), 1 );
1939 : }
1940 42660 : avg_elevation_index_projected = tmp_index;
1941 42660 : move16();
1942 : }
1943 :
1944 139763 : FOR( m = 0; m < nblocks; m++ )
1945 : {
1946 96400 : q_direction->band_data[b].elevation_index[m] = avg_elevation_index_projected; /*Q0*/
1947 96400 : move16();
1948 :
1949 : /*deduce aplhabet for azimuth*/
1950 96400 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
1951 : {
1952 2437 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][q_direction->band_data[b].elevation_index[m]]; /*Q0*/
1953 2437 : move16();
1954 : }
1955 : ELSE
1956 : {
1957 93963 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][extract_l( L_shr( L_add( q_direction->band_data[b].elevation_index[m], 1 ), 1 ) )]; /*Q0*/
1958 93963 : move16();
1959 : }
1960 :
1961 : /*decode elevation*/
1962 96400 : q_direction->band_data[b].elevation_fx[m] = deindex_elevation_fx( &q_direction->band_data[b].elevation_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->cfg.mc_ls_setup ); /*Q22*/
1963 96400 : move32();
1964 : }
1965 : }
1966 : }
1967 : }
1968 : ELSE
1969 : {
1970 734589 : FOR( b = start_band; b < nbands; b++ )
1971 : {
1972 639526 : IF( bands_entropic[b] )
1973 : {
1974 487411 : IF( hrmasa_flag )
1975 : {
1976 0 : diff_idx = 0;
1977 0 : move16();
1978 : }
1979 : ELSE
1980 : {
1981 487411 : diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
1982 487411 : move16();
1983 : }
1984 :
1985 2133428 : FOR( m = 0; m < nblocks; m++ )
1986 : {
1987 : Word16 tmp_index;
1988 1646017 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
1989 : {
1990 8144 : avg_elevation_index_projected = ivas_chan_project_elevation_index_fx( avg_elevation_idx, avg_elevation_alphabet, elev_alph[b] ); /*Q0*/
1991 8144 : tmp_index = ivas_qmetadata_DecodeExtendedGR( bitstream, index, sub( shl( elev_alph[b], 1 ), 1 ), gr_param_elev ); /*Q0*/
1992 8144 : IF( s_and( tmp_index, 1 ) )
1993 : {
1994 836 : tmp_index = add( avg_elevation_index_projected, shr( add( tmp_index, 1 ), 1 ) ); /*Q0*/
1995 : }
1996 : ELSE
1997 : {
1998 7308 : tmp_index = sub( avg_elevation_index_projected, shr( tmp_index, 1 ) );
1999 : }
2000 8144 : q_direction->band_data[b].elevation_index[m] = tmp_index;
2001 8144 : move16();
2002 :
2003 : /*deduce aplhabet for azimuth*/
2004 8144 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][q_direction->band_data[b].elevation_index[m]]; /*Q0*/
2005 8144 : move16();
2006 : }
2007 : ELSE
2008 : {
2009 1637873 : avg_elevation_index_projected = ivas_dirac_project_elevation_index_fx( avg_elevation_idx, avg_elevation_alphabet, elev_alph[b] ); /*Q0*/
2010 :
2011 1637873 : tmp_index = ivas_qmetadata_DecodeExtendedGR( bitstream, index, elev_alph[b], gr_param_elev ); /*Q0*/
2012 1637873 : tmp_index = ivas_qmetadata_ReorderElevationDecoded( tmp_index, avg_elevation_index_projected, elev_alph[b] ); /*Q0*/
2013 :
2014 : /*reorder elevation indexing*/
2015 1637873 : tmp_index = sub( tmp_index, elev_alph[b] / 2 );
2016 1637873 : IF( tmp_index < 0 )
2017 : {
2018 640213 : tmp_index = negate( shl( tmp_index, 1 ) );
2019 : }
2020 997660 : ELSE IF( tmp_index > 0 )
2021 : {
2022 305390 : tmp_index = sub( shl( tmp_index, 1 ), 1 );
2023 : }
2024 1637873 : q_direction->band_data[b].elevation_index[m] = tmp_index;
2025 1637873 : move16();
2026 :
2027 : /*deduce aplhabet for azimuth*/
2028 1637873 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][extract_l( L_shr( L_add( q_direction->band_data[b].elevation_index[m], 1 ), 1 ) )]; /*Q0*/
2029 1637873 : move16();
2030 : }
2031 :
2032 : /*decode elevation*/
2033 1646017 : q_direction->band_data[b].elevation_fx[m] = deindex_elevation_fx( &q_direction->band_data[b].elevation_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->cfg.mc_ls_setup ); /*Q22*/
2034 1646017 : move32();
2035 : }
2036 : }
2037 : }
2038 : }
2039 : }
2040 : ELSE
2041 : {
2042 385117 : FOR( b = start_band; b < nbands; b++ )
2043 : {
2044 338366 : IF( bands_entropic[b] )
2045 : {
2046 262304 : IF( hrmasa_flag )
2047 : {
2048 0 : diff_idx = 0;
2049 0 : move16();
2050 : }
2051 : ELSE
2052 : {
2053 262304 : diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
2054 262304 : move16();
2055 : }
2056 :
2057 927046 : FOR( m = 0; m < nblocks; m++ )
2058 : {
2059 664742 : q_direction->band_data[b].elevation_index[m] = 0;
2060 664742 : move16();
2061 :
2062 : /*deduce alphabet for azimuth*/
2063 664742 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2064 : {
2065 49118 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][q_direction->band_data[b].elevation_index[m]]; /*Q0*/
2066 49118 : move16();
2067 : }
2068 : ELSE
2069 : {
2070 615624 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][add( q_direction->band_data[b].elevation_index[m], 1 ) / 2]; /*Q0*/
2071 615624 : move16();
2072 : }
2073 :
2074 : /*decode elevation*/
2075 664742 : q_direction->band_data[b].elevation_fx[m] = deindex_elevation_fx( &q_direction->band_data[b].elevation_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->cfg.mc_ls_setup ); /*Q22*/
2076 664742 : move32();
2077 : }
2078 : }
2079 : }
2080 : }
2081 :
2082 : /*Azimuth*/
2083 160976 : avg_azimuth_alphabet = no_phi_masa[( bits_direction_masa[diff_idx_min] - 1 )][0]; /* average azimuth is quantized on the equatorial plane Q0*/
2084 160976 : move16();
2085 160976 : avg_azimuth_index = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, avg_azimuth_alphabet ); /*Q0*/
2086 160976 : avg_azimuth_index = ivas_qmetadata_dereorder_generic_fx( avg_azimuth_index ); /*Q0*/
2087 160976 : avg_azimuth_index = add( avg_azimuth_index, shr( avg_azimuth_alphabet, 1 ) ); /*Q0*/
2088 :
2089 160976 : gr_param_azith = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, 5 + 1 ); /*Q0*/
2090 160976 : IF( EQ_32( gr_param_azith, 5 ) ) /* all the azimuth distances are zero */
2091 : {
2092 261476 : FOR( b = start_band; b < nbands; b++ )
2093 : {
2094 223884 : IF( bands_entropic[b] )
2095 : {
2096 494900 : FOR( m = 0; m < nblocks; m++ )
2097 : {
2098 325792 : q_direction->band_data[b].azimuth_index[m] = ivas_dirac_project_azimuth_index_fx( avg_azimuth_index, avg_azimuth_alphabet, azith_alph[b][m] ); /*Q0*/
2099 325792 : move16();
2100 :
2101 325792 : IF( EQ_16( azith_alph[b][m], 1 ) )
2102 : {
2103 44 : q_direction->band_data[b].azimuth_fx[m] = 0;
2104 44 : move32();
2105 : }
2106 : ELSE
2107 : {
2108 325748 : q_direction->band_data[b].azimuth_fx[m] = deindex_azimuth_fx( q_direction->band_data[b].azimuth_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->band_data[b].elevation_index[m], 0, q_direction->cfg.mc_ls_setup ); /*Q22*/
2109 325748 : move32();
2110 : }
2111 : }
2112 : }
2113 : }
2114 : }
2115 : ELSE
2116 : {
2117 123384 : set32_fx( avg_direction_vector_fx, 0, 3 );
2118 123384 : use_adapt_avg = 0;
2119 123384 : move16();
2120 123384 : idx = 0;
2121 123384 : move16();
2122 :
2123 967437 : FOR( b = start_band; b < nbands; b++ )
2124 : {
2125 844053 : IF( bands_entropic[b] )
2126 : {
2127 2705337 : FOR( m = 0; m < nblocks; m++ )
2128 : {
2129 2081367 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && EQ_16( idx, MASA_LIMIT_IDX_AVG_AZI ) && GT_16( nblocks, 1 ) )
2130 : {
2131 2065 : use_adapt_avg = bitstream[*index]; /*Q0*/
2132 2065 : move16();
2133 2065 : ( *index ) = sub( *index, 1 );
2134 2065 : move16();
2135 : }
2136 2081367 : avg_azimuth_index_projected = ivas_dirac_project_azimuth_index_fx( avg_azimuth_index, avg_azimuth_alphabet, azith_alph[b][m] ); /*Q0*/
2137 2081367 : q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, azith_alph[b][m], gr_param_azith ); /*Q0*/
2138 2081367 : move16();
2139 2081367 : q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_ReorderElevationDecoded( q_direction->band_data[b].azimuth_index[m], avg_azimuth_index_projected, azith_alph[b][m] ); /*Q0*/
2140 2081367 : move16();
2141 :
2142 2081367 : IF( EQ_16( azith_alph[b][m], 1 ) )
2143 : {
2144 355 : q_direction->band_data[b].azimuth_fx[m] = 0;
2145 355 : move32();
2146 : }
2147 : ELSE
2148 : {
2149 2081012 : q_direction->band_data[b].azimuth_fx[m] = deindex_azimuth_fx( q_direction->band_data[b].azimuth_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->band_data[b].elevation_index[m], 0, q_direction->cfg.mc_ls_setup ); /*Q22*/
2150 2081012 : move32();
2151 : }
2152 :
2153 2081367 : test();
2154 2081367 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && GT_16( nblocks, 1 ) )
2155 : {
2156 37732 : IF( LT_16( idx, MASA_LIMIT_IDX_AVG_AZI ) )
2157 : {
2158 11800 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[b].azimuth_fx[m], q_direction->band_data[b].elevation_fx[m], direction_vector_fx );
2159 11800 : v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 ); /*Q25*/
2160 11800 : v_add_32( avg_direction_vector_fx, direction_vector_fx, avg_direction_vector_fx, 3 ); /*Q25*/
2161 : }
2162 : ELSE
2163 : {
2164 25932 : IF( EQ_16( use_adapt_avg, 1 ) )
2165 : {
2166 12376 : IF( m == 0 )
2167 : {
2168 12376 : FOR( Word16 l = 0; l < 3; l++ )
2169 : {
2170 9282 : avg_direction_vector_fx[l] = L_shr( avg_direction_vector_fx[l], 1 ); /*0.5f*/
2171 9282 : move32();
2172 : }
2173 : }
2174 : /*compute the average direction per already coded subband */
2175 12376 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[b].azimuth_fx[m], q_direction->band_data[b].elevation_fx[m], direction_vector_fx );
2176 12376 : v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 ); /*Q25*/
2177 12376 : v_add_32( avg_direction_vector_fx, direction_vector_fx, avg_direction_vector_fx, 3 ); /*Q25*/
2178 12376 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_fx, 30 - 5, &avg_azimuth_fx, &avg_elevation_fx );
2179 12376 : avg_azimuth_index = quantize_phi_fx( L_add( avg_azimuth_fx, DEGREE_180_Q_22 ), 0, &avg_azimuth_fx, avg_azimuth_alphabet ); /*Q0*/
2180 : }
2181 : }
2182 37732 : idx = add( idx, 1 );
2183 : }
2184 : }
2185 : }
2186 : }
2187 : }
2188 :
2189 160976 : return sub( index_start, *index );
2190 : }
2191 :
2192 : /*-------------------------------------------------------------------------
2193 : * ivas_qmetadata_raw_decode_dir_512_fx()
2194 : *
2195 : * Main function for raw decoding of the directions
2196 : *------------------------------------------------------------------------*/
2197 8938 : static Word16 ivas_qmetadata_raw_decode_dir_512_fx(
2198 : IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */
2199 : UWord16 *bitstream, /* i : bitstream Q0*/
2200 : Word16 *index, /*Q0*/
2201 : const Word16 nbands, /*Q0*/
2202 : const Word16 start_band, /*Q0*/
2203 : const SPHERICAL_GRID_DATA *sph_grid16 /* i : spherical grid for deindexing */
2204 : )
2205 : {
2206 : Word16 b, m, i;
2207 : Word16 nblocks;
2208 : Word16 index_start;
2209 : UWord16 value;
2210 :
2211 8938 : index_start = *index;
2212 8938 : move16();
2213 8938 : nblocks = q_direction->cfg.nblocks;
2214 8938 : move16();
2215 :
2216 204228 : FOR( b = start_band; b < nbands; b++ )
2217 : {
2218 698524 : FOR( m = 0; m < nblocks; m++ )
2219 : {
2220 503234 : value = 0;
2221 503234 : move16();
2222 7059358 : FOR( i = 0; i < q_direction->band_data[b].bits_sph_idx[m]; i++ )
2223 : {
2224 6556124 : value = (UWord16) L_add( (UWord16) L_shl( value, 1 ), bitstream[( *index )--] );
2225 : }
2226 503234 : q_direction->band_data[b].spherical_index[m] = value;
2227 503234 : move16();
2228 :
2229 503234 : IF( EQ_32( q_direction->band_data[b].bits_sph_idx[m], 16 ) )
2230 : {
2231 204110 : deindex_sph_idx_fx( value, sph_grid16, &( q_direction->band_data[b].elevation_fx[m] ), &( q_direction->band_data[b].azimuth_fx[m] ) );
2232 : }
2233 : ELSE
2234 : {
2235 299124 : deindex_spherical_component_fx( q_direction->band_data[b].spherical_index[m], &q_direction->band_data[b].azimuth_fx[m], &q_direction->band_data[b].elevation_fx[m], &q_direction->band_data[b].azimuth_index[m], &q_direction->band_data[b].elevation_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->cfg.mc_ls_setup );
2236 : }
2237 : }
2238 : }
2239 :
2240 8938 : return sub( index_start, *index );
2241 : }
2242 :
2243 :
2244 131697 : static Word16 ivas_qmetadata_raw_decode_dir_fx(
2245 : IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */
2246 : UWord16 *bitstream, /* i : bitstream Q0*/
2247 : Word16 *index, /*Q0*/
2248 : const Word16 nbands, /*Q0*/
2249 : const Word16 start_band, /*Q0*/
2250 : const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding Q0*/
2251 : )
2252 : {
2253 : Word16 b, m, azith_alph;
2254 : Word16 diff_idx;
2255 : Word16 nblocks;
2256 : Word16 index_start;
2257 :
2258 131697 : index_start = *index;
2259 131697 : move16();
2260 131697 : nblocks = q_direction->cfg.nblocks;
2261 131697 : move16();
2262 :
2263 765931 : FOR( b = start_band; b < nbands; b++ )
2264 : {
2265 634234 : IF( q_direction->not_in_2D > 0 )
2266 : {
2267 542527 : decode_fixed_rate_fx( q_direction, bitstream, index, b, nblocks );
2268 : }
2269 : ELSE
2270 : {
2271 91707 : IF( hrmasa_flag )
2272 : {
2273 0 : diff_idx = 0;
2274 0 : move16();
2275 : }
2276 : ELSE
2277 : {
2278 91707 : diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
2279 91707 : move16();
2280 : }
2281 :
2282 276249 : FOR( m = 0; m < nblocks; m++ )
2283 : {
2284 184542 : q_direction->band_data[b].elevation_fx[m] = 0;
2285 184542 : move32();
2286 184542 : q_direction->band_data[b].elevation_index[m] = 0;
2287 184542 : move16();
2288 184542 : azith_alph = no_phi_masa[bits_direction_masa[diff_idx] - 1][0]; /*Q0*/
2289 184542 : move16();
2290 184542 : q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, azith_alph ); /*Q0*/
2291 184542 : move16();
2292 184542 : q_direction->band_data[b].azimuth_fx[m] = deindex_azimuth_fx( q_direction->band_data[b].azimuth_index[m], q_direction->band_data[b].bits_sph_idx[m], 0, 1, q_direction->cfg.mc_ls_setup ); /*Q22*/
2293 184542 : move32();
2294 : }
2295 : }
2296 : }
2297 :
2298 131697 : return sub( index_start, *index );
2299 : }
2300 :
2301 : /*-------------------------------------------------------------------------
2302 : * ivas_qmetadata_DecodeQuasiUniform()
2303 : *
2304 : * Read the bitstream following the encoding scheme of EncodeQuasiUniform
2305 : *------------------------------------------------------------------------*/
2306 :
2307 : /*! r: Value read from the bitstream */
2308 2923252 : static UWord16 ivas_qmetadata_DecodeQuasiUniform(
2309 : const UWord16 *bitstream, /* i : pointer to the bitstream to read Q0*/
2310 : Word16 *index, /* i : position in the bitstream to start reading (gets updated with reading) Q0*/
2311 : const UWord16 alphabet_size /* i : size of the alphabet, used to calculate the number of bits needed Q0*/
2312 : )
2313 : {
2314 : Word16 i, bits;
2315 : UWord16 tresh, value;
2316 :
2317 :
2318 2923252 : bits = sub( 30, norm_l( alphabet_size ) ); /* bits = floor(log2(alphabet_size)) */
2319 2923252 : tresh = (UWord16) L_sub( (UWord16) L_shl( 1U, add( bits, 1 ) ), alphabet_size );
2320 :
2321 2923252 : value = 0;
2322 2923252 : move16();
2323 10921892 : FOR( i = 0; i < bits; i++ )
2324 : {
2325 7998640 : value = (UWord16) L_add( (UWord16) L_shl( value, 1 ), bitstream[( *index )--] ); /*Q0*/
2326 : }
2327 :
2328 2923252 : IF( GE_32( value, tresh ) )
2329 : {
2330 339036 : value = (UWord16) L_add( (UWord16) L_sub( (UWord16) L_shl( value, 1 ), tresh ), bitstream[( *index )--] ); /*Q0*/
2331 : }
2332 :
2333 2923252 : return value;
2334 : }
2335 :
2336 :
2337 : /*-------------------------------------------------------------------------
2338 : * ivas_qmetadata_DecodeExtendedGR()
2339 : *
2340 : * Reads the bitstream and decodes the value using the ExtendedGR algorithm
2341 : *------------------------------------------------------------------------*/
2342 :
2343 : /*! r: Value decoded from the bitstream */
2344 :
2345 5887571 : Word16 ivas_qmetadata_DecodeExtendedGR(
2346 : UWord16 *bitstream, /* i : pointer to the bitstream to read Q0*/
2347 : Word16 *index, /* i/o: position in the bitstream to start reading (gets updated with reading) */
2348 : const Word16 alph_size, /* i : size of the alphabet, used to calculate the number of bits needed */
2349 : const Word16 gr_param /* i : GR parameter that indicates the limit for the most significant bits (msb) */
2350 : )
2351 : {
2352 : Word16 i, msb_size;
2353 : UWord16 value;
2354 : Word16 msb, lsb;
2355 :
2356 5887571 : msb_size = shr( add( alph_size, sub( shl( 1, gr_param ), 1 ) ), gr_param ); /* ceil division Q0*/
2357 5887571 : IF( LE_16( msb_size, 3 ) )
2358 : {
2359 570782 : value = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, alph_size ); /*Q0*/
2360 : }
2361 : ELSE
2362 : {
2363 5316789 : msb = 0;
2364 5316789 : move16();
2365 5316789 : test();
2366 9459691 : WHILE( LT_16( msb, sub( msb_size, 1 ) ) && bitstream[*index] )
2367 : {
2368 4142902 : test();
2369 4142902 : msb = add( msb, 1 );
2370 4142902 : ( *index ) = sub( ( *index ), 1 );
2371 4142902 : move16();
2372 : }
2373 :
2374 5316789 : IF( EQ_16( msb, sub( msb_size, 1 ) ) )
2375 : {
2376 43557 : lsb = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, sub( alph_size, shl( sub( msb_size, 1 ), gr_param ) ) ); /*Q0*/
2377 : }
2378 : ELSE
2379 : {
2380 5273232 : ( *index ) = sub( ( *index ), 1 );
2381 5273232 : move16();
2382 5273232 : lsb = 0;
2383 5273232 : move16();
2384 8131218 : FOR( i = 0; i < gr_param; i++ )
2385 : {
2386 2857986 : lsb = extract_l( L_add( shl( lsb, 1 ), bitstream[( *index )--] ) ); /*Q0*/
2387 : }
2388 : }
2389 :
2390 5316789 : value = (UWord16) add( shl( msb, gr_param ), lsb ); /*Q0*/
2391 : }
2392 :
2393 5887571 : return value;
2394 : }
2395 :
2396 : /*-------------------------------------------------------------------------
2397 : * ivas_qmetadata_ReorderElevationDecoded()
2398 : *
2399 : * Calculates the correct elevation index from the decoded data
2400 : *------------------------------------------------------------------------*/
2401 :
2402 : /*! r: Elevation index as it will be read by the dequantizer */
2403 3719240 : static Word16 ivas_qmetadata_ReorderElevationDecoded(
2404 : const Word16 elev_dist, /* i : Distance to the average extracted from the bitstream Q0*/
2405 : const Word16 elev_avg, /* i : Average value over time-blocks extracted from the bitstream Q0*/
2406 : const Word16 elev_alph /* i : elevation alphabet Q0*/
2407 : )
2408 : {
2409 : Word16 dist_reorder;
2410 : Word16 elev_index_reorder;
2411 :
2412 3719240 : dist_reorder = ivas_qmetadata_dereorder_generic_fx( elev_dist ); /*Q0*/
2413 3719240 : elev_index_reorder = add( elev_avg, dist_reorder );
2414 :
2415 3719240 : IF( elev_index_reorder < 0 )
2416 : {
2417 19038 : elev_index_reorder = add( elev_index_reorder, elev_alph );
2418 : }
2419 3700202 : ELSE IF( GE_16( elev_index_reorder, elev_alph ) )
2420 : {
2421 27318 : elev_index_reorder = sub( elev_index_reorder, elev_alph );
2422 : }
2423 :
2424 3719240 : return elev_index_reorder; /*Q0*/
2425 : }
2426 :
2427 :
2428 : /*-----------------------------------------------------------------------*
2429 : * Local functions: requentizeEC3
2430 : *-----------------------------------------------------------------------*/
2431 :
2432 : /*! r: number of bits read */
2433 12783 : static Word16 read_directions_fx(
2434 : IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */
2435 : const UWord8 coding_subbands, /* i : number of directions Q0*/
2436 : const UWord8 masa_subframes, /* i : number of tiles Q0*/
2437 : UWord16 *bitstream, /* i : bitstream to be read Q0*/
2438 : Word16 *pbit_pos, /*Q0*/
2439 : Word16 *ind_order /*Q0*/ )
2440 : {
2441 : Word16 j, k, allowed_bits, last_j, nbits, fixed_rate;
2442 : Word16 i;
2443 : Word16 diff;
2444 : UWord16 byteBuffer;
2445 : Word16 use_vq, max_nb_idx;
2446 : Word16 bit_pos;
2447 : Word16 *bits_dir0;
2448 :
2449 12783 : bit_pos = *pbit_pos;
2450 12783 : move16();
2451 :
2452 12783 : diff = 0;
2453 12783 : move16();
2454 12783 : IF( q_direction->not_in_2D )
2455 : {
2456 :
2457 12437 : IF( GT_16( coding_subbands, 1 ) )
2458 : {
2459 12078 : j = ind_order[( coding_subbands - 1 )];
2460 12078 : move16();
2461 12078 : allowed_bits = 0;
2462 12078 : move16();
2463 :
2464 39264 : FOR( k = 0; k < masa_subframes; k++ )
2465 : {
2466 27186 : allowed_bits = extract_l( L_add( allowed_bits, q_direction->band_data[j].bits_sph_idx[k] ) ); /*Q0*/
2467 : }
2468 :
2469 12078 : last_j = sub( j, (Word16) ( allowed_bits == 0 ) );
2470 :
2471 52089 : FOR( j = 0; j < last_j; j++ )
2472 : {
2473 40011 : i = ind_order[j];
2474 40011 : move16();
2475 40011 : bits_dir0 = (Word16 *) q_direction->band_data[i].bits_sph_idx; /*Q0*/
2476 :
2477 40011 : nbits = 0;
2478 40011 : move16();
2479 40011 : allowed_bits = sum16_fx( bits_dir0, q_direction->cfg.nblocks );
2480 40011 : use_vq = 0;
2481 40011 : move16();
2482 40011 : max_nb_idx = 0;
2483 40011 : move16();
2484 :
2485 118356 : FOR( k = 0; k < q_direction->cfg.nblocks; k++ )
2486 : {
2487 78345 : IF( GT_16( bits_dir0[k], use_vq ) )
2488 : {
2489 44813 : use_vq = bits_dir0[k];
2490 44813 : move16();
2491 44813 : max_nb_idx = k;
2492 44813 : move16();
2493 : }
2494 : }
2495 :
2496 40011 : IF( EQ_16( q_direction->cfg.nblocks, 1 ) )
2497 : {
2498 27233 : byteBuffer = 0;
2499 27233 : move16();
2500 : }
2501 : ELSE
2502 : {
2503 12778 : byteBuffer = 0;
2504 12778 : move16();
2505 12778 : if ( LE_16( use_vq, 1 ) )
2506 : {
2507 29 : byteBuffer = 1;
2508 29 : move16();
2509 : }
2510 12778 : test();
2511 12778 : IF( GT_16( use_vq, 1 ) && LE_16( use_vq, LIMIT_USE_COMMON ) )
2512 : {
2513 2446 : bits_dir0[max_nb_idx] = sub( bits_dir0[max_nb_idx], 1 );
2514 2446 : move16();
2515 2446 : allowed_bits = sub( allowed_bits, 1 );
2516 : /* read 1 bit to tell if joint of VQ coding */
2517 2446 : byteBuffer = bitstream[bit_pos--];
2518 2446 : move16();
2519 : }
2520 : }
2521 :
2522 118356 : FOR( k = 0; k < masa_subframes; k++ )
2523 : {
2524 78345 : q_direction->band_data[i].bits_sph_idx[k] = bits_dir0[k]; /*Q0*/
2525 78345 : move16();
2526 78345 : IF( GT_16( bits_dir0[k], 2 ) )
2527 : {
2528 74696 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2529 : {
2530 4444 : q_direction->band_data[i].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3]; /*Q0*/
2531 4444 : move16();
2532 : }
2533 : ELSE
2534 : {
2535 70252 : q_direction->band_data[i].elevation_m_alphabet[k] = shl( no_theta_masa[bits_dir0[k] - 3], 1 ) - 1;
2536 70252 : move16();
2537 : }
2538 : }
2539 : ELSE
2540 : {
2541 3649 : q_direction->band_data[i].elevation_m_alphabet[k] = 1;
2542 3649 : move16();
2543 : }
2544 : }
2545 :
2546 40011 : IF( allowed_bits > 0 )
2547 : {
2548 40011 : IF( EQ_32( byteBuffer, 1 ) )
2549 : {
2550 2415 : nbits = read_common_direction_fx( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); /*Q0*/
2551 : }
2552 : ELSE
2553 : {
2554 37596 : test();
2555 37596 : IF( EQ_16( q_direction->cfg.nblocks, 1 ) && LE_32( q_direction->band_data[i].bits_sph_idx[0], L_add( MASA_MIN_BITS_TF, 1 ) ) )
2556 : {
2557 : /* there is fixed rate only, no need to read */
2558 13353 : fixed_rate = 1;
2559 13353 : move16();
2560 13353 : nbits = 0;
2561 13353 : move16();
2562 : }
2563 : ELSE
2564 : {
2565 : /* check if fixed_rate */
2566 24243 : fixed_rate = bitstream[bit_pos--];
2567 24243 : move16();
2568 24243 : nbits = 1;
2569 24243 : move16();
2570 : }
2571 :
2572 37596 : IF( EQ_16( fixed_rate, 1 ) )
2573 : {
2574 : /* decode_fixed_rate()*/
2575 31601 : nbits = add( nbits, decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) );
2576 : }
2577 : ELSE
2578 : {
2579 :
2580 : /* decode elevation */
2581 5995 : nbits = add( nbits, decode_elevation_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) ); /*Q0*/
2582 : /* decode azimuth */
2583 5995 : nbits = add( nbits, decode_azimuth_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) ); /*Q0*/
2584 : }
2585 : }
2586 : }
2587 : ELSE
2588 : {
2589 0 : set_zero_direction_fx( q_direction, i, masa_subframes );
2590 : }
2591 :
2592 40011 : diff = add( diff, sub( nbits, allowed_bits ) );
2593 :
2594 : /* update bits for next block */
2595 40011 : update_bits_next_block_fx( q_direction, &diff, ind_order[j + 1], coding_subbands, masa_subframes );
2596 : }
2597 : }
2598 : ELSE
2599 : {
2600 359 : last_j = q_direction->cfg.start_band; /*Q0*/
2601 359 : move16();
2602 : }
2603 :
2604 :
2605 32402 : FOR( j = last_j; j < coding_subbands; j++ )
2606 : {
2607 19965 : i = ind_order[j];
2608 19965 : move16();
2609 19965 : bits_dir0 = (Word16 *) q_direction->band_data[i].bits_sph_idx; /*Q0*/
2610 :
2611 19965 : nbits = 0;
2612 19965 : move16();
2613 19965 : allowed_bits = sum16_fx( bits_dir0, q_direction->cfg.nblocks ); /*Q0*/
2614 19965 : test();
2615 19965 : IF( allowed_bits > 0 && EQ_16( masa_subframes, 1 ) )
2616 : {
2617 12844 : nbits = add( nbits, decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) ); /*Q0*/
2618 : }
2619 : ELSE
2620 : {
2621 7121 : IF( allowed_bits > 0 )
2622 : {
2623 7121 : use_vq = 0;
2624 7121 : move16();
2625 7121 : max_nb_idx = 0;
2626 7121 : move16();
2627 35605 : FOR( k = 0; k < masa_subframes; k++ )
2628 : {
2629 28484 : IF( GT_16( bits_dir0[k], use_vq ) )
2630 : {
2631 10609 : use_vq = bits_dir0[k]; /*Q0*/
2632 10609 : move16();
2633 10609 : max_nb_idx = k;
2634 10609 : move16();
2635 : }
2636 : }
2637 :
2638 7121 : byteBuffer = 0;
2639 7121 : move16();
2640 :
2641 7121 : test();
2642 7121 : IF( GT_16( use_vq, 1 ) && LE_16( use_vq, LIMIT_USE_COMMON ) )
2643 : {
2644 1071 : bits_dir0[max_nb_idx] = sub( bits_dir0[max_nb_idx], 1 );
2645 1071 : move16();
2646 1071 : allowed_bits = sub( allowed_bits, 1 );
2647 :
2648 : /* read 1 bit to tell if joint of VQ coding */
2649 1071 : byteBuffer = bitstream[bit_pos--];
2650 1071 : move16();
2651 : }
2652 :
2653 7121 : IF( allowed_bits > 0 )
2654 : {
2655 7121 : test();
2656 7121 : IF( EQ_32( byteBuffer, 1 ) || LE_16( use_vq, 1 ) )
2657 : {
2658 1008 : nbits = read_common_direction_fx( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); /*Q0*/
2659 : }
2660 : ELSE
2661 : {
2662 : /* decode_fixed_rate()*/
2663 6113 : nbits = add( nbits, decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) );
2664 : }
2665 : }
2666 : ELSE
2667 : {
2668 0 : set_zero_direction_fx( q_direction, i, masa_subframes );
2669 : }
2670 : }
2671 : ELSE
2672 : {
2673 0 : set_zero_direction_fx( q_direction, i, masa_subframes );
2674 : }
2675 : }
2676 : }
2677 : }
2678 : ELSE
2679 : {
2680 : /* 2D */
2681 1391 : FOR( j = 0; j < coding_subbands; j++ )
2682 : {
2683 4670 : FOR( k = 0; k < q_direction->cfg.nblocks; k++ )
2684 : {
2685 3625 : q_direction->band_data[j].elevation_fx[k] = 0;
2686 3625 : move32();
2687 3625 : q_direction->band_data[j].elevation_index[k] = 0;
2688 3625 : move16();
2689 : }
2690 : }
2691 :
2692 346 : nbits = decode_azimuth2D_fx( q_direction, bitstream, coding_subbands, &bit_pos, masa_subframes ); /*Q0*/
2693 : }
2694 12783 : nbits = sub( *pbit_pos, bit_pos );
2695 12783 : *pbit_pos = bit_pos;
2696 12783 : move16();
2697 :
2698 12783 : return nbits;
2699 : }
2700 :
2701 : /*-------------------------------------------------------------------*
2702 : * decode_azimuth()
2703 : *
2704 : * read and decode the azimuth indexes for one subband
2705 : *-------------------------------------------------------------------*/
2706 :
2707 : /*! r: number of bits read */
2708 5995 : static Word16 decode_azimuth_fx(
2709 : IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */
2710 : UWord16 *bitstream, /* i : bitstream to be read Q0*/
2711 : Word16 *pbit_pos, /* i/o: current position in bitstream Q0*/
2712 : const Word16 idx_subband, /* i : subband index Q0*/
2713 : const Word16 masa_subframes /* i : number of tiles Q0*/
2714 : )
2715 : {
2716 : Word16 bit_pos, nbits, k;
2717 : UWord16 use_context, byteBuffer;
2718 : UWord16 min_idx;
2719 : Word16 j_az, max_val;
2720 :
2721 5995 : nbits = 0;
2722 5995 : move16();
2723 5995 : bit_pos = *pbit_pos;
2724 5995 : move16();
2725 5995 : byteBuffer = 0;
2726 5995 : move16();
2727 :
2728 5995 : j_az = 0;
2729 5995 : move16();
2730 : /* check number of valid indexes to decode */
2731 29234 : FOR( k = 0; k < masa_subframes; k++ )
2732 : {
2733 23239 : IF( LT_32( q_direction->band_data[idx_subband].azimuth_index[k], MASA_NO_INDEX ) )
2734 : {
2735 23237 : j_az = add( j_az, 1 );
2736 : }
2737 : ELSE
2738 : {
2739 2 : q_direction->band_data[idx_subband].azimuth_fx[k] = 0; /*To be in sync with encoder values.*/
2740 2 : move32();
2741 : }
2742 : }
2743 :
2744 5995 : IF( !j_az )
2745 : {
2746 0 : return nbits;
2747 : }
2748 :
2749 5995 : IF( !byteBuffer )
2750 : {
2751 : /* use context */
2752 5995 : use_context = 0;
2753 5995 : move16();
2754 29234 : FOR( k = 0; k < masa_subframes; k++ )
2755 : {
2756 23239 : if ( LE_32( q_direction->band_data[idx_subband].bits_sph_idx[k], 1 ) )
2757 : {
2758 0 : use_context = 1;
2759 0 : move16();
2760 : }
2761 : }
2762 :
2763 5995 : IF( EQ_32( use_context, 1 ) )
2764 : {
2765 0 : FOR( k = 0; k < masa_subframes; k++ )
2766 : {
2767 0 : IF( q_direction->band_data[idx_subband].bits_sph_idx[k] == 0 )
2768 : {
2769 0 : q_direction->band_data[idx_subband].azimuth_index[k] = 0;
2770 0 : move16();
2771 0 : q_direction->band_data[idx_subband].azimuth_fx[k] = 0;
2772 0 : move32();
2773 : }
2774 : ELSE
2775 : {
2776 0 : IF( EQ_32( q_direction->band_data[idx_subband].bits_sph_idx[k], 1 ) )
2777 : {
2778 0 : byteBuffer = bitstream[bit_pos--];
2779 0 : move16();
2780 0 : q_direction->band_data[idx_subband].azimuth_index[k] = byteBuffer; /*Q0*/
2781 0 : move16();
2782 :
2783 0 : q_direction->band_data[idx_subband].azimuth_fx[k] = L_shl( L_mult0( q_direction->band_data[idx_subband].azimuth_index[k], -180 ), Q22 ); /*Q22*/
2784 0 : move32();
2785 : }
2786 : ELSE
2787 : {
2788 0 : q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], sub( MASA_GR_ORD_AZ, (Word16) EQ_32( q_direction->band_data[idx_subband].bits_sph_idx[k], 2 ) ) ); /*Q0*/
2789 0 : move16();
2790 :
2791 0 : q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); /*Q22*/
2792 0 : move32();
2793 : }
2794 : }
2795 : }
2796 : }
2797 : ELSE
2798 : {
2799 : /* read bit to check if min removed encoding */
2800 5995 : byteBuffer = bitstream[bit_pos]; /*Q22*/
2801 5995 : move16();
2802 5995 : bit_pos = sub( bit_pos, 1 );
2803 5995 : IF( byteBuffer == 0 ) /* regular GR coding5 */
2804 : {
2805 : /* read GR_order */
2806 2048 : byteBuffer = bitstream[bit_pos];
2807 2048 : move16();
2808 2048 : bit_pos = sub( bit_pos, 1 );
2809 2048 : nbits = add( nbits, 1 );
2810 :
2811 9499 : FOR( k = 0; k < masa_subframes; k++ )
2812 : {
2813 7451 : IF( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 )
2814 : {
2815 7451 : IF( GT_16( no_phi_masa[L_sub( q_direction->band_data[idx_subband].bits_sph_idx[k], 1 )][q_direction->band_data[idx_subband].elevation_index[k]], 1 ) )
2816 : {
2817 7449 : q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], extract_l( L_sub( MASA_GR_ORD_AZ, byteBuffer ) ) ); /*Q0*/
2818 7449 : move16();
2819 7449 : q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); /*Q22*/
2820 7449 : move32();
2821 : }
2822 : ELSE
2823 : {
2824 2 : q_direction->band_data[idx_subband].azimuth_fx[k] = 0;
2825 2 : move32();
2826 2 : q_direction->band_data[idx_subband].azimuth_index[k] = 0;
2827 2 : move16();
2828 : }
2829 : }
2830 : ELSE
2831 : {
2832 0 : q_direction->band_data[idx_subband].azimuth_fx[k] = 0;
2833 0 : move32();
2834 0 : q_direction->band_data[idx_subband].azimuth_index[k] = 0;
2835 0 : move16();
2836 : }
2837 : }
2838 : }
2839 : ELSE
2840 : {
2841 : /* min removed GR coding */
2842 : /* read GR_order */
2843 3947 : byteBuffer = bitstream[bit_pos]; /*Q0*/
2844 3947 : move16();
2845 3947 : bit_pos = sub( bit_pos, 1 );
2846 : /* read min index value */
2847 3947 : maximum_s( q_direction->band_data[idx_subband].azimuth_m_alphabet, masa_subframes, &max_val );
2848 3947 : min_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, max_val, MASA_GR_ORD_AZ ); /*Q0*/
2849 :
2850 19735 : FOR( k = 0; k < masa_subframes; k++ )
2851 : {
2852 15788 : IF( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 )
2853 : {
2854 15788 : IF( GT_16( no_phi_masa[q_direction->band_data[idx_subband].bits_sph_idx[k] - 1][q_direction->band_data[idx_subband].elevation_index[k]], 1 ) )
2855 : {
2856 15788 : q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], extract_l( L_sub( MASA_GR_ORD_AZ - 1, byteBuffer ) ) ); /*Q0*/
2857 15788 : move16();
2858 15788 : q_direction->band_data[idx_subband].azimuth_index[k] = (UWord16) L_add( q_direction->band_data[idx_subband].azimuth_index[k], min_idx ); /*Q0*/
2859 15788 : move16();
2860 15788 : q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); /*Q22*/
2861 15788 : move32();
2862 : }
2863 : ELSE
2864 : {
2865 0 : q_direction->band_data[idx_subband].azimuth_fx[k] = 0;
2866 0 : move32();
2867 0 : q_direction->band_data[idx_subband].azimuth_index[k] = 0;
2868 0 : move16();
2869 : }
2870 : }
2871 : ELSE
2872 : {
2873 0 : q_direction->band_data[idx_subband].azimuth_fx[k] = 0;
2874 0 : move32();
2875 0 : q_direction->band_data[idx_subband].azimuth_index[k] = 0;
2876 0 : move16();
2877 : }
2878 : }
2879 : }
2880 : }
2881 : }
2882 :
2883 5995 : nbits = sub( *pbit_pos, bit_pos );
2884 :
2885 5995 : *pbit_pos = bit_pos;
2886 5995 : move16();
2887 :
2888 5995 : return nbits;
2889 : }
2890 :
2891 :
2892 : /*-------------------------------------------------------------------*
2893 : * decode_elevation()
2894 : *
2895 : * Reads the bitstream and decode the elevation index
2896 : *-------------------------------------------------------------------*/
2897 :
2898 : /*! r: number of bits read */
2899 5995 : static Word16 decode_elevation_fx(
2900 : IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */
2901 : UWord16 *bitstream, /* i : input bitstream Q0*/
2902 : Word16 *pbit_pos, /* i/o: current position to be read in bitstream Q0*/
2903 : const Word16 j, /* i : subband index Q0*/
2904 : const Word16 masa_subframes /* i : number of tiles Q0*/
2905 : )
2906 : {
2907 : Word16 nr_NO_INDEX, nbits;
2908 : Word16 bit_pos;
2909 : UWord16 byteBuffer;
2910 : Word16 k, GR_ord_elevation;
2911 : UWord16 same_idx;
2912 :
2913 5995 : nr_NO_INDEX = 0;
2914 5995 : move16();
2915 5995 : nbits = 0;
2916 5995 : move16();
2917 5995 : bit_pos = *pbit_pos;
2918 5995 : move16();
2919 :
2920 29234 : FOR( k = 0; k < masa_subframes; k++ )
2921 : {
2922 23239 : q_direction->band_data[j].elevation_index[k] = 0;
2923 23239 : move16();
2924 23239 : q_direction->band_data[j].elevation_fx[k] = 0;
2925 23239 : move32();
2926 :
2927 23239 : IF( q_direction->band_data[j].bits_sph_idx[k] > 0 )
2928 : {
2929 23239 : IF( LE_32( q_direction->band_data[j].bits_sph_idx[k], 2 ) )
2930 : {
2931 3 : q_direction->band_data[j].elevation_index[k] = MASA_NO_INDEX; /*Q0*/
2932 3 : move16();
2933 3 : nr_NO_INDEX = add( nr_NO_INDEX, 1 );
2934 3 : q_direction->band_data[j].elevation_fx[k] = 0;
2935 3 : move32();
2936 3 : q_direction->band_data[j].elevation_m_alphabet[k] = 1;
2937 3 : move16();
2938 : }
2939 : ELSE
2940 : {
2941 23236 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2942 : {
2943 2473 : q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[q_direction->band_data[j].bits_sph_idx[k] - 3]; /*Q0*/
2944 2473 : move16();
2945 : }
2946 : ELSE
2947 : {
2948 20763 : q_direction->band_data[j].elevation_m_alphabet[k] = shl( no_theta_masa[q_direction->band_data[j].bits_sph_idx[k] - 3], 1 ) - 1; /*Q0*/
2949 20763 : move16();
2950 : }
2951 : }
2952 : }
2953 : ELSE
2954 : {
2955 0 : nr_NO_INDEX = add( nr_NO_INDEX, 1 );
2956 : }
2957 : }
2958 :
2959 5995 : IF( LT_16( nr_NO_INDEX, masa_subframes ) )
2960 : {
2961 : {
2962 : /* read if same or not */
2963 5995 : byteBuffer = bitstream[bit_pos];
2964 5995 : move16();
2965 5995 : bit_pos = sub( bit_pos, 1 );
2966 5995 : IF( EQ_32( byteBuffer, 1 ) ) /* same value */
2967 : {
2968 : /* read value */
2969 4435 : byteBuffer = bitstream[bit_pos]; /*Q0*/
2970 4435 : move16();
2971 4435 : bit_pos = sub( bit_pos, 1 );
2972 4435 : byteBuffer = (UWord16) L_add( L_shl( byteBuffer, 1 ), bitstream[bit_pos] );
2973 4435 : move16();
2974 4435 : bit_pos = sub( bit_pos, 1 );
2975 4435 : same_idx = byteBuffer;
2976 4435 : move16();
2977 :
2978 21434 : FOR( k = 0; k < masa_subframes; k++ )
2979 : {
2980 16999 : IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) )
2981 : {
2982 16999 : q_direction->band_data[j].elevation_index[k] = same_idx; /*Q0*/
2983 16999 : move16();
2984 16999 : q_direction->band_data[j].elevation_fx[k] = deindex_elevation_fx( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); /*Q22*/
2985 16999 : move32();
2986 : }
2987 : }
2988 : }
2989 : ELSE
2990 : {
2991 : /* not same; decode mean removed GR */
2992 1560 : byteBuffer = bitstream[bit_pos]; /*Q0*/
2993 1560 : bit_pos = sub( bit_pos, 1 );
2994 1560 : move16();
2995 1560 : GR_ord_elevation = extract_l( L_sub( MASA_GR_ORD_EL, byteBuffer ) ); /*Q0*/
2996 :
2997 7800 : FOR( k = 0; k < masa_subframes; k++ )
2998 : {
2999 6240 : IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) )
3000 : {
3001 6237 : q_direction->band_data[j].elevation_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[j].elevation_m_alphabet[k], GR_ord_elevation ); /*Q0*/
3002 6237 : move16();
3003 6237 : q_direction->band_data[j].elevation_fx[k] = deindex_elevation_fx( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); /*Q22*/
3004 6237 : move32();
3005 : }
3006 : }
3007 : }
3008 : }
3009 : }
3010 :
3011 29234 : FOR( k = 0; k < masa_subframes; k++ )
3012 : {
3013 23239 : test();
3014 23239 : IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) &&
3015 : LE_16( no_phi_masa[sub( q_direction->band_data[j].bits_sph_idx[k], 1 )][q_direction->band_data[j].elevation_index[k]], 1 ) )
3016 : {
3017 2 : q_direction->band_data[j].azimuth_index[k] = MASA_NO_INDEX; /*Q0*/
3018 2 : move16();
3019 2 : q_direction->band_data[j].azimuth_m_alphabet[k] = 1; /*Q0*/
3020 2 : move16();
3021 : }
3022 : ELSE
3023 : {
3024 23237 : q_direction->band_data[j].azimuth_index[k] = 0;
3025 23237 : move16();
3026 23237 : IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) )
3027 : {
3028 23234 : q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[sub( q_direction->band_data[j].bits_sph_idx[k], 1 )][q_direction->band_data[j].elevation_index[k]]; /*Q0*/
3029 23234 : move16();
3030 : }
3031 : ELSE
3032 : {
3033 3 : q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[sub( q_direction->band_data[j].bits_sph_idx[k], 1 )][0]; /*Q0*/
3034 3 : move16();
3035 3 : q_direction->band_data[j].elevation_index[k] = 0;
3036 3 : move16();
3037 : }
3038 : }
3039 : }
3040 :
3041 5995 : nbits = sub( *pbit_pos, bit_pos );
3042 5995 : *pbit_pos = bit_pos;
3043 5995 : move16();
3044 :
3045 5995 : return nbits;
3046 : }
3047 :
3048 :
3049 791882 : static Word16 decode_fixed_rate_fx(
3050 : IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata */
3051 : const UWord16 *bitstream, /* i : bitstream to be read Q0*/
3052 : Word16 *pbit_pos, /* i/o: position in bitstream Q0*/
3053 : const Word16 b, /* i : subband index Q0*/
3054 : const Word16 nblocks /* i : number of tiles in subband Q0*/
3055 : )
3056 : {
3057 : Word16 nbits, m, i;
3058 : UWord16 value;
3059 :
3060 791882 : nbits = 0;
3061 791882 : move16();
3062 :
3063 2806744 : FOR( m = 0; m < nblocks; m++ )
3064 : {
3065 2014862 : value = 0;
3066 2014862 : move16();
3067 10247363 : FOR( i = 0; i < q_direction->band_data[b].bits_sph_idx[m]; i++ )
3068 : {
3069 8232501 : value = (UWord16) L_add( L_shl( value, 1 ), bitstream[( *pbit_pos )--] ); /*Q0*/
3070 8232501 : move16();
3071 : }
3072 :
3073 2014862 : q_direction->band_data[b].spherical_index[m] = value; /*Q0*/
3074 2014862 : move16();
3075 2014862 : nbits = extract_l( L_add( nbits, q_direction->band_data[b].bits_sph_idx[m] ) ); /*Q0*/
3076 :
3077 2014862 : deindex_spherical_component_fx( q_direction->band_data[b].spherical_index[m], &q_direction->band_data[b].azimuth_fx[m], &q_direction->band_data[b].elevation_fx[m], &q_direction->band_data[b].azimuth_index[m], &q_direction->band_data[b].elevation_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->cfg.mc_ls_setup );
3078 : }
3079 :
3080 791882 : return nbits;
3081 : }
3082 :
3083 : /*-------------------------------------------------------------------*
3084 : * decode_azimuth2D()
3085 : *
3086 : * Azimuth bitstream reading and decoding in 2D case
3087 : *-------------------------------------------------------------------*/
3088 :
3089 : /*! r: number of bits read */
3090 346 : static Word16 decode_azimuth2D_fx(
3091 : IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */
3092 : UWord16 *bitstream, /* i : bitstream to be read Q0*/
3093 : const Word16 coding_subbands, /* i : number of subbands Q0*/
3094 : Word16 *pbit_pos, /*Q0*/
3095 : const Word16 no_frames /*Q0*/ )
3096 : {
3097 : Word16 i, j, k;
3098 : Word16 allowed_bits, nbits;
3099 : Word16 use_vq;
3100 : UWord16 Buffer;
3101 : Word16 bit_pos;
3102 : Word16 *bits_dir0;
3103 :
3104 346 : bit_pos = *pbit_pos;
3105 346 : move16();
3106 346 : nbits = 0;
3107 346 : move16();
3108 1391 : FOR( j = 0; j < coding_subbands; j++ )
3109 : {
3110 1045 : bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx; /*Q0*/
3111 1045 : allowed_bits = sum16_fx( bits_dir0, no_frames );
3112 :
3113 1045 : IF( allowed_bits > 0 )
3114 : {
3115 1045 : use_vq = 0;
3116 1045 : move16();
3117 4670 : FOR( k = 0; k < no_frames; k++ )
3118 : {
3119 3625 : q_direction->band_data[j].elevation_fx[k] = 0;
3120 3625 : move32();
3121 3625 : q_direction->band_data[j].elevation_index[k] = 0;
3122 3625 : move16();
3123 :
3124 3625 : IF( GT_16( bits_dir0[k], use_vq ) )
3125 : {
3126 1244 : use_vq = bits_dir0[k];
3127 1244 : move16();
3128 : }
3129 : }
3130 :
3131 1045 : test();
3132 1045 : IF( LE_16( use_vq, 3 ) && LE_16( allowed_bits, 11 ) )
3133 : {
3134 296 : IF( LE_16( allowed_bits, add( no_frames, 1 ) ) )
3135 : {
3136 224 : set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_frames );
3137 676 : FOR( k = 0; k < s_min( allowed_bits, no_frames ); k++ )
3138 : {
3139 452 : q_direction->band_data[j].azimuth_fx[k] = L_shl( L_mult0( -180, bitstream[bit_pos] ), Q22 ); /*Q22*/
3140 452 : move32();
3141 452 : bit_pos = sub( bit_pos, 1 );
3142 452 : nbits = add( nbits, 1 );
3143 : }
3144 : }
3145 : ELSE
3146 : {
3147 72 : nbits = add( nbits, read_truncGR_azimuth_fx( bitstream, q_direction, j, no_frames, &bit_pos ) ); /*Q0*/
3148 : }
3149 : }
3150 : ELSE
3151 : {
3152 3661 : FOR( k = 0; k < no_frames; k++ )
3153 : {
3154 2912 : Buffer = 0;
3155 2912 : move16();
3156 16271 : FOR( i = 0; i < bits_dir0[k]; i++ )
3157 : {
3158 13359 : Buffer = (UWord16) L_add( L_shl( Buffer, 1 ), bitstream[bit_pos] ); /*Q0*/
3159 13359 : bit_pos = sub( bit_pos, 1 );
3160 : }
3161 :
3162 2912 : nbits = add( nbits, bits_dir0[k] );
3163 :
3164 2912 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
3165 : {
3166 2463 : q_direction->band_data[j].azimuth_fx[k] = L_sub( W_extract_l( W_mult0_32_32( L_shl( 360, sub( Q22, bits_dir0[k] ) ), Buffer ) ), L_shl( 180, Q22 ) ); /*Q22*/
3167 2463 : move32();
3168 4926 : q_direction->band_data[j].azimuth_fx[k] = companding_azimuth_fx( q_direction->band_data[j].azimuth_fx[k], q_direction->cfg.mc_ls_setup,
3169 2463 : (Word16) GT_32( q_direction->band_data[j].elevation_fx[k], L_shl( MC_MASA_THR_ELEVATION, 22 ) ), -1 ); /*Q22*/
3170 2463 : move32();
3171 : }
3172 : ELSE
3173 : {
3174 449 : q_direction->band_data[j].azimuth_fx[k] = L_sub( W_extract_l( W_mult0_32_32( L_shl( 360, sub( Q22, bits_dir0[k] ) ), Buffer ) ), L_shl( 180, Q22 ) ); /*Q22*/
3175 449 : move32();
3176 : }
3177 : }
3178 : }
3179 : }
3180 : ELSE
3181 : {
3182 0 : set_zero_direction_fx( q_direction, j, no_frames );
3183 : }
3184 : }
3185 346 : *pbit_pos = bit_pos;
3186 346 : move16();
3187 :
3188 346 : return nbits;
3189 : }
3190 :
3191 : /*-------------------------------------------------------------------*
3192 : * set_zero_direction()
3193 : *
3194 : *
3195 : *-------------------------------------------------------------------*/
3196 :
3197 3423 : static void set_zero_direction_fx(
3198 : IVAS_QDIRECTION *q_direction,
3199 : const Word16 idx_band, /*Q0*/
3200 : const Word16 len /*Q0*/ )
3201 : {
3202 : Word16 k;
3203 :
3204 17115 : FOR( k = 0; k < len; k++ )
3205 : {
3206 13692 : q_direction->band_data[idx_band].azimuth_fx[k] = 0;
3207 13692 : move32();
3208 13692 : q_direction->band_data[idx_band].azimuth_index[k] = 0;
3209 13692 : move16();
3210 13692 : q_direction->band_data[idx_band].elevation_fx[k] = 0;
3211 13692 : move32();
3212 13692 : q_direction->band_data[idx_band].elevation_index[k] = 0;
3213 13692 : move16();
3214 13692 : q_direction->band_data[idx_band].spherical_index[k] = 0;
3215 13692 : move16();
3216 : }
3217 :
3218 3423 : return;
3219 : }
3220 :
3221 :
3222 : /*-------------------------------------------------------------------*
3223 : * read_truncGR_azimuth()
3224 : *
3225 : *
3226 : *-------------------------------------------------------------------*/
3227 :
3228 3400 : static Word16 read_truncGR_azimuth_fx(
3229 : UWord16 *bitstream, /* i : bitstream to be read Q0*/
3230 : IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */
3231 : const Word16 j, /* i : subband index Q0*/
3232 : const Word16 no_subframes, /* i : number of tiles Q0*/
3233 : Word16 *pbit_pos /* i/o: position in bitstream Q0*/
3234 : )
3235 : {
3236 : Word16 i;
3237 : Word16 nbits;
3238 : UWord16 idx;
3239 : Word16 no_symb, allowed_bits;
3240 :
3241 3400 : allowed_bits = sum16_fx( (Word16 *) q_direction->band_data[j].bits_sph_idx, no_subframes ); /*Q0*/
3242 3400 : nbits = 0;
3243 3400 : move16();
3244 3400 : IF( LE_16( allowed_bits, add( no_subframes, 1 ) ) )
3245 : {
3246 0 : Word16 len = s_min( allowed_bits, no_subframes );
3247 0 : FOR( i = 0; i < len; i++ )
3248 : {
3249 0 : IF( bitstream[( *pbit_pos )--] == 0 )
3250 : {
3251 0 : q_direction->band_data[j].azimuth_fx[i] = 0;
3252 0 : move32();
3253 : }
3254 : ELSE
3255 : {
3256 0 : q_direction->band_data[j].azimuth_fx[i] = ( -180 * ONE_IN_Q22 ); /*Q22*/
3257 0 : move32();
3258 : }
3259 0 : nbits = add( nbits, 1 );
3260 : }
3261 :
3262 0 : return nbits;
3263 : }
3264 :
3265 3400 : IF( NE_16( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
3266 : {
3267 502 : no_symb = 9;
3268 502 : move16();
3269 : }
3270 : ELSE
3271 : {
3272 2898 : no_symb = 8;
3273 2898 : move16();
3274 : }
3275 3400 : nbits = 0;
3276 3400 : move16();
3277 :
3278 3400 : nbits = *pbit_pos;
3279 3400 : move16();
3280 :
3281 16973 : FOR( i = 0; i < no_subframes; i++ )
3282 : {
3283 13573 : idx = ivas_qmetadata_DecodeExtendedGR( bitstream, pbit_pos, no_symb, 0 );
3284 13573 : q_direction->band_data[j].azimuth_index[i] = idx; /*Q0*/
3285 13573 : move16();
3286 13573 : IF( NE_16( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
3287 : {
3288 2002 : q_direction->band_data[j].azimuth_fx[i] = cb_azi_chan_fx[(UWord16) ( (UWord16) ( idx + 1 ) / 2 )]; /*Q22*/
3289 2002 : move32();
3290 2002 : IF( L_and( idx, 1 ) > 0 )
3291 : {
3292 790 : q_direction->band_data[j].azimuth_fx[i] = L_negate( q_direction->band_data[j].azimuth_fx[i] ); /*Q22*/
3293 790 : move32();
3294 : }
3295 : }
3296 : ELSE
3297 : {
3298 11571 : q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[idx]; /*Q22*/
3299 11571 : move32();
3300 : }
3301 : }
3302 :
3303 3400 : nbits = sub( nbits, *pbit_pos );
3304 :
3305 3400 : return nbits;
3306 : }
3307 :
3308 : /*-------------------------------------------------------------------*
3309 : * read_common_direction()
3310 : *
3311 : *
3312 : *-------------------------------------------------------------------*/
3313 :
3314 : /*! r: number of bits read */
3315 3423 : static Word16 read_common_direction_fx(
3316 : UWord16 *bitstream, /* i : bitstream to be read Q0*/
3317 : IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */
3318 : const Word16 j, /* i : subband index Q0*/
3319 : const Word16 no_subframes, /* i : number of tiles Q0*/
3320 : const Word16 bits_total, /* i : number of bits for subband directional data Q0*/
3321 : Word16 *pbit_pos /* i/o: position in bitstream Q0*/
3322 : )
3323 : {
3324 : Word16 nbits;
3325 : Word16 bit_pos;
3326 : Word16 i;
3327 : UWord16 byteBuffer;
3328 : Word16 bits_el;
3329 :
3330 3423 : bit_pos = *pbit_pos;
3331 3423 : move16();
3332 3423 : nbits = 0;
3333 3423 : move16();
3334 :
3335 3423 : set_zero_direction_fx( q_direction, j, no_subframes );
3336 3423 : IF( !bits_total )
3337 : {
3338 0 : return nbits;
3339 : }
3340 :
3341 3423 : IF( LE_16( bits_total, add( no_subframes, 1 ) ) )
3342 : {
3343 320 : FOR( i = 0; i < s_min( no_subframes, bits_total ); i++ )
3344 : {
3345 256 : byteBuffer = bitstream[bit_pos--]; /*Q0*/
3346 256 : move16();
3347 : /*qdirection->azimuth_index[j][i] = (uint16_t)byteBuffer; */
3348 256 : q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[byteBuffer]; /*Q22*/
3349 256 : move32();
3350 256 : nbits = add( nbits, 1 );
3351 : }
3352 64 : *pbit_pos = bit_pos;
3353 64 : move16();
3354 :
3355 : /*nbits += read_truncGR_azimuth(bitstream, qdirection, j, no_subframes, pbit_pos); */
3356 64 : return nbits;
3357 : }
3358 :
3359 :
3360 3359 : byteBuffer = bitstream[bit_pos]; /*Q0*/
3361 3359 : move16();
3362 3359 : bit_pos = sub( bit_pos, 1 );
3363 3359 : bits_el = 1;
3364 3359 : move16();
3365 3359 : nbits = add( nbits, 1 );
3366 : /* elevation is already set to 0*/
3367 3359 : IF( EQ_32( byteBuffer, 1 ) )
3368 : {
3369 1255 : byteBuffer = bitstream[bit_pos--]; /*Q0*/
3370 1255 : move16();
3371 1255 : bits_el = add( bits_el, 1 );
3372 1255 : nbits = add( nbits, 1 );
3373 1255 : IF( byteBuffer == 0 )
3374 : {
3375 3840 : FOR( i = 0; i < no_subframes; i++ )
3376 : {
3377 3072 : q_direction->band_data[j].elevation_fx[i] = delta_theta_masa_fx[2]; /*Q22*/
3378 3072 : move32();
3379 : }
3380 : }
3381 : ELSE
3382 : {
3383 487 : byteBuffer = bitstream[bit_pos--];
3384 487 : move16();
3385 487 : bits_el = add( bits_el, 1 );
3386 487 : nbits = add( nbits, 1 );
3387 487 : IF( byteBuffer == 0 )
3388 : {
3389 2310 : FOR( i = 0; i < no_subframes; i++ )
3390 : {
3391 1848 : q_direction->band_data[j].elevation_fx[i] = L_negate( delta_theta_masa_fx[2] ); /*Q22*/
3392 1848 : move32();
3393 : }
3394 : }
3395 : ELSE
3396 : {
3397 : /* theta is +/- 90; no azimuth is read */
3398 25 : byteBuffer = bitstream[bit_pos--];
3399 25 : move16();
3400 25 : nbits = add( nbits, 1 );
3401 25 : IF( byteBuffer == 0 )
3402 : {
3403 12 : set32_fx( q_direction->band_data[j].elevation_fx, ( 90 * ONE_IN_Q22 ), no_subframes ); /*Q22*/
3404 12 : set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_subframes ); /*Q22*/
3405 : }
3406 : ELSE
3407 : {
3408 13 : set32_fx( q_direction->band_data[j].elevation_fx, ( -90 * ONE_IN_Q22 ), no_subframes ); /*Q22*/
3409 13 : set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_subframes ); /*Q22*/
3410 : }
3411 25 : *pbit_pos = bit_pos;
3412 25 : move16();
3413 :
3414 25 : return nbits;
3415 : }
3416 : }
3417 : }
3418 :
3419 3334 : bits_el = sub( sum16_fx( (Word16 *) q_direction->band_data[j].bits_sph_idx, no_subframes ), bits_el ); /*Q0*/
3420 :
3421 3334 : IF( LE_16( bits_el, add( no_subframes, 1 ) ) )
3422 : {
3423 6 : nbits = add( nbits, s_min( no_subframes, bits_el ) );
3424 30 : FOR( i = 0; i < s_min( no_subframes, bits_el ); i++ )
3425 : {
3426 24 : byteBuffer = bitstream[bit_pos]; /*Q0*/
3427 24 : move16();
3428 24 : bit_pos = sub( bit_pos, 1 );
3429 : /*qdirection->azimuth_index[j][i] = (uint16_t) byteBuffer; */
3430 24 : q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[byteBuffer]; /*Q22*/
3431 24 : move32();
3432 : }
3433 : }
3434 : ELSE
3435 : {
3436 3328 : nbits = add( nbits, read_truncGR_azimuth_fx( bitstream, q_direction, j, no_subframes, &bit_pos ) );
3437 : }
3438 :
3439 3334 : *pbit_pos = bit_pos;
3440 3334 : move16();
3441 :
3442 3334 : return nbits;
3443 : }
3444 :
3445 : /*-----------------------------------------------------------------------*
3446 : * Local functions: coherence
3447 : *-----------------------------------------------------------------------*/
3448 :
3449 42588 : static void decode_spread_coherence_fx(
3450 : IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: quantized metadata structure */
3451 : Word16 idx_d, /* i : direction index Q0*/
3452 : const Word16 no_frames, /* i : number of time subframes Q0*/
3453 : const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding Q0*/
3454 : )
3455 : {
3456 : Word16 i, j;
3457 : Word64 var_azi_fx;
3458 : Word16 idx_sub_cb;
3459 : Word32 dct_coh_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
3460 : Word16 MASA_grouping[MASA_MAXIMUM_CODING_SUBBANDS];
3461 : IVAS_QDIRECTION *q_direction;
3462 : Word16 coding_subbands, coding_subbands_0, d, two_dir_band[MASA_MAXIMUM_CODING_SUBBANDS];
3463 : Word16 min_index;
3464 :
3465 42588 : coding_subbands_0 = hQMetaData->q_direction[0].cfg.nbands;
3466 42588 : move16();
3467 42588 : coding_subbands = hQMetaData->q_direction[idx_d].cfg.nbands;
3468 42588 : move16();
3469 42588 : IF( LE_16( coding_subbands_0, 5 ) )
3470 : {
3471 171582 : FOR( j = 0; j < 5; j++ )
3472 : {
3473 142985 : MASA_grouping[j] = j;
3474 142985 : move16();
3475 : }
3476 : }
3477 : ELSE
3478 : {
3479 13991 : IF( LE_16( coding_subbands_0, 8 ) )
3480 : {
3481 4750 : Copy( MASA_grouping_8_to_5, MASA_grouping, 8 ); /*Q0*/
3482 : }
3483 9241 : ELSE IF( LE_16( coding_subbands_0, 12 ) )
3484 : {
3485 2686 : Copy( MASA_grouping_12_to_5, MASA_grouping, 12 ); /*Q0*/
3486 : }
3487 6555 : ELSE IF( LE_16( coding_subbands_0, 18 ) )
3488 : {
3489 3633 : Copy( MASA_grouping_18_to_5, MASA_grouping, 18 ); /*Q0*/
3490 : }
3491 : ELSE
3492 : {
3493 2922 : IF( LE_16( coding_subbands_0, 24 ) )
3494 : {
3495 2922 : Copy( MASA_grouping_24_to_5, MASA_grouping, 24 ); /*Q0*/
3496 : }
3497 : }
3498 : }
3499 :
3500 42588 : IF( LT_16( coding_subbands, coding_subbands_0 ) )
3501 : {
3502 9583 : d = 0;
3503 9583 : move16();
3504 83086 : FOR( j = 0; j < coding_subbands_0; j++ )
3505 : {
3506 73503 : IF( EQ_16( hQMetaData->twoDirBands[j], 1 ) )
3507 : {
3508 26823 : two_dir_band[d] = j;
3509 26823 : move16();
3510 26823 : d = add( d, 1 );
3511 : }
3512 : }
3513 : }
3514 : ELSE
3515 : {
3516 33005 : set16_fx( two_dir_band, 0, coding_subbands );
3517 : }
3518 :
3519 42588 : q_direction = &hQMetaData->q_direction[idx_d];
3520 :
3521 339115 : FOR( i = 0; i < coding_subbands; i++ )
3522 : {
3523 296527 : var_azi_fx = var_32_fx( q_direction->band_data[i].azimuth_fx, no_frames, 22 ); /*Q22*/
3524 296527 : IF( hrmasa_flag )
3525 : {
3526 0 : minimum_s( (Word16 *) ( q_direction->band_data[i].energy_ratio_index ), q_direction->cfg.nblocks, &min_index );
3527 0 : min_index = shr( min_index, 1 );
3528 : }
3529 : ELSE
3530 : {
3531 296527 : min_index = q_direction->band_data[i].energy_ratio_index[0]; /*Q0*/
3532 296527 : move16();
3533 : }
3534 :
3535 296527 : IF( LT_64( var_azi_fx, L_shl( MASA_DELTA_AZI_DCT0, 22 ) ) )
3536 : {
3537 150134 : idx_sub_cb = i_mult( MASA_NO_CV_COH, min_index ); /*Q0*/
3538 : }
3539 : ELSE
3540 : {
3541 146393 : idx_sub_cb = i_mult( MASA_NO_CV_COH, add( min_index, DIRAC_DIFFUSE_LEVELS ) ); /* NO_CV_COH = 8 */
3542 : }
3543 :
3544 296527 : dct_coh_fx[i][0] = coherence_cb0_masa_fx[idx_sub_cb + q_direction->coherence_band_data[i].spread_coherence_dct0_index];
3545 296527 : move32();
3546 :
3547 296527 : IF( LT_16( coding_subbands, coding_subbands_0 ) )
3548 : {
3549 26823 : assert( EQ_16( idx_d, 1 ) );
3550 26823 : dct_coh_fx[i][1] = coherence_cb1_masa_fx[( ( MASA_grouping[two_dir_band[i]] * MASA_NO_CV_COH1 ) + q_direction->coherence_band_data[i].spread_coherence_dct1_index )]; /*Q21*/
3551 26823 : move32();
3552 : }
3553 : ELSE
3554 : {
3555 269704 : dct_coh_fx[i][1] = coherence_cb1_masa_fx[( ( MASA_grouping[i] * MASA_NO_CV_COH1 ) + q_direction->coherence_band_data[i].spread_coherence_dct1_index )]; /*Q21*/
3556 269704 : move32();
3557 : }
3558 :
3559 889581 : FOR( j = 2; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
3560 : {
3561 593054 : dct_coh_fx[i][j] = 0;
3562 593054 : move32();
3563 : }
3564 :
3565 296527 : invdct4_transform_fx( dct_coh_fx[i], q_direction->coherence_band_data[i].spread_coherence, 21 );
3566 : }
3567 :
3568 42588 : return;
3569 : }
3570 :
3571 : /*-------------------------------------------------------------------*
3572 : * read_huf()
3573 : *
3574 : * Read Hufman code
3575 : *-------------------------------------------------------------------*/
3576 :
3577 : /*! r: number of bits read */
3578 42588 : static ivas_error read_huf(
3579 : Word16 *num_bits_read, /*Q0*/
3580 : const UWord16 *bitstream, /* i : bitstream to be read Q0*/
3581 : UWord16 *out, /* o : decoded value Q0*/
3582 : const Word16 start_pos, /* i : starting position for reading Q0*/
3583 : const Word16 len, /* i : number of codewords Q0*/
3584 : const Word16 *huff_code, /* i : Huffman table Q0*/
3585 : const Word16 max_len /* i : maximum codeword length Q0*/
3586 : )
3587 : {
3588 42588 : Word16 done = 0, end_pos;
3589 42588 : move16();
3590 : UWord16 ByteBuffer;
3591 : Word16 nbits, val;
3592 : UWord16 i;
3593 :
3594 42588 : end_pos = start_pos;
3595 42588 : move16();
3596 42588 : nbits = 0;
3597 42588 : move16();
3598 42588 : val = 0;
3599 42588 : move16();
3600 201362 : WHILE( !done && LT_16( nbits, max_len ) )
3601 : {
3602 158774 : ByteBuffer = bitstream[end_pos--]; /*Q0*/
3603 158774 : move16();
3604 158774 : val = add( shl( val, 1 ), ByteBuffer & 1 ); /*Q0*/
3605 158774 : nbits = add( nbits, 1 );
3606 746513 : FOR( i = 0; i < len; i++ )
3607 : {
3608 630327 : IF( EQ_16( val, huff_code[i] ) )
3609 : {
3610 42588 : *out = i;
3611 42588 : move16();
3612 42588 : done = 1;
3613 42588 : move16();
3614 42588 : BREAK;
3615 : }
3616 : }
3617 : }
3618 :
3619 42588 : *num_bits_read = end_pos;
3620 42588 : move16();
3621 :
3622 42588 : return IVAS_ERR_OK;
3623 : }
3624 :
3625 :
3626 : /*-------------------------------------------------------------------*
3627 : * read_GR_min_removed_data()
3628 : *
3629 : *
3630 : *-------------------------------------------------------------------*/
3631 14183 : static Word16 read_GR_min_removed_data(
3632 : UWord16 *bitstream, /* i : bitstream Q0*/
3633 : Word16 *p_bit_pos, /* i : position in the bitstream Q0*/
3634 : const Word16 *no_cv_vec, /*Q0*/
3635 : const Word16 no_data, /*Q0*/
3636 : Word16 *decoded_idx, /*Q0*/
3637 : const Word16 no_symb /*Q0*/ )
3638 : {
3639 : Word16 j;
3640 : Word16 bit_pos;
3641 : Word16 nbits, bits_GR;
3642 : UWord16 byteBuffer;
3643 : Word16 min_index;
3644 :
3645 14183 : bit_pos = *p_bit_pos;
3646 14183 : move16();
3647 :
3648 : /* read GR order */
3649 14183 : byteBuffer = bitstream[bit_pos]; /*Q0*/
3650 14183 : move16();
3651 14183 : bit_pos = sub( bit_pos, 1 );
3652 14183 : nbits = 1;
3653 14183 : move16();
3654 :
3655 : /* read min index */
3656 14183 : bits_GR = bit_pos;
3657 14183 : move16();
3658 14183 : min_index = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, no_symb, 0 ); /*Q0*/
3659 14183 : nbits = add( nbits, sub( bits_GR, bit_pos ) );
3660 :
3661 : /* read GR data */
3662 193752 : FOR( j = 0; j < no_data; j++ )
3663 : {
3664 179569 : bits_GR = bit_pos;
3665 179569 : move16();
3666 179569 : IF( GT_16( no_cv_vec[j], 1 ) )
3667 : {
3668 177579 : decoded_idx[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, sub( no_cv_vec[j], min_index ), extract_l( L_and( byteBuffer, 1 ) ) ); /*Q0*/
3669 177579 : move16();
3670 177579 : nbits = add( nbits, sub( bits_GR, bit_pos ) );
3671 : }
3672 : ELSE
3673 : {
3674 1990 : decoded_idx[j] = 0;
3675 1990 : move16();
3676 : }
3677 : }
3678 :
3679 193752 : FOR( j = 0; j < no_data; j++ ){
3680 179569 : IF( GT_16( no_cv_vec[j], 1 ) ){
3681 177579 : decoded_idx[j] = add( decoded_idx[j], min_index );
3682 177579 : move16();
3683 : }
3684 : }
3685 :
3686 14183 : *p_bit_pos = bit_pos;
3687 14183 : move16();
3688 :
3689 14183 : return nbits;
3690 : }
3691 :
3692 :
3693 : /*-------------------------------------------------------------------*
3694 : * decode_fixed_rate_composed_index_coherence()
3695 : *
3696 : *
3697 : *-------------------------------------------------------------------*/
3698 :
3699 32884 : static Word16 decode_fixed_rate_composed_index_coherence_fx(
3700 : UWord16 *bitstream, /* i : bitstream Q0*/
3701 : Word16 *p_bit_pos, /* i : position in the bitstream Q0*/
3702 : const Word16 no_bands, /*Q0*/
3703 : Word16 *no_cv_vec, /*Q0*/
3704 : UWord16 *decoded_index, /*Q0*/
3705 : const Word16 no_symb /*Q0*/ )
3706 : {
3707 : /* fixed rate */
3708 : UWord64 no_cb;
3709 : UWord16 temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
3710 : UWord64 idx_fr;
3711 : Word16 no_bits_vec1, half_no_bands;
3712 : Word16 bit_pos;
3713 : Word16 nbits, bits_GR;
3714 : Word16 j;
3715 : Word16 no_vals_local;
3716 : Word16 no_bits_vec;
3717 :
3718 32884 : bit_pos = *p_bit_pos;
3719 32884 : move16();
3720 32884 : set16_fx( (Word16 *) temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
3721 :
3722 32884 : no_cb = 1;
3723 32884 : move64();
3724 32884 : nbits = 0;
3725 32884 : move16();
3726 32884 : IF( GT_16( no_bands, MASA_LIMIT_NO_BANDS_SUR_COH ) )
3727 : {
3728 : /* read 8-max_val with GR0 */
3729 17725 : bits_GR = bit_pos;
3730 17725 : move16();
3731 17725 : no_vals_local = sub( no_symb, ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, no_symb, 0 ) );
3732 17725 : nbits = add( nbits, sub( bits_GR, bit_pos ) );
3733 359267 : FOR( j = 0; j < no_bands; j++ )
3734 : {
3735 341542 : IF( GT_16( no_cv_vec[j], no_vals_local ) )
3736 : {
3737 229800 : no_cv_vec[j] = no_vals_local; /*Q0*/
3738 229800 : move16();
3739 : }
3740 : }
3741 : }
3742 :
3743 32884 : half_no_bands = shr( no_bands, 1 ); /* no_bands / 2 */
3744 32884 : IF( GT_16( sum16_fx( no_cv_vec, no_bands ), MASA_COH_LIMIT_2IDX ) )
3745 : {
3746 8591 : no_cb = 1;
3747 8591 : move64();
3748 :
3749 105648 : FOR( j = 0; j < half_no_bands; j++ )
3750 : {
3751 97057 : no_cb *= no_cv_vec[j]; /*Q0*/
3752 97057 : move16();
3753 : }
3754 8591 : no_bits_vec = (Word16) ceil_log_2( no_cb );
3755 8591 : no_cb = 1;
3756 8591 : move64();
3757 106604 : FOR( j = half_no_bands; j < no_bands; j++ )
3758 : {
3759 98013 : no_cb *= no_cv_vec[j]; /*Q0*/
3760 98013 : move16();
3761 : }
3762 8591 : no_bits_vec1 = (Word16) ceil_log_2( no_cb );
3763 : }
3764 : ELSE
3765 : {
3766 24293 : no_cb = 1;
3767 24293 : move64();
3768 237916 : FOR( j = 0; j < no_bands; j++ )
3769 : {
3770 213623 : no_cb *= no_cv_vec[j]; /*Q0*/
3771 213623 : move16();
3772 : }
3773 24293 : no_bits_vec = (Word16) ceil_log_2( no_cb );
3774 24293 : no_bits_vec1 = 0;
3775 24293 : move16();
3776 : }
3777 32884 : IF( no_bits_vec1 > 0 )
3778 : {
3779 8591 : idx_fr = 0;
3780 8591 : move64();
3781 278479 : FOR( j = 0; j < no_bits_vec; j++ )
3782 : {
3783 269888 : idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos]; /*Q0*/
3784 269888 : bit_pos = sub( bit_pos, 1 );
3785 269888 : move64();
3786 : }
3787 :
3788 8591 : nbits = add( nbits, no_bits_vec );
3789 :
3790 8591 : decode_combined_index_fx( idx_fr, no_cv_vec, temp_index, half_no_bands );
3791 :
3792 8591 : idx_fr = 0;
3793 8591 : move64();
3794 282173 : FOR( j = 0; j < no_bits_vec1; j++ )
3795 : {
3796 273582 : idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos]; /*Q0*/
3797 273582 : bit_pos = sub( bit_pos, 1 );
3798 273582 : move64();
3799 : }
3800 8591 : nbits = add( nbits, no_bits_vec1 );
3801 8591 : decode_combined_index_fx( idx_fr, &no_cv_vec[half_no_bands], &temp_index[half_no_bands], half_no_bands );
3802 : }
3803 : ELSE
3804 : {
3805 24293 : idx_fr = 0;
3806 24293 : move64();
3807 314066 : FOR( j = 0; j < no_bits_vec; j++ )
3808 : {
3809 289773 : idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos]; /*Q0*/
3810 289773 : bit_pos = sub( bit_pos, 1 );
3811 289773 : move64();
3812 : }
3813 24293 : nbits = add( nbits, no_bits_vec );
3814 24293 : decode_combined_index_fx( idx_fr, no_cv_vec, temp_index, no_bands );
3815 : }
3816 :
3817 441577 : FOR( j = 0; j < no_bands; j++ )
3818 : {
3819 408693 : decoded_index[j] = temp_index[j]; /*Q0*/
3820 408693 : move16();
3821 : }
3822 32884 : nbits = sub( *p_bit_pos, bit_pos );
3823 :
3824 32884 : *p_bit_pos = bit_pos; /*Q0*/
3825 32884 : move16();
3826 :
3827 32884 : return nbits;
3828 : }
3829 :
3830 : /*-------------------------------------------------------------------*
3831 : * read_coherence_data_hr_512()
3832 : *
3833 : * Read coherence data at HR
3834 : *-------------------------------------------------------------------*/
3835 :
3836 : /*! r: number of bits read */
3837 7540 : static Word16 read_coherence_data_hr_512_fx(
3838 : UWord16 *bitstream, /* i : bitstream Q0*/
3839 : Word16 *p_bit_pos, /* i : position in the bitstream Q0*/
3840 : IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata structure */
3841 : const Word16 idx_dir, /* i : direction index Q0*/
3842 : const Word16 nbits_coh /*Q0*/ )
3843 : {
3844 : Word16 j, k, i;
3845 : Word16 nbands, nblocks;
3846 : Word16 min_index, GR_param;
3847 : Word16 cb_size, nbits;
3848 : Word16 decoded_idx;
3849 : Word32 delta_fx, decoded_idx_fx; // q = 22, q = 9
3850 :
3851 7540 : nbands = hQMetaData->q_direction[idx_dir].cfg.nbands;
3852 7540 : move16();
3853 7540 : nblocks = hQMetaData->q_direction[idx_dir].cfg.nblocks;
3854 7540 : move16();
3855 :
3856 7540 : cb_size = shl( 1, nbits_coh );
3857 7540 : delta_fx = L_shl( 256, sub( 22, nbits_coh ) );
3858 7540 : nbits = *p_bit_pos;
3859 7540 : move16();
3860 29339 : FOR( k = 0; k < nblocks; k++ )
3861 : {
3862 : /* read method */
3863 21799 : IF( EQ_32( bitstream[( *p_bit_pos )--], 1 ) )
3864 : {
3865 : /* average removed */
3866 : /* read average index */
3867 8552 : min_index = 0;
3868 8552 : move16();
3869 37452 : FOR( i = 0; i < nbits_coh; i++ )
3870 : {
3871 28900 : min_index = add( shl( min_index, 1 ), bitstream[( *p_bit_pos )] ); /*Q0*/
3872 28900 : ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
3873 28900 : move16();
3874 : }
3875 : /* read GR param */
3876 8552 : GR_param = bitstream[( *p_bit_pos )]; /*Q0*/
3877 8552 : move16();
3878 8552 : ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
3879 8552 : move16();
3880 195062 : FOR( j = 0; j < nbands; j++ )
3881 : {
3882 186510 : decoded_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, p_bit_pos, shl( cb_size, 1 ), GR_param ); /*Q0*/
3883 186510 : IF( EQ_16( s_and( decoded_idx, 1 ), 1 ) )
3884 : {
3885 75978 : decoded_idx = add( shr( add( decoded_idx, 1 ), 1 ), min_index );
3886 : }
3887 : ELSE
3888 : {
3889 110532 : decoded_idx = add( negate( shr( decoded_idx, 1 ) ), min_index );
3890 : }
3891 186510 : decoded_idx_fx = L_shl( decoded_idx, 9 );
3892 186510 : hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (UWord8) L_add( Mpy_32_32( decoded_idx_fx, delta_fx ), L_shr( delta_fx, 23 ) ); /*Q0*/
3893 186510 : move16();
3894 : }
3895 : }
3896 : ELSE
3897 : {
3898 : /* read min_index */
3899 13247 : min_index = 0;
3900 13247 : move16();
3901 57630 : FOR( i = 0; i < nbits_coh; i++ )
3902 : {
3903 44383 : min_index = add( shl( min_index, 1 ), bitstream[( *p_bit_pos )] ); /*Q0*/
3904 44383 : ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
3905 44383 : move16();
3906 : }
3907 :
3908 : /* read GR param */
3909 13247 : GR_param = bitstream[( *p_bit_pos )]; /*Q0*/
3910 13247 : move16();
3911 13247 : ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
3912 13247 : move16();
3913 295944 : FOR( j = 0; j < nbands; j++ )
3914 : {
3915 282697 : decoded_idx = add( ivas_qmetadata_DecodeExtendedGR( bitstream, p_bit_pos, cb_size - min_index, GR_param ), min_index ); /*Q0*/
3916 282697 : decoded_idx_fx = L_shl( decoded_idx, 9 ); /*Q9*/
3917 282697 : hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (UWord8) L_add( Mpy_32_32( decoded_idx_fx, delta_fx ), L_shr( delta_fx, 23 ) ); /*Q0*/
3918 282697 : move16();
3919 : }
3920 : }
3921 : }
3922 :
3923 7540 : nbits = sub( nbits, *p_bit_pos );
3924 :
3925 7540 : return nbits;
3926 : }
3927 :
3928 : /*------------------------------------------------------------------- *
3929 : * read_coherence_data()
3930 : *
3931 : * Read coherence data
3932 : *------------------------------------------------------------------- */
3933 :
3934 : /*! r: number of bits read */
3935 68925 : static Word16 read_coherence_data_fx(
3936 : UWord16 *bitstream, /* i : bitstream Q0*/
3937 : Word16 *p_bit_pos, /* i : position in the bitstream Q0*/
3938 : IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata structure */
3939 : const Word16 idx_dir, /* i : direction index Q0*/
3940 : const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding Q0*/
3941 : )
3942 : {
3943 : Word16 j;
3944 : Word16 no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS];
3945 : UWord64 no_cb;
3946 : Word16 no_bits_vec, nbits;
3947 : Word16 bits_GR;
3948 : UWord16 idx_dct1[MASA_MAXIMUM_CODING_SUBBANDS];
3949 : UWord16 av_index;
3950 : Word16 no_bits_vec1;
3951 : Word16 bit_pos;
3952 : IVAS_QDIRECTION *q_direction;
3953 : Word16 coding_subbands;
3954 : UWord64 dct0_index;
3955 : Word16 decoded_idx[MASA_MAXIMUM_CODING_SUBBANDS];
3956 : UWord16 byteBuffer;
3957 : Word16 idx_ER;
3958 : Word16 min_index;
3959 : Word16 extra_cv;
3960 : Word16 num, den, q_num, q_den, q_res;
3961 : Word32 res;
3962 :
3963 68925 : coding_subbands = hQMetaData->q_direction[idx_dir].cfg.nbands;
3964 68925 : move16();
3965 68925 : extra_cv = idiv1616( coding_subbands, MASA_FACTOR_CV_COH ); /*Q0*/
3966 68925 : move16();
3967 68925 : q_direction = &( hQMetaData->q_direction[idx_dir] );
3968 68925 : bit_pos = *p_bit_pos;
3969 68925 : move16();
3970 68925 : nbits = 0;
3971 68925 : move16();
3972 :
3973 68925 : IF( EQ_16( q_direction->cfg.nblocks, 1 ) )
3974 : {
3975 313354 : FOR( j = 0; j < coding_subbands; j++ )
3976 : {
3977 287017 : IF( hrmasa_flag )
3978 : {
3979 0 : idx_ER = extract_l( L_add( L_sub( 7, L_shr( q_direction->band_data[j].energy_ratio_index_mod[0], 1 ) ), extra_cv ) ); /*Q0*/
3980 : }
3981 : ELSE
3982 : {
3983 287017 : idx_ER = extract_l( L_add( L_sub( 7, q_direction->band_data[j].energy_ratio_index_mod[0] ), extra_cv ) ); /*Q0*/
3984 : }
3985 287017 : no_cv_vec[j] = add( idx_ER, 1 );
3986 287017 : move16();
3987 : }
3988 :
3989 26337 : IF( EQ_16( sum16_fx( no_cv_vec, coding_subbands ), coding_subbands ) )
3990 : {
3991 6533 : FOR( j = 0; j < coding_subbands; j++ )
3992 : {
3993 5171 : q_direction->coherence_band_data[j].spread_coherence[0] = 0;
3994 : }
3995 :
3996 1362 : return 0;
3997 : }
3998 24975 : byteBuffer = bitstream[bit_pos]; /*Q0*/
3999 24975 : move16();
4000 24975 : bit_pos = sub( bit_pos, 1 );
4001 24975 : nbits = add( nbits, 1 );
4002 :
4003 24975 : IF( L_and( byteBuffer, 1 ) )
4004 : {
4005 : /* decode GR min removed */
4006 14183 : nbits = add( nbits, read_GR_min_removed_data( bitstream, &bit_pos, no_cv_vec, coding_subbands, decoded_idx, MASA_MAX_NO_CV_SUR_COH + extra_cv ) ); /*Q0*/
4007 193752 : FOR( j = 0; j < coding_subbands; j++ )
4008 : {
4009 179569 : IF( GT_16( no_cv_vec[j], 1 ) )
4010 : {
4011 177579 : num = i_mult( decoded_idx[j], 255 ); /*Q0*/
4012 177579 : move16();
4013 177579 : den = extract_l( L_add( L_sub( 7, L_shr( q_direction->band_data[j].energy_ratio_index_mod[0], hrmasa_flag ) ), coding_subbands / MASA_FACTOR_CV_COH ) ); /*Q0*/
4014 177579 : q_den = norm_s( den );
4015 177579 : q_num = sub( norm_s( num ), 1 );
4016 177579 : res = div_s( shl( num, q_num ), shl( den, q_den ) ); /*Q15*/
4017 177579 : q_res = add( sub( 15, q_den ), q_num );
4018 177579 : res = L_shl( res, sub( 16, q_res ) ); /*Q16*/
4019 177579 : q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) ( round_fx( res ) ); /*Q0*/
4020 177579 : move16();
4021 : }
4022 : ELSE
4023 : {
4024 1990 : q_direction->coherence_band_data[j].spread_coherence[0] = 0;
4025 1990 : move16();
4026 : }
4027 : }
4028 : }
4029 : ELSE
4030 : {
4031 : UWord16 decoded_index[MASA_MAXIMUM_CODING_SUBBANDS];
4032 : /* decode joint index */
4033 10792 : nbits = add( nbits, decode_fixed_rate_composed_index_coherence_fx( bitstream, &bit_pos, coding_subbands, no_cv_vec, decoded_index, add( MASA_NO_CV_COH, coding_subbands / MASA_FACTOR_CV_COH ) ) ); /*Q0*/
4034 113069 : FOR( j = 0; j < coding_subbands; j++ )
4035 : {
4036 102277 : IF( GT_16( no_cv_vec[j], 1 ) )
4037 : {
4038 24262 : num = i_mult( decoded_index[j], 255 ); /*Q0*/
4039 24262 : move16();
4040 24262 : den = extract_l( L_add( L_sub( 7, L_shr( q_direction->band_data[j].energy_ratio_index_mod[0], hrmasa_flag ) ), coding_subbands / MASA_FACTOR_CV_COH ) ); /*Q0*/
4041 24262 : q_den = norm_s( den );
4042 24262 : q_num = sub( norm_s( num ), 1 );
4043 24262 : res = div_s( shl( num, q_num ), shl( den, q_den ) ); /*Q15*/
4044 24262 : q_res = add( sub( 15, q_den ), q_num );
4045 24262 : res = L_shl( res, sub( 16, q_res ) ); /*Q16*/
4046 24262 : q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) ( round_fx( res ) ); /*Q0*/
4047 24262 : move16();
4048 : }
4049 : ELSE
4050 : {
4051 78015 : q_direction->coherence_band_data[j].spread_coherence[0] = 0;
4052 78015 : move16();
4053 : }
4054 : }
4055 : }
4056 : }
4057 : ELSE
4058 : {
4059 339115 : FOR( j = 0; j < coding_subbands; j++ )
4060 : {
4061 296527 : IF( hrmasa_flag )
4062 : {
4063 0 : minimum_s( (Word16 *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); /*Q0*/
4064 0 : no_cv_vec[j] = len_cb_dct0_masa[( min_index / 2 )]; /*Q0*/
4065 0 : move16(); /* spread coherence DCT0*/
4066 : }
4067 : ELSE
4068 : {
4069 296527 : no_cv_vec[j] = len_cb_dct0_masa[q_direction->band_data[j].energy_ratio_index[0]]; /*Q0*/
4070 296527 : move16(); /* spread coherence DCT0*/
4071 : }
4072 : }
4073 :
4074 42588 : IF( GT_16( sum16_fx( no_cv_vec, coding_subbands ), MASA_COH_LIMIT_2IDX ) )
4075 : {
4076 : UWord16 spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
4077 :
4078 119 : no_cb = 1;
4079 119 : move64();
4080 1532 : FOR( j = 0; j < shr( coding_subbands, 1 ); j++ )
4081 : {
4082 1413 : no_cb *= no_cv_vec[j];
4083 1413 : move64();
4084 : }
4085 :
4086 119 : no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); Q0
4087 119 : no_cb = 1;
4088 119 : move64();
4089 :
4090 1532 : FOR( j = coding_subbands / 2; j < coding_subbands; j++ )
4091 : {
4092 1413 : no_cb *= no_cv_vec[j];
4093 1413 : move64();
4094 : }
4095 :
4096 119 : no_bits_vec1 = ceil_log_2( no_cb ); // (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); Q0
4097 119 : dct0_index = 0;
4098 119 : move64();
4099 :
4100 3079 : FOR( j = 0; j < no_bits_vec; j++ )
4101 : {
4102 2960 : dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos]; /*Q0*/
4103 2960 : bit_pos = sub( bit_pos, 1 );
4104 2960 : move64();
4105 : }
4106 :
4107 119 : nbits = add( nbits, no_bits_vec );
4108 119 : set_s( (Word16 *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
4109 :
4110 119 : decode_combined_index_fx( dct0_index, no_cv_vec, spr_coh_temp_index, shr( coding_subbands, 1 ) );
4111 :
4112 119 : dct0_index = 0;
4113 119 : move64();
4114 3084 : FOR( j = 0; j < no_bits_vec1; j++ )
4115 : {
4116 2965 : dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos]; /*Q0*/
4117 2965 : bit_pos = sub( bit_pos, 1 );
4118 2965 : move64();
4119 : }
4120 :
4121 119 : nbits = add( nbits, no_bits_vec1 );
4122 :
4123 119 : decode_combined_index_fx( dct0_index, &no_cv_vec[shr( coding_subbands, 1 )], &spr_coh_temp_index[shr( coding_subbands, 1 )], shr( coding_subbands, 1 ) );
4124 :
4125 2945 : FOR( j = 0; j < coding_subbands; j++ )
4126 : {
4127 2826 : q_direction->coherence_band_data[j].spread_coherence_dct0_index = spr_coh_temp_index[j]; /*Q0*/
4128 2826 : move16();
4129 : }
4130 : }
4131 : ELSE
4132 : {
4133 : /* spread coherence */
4134 : UWord16 spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
4135 :
4136 42469 : no_cb = 1;
4137 42469 : move64();
4138 :
4139 336170 : FOR( j = 0; j < coding_subbands; j++ )
4140 : {
4141 293701 : no_cb *= no_cv_vec[j];
4142 293701 : move64();
4143 : }
4144 :
4145 42469 : no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); Q0
4146 :
4147 : /* read joint index for DCT0 */
4148 42469 : no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); Q0
4149 42469 : dct0_index = 0;
4150 42469 : move64();
4151 :
4152 530962 : FOR( j = 0; j < no_bits_vec; j++ )
4153 : {
4154 488493 : dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos]; /*Q0*/
4155 488493 : bit_pos = sub( bit_pos, 1 );
4156 488493 : move64();
4157 : }
4158 :
4159 42469 : nbits = add( nbits, no_bits_vec );
4160 :
4161 42469 : set16_fx( (Word16 *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
4162 :
4163 42469 : decode_combined_index_fx( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands );
4164 :
4165 336170 : FOR( j = 0; j < coding_subbands; j++ )
4166 : {
4167 293701 : q_direction->coherence_band_data[j].spread_coherence_dct0_index = spr_coh_temp_index[j]; /*Q0*/
4168 293701 : move16();
4169 : }
4170 : }
4171 :
4172 : /* read GR data for DCT1 */
4173 339115 : FOR( j = 0; j < coding_subbands; j++ )
4174 : {
4175 296527 : bits_GR = bit_pos;
4176 296527 : idx_dct1[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, shl( MASA_NO_CV_COH1, 1 ), 0 ); /*Q0*/
4177 296527 : move16();
4178 296527 : nbits = add( nbits, sub( bits_GR, bit_pos ) );
4179 : }
4180 42588 : bits_GR = bit_pos;
4181 42588 : move16(); /* just to store the data */
4182 :
4183 : /* read average index */
4184 42588 : read_huf( &bit_pos, bitstream, &av_index, bit_pos, MASA_NO_CV_COH1, huff_code_av_masa, 10 ); /* 10 is MAX_LEN*/
4185 42588 : nbits = add( nbits, sub( bits_GR, bit_pos ) );
4186 :
4187 : /* write indexes in metadata structure */
4188 339115 : FOR( j = 0; j < coding_subbands; j++ )
4189 : {
4190 296527 : IF( L_and( idx_dct1[j], 1 ) )
4191 : {
4192 25731 : q_direction->coherence_band_data[j].spread_coherence_dct1_index = (UWord16) L_add( L_shr( L_add( idx_dct1[j], 1 ), 1 ), av_index ); /*Q0*/
4193 25731 : move16();
4194 : }
4195 : ELSE
4196 : {
4197 270796 : q_direction->coherence_band_data[j].spread_coherence_dct1_index = (UWord16) L_add( L_shr( L_negate( idx_dct1[j] ), 1 ), av_index ); /*Q0*/
4198 270796 : move16();
4199 : }
4200 : }
4201 : }
4202 67563 : nbits = sub( *p_bit_pos, bit_pos );
4203 :
4204 67563 : *p_bit_pos = bit_pos;
4205 67563 : move16();
4206 :
4207 67563 : return nbits;
4208 : }
4209 :
4210 : /*-------------------------------------------------------------------*
4211 : * read_surround_coherence()
4212 : *
4213 : *
4214 : *-------------------------------------------------------------------*/
4215 :
4216 53143 : static Word16 read_surround_coherence(
4217 : UWord16 *bitstream, /* i : bitstream Q0*/
4218 : Word16 *p_bit_pos, /* i : position in the bitstream Q0*/
4219 : IVAS_QMETADATA *hQMetaData /* i/o: quantized metadata structure */
4220 : )
4221 : {
4222 : Word16 coding_subbands;
4223 : Word16 no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS];
4224 : Word16 bit_pos;
4225 : Word32 error_ratio_surr;
4226 : Word16 idx_ER[MASA_MAXIMUM_CODING_SUBBANDS];
4227 : Word16 bits_sur_coherence, bits_GR;
4228 : Word16 j, d, k, idx;
4229 : UWord16 byteBuffer;
4230 : UWord16 idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
4231 : IVAS_QDIRECTION *q_direction;
4232 : Word16 min_index;
4233 :
4234 53143 : coding_subbands = hQMetaData->q_direction[0].cfg.nbands;
4235 53143 : q_direction = hQMetaData->q_direction;
4236 :
4237 53143 : bits_sur_coherence = 0;
4238 53143 : move16();
4239 53143 : bit_pos = *p_bit_pos;
4240 53143 : move16();
4241 :
4242 53143 : d = 0;
4243 53143 : move16();
4244 582890 : FOR( j = 0; j < coding_subbands; j++ )
4245 : {
4246 529747 : error_ratio_surr = ONE_IN_Q30;
4247 529747 : move32();
4248 :
4249 529747 : IF( EQ_16( hQMetaData->no_directions, 2 ) )
4250 : {
4251 164247 : d = add( d, hQMetaData->twoDirBands[j] );
4252 164247 : idx = s_max( sub( d, 1 ), 0 );
4253 164247 : IF( EQ_16( hQMetaData->twoDirBands[j], 1 ) )
4254 : {
4255 52972 : error_ratio_surr = L_sub( L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ), q_direction[1].band_data[idx].energy_ratio_fx[0] ); /*Q30*/
4256 : }
4257 : ELSE
4258 : {
4259 111275 : error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ); /*Q30*/
4260 : }
4261 : }
4262 : ELSE
4263 : {
4264 365500 : error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ); /*Q30*/
4265 : }
4266 :
4267 529747 : IF( error_ratio_surr <= 0 )
4268 : {
4269 390 : error_ratio_surr = 0;
4270 390 : move32();
4271 390 : no_cv_vec[j] = 1;
4272 390 : move16();
4273 390 : idx_ER[j] = masa_sq_fx( 0, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
4274 390 : move16();
4275 : }
4276 : ELSE
4277 : {
4278 529357 : idx_ER[j] = masa_sq_fx( error_ratio_surr, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
4279 529357 : move16();
4280 529357 : no_cv_vec[j] = add( idx_cb_sur_coh_masa[idx_ER[j]], 2 );
4281 529357 : move16();
4282 : }
4283 : }
4284 :
4285 53143 : IF( EQ_16( sum16_fx( no_cv_vec, coding_subbands ), coding_subbands ) )
4286 : {
4287 : /* surround coherence is zero */
4288 0 : FOR( j = 0; j < coding_subbands; j++ )
4289 : {
4290 0 : FOR( k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ )
4291 : {
4292 0 : if ( hQMetaData->surcoh_band_data != NULL )
4293 : {
4294 0 : hQMetaData->surcoh_band_data[j].surround_coherence[k] = 0;
4295 0 : move16();
4296 : }
4297 : }
4298 : }
4299 :
4300 0 : return bits_sur_coherence;
4301 : }
4302 :
4303 : /* read how the surround coherence is encoded */
4304 53143 : byteBuffer = bitstream[bit_pos]; /*Q0*/
4305 53143 : bit_pos = sub( bit_pos, 1 );
4306 53143 : move16();
4307 53143 : bits_sur_coherence = add( bits_sur_coherence, 1 );
4308 :
4309 53143 : IF( L_and( byteBuffer, 1 ) )
4310 : {
4311 : /* GR decoding */
4312 : /* read GR order */
4313 37046 : byteBuffer = bitstream[bit_pos]; /*Q0*/
4314 37046 : bit_pos = sub( bit_pos, 1 );
4315 37046 : bits_sur_coherence = add( bits_sur_coherence, 1 );
4316 :
4317 : /* read min index */
4318 37046 : bits_GR = bit_pos;
4319 37046 : move16();
4320 37046 : min_index = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, MASA_MAX_NO_CV_SUR_COH, 0 ); /*Q0*/
4321 37046 : bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
4322 :
4323 : /* read GR data */
4324 403247 : FOR( j = 0; j < coding_subbands; j++ )
4325 : {
4326 366201 : bits_GR = bit_pos;
4327 366201 : move16();
4328 : /* decoding for min removed */
4329 366201 : IF( GT_16( no_cv_vec[j], 1 ) )
4330 : {
4331 365874 : idx_sur_coh[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, sub( no_cv_vec[j], min_index ), ( byteBuffer & 1 ) ); /*Q30*/
4332 365874 : move16();
4333 365874 : bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
4334 : }
4335 : ELSE
4336 : {
4337 327 : idx_sur_coh[j] = 0;
4338 327 : move16();
4339 : }
4340 : }
4341 :
4342 403247 : FOR( j = 0; j < coding_subbands; j++ )
4343 : {
4344 366201 : IF( GT_16( no_cv_vec[j], 1 ) )
4345 : {
4346 365874 : hQMetaData->surcoh_band_data[j].sur_coherence_index = add( idx_sur_coh[j], min_index ); /*Q0*/
4347 365874 : move16();
4348 : }
4349 : ELSE
4350 : {
4351 327 : hQMetaData->surcoh_band_data[j].sur_coherence_index = idx_sur_coh[j]; /*Q0*/
4352 327 : move16();
4353 : }
4354 :
4355 366201 : hQMetaData->surcoh_band_data[j].surround_coherence[0] = sur_coherence_cb_masa[( ( idx_cb_sur_coh_masa[idx_ER[j]] * 8 ) + hQMetaData->surcoh_band_data[j].sur_coherence_index )]; /*Q0*/
4356 366201 : move16();
4357 : }
4358 : }
4359 : ELSE
4360 : {
4361 : /* fixed rate */
4362 : UWord16 sur_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
4363 16097 : set16_fx( (Word16 *) sur_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
4364 :
4365 16097 : decode_fixed_rate_composed_index_coherence_fx( bitstream, &bit_pos, coding_subbands, no_cv_vec, sur_coh_temp_index, MASA_MAX_NO_CV_SUR_COH );
4366 :
4367 179643 : FOR( j = 0; j < coding_subbands; j++ )
4368 : {
4369 163546 : hQMetaData->surcoh_band_data[j].sur_coherence_index = sur_coh_temp_index[j]; /*Q0*/
4370 163546 : move16();
4371 : }
4372 :
4373 : /* deindex surround coherence */
4374 179643 : FOR( j = 0; j < coding_subbands; j++ )
4375 : {
4376 163546 : IF( GT_16( no_cv_vec[j], 1 ) )
4377 : {
4378 156973 : hQMetaData->surcoh_band_data[j].surround_coherence[0] = sur_coherence_cb_masa[( ( idx_cb_sur_coh_masa[idx_ER[j]] * 8 ) + hQMetaData->surcoh_band_data[j].sur_coherence_index )]; /*Q0*/
4379 156973 : move16();
4380 : }
4381 : ELSE
4382 : {
4383 6573 : hQMetaData->surcoh_band_data[j].surround_coherence[0] = 0;
4384 6573 : move16();
4385 : }
4386 : }
4387 : }
4388 :
4389 582890 : FOR( j = 0; j < coding_subbands; j++ )
4390 : {
4391 2118988 : FOR( k = 1; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ )
4392 : {
4393 1589241 : hQMetaData->surcoh_band_data[j].surround_coherence[k] = hQMetaData->surcoh_band_data[j].surround_coherence[0]; /*Q0*/
4394 1589241 : move16();
4395 : }
4396 : }
4397 :
4398 : /* Replace return value with the actual read bits. bits_sur_coherence might show wrong count at this point. */
4399 53143 : bits_sur_coherence = sub( *p_bit_pos, bit_pos );
4400 53143 : *p_bit_pos = bit_pos;
4401 53143 : move16();
4402 :
4403 53143 : return bits_sur_coherence;
4404 : }
4405 :
4406 :
4407 : /*-------------------------------------------------------------------*
4408 : * read_surround_coherence_hr()
4409 : *
4410 : *
4411 : *-------------------------------------------------------------------*/
4412 5640 : static Word16 read_surround_coherence_hr_fx(
4413 : UWord16 *bitstream, /* i : bitstream Q0*/
4414 : Word16 *p_bit_pos, /* i : position in the bitstream Q0*/
4415 : IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata structure */
4416 : Word64 energy_ratio[][MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] /*Q62*/ )
4417 : {
4418 : Word16 coding_subbands;
4419 : Word16 no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS];
4420 : Word16 bit_pos;
4421 : Word64 error_ratio_surr_fx;
4422 : Word16 idx_ER[MASA_MAXIMUM_CODING_SUBBANDS];
4423 : Word16 bits_sur_coherence, bits_GR;
4424 : Word16 j, k, sf;
4425 : UWord16 byteBuffer;
4426 : UWord16 idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
4427 : // IVAS_QDIRECTION *q_direction;
4428 : Word16 min_index;
4429 : Word16 d, idx;
4430 5640 : coding_subbands = hQMetaData->q_direction[0].cfg.nbands;
4431 : // q_direction = hQMetaData->q_direction;
4432 :
4433 5640 : bits_sur_coherence = 0;
4434 5640 : move16();
4435 5640 : bit_pos = *p_bit_pos;
4436 5640 : move16();
4437 :
4438 22233 : FOR( sf = 0; sf < hQMetaData->q_direction[0].cfg.nblocks; sf++ )
4439 : {
4440 16593 : d = 0;
4441 16593 : move16();
4442 :
4443 411808 : FOR( j = 0; j < coding_subbands; j++ )
4444 : {
4445 395215 : error_ratio_surr_fx = ONE_IN_Q62;
4446 395215 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
4447 : {
4448 124227 : d = add( d, hQMetaData->twoDirBands[j] ); /*Q0*/
4449 124227 : idx = s_max( sub( d, 1 ), 0 );
4450 124227 : error_ratio_surr_fx = W_sub(
4451 : W_sub( ONE_IN_Q62, energy_ratio[0][j][sf] ),
4452 124227 : energy_ratio[1][idx][sf] * hQMetaData->twoDirBands[j] ); /*Q62*/
4453 : }
4454 : ELSE
4455 : {
4456 270988 : error_ratio_surr_fx = W_sub( ONE_IN_Q62, energy_ratio[0][j][sf] ); /*Q62*/
4457 : }
4458 :
4459 395215 : IF( LE_64( error_ratio_surr_fx, ( 461168601842 ) ) ) // 1e-7 in Q62
4460 : {
4461 608 : error_ratio_surr_fx = 0;
4462 608 : move64();
4463 608 : no_cv_vec[j] = 1;
4464 608 : move16();
4465 608 : idx_ER[j] = 0;
4466 608 : move16();
4467 : }
4468 : ELSE
4469 : {
4470 394607 : idx_ER[j] = 7; // masa_sq( error_ratio_surr, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
4471 394607 : no_cv_vec[j] = add( idx_cb_sur_coh_masa[idx_ER[j]], 2 ); /*Q0*/
4472 394607 : move16();
4473 394607 : move16();
4474 : }
4475 : }
4476 :
4477 16593 : IF( EQ_16( sum_s( no_cv_vec, coding_subbands ), coding_subbands ) )
4478 : {
4479 : /* surround coherence is zero */
4480 0 : FOR( j = 0; j < coding_subbands; j++ )
4481 : {
4482 0 : FOR( k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ )
4483 : {
4484 0 : IF( hQMetaData->surcoh_band_data != NULL )
4485 : {
4486 0 : hQMetaData->surcoh_band_data[j].surround_coherence[k] = 0;
4487 0 : move16();
4488 : }
4489 : }
4490 : }
4491 : }
4492 : ELSE
4493 : {
4494 : /* read how the surround coherence is encoded */
4495 16593 : byteBuffer = bitstream[bit_pos]; /*Q0*/
4496 16593 : move16();
4497 16593 : bit_pos = sub( bit_pos, 1 );
4498 16593 : bits_sur_coherence = add( bits_sur_coherence, 1 );
4499 :
4500 16593 : IF( byteBuffer & 1 )
4501 : {
4502 : /* GR decoding */
4503 : /* read GR order */
4504 10598 : byteBuffer = bitstream[bit_pos]; /*Q0*/
4505 10598 : move16();
4506 10598 : bit_pos = sub( bit_pos, 1 );
4507 10598 : bits_sur_coherence = add( bits_sur_coherence, 1 );
4508 :
4509 : /* read min index */
4510 10598 : bits_GR = bit_pos;
4511 10598 : min_index = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, MASA_MAX_NO_CV_SUR_COH, 0 ); /*Q0*/
4512 10598 : bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
4513 :
4514 : /* read GR data */
4515 262943 : FOR( j = 0; j < coding_subbands; j++ )
4516 : {
4517 252345 : bits_GR = bit_pos;
4518 252345 : move16();
4519 : /* decoding for min removed */
4520 252345 : IF( GT_16( no_cv_vec[j], 1 ) )
4521 : {
4522 251863 : idx_sur_coh[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, sub( no_cv_vec[j], min_index ), ( byteBuffer & 1 ) ); /*Q0*/
4523 251863 : move16();
4524 251863 : bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
4525 : }
4526 : ELSE
4527 : {
4528 482 : idx_sur_coh[j] = 0;
4529 482 : move16();
4530 : }
4531 : }
4532 :
4533 262943 : FOR( j = 0; j < coding_subbands; j++ )
4534 : {
4535 252345 : IF( GT_16( no_cv_vec[j], 1 ) )
4536 : {
4537 251863 : hQMetaData->surcoh_band_data[j].sur_coherence_index = (UWord16) L_add( (Word32) idx_sur_coh[j], L_deposit_l( min_index ) ); /*Q0*/
4538 251863 : move16();
4539 251863 : hQMetaData->surcoh_band_data[j].surround_coherence[sf] = sur_coherence_cb_masa[( ( idx_cb_sur_coh_masa[idx_ER[j]] * MASA_MAX_NO_CV_SUR_COH ) + hQMetaData->surcoh_band_data[j].sur_coherence_index )];
4540 251863 : move16();
4541 : }
4542 : ELSE
4543 : {
4544 482 : hQMetaData->surcoh_band_data[j].sur_coherence_index = idx_sur_coh[j]; /*Q0*/
4545 482 : move16();
4546 482 : hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0;
4547 482 : move16();
4548 : }
4549 : }
4550 : }
4551 : ELSE
4552 : {
4553 : /* fixed rate */
4554 : UWord16 sur_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
4555 5995 : set16_fx( (Word16 *) sur_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
4556 :
4557 5995 : decode_fixed_rate_composed_index_coherence_fx( bitstream, &bit_pos, coding_subbands, no_cv_vec, sur_coh_temp_index, MASA_MAX_NO_CV_SUR_COH );
4558 :
4559 148865 : FOR( j = 0; j < coding_subbands; j++ )
4560 : {
4561 142870 : hQMetaData->surcoh_band_data[j].sur_coherence_index = sur_coh_temp_index[j]; /*Q0*/
4562 142870 : move16();
4563 : }
4564 :
4565 : /* deindex surround coherence */
4566 148865 : FOR( j = 0; j < coding_subbands; j++ )
4567 : {
4568 142870 : IF( GT_16( no_cv_vec[j], 1 ) )
4569 : {
4570 142721 : hQMetaData->surcoh_band_data[j].surround_coherence[sf] = sur_coherence_cb_masa[( ( idx_cb_sur_coh_masa[idx_ER[j]] * MASA_MAX_NO_CV_SUR_COH ) + hQMetaData->surcoh_band_data[j].sur_coherence_index )]; /*Q0*/
4571 142721 : move16();
4572 : }
4573 : ELSE
4574 : {
4575 149 : hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0;
4576 149 : move16();
4577 : }
4578 : }
4579 : }
4580 : }
4581 : }
4582 :
4583 : /* Replace return value with the actual read bits. bits_sur_coherence might show wrong count at this point. */
4584 5640 : bits_sur_coherence = sub( *p_bit_pos, bit_pos );
4585 5640 : *p_bit_pos = bit_pos;
4586 5640 : move16();
4587 :
4588 5640 : return bits_sur_coherence;
4589 : }
4590 :
4591 :
4592 : /*-------------------------------------------------------------------*
4593 : * decode_combined_index()
4594 : *
4595 : * Decode combined index into several indexes
4596 : *-------------------------------------------------------------------*/
4597 :
4598 84182 : static void decode_combined_index_fx(
4599 : UWord64 comb_index, /* i : index to be decoded Q0*/
4600 : const Word16 *no_cv_vec, /* i : number of codewords for each element Q0*/
4601 : UWord16 *index, /* o : decoded indexes Q0*/
4602 : const Word16 len /* i : number of elements Q0*/
4603 : )
4604 : {
4605 : Word16 i;
4606 : UWord64 base[MASA_MAXIMUM_CODING_SUBBANDS + 1];
4607 :
4608 84182 : base[0] = 1;
4609 84182 : move64();
4610 704264 : FOR( i = 1; i < len; i++ )
4611 : {
4612 620082 : base[i] = base[i - 1] * no_cv_vec[i - 1];
4613 : }
4614 :
4615 704264 : FOR( i = len - 1; i > 0; i-- )
4616 : {
4617 620082 : index[i] = (UWord16) ( comb_index / base[i] );
4618 620082 : comb_index -= index[i] * base[i];
4619 : }
4620 :
4621 84182 : index[0] = (UWord16) comb_index;
4622 84182 : move16();
4623 :
4624 84182 : return;
4625 : }
4626 :
4627 :
4628 7949 : static void read_stream_dct_coeffs_omasa_fx(
4629 : Word16 *q_idx, /*Q0*/
4630 : Word32 *q_dct_data_fx,
4631 : const Word16 len_stream, /*Q0*/
4632 : UWord16 *bit_stream, /*Q0*/
4633 : Word16 *index, /*Q0*/
4634 : const Word16 first_line /*Q0*/ )
4635 : {
4636 : Word16 sign;
4637 : Word16 i, j, i_min;
4638 : Word32 step;
4639 : Word16 GR1, GR2;
4640 :
4641 7949 : step = STEP_M2T_FX;
4642 7949 : move32();
4643 7949 : move16();
4644 7949 : sign = 1;
4645 7949 : move16();
4646 7949 : IF( !first_line )
4647 : {
4648 : /* read sign */
4649 0 : sign = bit_stream[( *index )--]; /*Q0*/
4650 0 : move16();
4651 0 : IF( !sign )
4652 : {
4653 0 : sign = -1;
4654 0 : move16();
4655 : }
4656 : }
4657 :
4658 7949 : set16_fx( q_idx, 0, len_stream );
4659 : /* read DCT 0 component */
4660 55643 : FOR( i = 0; i < BITS_MASA2TOTTAL_DCT0; i++ )
4661 : {
4662 47694 : q_idx[0] = add( shl( q_idx[0], 1 ), bit_stream[( *index )--] ); /*Q0*/
4663 47694 : move16();
4664 : }
4665 7949 : q_idx[0] = i_mult( q_idx[0], sign ); /*Q0*/
4666 7949 : move16();
4667 :
4668 7949 : IF( q_idx[0] != 0 )
4669 : {
4670 7139 : IF( GE_16( len_stream, 8 ) )
4671 : {
4672 : /* read index of last index encoded with GR2 */
4673 5655 : i_min = 0;
4674 5655 : move16();
4675 5655 : j = 4;
4676 5655 : move16();
4677 28275 : FOR( i = 0; i < j; i++ )
4678 : {
4679 22620 : i_min = extract_l( L_add( shl( i_min, 1 ), bit_stream[( *index )--] ) ); /*Q0*/
4680 : }
4681 :
4682 : /* read GR orders */
4683 5655 : GR1 = extract_l( L_add( bit_stream[( *index )--], 1 ) ); /*Q0*/
4684 5655 : IF( EQ_16( GR1, 2 ) )
4685 : {
4686 2435 : GR2 = bit_stream[( *index )--]; /*Q0*/
4687 2435 : move16();
4688 : }
4689 : ELSE
4690 : {
4691 3220 : GR2 = 0;
4692 3220 : move16();
4693 : }
4694 :
4695 : /* read GR data */
4696 24292 : FOR( i = 1; i <= i_min; i++ )
4697 : {
4698 18637 : q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 ); /*Q0*/
4699 18637 : move16();
4700 : }
4701 73415 : FOR( i = ( i_min + 1 ); i < len_stream; i++ )
4702 : {
4703 67760 : q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR2 ); /*Q0*/
4704 67760 : move16();
4705 : }
4706 : }
4707 : ELSE
4708 : {
4709 : /* read GR order (only one) */
4710 1484 : GR1 = bit_stream[( *index )]; /*Q0*/
4711 1484 : move16();
4712 1484 : ( *index ) = sub( ( *index ), 1 );
4713 1484 : move16();
4714 7358 : FOR( i = 1; i < len_stream; i++ )
4715 : {
4716 5874 : q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 ); /*Q0*/
4717 5874 : move16();
4718 : }
4719 : }
4720 : }
4721 :
4722 : /* deindex */
4723 7949 : q_dct_data_fx[0] = L_shl( Mpy_32_16_1( step, shl( q_idx[0], 7 ) ), 2 ); // q = 25
4724 7949 : move32();
4725 111851 : FOR( i = 1; i < len_stream; i++ )
4726 : {
4727 103902 : IF( s_and( q_idx[i], 1 ) == 0 )
4728 : {
4729 83321 : q_dct_data_fx[i] = L_shl( Mpy_32_16_1( step, negate( shl( q_idx[i], 6 ) ) ), 2 ); /*Q25*/
4730 83321 : move32();
4731 : }
4732 : ELSE
4733 : {
4734 20581 : q_dct_data_fx[i] = L_shl( Mpy_32_16_1( step, shl( q_idx[i] + 1, 6 ) ), 2 ); /*Q25*/
4735 20581 : move32();
4736 : }
4737 : }
4738 :
4739 7949 : return;
4740 : }
4741 :
4742 :
4743 : /*-------------------------------------------------------------------------
4744 : * ivas_omasa_decode_masa_to_total()
4745 : *
4746 : *------------------------------------------------------------------------*/
4747 :
4748 7949 : void ivas_omasa_decode_masa_to_total_fx(
4749 : UWord16 *bit_stream, /*Q0*/
4750 : Word16 *index, /*Q0*/
4751 : Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*Q30*/
4752 : const Word16 nbands, /*Q0*/
4753 : const Word16 nblocks /*Q0*/ )
4754 : {
4755 : Word16 i, j, k;
4756 : Word16 q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
4757 : Word32 q_dct_data_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS], // q = 25
4758 : dct_data_tmp_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; // q = 25
4759 : Word16 n_streams, len_stream;
4760 :
4761 : /* Setup coding parameters */
4762 7949 : n_streams = 1;
4763 7949 : move16();
4764 7949 : len_stream = i_mult( nbands, nblocks );
4765 7949 : IF( EQ_16( len_stream, 32 ) )
4766 : {
4767 0 : n_streams = 4;
4768 0 : move16();
4769 0 : len_stream = 8;
4770 0 : move16();
4771 : }
4772 :
4773 7949 : set16_fx( q_idx, 0, i_mult( nbands, nblocks ) );
4774 15898 : FOR( i = 0; i < n_streams; i++ )
4775 : {
4776 7949 : read_stream_dct_coeffs_omasa_fx( &q_idx[( i * len_stream )], &q_dct_data_fx[( i * len_stream )], len_stream, bit_stream, index, i == 0 );
4777 : }
4778 :
4779 : /* inverse DCT2 transform */
4780 7949 : SWITCH( len_stream )
4781 : {
4782 63 : case 4:
4783 63 : matrix_product_q30_fx( dct4_fx, nblocks, nblocks, 1, q_dct_data_fx, nblocks, 1, 0, dct_data_tmp_fx );
4784 63 : Copy32( dct_data_tmp_fx, q_dct_data_fx, nblocks ); /*Q30*/
4785 63 : BREAK;
4786 1535 : case 5:
4787 1535 : matrix_product_q30_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
4788 1535 : Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
4789 1535 : BREAK;
4790 0 : case 8:
4791 0 : matrix_product_q30_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
4792 0 : Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
4793 0 : BREAK;
4794 2887 : case 12:
4795 2887 : matrix_product_q30_fx( dct12_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
4796 2887 : Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
4797 2887 : BREAK;
4798 3464 : case 20:
4799 3464 : matrix_product_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx );
4800 3464 : matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx ); /* reuse of variable*/
4801 3464 : BREAK;
4802 0 : case 32:
4803 0 : matrix_product_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx );
4804 0 : matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx );
4805 0 : BREAK;
4806 0 : default:
4807 0 : printf( "Incorrect number of coefficients for OMASA.\n" );
4808 0 : BREAK;
4809 : }
4810 7949 : k = 0;
4811 7949 : move16();
4812 26479 : FOR( i = 0; i < nblocks; i++ )
4813 : {
4814 130381 : FOR( j = 0; j < nbands; j++ )
4815 : {
4816 111851 : masa_to_total_energy_ratio_fx[i][j] = L_max( 0, q_dct_data_fx[k] ); // Q30
4817 111851 : move32();
4818 111851 : masa_to_total_energy_ratio_fx[i][j] = L_min( ONE_IN_Q30, masa_to_total_energy_ratio_fx[i][j] ); /*Q30*/
4819 111851 : move32();
4820 111851 : k = add( k, 1 );
4821 : }
4822 : }
4823 :
4824 7949 : IF( EQ_16( nblocks, 1 ) )
4825 : {
4826 17688 : FOR( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
4827 : {
4828 140223 : FOR( j = 0; j < nbands; j++ )
4829 : {
4830 126957 : masa_to_total_energy_ratio_fx[i][j] = masa_to_total_energy_ratio_fx[0][j]; /*Q30*/
4831 126957 : move32();
4832 : }
4833 : }
4834 : }
4835 :
4836 7949 : IF( EQ_16( nbands, 1 ) )
4837 : {
4838 315 : FOR( j = 1; j < 5; j++ )
4839 : {
4840 1260 : FOR( i = 0; i < nblocks; i++ )
4841 : {
4842 1008 : masa_to_total_energy_ratio_fx[i][j] = masa_to_total_energy_ratio_fx[i][0]; /*Q30*/
4843 1008 : move32();
4844 : }
4845 : }
4846 : }
4847 :
4848 7949 : return;
4849 : }
|