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 193697 : 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 193697 : ec_flag = 0;
124 193697 : move16();
125 193697 : start_index_0 = *index;
126 193697 : move16();
127 :
128 : /*Coherence flag decoding*/
129 193697 : bits_no_dirs_coh = 0;
130 193697 : move16();
131 193697 : all_coherence_zero = 1;
132 193697 : move16();
133 :
134 193697 : IF( hQMetaData->coherence_flag )
135 : {
136 : /* read if coherence is zero */
137 27110 : all_coherence_zero = bitstream[( *index )--]; /*Q0*/
138 27110 : move16();
139 27110 : bits_no_dirs_coh = add( bits_no_dirs_coh, 1 );
140 : }
141 :
142 193697 : hQMetaData->all_coherence_zero = (UWord8) all_coherence_zero;
143 :
144 193697 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
145 : {
146 : /* Read which bands have 2 directions */
147 20104 : hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands; /*Q0*/
148 20104 : move16();
149 20104 : set_c( (Word8 *) hQMetaData->twoDirBands, 0, hQMetaData->q_direction[0].cfg.nbands );
150 20104 : d = *index;
151 20104 : move16();
152 20104 : dif_p[0] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
153 20104 : move16();
154 20104 : p[0] = dif_p[0]; /*Q0*/
155 20104 : move16();
156 20104 : hQMetaData->twoDirBands[p[0]] = 1;
157 20104 : move16();
158 188763 : FOR( b = 1; b < hQMetaData->numTwoDirBands; b++ )
159 : {
160 168659 : dif_p[b] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
161 168659 : move16();
162 168659 : p[b] = add( add( p[b - 1], dif_p[b] ), 1 );
163 168659 : move16();
164 168659 : hQMetaData->twoDirBands[p[b]] = 1;
165 168659 : move16();
166 : }
167 20104 : bits_no_dirs_coh = add( bits_no_dirs_coh, sub( d, *index ) );
168 : }
169 :
170 193697 : bits_diff_sum = 0;
171 193697 : move16();
172 193697 : 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 193697 : IF( hodirac_flag )
175 : {
176 16051 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
177 : {
178 : /* Calculate bits for dfRatio */
179 16051 : dir2band = 0;
180 16051 : move16();
181 192612 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
182 : {
183 176561 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
184 : {
185 176561 : dfRatio_bits[dir2band] = ivas_get_df_ratio_bits_hodirac_fx( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); /*Q0*/
186 176561 : move16();
187 176561 : dir2band = add( dir2band, 1 );
188 : }
189 : }
190 :
191 16051 : 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 177646 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
197 : {
198 : /* Calculate bits for dfRatio */
199 4053 : dir2band = 0;
200 4053 : move16();
201 40541 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
202 : {
203 36488 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
204 : {
205 12202 : dfRatio_bits[dir2band] = ivas_get_df_ratio_bits_fx( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); /*Q0*/
206 12202 : move16();
207 12202 : dir2band = add( dir2band, 1 );
208 : }
209 : }
210 :
211 4053 : 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 193697 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
217 : {
218 20104 : dir2band = 0;
219 20104 : move16();
220 233153 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
221 : {
222 213049 : 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 188763 : diffRatio_fx = diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; // Q30
229 188763 : move32();
230 :
231 188763 : dfRatio_qsteps = shl( 1, dfRatio_bits[dir2band] ); /*1 << dfRatio_bits[dir2band]*/
232 : /* already encoded as total and ratios in HO-DirAC */
233 188763 : IF( hodirac_flag )
234 : {
235 176561 : dfRatio_fx = usdequant32_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], 0 /* Q15 */, inv_dfRatio_qsteps[dfRatio_qsteps] ); // Q31
236 176561 : dir1ratio_fx = L_sub( ONE_IN_Q30, diffRatio_fx );
237 176561 : dir2ratio_fx = L_shr( dfRatio_fx, 1 ); /*Q30*/
238 : }
239 : ELSE
240 : {
241 12202 : IF( EQ_16( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], sub( dfRatio_qsteps, 1 ) ) )
242 : {
243 461 : dfRatio_fx = MAX_32; // Q31
244 461 : move16();
245 461 : dir1ratio_fx = L_sub( ONE_IN_Q30, diffRatio_fx ); // Q30
246 : }
247 : ELSE
248 : {
249 11741 : 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 11741 : dir1ratio_fx = Mpy_32_32( L_sub( ONE_IN_Q30, diffRatio_fx ), dfRatio_fx ); // Q30
251 : }
252 :
253 12202 : 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 188763 : 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 188763 : move16();
260 188763 : IF( hodirac_flag )
261 : {
262 : Word16 tmp_fx;
263 176561 : 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 176561 : move16();
265 : }
266 : ELSE
267 : {
268 12202 : 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 12202 : move16();
270 : }
271 :
272 934896 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
273 : {
274 746133 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = dir1ratio_fx; // Q30
275 746133 : move32();
276 746133 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
277 746133 : move16();
278 : }
279 :
280 934896 : FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
281 : {
282 746133 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[m] = dir2ratio_fx; /*Q30*/
283 746133 : move32();
284 746133 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[m] = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0]; /*Q0*/
285 746133 : move16();
286 : }
287 :
288 188763 : dir2band = add( dir2band, 1 );
289 : }
290 : ELSE
291 : {
292 : /* 1dir band */
293 24286 : 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 24286 : move32();
295 65275 : FOR( m = 1; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
296 : {
297 40989 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0]; /*Q30*/
298 40989 : move32();
299 40989 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
300 40989 : 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 813693 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
309 : {
310 640100 : 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 640100 : move32();
312 2068631 : FOR( m = 1; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
313 : {
314 1428531 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0]; /*Q30*/
315 1428531 : move32();
316 1428531 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
317 1428531 : 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 193697 : bits_dir_raw_pre[0] = 0;
325 193697 : move16();
326 193697 : bits_dir_raw_pre[1] = 0;
327 193697 : move16();
328 193697 : dir2band = 0;
329 193697 : move16();
330 1046846 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
331 : {
332 853149 : test();
333 853149 : IF( EQ_32( hQMetaData->no_directions, 2 ) && EQ_16( hQMetaData->twoDirBands[b], 1 ) )
334 188763 : {
335 : Word16 index_dirRatio1Inv, index_dirRatio2Inv, index_dirRatio1Inv_mod, index_dirRatio2Inv_mod;
336 :
337 188763 : index_dirRatio1Inv = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
338 188763 : move16();
339 188763 : index_dirRatio2Inv = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0]; /*Q0*/
340 188763 : move16();
341 :
342 188763 : masa_compensate_two_dir_energy_ratio_index_fx( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod, hodirac_flag );
343 :
344 934896 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
345 : {
346 746133 : hQMetaData->q_direction[0].band_data[b].energy_ratio_index_mod[m] = index_dirRatio1Inv_mod; /*Q0*/
347 746133 : move16();
348 746133 : hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] = bits_direction_masa[index_dirRatio1Inv_mod]; /*Q0*/
349 746133 : move16();
350 746133 : bits_dir_raw_pre[0] = add( bits_dir_raw_pre[0], hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] );
351 746133 : move16();
352 : }
353 :
354 934896 : FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
355 : {
356 746133 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index_mod[m] = index_dirRatio2Inv_mod; /*Q0*/
357 746133 : move16();
358 746133 : hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[m] = bits_direction_masa[index_dirRatio2Inv_mod]; /*Q0*/
359 746133 : move16();
360 746133 : bits_dir_raw_pre[1] = add( bits_dir_raw_pre[1], hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[m] );
361 746133 : move16();
362 : }
363 :
364 188763 : dir2band = add( dir2band, 1 );
365 : }
366 : ELSE
367 : {
368 2798292 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
369 : {
370 2133906 : 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 2133906 : move16();
372 2133906 : 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 2133906 : move16();
374 2133906 : bits_dir_raw_pre[0] = add( bits_dir_raw_pre[0], hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] );
375 2133906 : move16();
376 : }
377 : }
378 : }
379 :
380 193697 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
381 : {
382 20104 : 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 20104 : 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 20104 : test();
385 20104 : IF( !all_coherence_zero && GE_32( tmp32, L_deposit_h( MASA_MIN_BITS_SURR_COH ) ) )
386 : {
387 4053 : bits_sur_coherence = read_surround_coherence( bitstream, index, hQMetaData ); /*Q0*/
388 : }
389 : ELSE
390 : {
391 16051 : bits_sur_coherence = 0;
392 16051 : move16();
393 : /*Surround coherence*/
394 192612 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
395 : {
396 176561 : IF( hQMetaData->surcoh_band_data != NULL )
397 : {
398 0 : set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
399 : }
400 : }
401 : }
402 20104 : bits_no_dirs_coh = add( bits_no_dirs_coh, bits_sur_coherence );
403 20104 : 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 173593 : no_TF = i_mult2( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ); /*Q0*/
408 173593 : 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 173593 : test();
410 173593 : IF( !all_coherence_zero && GE_32( tmp32, L_deposit_h( MASA_MIN_BITS_SURR_COH ) ) )
411 : {
412 21785 : bits_sur_coherence = read_surround_coherence( bitstream, index, hQMetaData ); /*Q0*/
413 : }
414 : ELSE
415 : {
416 151808 : bits_sur_coherence = 0;
417 151808 : move16();
418 : /*Surround coherence*/
419 637854 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
420 : {
421 486046 : IF( hQMetaData->surcoh_band_data != NULL )
422 : {
423 14417 : set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
424 : }
425 : }
426 : }
427 173593 : bits_no_dirs_coh = add( bits_no_dirs_coh, bits_sur_coherence );
428 :
429 173593 : total_bits_1dir = sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh );
430 : }
431 :
432 193697 : bits_dir_target = 0;
433 193697 : move16();
434 193697 : bits_dir_used = 0;
435 193697 : move16();
436 :
437 407498 : FOR( d = 0; d < hQMetaData->no_directions; d++ )
438 : {
439 213801 : q_direction = &hQMetaData->q_direction[d];
440 213801 : nbands = q_direction->cfg.nbands; /*Q0*/
441 213801 : move16();
442 213801 : nblocks = q_direction->cfg.nblocks; /*Q0*/
443 213801 : move16();
444 213801 : start_band = q_direction->cfg.start_band; /*Q0*/
445 213801 : move16();
446 :
447 213801 : diffuseness_index_max_ec_frame = diffuseness_index_max_ec_frame_pre[0]; /*Q0*/
448 213801 : move16();
449 213801 : IF( d == 0 )
450 : {
451 193697 : bits_diff = bits_diff_sum; /*Q0*/
452 193697 : move16();
453 : }
454 : ELSE
455 : {
456 20104 : bits_diff = 0;
457 20104 : move16();
458 : }
459 213801 : bits_dir_raw = bits_dir_raw_pre[d]; /*Q0*/
460 213801 : move16();
461 :
462 : /* Read coherence, if any */
463 213801 : bits_coherence = 0;
464 213801 : move16();
465 :
466 213801 : IF( all_coherence_zero == 0 )
467 : {
468 30043 : bits_coherence = read_coherence_data_fx( bitstream, index, hQMetaData, d, 0 ); /*Q0*/
469 : }
470 : ELSE
471 : {
472 : /*Surround coherence*/
473 1022166 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
474 : {
475 838408 : IF( hQMetaData->surcoh_band_data != NULL )
476 : {
477 13657 : set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
478 : }
479 :
480 838408 : IF( hQMetaData->q_direction[d].coherence_band_data != NULL )
481 : {
482 13657 : 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 213801 : q_direction->not_in_2D = bitstream[( *index )--]; /*Q0*/
489 213801 : move16();
490 213801 : signal_bits = 1;
491 213801 : move16();
492 :
493 : /* Read EC signaling */
494 213801 : ec_flag = 0;
495 213801 : move16();
496 213801 : IF( LE_16( add( total_bits_1dir, bits_sur_coherence ), hQMetaData->qmetadata_max_bit_req ) )
497 : {
498 148589 : ec_flag = bitstream[( *index )];
499 148589 : move16();
500 148589 : ( *index ) = sub( ( *index ), 1 );
501 148589 : move16();
502 148589 : signal_bits = add( signal_bits, 1 );
503 148589 : IF( GT_16( nblocks, 1 ) )
504 : {
505 111934 : IF( ec_flag )
506 : {
507 7345 : ec_flag = add( ec_flag, (Word16) bitstream[( *index )--] );
508 7345 : signal_bits = add( signal_bits, 1 );
509 : }
510 : }
511 : }
512 :
513 : /* Decode quantized directions frame-wise */
514 213801 : test();
515 213801 : IF( !ec_flag ) /* EC 1*/
516 : {
517 203192 : bits_dir = 0;
518 203192 : move16();
519 203192 : raw_flag[0] = bitstream[( *index )--]; /*Q0*/
520 203192 : move16();
521 203192 : bits_dir = add( bits_dir, 1 );
522 :
523 203192 : IF( !raw_flag[0] )
524 : {
525 108134 : 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 95058 : 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 10609 : ELSE IF( EQ_16( ec_flag, 1 ) && GT_16( nblocks, 1 ) ) /* EC2 */
534 : {
535 2179 : bits_dir = 0;
536 2179 : move16();
537 10606 : FOR( b = start_band; b < nbands; b++ )
538 : {
539 8427 : raw_flag[b] = bitstream[( *index )--]; /*Q0*/
540 8427 : move16();
541 8427 : bits_dir = add( bits_dir, 1 );
542 : }
543 :
544 : /* Read EC bits*/
545 2179 : diff_bits = add( bits_diff, add( bits_coherence, sub( signal_bits, total_bits_1dir ) ) );
546 :
547 10606 : FOR( b = start_band; b < nbands; b++ )
548 : {
549 8427 : IF( !raw_flag[b] )
550 : {
551 3067 : 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 5360 : diff_bits = add( diff_bits, q_direction->band_data[b].bits_sph_idx[0] * q_direction->cfg.nblocks );
556 : }
557 : }
558 2179 : diff_bits = add( diff_bits, bits_dir );
559 :
560 : /* Small requantization?*/
561 2179 : 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 10339 : FOR( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
568 : {
569 41035 : FOR( j = 0; j < q_direction->cfg.nblocks; j++ )
570 : {
571 32828 : bits_temp[i][j] = q_direction->band_data[i].bits_sph_idx[j]; /*Q0*/
572 32828 : move16();
573 : }
574 : }
575 :
576 2132 : small_reduction_direction_fx( q_direction, bits_temp, raw_flag, &diff_bits );
577 :
578 10339 : FOR( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
579 : {
580 41035 : FOR( j = 0; j < q_direction->cfg.nblocks; j++ )
581 : {
582 32828 : q_direction->band_data[i].bits_sph_idx[j] = bits_temp[i][j]; /*Q0*/
583 32828 : move16();
584 : }
585 : }
586 : }
587 :
588 : /* Read raw-coded bits*/
589 10606 : FOR( b = start_band; b < nbands; b++ )
590 : {
591 8427 : IF( raw_flag[b] )
592 : {
593 5360 : 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 8430 : ec_flag = 2;
602 8430 : move16();
603 :
604 8430 : IF( hQMetaData->is_masa_ivas_format == 0 )
605 : {
606 3146 : reduce_bits = sub( bits_dir_raw, sub( sub( sub( total_bits_1dir, bits_diff ), bits_coherence ), signal_bits ) ); /*Q0*/
607 3146 : ind_order[0] = -1;
608 3146 : move16();
609 : }
610 : ELSE
611 : {
612 5284 : ind_order[0] = 0;
613 5284 : move16();
614 5284 : 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 5284 : IF( GT_16( reduce_bits, sub( bits_dir_raw, i_mult2( nbands, nblocks ) ) ) )
616 : {
617 75 : reduce_bits = sub( bits_dir_raw, i_mult2( nbands, nblocks ) );
618 : }
619 : }
620 8430 : only_reduce_bits_direction_fx( &dummy, q_direction, reduce_bits, nbands, nblocks, ind_order );
621 :
622 : /* Read directions */
623 8430 : bits_dir = read_directions_fx( q_direction, (UWord8) nbands, (UWord8) nblocks, bitstream, index, ind_order ); /*Q0*/
624 : }
625 :
626 213801 : IF( bits_coherence > 0 )
627 : {
628 29177 : IF( GT_16( nblocks, 1 ) )
629 : {
630 21931 : decode_spread_coherence_fx( hQMetaData, d, nblocks, 0 );
631 : }
632 : }
633 : ELSE
634 : {
635 1027071 : FOR( b = start_band; b < nbands; b++ )
636 : {
637 842447 : IF( q_direction->coherence_band_data != NULL )
638 : {
639 17696 : set_c( (Word8 *) q_direction->coherence_band_data[b].spread_coherence, 0, nblocks );
640 : }
641 : }
642 : }
643 213801 : IF( d == 0 )
644 : {
645 193697 : total_bits_1dir = sub( hQMetaData->metadata_max_bits, sub( start_index_0, *index ) ); /*Q0*/
646 : }
647 :
648 213801 : bits_dir_target = add( bits_dir_target, bits_dir_raw );
649 213801 : bits_dir_used = add( bits_dir_used, bits_dir );
650 : }
651 : /* move 2 dir data to its correct subband */
652 193697 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
653 : {
654 20104 : d = sub( hQMetaData->q_direction[1].cfg.nbands, 1 );
655 20104 : nblocks = hQMetaData->q_direction[0].cfg.nblocks;
656 20104 : move16();
657 :
658 233153 : FOR( b = hQMetaData->q_direction[0].cfg.nbands - 1; b >= 0; b-- )
659 : {
660 213049 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
661 : {
662 188763 : Copy32( hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].band_data[b].azimuth_fx, nblocks ); /*Q22*/
663 188763 : Copy32( hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].band_data[b].elevation_fx, nblocks ); /*Q22*/
664 188763 : 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 188763 : IF( LT_32( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0], 7 ) )
667 : {
668 660154 : FOR( m = 0; m < nblocks; m++ )
669 : {
670 526439 : Word32 a1 = hQMetaData->q_direction[1].band_data[b].azimuth_fx[m]; /*Q22*/
671 526439 : move32();
672 526439 : a1 = L_shr( hQMetaData->q_direction[1].band_data[b].azimuth_fx[m], 1 ); /*Q21*/
673 526439 : Word32 b1 = hQMetaData->q_direction[0].band_data[b].azimuth_fx[m]; /*Q22*/
674 526439 : move32();
675 526439 : b1 = L_shr( hQMetaData->q_direction[0].band_data[b].azimuth_fx[m], 1 ); /*Q21*/
676 526439 : Word32 c = L_shr( DEGREE_180_Q_22, 1 ); /*Q21*/
677 526439 : a1 = L_add( a1, L_sub( b1, c ) );
678 526439 : 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 526439 : IF( LT_32( a1, L_shr( -DEGREE_180_Q_22, 1 ) ) )
683 : {
684 44393 : a1 = L_add( a1, L_shr( DEGREE_360_Q_22, 1 ) ); /*Q21*/
685 : }
686 :
687 526439 : hQMetaData->q_direction[1].band_data[b].azimuth_fx[m] = L_shl( a1, 1 ); /*Q22*/
688 526439 : move32();
689 : }
690 : }
691 :
692 188763 : IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
693 : {
694 12202 : 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 188763 : d = sub( d, 1 );
697 : }
698 : ELSE
699 : {
700 24286 : set32_fx( hQMetaData->q_direction[1].band_data[b].azimuth_fx, 0, nblocks );
701 24286 : set32_fx( hQMetaData->q_direction[1].band_data[b].elevation_fx, 0, nblocks );
702 24286 : set32_fx( hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, 0, nblocks );
703 :
704 24286 : IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
705 : {
706 24286 : 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 20104 : IF( hodirac_flag == 0 )
713 : {
714 40541 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
715 : {
716 : Word32 ratioSum_flt_fx;
717 :
718 36488 : 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 36488 : 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 193697 : hQMetaData->ec_flag = ec_flag;
731 193697 : move16();
732 :
733 193697 : IF( GT_16( bits_dir_used, bits_dir_target ) )
734 : {
735 76088 : hQMetaData->dir_comp_ratio_fx = MAX_WORD16; /*Q15*/
736 76088 : move16();
737 : }
738 : ELSE
739 : {
740 117609 : hQMetaData->dir_comp_ratio_fx = divide3232( bits_dir_used, bits_dir_target ); /*Q15*/
741 : }
742 193697 : 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 2239 : 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 2239 : sf_nbands1 = 1;
769 2239 : move16();
770 : Word64 W_nrg_ratio[2][MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
771 :
772 2239 : start_index_0 = *index;
773 2239 : move16();
774 : /* read number of higher inactive/not encoded bands */
775 2239 : IF( bitstream[( *index )--] )
776 : {
777 285 : codedBands = sub( sub( MASA_MAXIMUM_CODING_SUBBANDS, ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 1 ) ), 1 ); /*Q0*/
778 : }
779 : ELSE
780 : {
781 1954 : codedBands = MASA_MAXIMUM_CODING_SUBBANDS; /*Q0*/
782 1954 : move16();
783 : }
784 2524 : FOR( b = codedBands; b < ncoding_bands_config; b++ )
785 : {
786 1425 : FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ )
787 : {
788 :
789 1140 : hQMetaData->q_direction[0].band_data[b].azimuth_fx[m] = 0;
790 1140 : move32();
791 1140 : hQMetaData->q_direction[0].band_data[b].elevation_fx[m] = 0;
792 1140 : move32();
793 1140 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = 0;
794 1140 : move32();
795 1140 : W_nrg_ratio[0][b][m] = 0;
796 1140 : move64();
797 :
798 1140 : test();
799 1140 : IF( hQMetaData->coherence_flag && hQMetaData->q_direction[0].coherence_band_data != NULL )
800 : {
801 1140 : hQMetaData->q_direction[0].coherence_band_data[b].spread_coherence[m] = 0u;
802 1140 : move16();
803 : }
804 :
805 1140 : 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 1140 : test();
826 1140 : IF( hQMetaData->coherence_flag && hQMetaData->surcoh_band_data != NULL )
827 : {
828 1140 : hQMetaData->surcoh_band_data[b].surround_coherence[m] = 0u;
829 1140 : move16();
830 : }
831 : }
832 :
833 285 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
834 : {
835 285 : hQMetaData->twoDirBands[b] = 0;
836 285 : move16();
837 : }
838 : }
839 2239 : sf_nbands0 = hQMetaData->q_direction[0].cfg.nbands; /*Q0*/
840 2239 : move16();
841 :
842 2239 : hQMetaData->q_direction[0].cfg.nbands = codedBands; /*Q0*/
843 2239 : move16();
844 :
845 : /*Coherence flag decoding*/
846 2239 : all_coherence_zero = 1;
847 2239 : move16();
848 2239 : IF( hQMetaData->coherence_flag )
849 : {
850 : /* read if coherence is zero */
851 2239 : all_coherence_zero = bitstream[( *index )--]; /*Q0*/
852 2239 : move16();
853 : }
854 :
855 2239 : hQMetaData->all_coherence_zero = (UWord8) all_coherence_zero; /*Q0*/
856 :
857 2239 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
858 : {
859 1239 : set_c( (Word8 *) hQMetaData->twoDirBands, 1, hQMetaData->q_direction[0].cfg.nbands );
860 : }
861 :
862 2239 : test();
863 2239 : IF( EQ_16( bits_sph_idx, 11 ) && EQ_32( hQMetaData->no_directions, 2 ) )
864 : {
865 : /* Read which bands have 2 directions */
866 859 : hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands; /*Q0*/
867 859 : move16();
868 859 : sf_nbands1 = hQMetaData->q_direction[1].cfg.nbands; /*Q0*/
869 859 : move16();
870 859 : 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 859 : set_c( (Word8 *) hQMetaData->twoDirBands, 0, hQMetaData->q_direction[0].cfg.nbands );
876 859 : d = *index;
877 859 : move16();
878 859 : dif_p[0] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
879 859 : move16();
880 859 : p[0] = dif_p[0];
881 859 : move16();
882 859 : hQMetaData->twoDirBands[p[0]] = 1;
883 859 : move16();
884 8154 : FOR( b = 1; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
885 : {
886 7295 : dif_p[b] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
887 7295 : move16();
888 7295 : p[b] = add( add( p[b - 1], dif_p[b] ), 1 );
889 7295 : move16();
890 7295 : hQMetaData->twoDirBands[p[b]] = 1;
891 7295 : move16();
892 : }
893 : }
894 :
895 2239 : test();
896 2239 : IF( EQ_16( bits_sph_idx, 16 ) && EQ_32( hQMetaData->no_directions, 2 ) )
897 : {
898 380 : sf_nbands1 = hQMetaData->q_direction[1].cfg.nbands; /*Q0*/
899 380 : move16();
900 380 : 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 2239 : ivas_qmetadata_entropy_decode_diffuseness_hr_512( bitstream, index, &( hQMetaData->q_direction[0] ) );
907 :
908 2239 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
909 : {
910 1239 : ivas_qmetadata_entropy_decode_diffuseness_hr_512( bitstream, index, &( hQMetaData->q_direction[1] ) );
911 : }
912 :
913 :
914 55690 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
915 : {
916 257526 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
917 : {
918 204075 : 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 204075 : move64();
920 : }
921 : }
922 2239 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
923 : {
924 : Word32 ratioSum;
925 1239 : IF( EQ_16( bits_sph_idx, 16 ) )
926 : {
927 9500 : FOR( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
928 : {
929 45600 : FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
930 : {
931 36480 : 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 36480 : move64();
933 :
934 : /* Scale energy ratios that sum to over one */
935 36480 : ratioSum = W_round64_L( W_add( W_nrg_ratio[0][b][m], W_nrg_ratio[1][b][m] ) ); /*Q30*/
936 :
937 36480 : IF( GT_32( ratioSum, ONE_IN_Q30 ) )
938 : {
939 1294 : W_nrg_ratio[0][b][m] = W_shl( (Word64) ( W_nrg_ratio[0][b][m] / ratioSum ), 30 ); // Q62
940 1294 : move64();
941 1294 : W_nrg_ratio[1][b][m] = W_shl( (Word64) ( W_nrg_ratio[1][b][m] / ratioSum ), 30 ); // Q62
942 1294 : move64();
943 : }
944 : }
945 : }
946 : }
947 : ELSE
948 : {
949 : Word16 pos_2dir_band[MASA_MAXIMUM_CODING_SUBBANDS];
950 859 : d = 0;
951 859 : move16();
952 21190 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
953 : {
954 20331 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
955 : {
956 8154 : pos_2dir_band[d] = b; /*Q0*/
957 8154 : move16();
958 8154 : d = add( d, 1 );
959 : }
960 : ELSE
961 : {
962 12177 : pos_2dir_band[d] = 0;
963 12177 : move16();
964 : }
965 : }
966 9013 : FOR( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
967 : {
968 35694 : FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
969 : {
970 :
971 27540 : 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 27540 : move64();
973 :
974 27540 : ratioSum = W_round64_L( W_add( W_nrg_ratio[0][pos_2dir_band[b]][m], W_nrg_ratio[1][b][m] ) ); /*Q30*/
975 :
976 27540 : IF( GT_32( ratioSum, ONE_IN_Q30 ) )
977 : {
978 324 : 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 324 : move64();
980 324 : W_nrg_ratio[1][b][m] = W_shl( (Word64) ( W_nrg_ratio[1][b][m] / ratioSum ), 30 ); /*Q62*/
981 324 : move64();
982 : }
983 : }
984 : }
985 : }
986 : }
987 :
988 2239 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
989 : {
990 18513 : FOR( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
991 : {
992 81294 : FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
993 : {
994 64020 : 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 64020 : move16();
996 64020 : hQMetaData->q_direction[1].band_data[b].bits_sph_idx[m] = bits_sph_idx; /*Q0*/
997 64020 : move16();
998 : }
999 : }
1000 : }
1001 :
1002 55690 : FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1003 : {
1004 257526 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
1005 : {
1006 204075 : 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 204075 : move16();
1008 204075 : hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] = bits_sph_idx; /*Q0*/
1009 204075 : move16();
1010 : }
1011 : }
1012 :
1013 2239 : IF( !all_coherence_zero )
1014 : {
1015 2239 : read_surround_coherence_hr_fx( bitstream, index, hQMetaData, W_nrg_ratio );
1016 : }
1017 : ELSE
1018 : {
1019 : /*Surround coherence*/
1020 0 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1021 : {
1022 0 : IF( hQMetaData->surcoh_band_data != NULL )
1023 : {
1024 0 : set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
1025 : }
1026 : }
1027 : }
1028 :
1029 5717 : FOR( d = 0; d < hQMetaData->no_directions; d++ )
1030 : {
1031 3478 : q_direction = &hQMetaData->q_direction[d];
1032 3478 : nbands = q_direction->cfg.nbands;
1033 3478 : move16();
1034 3478 : start_band = q_direction->cfg.start_band;
1035 3478 : move16();
1036 :
1037 : /* Read coherence, IF any */
1038 3478 : IF( !all_coherence_zero )
1039 : {
1040 3478 : read_coherence_data_hr_512_fx( bitstream, index, hQMetaData, d, bits_sp_coh );
1041 : }
1042 : ELSE
1043 : {
1044 : /*Surround coherence*/
1045 0 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1046 : {
1047 0 : IF( hQMetaData->surcoh_band_data != NULL )
1048 : {
1049 0 : set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
1050 : }
1051 :
1052 0 : IF( hQMetaData->q_direction[d].coherence_band_data != NULL )
1053 : {
1054 0 : 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 3478 : ivas_qmetadata_raw_decode_dir_512_fx( q_direction, bitstream, index, nbands, start_band, sph_grid16 );
1062 : }
1063 :
1064 2239 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
1065 : {
1066 : /* move 2 dir data to its correct subband */
1067 1239 : IF( EQ_16( bits_sph_idx, 11 ) )
1068 : {
1069 : Word16 nblocks;
1070 859 : d = sub( hQMetaData->q_direction[1].cfg.nbands, 1 );
1071 859 : nblocks = hQMetaData->q_direction[0].cfg.nblocks;
1072 859 : move16();
1073 :
1074 21190 : FOR( b = hQMetaData->q_direction[0].cfg.nbands - 1; b >= 0; b-- )
1075 : {
1076 20331 : IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
1077 : {
1078 :
1079 8154 : Copy32( hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].band_data[b].azimuth_fx, nblocks ); /*Q22*/
1080 8154 : Copy32( hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].band_data[b].elevation_fx, nblocks ); /*Q22*/
1081 8154 : Copy32( hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, nblocks ); /*Q30*/
1082 8154 : Copy64( W_nrg_ratio[1][d], W_nrg_ratio[1][b], nblocks );
1083 :
1084 8154 : IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
1085 : {
1086 8154 : 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 8154 : d = sub( d, 1 );
1089 : }
1090 : ELSE
1091 : {
1092 12177 : set32_fx( hQMetaData->q_direction[1].band_data[b].azimuth_fx, 0, nblocks );
1093 12177 : set32_fx( hQMetaData->q_direction[1].band_data[b].elevation_fx, 0, nblocks );
1094 12177 : set32_fx( hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, 0, nblocks );
1095 12177 : set64_fx( W_nrg_ratio[1][b], 0, nblocks );
1096 :
1097 12177 : IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
1098 : {
1099 12177 : 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 30690 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1107 : {
1108 137526 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
1109 : {
1110 : Word32 ratioSum;
1111 108075 : ratioSum = W_round64_L( W_add( W_nrg_ratio[0][b][m], W_nrg_ratio[1][b][m] ) ); /*Q30*/
1112 108075 : 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 55690 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1124 : {
1125 257526 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
1126 : {
1127 204075 : hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[0][b][m] ); /*Q30*/
1128 204075 : move32();
1129 : }
1130 : }
1131 2239 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
1132 : {
1133 30690 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1134 : {
1135 137526 : FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
1136 : {
1137 108075 : hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[1][b][m] ); /*Q30*/
1138 108075 : move32();
1139 : }
1140 : }
1141 : }
1142 : /* Store status information for renderer use */
1143 2239 : hQMetaData->ec_flag = 0;
1144 2239 : move16();
1145 2239 : hQMetaData->dir_comp_ratio_fx = MAX_WORD16; /*Q15*/
1146 2239 : move16();
1147 :
1148 :
1149 2239 : hQMetaData->q_direction[0].cfg.nbands = sf_nbands0; /*Q0*/
1150 2239 : move16();
1151 2239 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
1152 : {
1153 1239 : hQMetaData->q_direction[1].cfg.nbands = sf_nbands1; /*Q0*/
1154 1239 : move16();
1155 : }
1156 :
1157 2239 : 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 690 : 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 690 : IF( EQ_16( ivas_format, SBA_FORMAT ) )
1191 : {
1192 499 : sba_spar_bitlen = ivas_sba_spar_sid_bitlen_fx( nchan_transport );
1193 499 : 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 499 : metadata_sid_bits = sub( metadata_sid_bits, sba_spar_bitlen );
1195 : }
1196 : ELSE
1197 : {
1198 191 : metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS;
1199 191 : move16();
1200 : }
1201 :
1202 690 : start_index = *index;
1203 690 : move16();
1204 :
1205 : /* read MASA SID descriptor */
1206 690 : test();
1207 690 : 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 690 : q_direction = &hQMetaData->q_direction[0]; /* only 1 direction */
1225 690 : IF( EQ_16( ivas_format, SBA_FORMAT ) )
1226 : {
1227 499 : nbands = DIRAC_DTX_BANDS; /* only 2 bands transmitted */
1228 499 : move16();
1229 : }
1230 : ELSE
1231 : {
1232 191 : nbands = 5; /* only 5 bands transmitted */
1233 191 : move16();
1234 : }
1235 :
1236 690 : nblocks = q_direction->cfg.nblocks; /* only 1 block transmitted but up to 4 blocks re-generated Q0*/
1237 690 : move16();
1238 690 : start_band = 0; /* start from band 0 */
1239 690 : move16();
1240 :
1241 : /* Read 2D signaling*/
1242 690 : IF( NE_16( ivas_format, SBA_FORMAT ) )
1243 : {
1244 191 : q_direction->not_in_2D = bitstream[( *index )--]; /*Q0*/
1245 191 : move16();
1246 : }
1247 : ELSE
1248 : {
1249 499 : q_direction->not_in_2D = 1;
1250 499 : move16();
1251 : }
1252 :
1253 690 : bits_dir = 0;
1254 690 : move16();
1255 690 : IF( NE_16( ivas_format, SBA_FORMAT ) )
1256 : {
1257 : /* Decode diffuseness*/
1258 1146 : FOR( b = start_band; b < nbands; b++ )
1259 : {
1260 955 : diffuseness_index[b] = (UWord16) L_add( ivas_qmetadata_DecodeQuasiUniform( bitstream, index, sub( DIRAC_DIFFUSE_LEVELS, 4 ) ), 4 ); /*Q0*/
1261 955 : move16();
1262 955 : q_direction->band_data[b].energy_ratio_index[0] = diffuseness_index[b]; /*Q0*/
1263 955 : move16();
1264 955 : q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[diffuseness_index[b]]; /*Q0*/
1265 955 : move16();
1266 955 : bits_dir = extract_l( L_add( bits_dir, q_direction->band_data[b].bits_sph_idx[0] ) ); /*Q0*/
1267 955 : 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 955 : move16();
1269 : }
1270 :
1271 191 : bits_delta = sub( sub( metadata_sid_bits, sub( start_index, *index ) ), bits_dir ); /* bit_diff is already read */
1272 :
1273 191 : IF( bits_delta > 0 )
1274 : {
1275 904 : WHILE( bits_delta > 0 )
1276 : {
1277 3875 : FOR( b = start_band; b < nbands && ( bits_delta > 0 ); b++ )
1278 : {
1279 3162 : IF( LT_32( q_direction->band_data[b].bits_sph_idx[0], 11 ) )
1280 : {
1281 3162 : bits_delta = sub( bits_delta, 1 );
1282 3162 : q_direction->band_data[b].bits_sph_idx[0] = add( q_direction->band_data[b].bits_sph_idx[0], 1 );
1283 3162 : move16();
1284 : }
1285 : }
1286 : }
1287 :
1288 191 : 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 1497 : FOR( b = start_band; b < nbands; b++ )
1326 : {
1327 998 : diffuseness_index[b] = (UWord16) L_add( ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS - 4 ), 4 ); /*Q0*/
1328 998 : move16();
1329 998 : q_direction->band_data[b].energy_ratio_index[0] = diffuseness_index[b];
1330 998 : move16();
1331 998 : q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[diffuseness_index[b]];
1332 998 : move16();
1333 998 : q_direction->band_data[b].azimuth_m_alphabet[0] = no_phi_masa[q_direction->band_data[b].bits_sph_idx[0] - 1][0];
1334 998 : move16();
1335 : }
1336 : }
1337 :
1338 2643 : FOR( b = start_band; b < nbands; b++ )
1339 : {
1340 1953 : q_direction->band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[diffuseness_index[b]] ); /*Q30*/
1341 1953 : move32();
1342 9765 : FOR( i = 0; i < nblocks; i++ )
1343 : {
1344 7812 : q_direction->band_data[b].energy_ratio_fx[i] = q_direction->band_data[b].energy_ratio_fx[0]; /*Q30*/
1345 7812 : move32();
1346 : }
1347 : }
1348 :
1349 : /* Decoder DOAs*/
1350 690 : IF( q_direction->not_in_2D > 0 )
1351 : {
1352 2643 : FOR( b = start_band; b < nbands; b++ )
1353 : {
1354 1953 : value = 0;
1355 1953 : move16();
1356 12895 : FOR( i = 0; i < q_direction->band_data[b].bits_sph_idx[0]; i++ )
1357 : {
1358 10942 : value = (UWord16) L_add( L_shl( value, 1 ), bitstream[( *index )--] );
1359 : }
1360 9765 : FOR( i = 0; i < nblocks; i++ )
1361 : {
1362 7812 : q_direction->band_data[b].spherical_index[i] = value;
1363 7812 : move16();
1364 : }
1365 :
1366 1953 : 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 1953 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( avg_azimuth_fx, avg_elevation_fx, avg_direction_vector_fx );
1369 1953 : 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 1953 : v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 ); /*Q25*/
1372 1953 : v_shr_32( avg_direction_vector_fx, avg_direction_vector_fx, 3, 5 ); /*Q25*/
1373 7812 : FOR( m = 0; m < nblocks - 1; m++ )
1374 : {
1375 5859 : v_add_32( direction_vector_fx, avg_direction_vector_fx, direction_vector_fx, 3 ); /*Q25*/
1376 5859 : 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 1953 : 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 2967 : WHILE( LT_16( sub( start_index, *index ), metadata_sid_bits ) )
1426 : {
1427 2277 : b = bitstream[( *index )--];
1428 2277 : move16();
1429 : }
1430 :
1431 690 : return sub( start_index, *index );
1432 : }
1433 :
1434 : /*-----------------------------------------------------------------------*
1435 : * Local function definitions for diffuseness/energy ratios
1436 : *-----------------------------------------------------------------------*/
1437 :
1438 198034 : 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 198034 : val = 0;
1446 198034 : move16();
1447 387191 : WHILE( LE_16( val, DIFF_EC_HUFF_GR0_LIMIT ) )
1448 : {
1449 386916 : IF( EQ_16( bitstream[( *index )--], 1 ) )
1450 : {
1451 189157 : val = add( val, 1 );
1452 : }
1453 : ELSE
1454 : {
1455 197759 : BREAK;
1456 : }
1457 : }
1458 :
1459 198034 : IF( EQ_16( val, DIFF_EC_HUFF_GR0_LIMIT + 1 ) )
1460 : {
1461 275 : val = add( val, shl( bitstream[( *index )--], 1 ) );
1462 275 : val = add( val, bitstream[( *index )--] );
1463 : }
1464 :
1465 198034 : IF( val % 2 == 0 )
1466 : {
1467 129775 : return add( negate( shr( val, 1 ) ), av );
1468 : }
1469 : ELSE
1470 : {
1471 68259 : return add( shr( add( val, 1 ), 1 ), av );
1472 : }
1473 : }
1474 :
1475 : /*-------------------------------------------------------------------*
1476 : * ivas_qmetadata_entropy_decode_diffuseness()
1477 : *
1478 : *
1479 : *-------------------------------------------------------------------*/
1480 193697 : 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 193697 : index_start = *index;
1493 193697 : move16();
1494 193697 : nbands = q_direction->cfg.nbands;
1495 193697 : move16();
1496 193697 : start_band = q_direction->cfg.start_band;
1497 193697 : move16();
1498 :
1499 : /* diffuseness decoding */
1500 : /* Handle one band as special case*/
1501 193697 : IF( EQ_16( nbands, 1 ) )
1502 : {
1503 3883 : q_direction->band_data[0].energy_ratio_index[0] = 0;
1504 3883 : move16();
1505 15532 : FOR( b = 0; b < MASA_BITS_ER; b++ )
1506 : {
1507 11649 : 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 11649 : move16();
1509 : }
1510 3883 : *diffuseness_index_max_ec_frame = 5;
1511 3883 : move16();
1512 :
1513 3883 : return MASA_BITS_ER;
1514 : }
1515 :
1516 189814 : 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 105485 : IF( LT_16( nbands, DIFF_EC_HUFF_BAND_LIMIT ) )
1520 : {
1521 88871 : IF( bitstream[( *index )--] ) /* dif_have_unique_value */
1522 : {
1523 51888 : dif_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS ); /* dif_unique_value Q0*/
1524 :
1525 205774 : FOR( b = start_band; b < nbands; b++ )
1526 : {
1527 153886 : q_direction->band_data[b].energy_ratio_index[0] = dif_min; /*Q0*/
1528 153886 : move16();
1529 : }
1530 : }
1531 : ELSE /* all diffuseness values are dif_min_value or dif_min_value + 1 */
1532 : {
1533 36983 : dif_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS - 1 ); /* dif_min_value Q0*/
1534 :
1535 162208 : FOR( b = start_band; b < nbands; b++ )
1536 : {
1537 125225 : q_direction->band_data[b].energy_ratio_index[0] = (UWord16) L_add( dif_min, bitstream[( *index )--] ); /* dif_bit_offset_values Q0*/
1538 125225 : move16();
1539 : }
1540 : }
1541 : }
1542 : ELSE
1543 : {
1544 : Word16 av;
1545 :
1546 : /* read average on 3 bits*/
1547 16614 : av = 0;
1548 16614 : move16();
1549 66456 : FOR( b = 0; b < MASA_BITS_ER; b++ )
1550 : {
1551 49842 : av = add( av, i_mult( (Word16) bitstream[( *index )--], shl( 1, sub( sub( MASA_BITS_ER, 1 ), b ) ) ) ); /*Q0*/
1552 : }
1553 :
1554 16614 : dif_min = DIRAC_DIFFUSE_LEVELS;
1555 16614 : move16();
1556 : /* read average removed data (average is added inside)*/
1557 214648 : FOR( b = start_band; b < nbands; b++ )
1558 : {
1559 198034 : q_direction->band_data[b].energy_ratio_index[0] = ivas_diffuseness_huff_ec_decode_fx( bitstream, index, av ); /*Q0*/
1560 198034 : move16();
1561 198034 : dif_min = (UWord16) L_min( dif_min, q_direction->band_data[b].energy_ratio_index[0] );
1562 198034 : move16();
1563 : }
1564 : }
1565 : }
1566 : ELSE /* different values for diffuseness */
1567 : {
1568 84329 : dif_min = DIRAC_DIFFUSE_LEVELS;
1569 84329 : move16();
1570 :
1571 456450 : FOR( b = start_band; b < nbands; b++ )
1572 : {
1573 372121 : q_direction->band_data[b].energy_ratio_index[0] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
1574 372121 : move16();
1575 372121 : dif_min = (UWord16) L_min( dif_min, q_direction->band_data[b].energy_ratio_index[0] );
1576 372121 : move16();
1577 : }
1578 : }
1579 :
1580 189814 : *diffuseness_index_max_ec_frame = 5;
1581 189814 : move16();
1582 : /* adaptively select the diffuseness_index_max_ec threshold */
1583 189814 : if ( GT_32( dif_min, 5 ) )
1584 : {
1585 73621 : *diffuseness_index_max_ec_frame = (UWord16) DIRAC_DIFFUSE_LEVELS - 1;
1586 73621 : move16();
1587 : }
1588 :
1589 189814 : return sub( index_start, *index );
1590 : }
1591 :
1592 : /*-------------------------------------------------------------------*
1593 : * ivas_qmetadata_entropy_decode_diffuseness_hr_512()
1594 : *
1595 : *
1596 : *-------------------------------------------------------------------*/
1597 :
1598 3478 : 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 3478 : index_start = *index;
1610 3478 : move16();
1611 3478 : nbands = q_direction->cfg.nbands;
1612 3478 : move16();
1613 3478 : nblocks = q_direction->cfg.nblocks;
1614 3478 : move16();
1615 3478 : start_band = q_direction->cfg.start_band;
1616 3478 : move16();
1617 :
1618 : /* diffuseness decoding */
1619 : /* Handle one band as special case*/
1620 3478 : 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 74203 : FOR( b = start_band; b < nbands; b++ )
1634 : {
1635 338820 : FOR( k = 0; k < nblocks; k++ )
1636 : {
1637 268095 : q_direction->band_data[b].energy_ratio_index[k] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, HR_MASA_ER_LEVELS ); /*Q0*/
1638 268095 : move16();
1639 : }
1640 : }
1641 :
1642 3478 : return sub( index_start, *index );
1643 : }
1644 :
1645 :
1646 : /*-------------------------------------------------------------------*
1647 : * ivas_qmetadata_entropy_decode_df_ratio()
1648 : *
1649 : *
1650 : *-------------------------------------------------------------------*/
1651 20104 : 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 20104 : index_start = *index;
1669 20104 : move16();
1670 20104 : nbands = q_direction->cfg.nbands;
1671 20104 : move16();
1672 20104 : start_band = q_direction->cfg.start_band;
1673 20104 : move16();
1674 :
1675 : /* Handle one band as special case*/
1676 20104 : IF( EQ_16( nbands, 1 ) )
1677 : {
1678 1408 : q_direction->band_data[0].energy_ratio_index[0] = 0;
1679 1408 : move16();
1680 4360 : 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 2952 : 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 2952 : move16();
1685 : }
1686 1408 : return dfRatio_bits[0];
1687 : }
1688 :
1689 : /* Calculate raw coding bits and decide what modes are possible */
1690 18696 : bits_raw = 0;
1691 18696 : move16();
1692 18696 : max_dfRatio_bits = 0;
1693 18696 : move16();
1694 206051 : FOR( b = start_band; b < nbands; b++ )
1695 : {
1696 : // bits_raw += dfRatio_bits[b];
1697 187355 : bits_raw = add( bits_raw, dfRatio_bits[b] );
1698 187355 : max_dfRatio_bits = s_max( max_dfRatio_bits, dfRatio_bits[b] );
1699 : }
1700 :
1701 : /* Decide what modes are possible */
1702 18696 : IF( GE_16( bits_raw, add( add( max_dfRatio_bits, 2 ), nbands ) ) )
1703 : {
1704 11609 : ec_mode = 2;
1705 11609 : move16();
1706 : }
1707 7087 : ELSE IF( GE_16( bits_raw, add( max_dfRatio_bits, 1 ) ) )
1708 : {
1709 7087 : ec_mode = 1;
1710 7087 : move16();
1711 : }
1712 : ELSE
1713 : {
1714 0 : ec_mode = 0;
1715 0 : move16();
1716 : }
1717 18696 : max_alphabet_size = shl( 1, max_dfRatio_bits ); /* 1 << max_dfRatio_bits */
1718 :
1719 18696 : dec_mode = 2; /* Default to raw decoding */
1720 18696 : move16();
1721 18696 : IF( EQ_16( ec_mode, 1 ) )
1722 : {
1723 7087 : if ( bitstream[( *index )--] == 0 )
1724 : {
1725 271 : dec_mode = 1; /* Switch to one value EC coding */
1726 271 : move16();
1727 : }
1728 : }
1729 11609 : ELSE IF( EQ_16( ec_mode, 2 ) )
1730 : {
1731 11609 : IF( bitstream[( *index )--] == 0 )
1732 : {
1733 1325 : IF( bitstream[( *index )--] == 0 )
1734 : {
1735 99 : dec_mode = 1; /* Switch to one value EC coding */
1736 99 : move16();
1737 : }
1738 : ELSE
1739 : {
1740 1226 : dec_mode = 0; /* Use one-bit diff bandwise mode */
1741 1226 : move16();
1742 : }
1743 : }
1744 : }
1745 :
1746 18696 : IF( EQ_16( dec_mode, 2 ) ) /* Raw decoding */
1747 : {
1748 191931 : FOR( b = start_band; b < nbands; b++ )
1749 : {
1750 174831 : q_direction->band_data[b].energy_ratio_index[0] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, (UWord16) L_shl( 1, dfRatio_bits[b] ) ); /*Q0*/
1751 174831 : move16();
1752 : }
1753 : }
1754 1596 : ELSE IF( EQ_16( dec_mode, 1 ) ) /* One value decoding */
1755 : {
1756 370 : ratio_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, max_alphabet_size ); /* dif_unique_value Q0*/
1757 :
1758 2139 : FOR( b = start_band; b < nbands; b++ )
1759 : {
1760 1769 : q_direction->band_data[b].energy_ratio_index[0] = ratio_min; /*Q0*/
1761 1769 : move16();
1762 : }
1763 : }
1764 : ELSE /* Bandwise 1-bit diff decoding */
1765 : {
1766 1226 : ratio_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, max_alphabet_size - 1 ); /* dif_min_value Q0*/
1767 :
1768 11981 : FOR( b = start_band; b < nbands; b++ )
1769 : {
1770 10755 : q_direction->band_data[b].energy_ratio_index[0] = (UWord16) L_add( ratio_min, bitstream[( *index )--] ); /* dif_bit_offset_values Q0*/
1771 10755 : move16();
1772 : }
1773 : }
1774 :
1775 18696 : 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 111201 : 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 111201 : index_start = *index;
1816 111201 : move16();
1817 111201 : nblocks = q_direction->cfg.nblocks;
1818 111201 : move16();
1819 :
1820 111201 : diff_idx_min = DIRAC_DIFFUSE_LEVELS;
1821 111201 : move16();
1822 :
1823 : /*Raw coding for high diffuseness*/
1824 747503 : FOR( b = start_band; b < nbands; b++ )
1825 : {
1826 636302 : IF( hrmasa_flag )
1827 : {
1828 0 : diff_idx = 0;
1829 0 : move16();
1830 : }
1831 : ELSE
1832 : {
1833 636302 : diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
1834 636302 : move16();
1835 : }
1836 :
1837 636302 : diff_idx_min = s_min( diff_idx_min, diff_idx );
1838 636302 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
1839 : {
1840 31381 : elev_alph[b] = no_theta_masa[( bits_direction_masa[diff_idx] - 3 )]; /*Q0*/
1841 31381 : move16();
1842 : }
1843 : ELSE
1844 : {
1845 604921 : elev_alph[b] = sub( shl( no_theta_masa[( bits_direction_masa[diff_idx] - 3 )], 1 ), 1 ); /*Q0*/
1846 604921 : move16();
1847 : }
1848 :
1849 636302 : IF( GT_32( q_direction->band_data[b].energy_ratio_index_mod[0], diffuseness_index_max_ec_frame ) )
1850 : {
1851 155512 : bands_entropic[b] = 0;
1852 155512 : move16();
1853 :
1854 155512 : IF( q_direction->not_in_2D > 0 )
1855 : {
1856 137406 : decode_fixed_rate_fx( q_direction, bitstream, index, b, nblocks );
1857 : }
1858 : ELSE
1859 : {
1860 : /* in 2D */
1861 83015 : FOR( m = 0; m < nblocks; m++ )
1862 : {
1863 64909 : q_direction->band_data[b].elevation_fx[m] = 0;
1864 64909 : move32();
1865 64909 : q_direction->band_data[b].elevation_index[m] = 0;
1866 64909 : move16();
1867 :
1868 64909 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][0]; /*Q0*/
1869 64909 : move16();
1870 64909 : q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, azith_alph[b][m] ); /*Q0*/
1871 64909 : move16();
1872 64909 : 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 64909 : move32();
1874 : }
1875 : }
1876 : }
1877 : ELSE
1878 : {
1879 480790 : bands_entropic[b] = 1;
1880 480790 : move16();
1881 : }
1882 : }
1883 :
1884 : /*EC for the low diffuseness*/
1885 :
1886 : /*Elevation only if not 2D */
1887 111201 : IF( q_direction->not_in_2D > 0 )
1888 : {
1889 90600 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
1890 : {
1891 1006 : avg_elevation_alphabet = no_theta_masa[( bits_direction_masa[diff_idx_min] - 3 )]; /*Q0*/
1892 1006 : move16();
1893 1006 : avg_elevation_idx = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, avg_elevation_alphabet ); /*Q0*/
1894 : }
1895 : ELSE
1896 : {
1897 89594 : avg_elevation_alphabet = sub( shl( no_theta_masa[( bits_direction_masa[diff_idx_min] - 3 )], 1 ), 1 ); /*Q0*/
1898 89594 : avg_elevation_idx = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, avg_elevation_alphabet );
1899 89594 : avg_elevation_idx = add( ivas_qmetadata_dereorder_generic_fx( avg_elevation_idx ), shr( avg_elevation_alphabet, 1 ) ); /*Q0*/
1900 : }
1901 :
1902 90600 : gr_param_elev = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, 4 + 1 );
1903 90600 : move16();
1904 90600 : IF( EQ_32( gr_param_elev, 4 ) ) /* all the elevation distances are zero */
1905 : {
1906 53348 : FOR( b = start_band; b < nbands; b++ )
1907 : {
1908 40873 : IF( bands_entropic[b] )
1909 : {
1910 : Word16 tmp_index;
1911 19595 : IF( hrmasa_flag )
1912 : {
1913 0 : diff_idx = 0;
1914 0 : move16();
1915 : }
1916 : ELSE
1917 : {
1918 19595 : diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
1919 19595 : move16();
1920 : }
1921 :
1922 19595 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
1923 : {
1924 661 : 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 18934 : 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 18934 : tmp_index = sub( avg_elevation_index_projected, shr( elev_alph[b], 1 ) ); /*Q0*/
1932 18934 : IF( tmp_index < 0 )
1933 : {
1934 7230 : tmp_index = negate( imult1616( tmp_index, 2 ) );
1935 : }
1936 11704 : ELSE IF( tmp_index > 0 )
1937 : {
1938 2734 : tmp_index = sub( imult1616( tmp_index, 2 ), 1 );
1939 : }
1940 18934 : avg_elevation_index_projected = tmp_index;
1941 18934 : move16();
1942 : }
1943 :
1944 82066 : FOR( m = 0; m < nblocks; m++ )
1945 : {
1946 62471 : q_direction->band_data[b].elevation_index[m] = avg_elevation_index_projected; /*Q0*/
1947 62471 : move16();
1948 :
1949 : /*deduce aplhabet for azimuth*/
1950 62471 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
1951 : {
1952 2317 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][q_direction->band_data[b].elevation_index[m]]; /*Q0*/
1953 2317 : move16();
1954 : }
1955 : ELSE
1956 : {
1957 60154 : 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 60154 : move16();
1959 : }
1960 :
1961 : /*decode elevation*/
1962 62471 : 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 62471 : move32();
1964 : }
1965 : }
1966 : }
1967 : }
1968 : ELSE
1969 : {
1970 572126 : FOR( b = start_band; b < nbands; b++ )
1971 : {
1972 494001 : IF( bands_entropic[b] )
1973 : {
1974 377873 : IF( hrmasa_flag )
1975 : {
1976 0 : diff_idx = 0;
1977 0 : move16();
1978 : }
1979 : ELSE
1980 : {
1981 377873 : diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
1982 377873 : move16();
1983 : }
1984 :
1985 1806373 : FOR( m = 0; m < nblocks; m++ )
1986 : {
1987 : Word16 tmp_index;
1988 1428500 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
1989 : {
1990 7747 : avg_elevation_index_projected = ivas_chan_project_elevation_index_fx( avg_elevation_idx, avg_elevation_alphabet, elev_alph[b] ); /*Q0*/
1991 7747 : tmp_index = ivas_qmetadata_DecodeExtendedGR( bitstream, index, sub( shl( elev_alph[b], 1 ), 1 ), gr_param_elev ); /*Q0*/
1992 7747 : IF( s_and( tmp_index, 1 ) )
1993 : {
1994 793 : tmp_index = add( avg_elevation_index_projected, shr( add( tmp_index, 1 ), 1 ) ); /*Q0*/
1995 : }
1996 : ELSE
1997 : {
1998 6954 : tmp_index = sub( avg_elevation_index_projected, shr( tmp_index, 1 ) );
1999 : }
2000 7747 : q_direction->band_data[b].elevation_index[m] = tmp_index;
2001 7747 : move16();
2002 :
2003 : /*deduce aplhabet for azimuth*/
2004 7747 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][q_direction->band_data[b].elevation_index[m]]; /*Q0*/
2005 7747 : move16();
2006 : }
2007 : ELSE
2008 : {
2009 1420753 : avg_elevation_index_projected = ivas_dirac_project_elevation_index_fx( avg_elevation_idx, avg_elevation_alphabet, elev_alph[b] ); /*Q0*/
2010 :
2011 1420753 : tmp_index = ivas_qmetadata_DecodeExtendedGR( bitstream, index, elev_alph[b], gr_param_elev ); /*Q0*/
2012 1420753 : tmp_index = ivas_qmetadata_ReorderElevationDecoded( tmp_index, avg_elevation_index_projected, elev_alph[b] ); /*Q0*/
2013 :
2014 : /*reorder elevation indexing*/
2015 1420753 : tmp_index = sub( tmp_index, elev_alph[b] / 2 );
2016 1420753 : IF( tmp_index < 0 )
2017 : {
2018 568532 : tmp_index = negate( shl( tmp_index, 1 ) );
2019 : }
2020 852221 : ELSE IF( tmp_index > 0 )
2021 : {
2022 276112 : tmp_index = sub( shl( tmp_index, 1 ), 1 );
2023 : }
2024 1420753 : q_direction->band_data[b].elevation_index[m] = tmp_index;
2025 1420753 : move16();
2026 :
2027 : /*deduce aplhabet for azimuth*/
2028 1420753 : 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 1420753 : move16();
2030 : }
2031 :
2032 : /*decode elevation*/
2033 1428500 : 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 1428500 : move32();
2035 : }
2036 : }
2037 : }
2038 : }
2039 : }
2040 : ELSE
2041 : {
2042 122029 : FOR( b = start_band; b < nbands; b++ )
2043 : {
2044 101428 : IF( bands_entropic[b] )
2045 : {
2046 83322 : IF( hrmasa_flag )
2047 : {
2048 0 : diff_idx = 0;
2049 0 : move16();
2050 : }
2051 : ELSE
2052 : {
2053 83322 : diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
2054 83322 : move16();
2055 : }
2056 :
2057 352713 : FOR( m = 0; m < nblocks; m++ )
2058 : {
2059 269391 : q_direction->band_data[b].elevation_index[m] = 0;
2060 269391 : move16();
2061 :
2062 : /*deduce alphabet for azimuth*/
2063 269391 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2064 : {
2065 48502 : azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][q_direction->band_data[b].elevation_index[m]]; /*Q0*/
2066 48502 : move16();
2067 : }
2068 : ELSE
2069 : {
2070 220889 : 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 220889 : move16();
2072 : }
2073 :
2074 : /*decode elevation*/
2075 269391 : 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 269391 : move32();
2077 : }
2078 : }
2079 : }
2080 : }
2081 :
2082 : /*Azimuth*/
2083 111201 : avg_azimuth_alphabet = no_phi_masa[( bits_direction_masa[diff_idx_min] - 1 )][0]; /* average azimuth is quantized on the equatorial plane Q0*/
2084 111201 : move16();
2085 111201 : avg_azimuth_index = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, avg_azimuth_alphabet ); /*Q0*/
2086 111201 : avg_azimuth_index = ivas_qmetadata_dereorder_generic_fx( avg_azimuth_index ); /*Q0*/
2087 111201 : avg_azimuth_index = add( avg_azimuth_index, shr( avg_azimuth_alphabet, 1 ) ); /*Q0*/
2088 :
2089 111201 : gr_param_azith = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, 5 + 1 ); /*Q0*/
2090 111201 : IF( EQ_32( gr_param_azith, 5 ) ) /* all the azimuth distances are zero */
2091 : {
2092 65744 : FOR( b = start_band; b < nbands; b++ )
2093 : {
2094 50709 : IF( bands_entropic[b] )
2095 : {
2096 125151 : FOR( m = 0; m < nblocks; m++ )
2097 : {
2098 91167 : 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 91167 : move16();
2100 :
2101 91167 : IF( EQ_16( azith_alph[b][m], 1 ) )
2102 : {
2103 7 : q_direction->band_data[b].azimuth_fx[m] = 0;
2104 7 : move32();
2105 : }
2106 : ELSE
2107 : {
2108 91160 : 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 91160 : move32();
2110 : }
2111 : }
2112 : }
2113 : }
2114 : }
2115 : ELSE
2116 : {
2117 96166 : set32_fx( avg_direction_vector_fx, 0, 3 );
2118 96166 : use_adapt_avg = 0;
2119 96166 : move16();
2120 96166 : idx = 0;
2121 96166 : move16();
2122 :
2123 681759 : FOR( b = start_band; b < nbands; b++ )
2124 : {
2125 585593 : IF( bands_entropic[b] )
2126 : {
2127 2116001 : FOR( m = 0; m < nblocks; m++ )
2128 : {
2129 1669195 : 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 2017 : use_adapt_avg = bitstream[*index]; /*Q0*/
2132 2017 : move16();
2133 2017 : ( *index ) = sub( *index, 1 );
2134 2017 : move16();
2135 : }
2136 1669195 : avg_azimuth_index_projected = ivas_dirac_project_azimuth_index_fx( avg_azimuth_index, avg_azimuth_alphabet, azith_alph[b][m] ); /*Q0*/
2137 1669195 : q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, azith_alph[b][m], gr_param_azith ); /*Q0*/
2138 1669195 : move16();
2139 1669195 : 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 1669195 : move16();
2141 :
2142 1669195 : IF( EQ_16( azith_alph[b][m], 1 ) )
2143 : {
2144 433 : q_direction->band_data[b].azimuth_fx[m] = 0;
2145 433 : move32();
2146 : }
2147 : ELSE
2148 : {
2149 1668762 : 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 1668762 : move32();
2151 : }
2152 :
2153 1669195 : test();
2154 1669195 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && GT_16( nblocks, 1 ) )
2155 : {
2156 36812 : IF( LT_16( idx, MASA_LIMIT_IDX_AVG_AZI ) )
2157 : {
2158 11468 : 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 11468 : v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 ); /*Q25*/
2160 11468 : v_add_32( avg_direction_vector_fx, direction_vector_fx, avg_direction_vector_fx, 3 ); /*Q25*/
2161 : }
2162 : ELSE
2163 : {
2164 25344 : IF( EQ_16( use_adapt_avg, 1 ) )
2165 : {
2166 11908 : IF( m == 0 )
2167 : {
2168 11908 : FOR( Word16 l = 0; l < 3; l++ )
2169 : {
2170 8931 : avg_direction_vector_fx[l] = L_shr( avg_direction_vector_fx[l], 1 ); /*0.5f*/
2171 8931 : move32();
2172 : }
2173 : }
2174 : /*compute the average direction per already coded subband */
2175 11908 : 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 11908 : v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 ); /*Q25*/
2177 11908 : v_add_32( avg_direction_vector_fx, direction_vector_fx, avg_direction_vector_fx, 3 ); /*Q25*/
2178 11908 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_fx, 30 - 5, &avg_azimuth_fx, &avg_elevation_fx );
2179 11908 : 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 36812 : idx = add( idx, 1 );
2183 : }
2184 : }
2185 : }
2186 : }
2187 : }
2188 :
2189 111201 : 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 3478 : 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 3478 : index_start = *index;
2212 3478 : move16();
2213 3478 : nblocks = q_direction->cfg.nblocks;
2214 3478 : move16();
2215 :
2216 74203 : FOR( b = start_band; b < nbands; b++ )
2217 : {
2218 338820 : FOR( m = 0; m < nblocks; m++ )
2219 : {
2220 268095 : value = 0;
2221 268095 : move16();
2222 3778740 : FOR( i = 0; i < q_direction->band_data[b].bits_sph_idx[m]; i++ )
2223 : {
2224 3510645 : value = (UWord16) L_add( (UWord16) L_shl( value, 1 ), bitstream[( *index )--] );
2225 : }
2226 268095 : q_direction->band_data[b].spherical_index[m] = value;
2227 268095 : move16();
2228 :
2229 268095 : IF( EQ_32( q_direction->band_data[b].bits_sph_idx[m], 16 ) )
2230 : {
2231 112320 : 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 155775 : 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 3478 : return sub( index_start, *index );
2241 : }
2242 :
2243 :
2244 100418 : 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 100418 : index_start = *index;
2259 100418 : move16();
2260 100418 : nblocks = q_direction->cfg.nblocks;
2261 100418 : move16();
2262 :
2263 466355 : FOR( b = start_band; b < nbands; b++ )
2264 : {
2265 365937 : IF( q_direction->not_in_2D > 0 )
2266 : {
2267 311649 : decode_fixed_rate_fx( q_direction, bitstream, index, b, nblocks );
2268 : }
2269 : ELSE
2270 : {
2271 54288 : IF( hrmasa_flag )
2272 : {
2273 0 : diff_idx = 0;
2274 0 : move16();
2275 : }
2276 : ELSE
2277 : {
2278 54288 : diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
2279 54288 : move16();
2280 : }
2281 :
2282 189876 : FOR( m = 0; m < nblocks; m++ )
2283 : {
2284 135588 : q_direction->band_data[b].elevation_fx[m] = 0;
2285 135588 : move32();
2286 135588 : q_direction->band_data[b].elevation_index[m] = 0;
2287 135588 : move16();
2288 135588 : azith_alph = no_phi_masa[bits_direction_masa[diff_idx] - 1][0]; /*Q0*/
2289 135588 : move16();
2290 135588 : q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, azith_alph ); /*Q0*/
2291 135588 : move16();
2292 135588 : 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 135588 : move32();
2294 : }
2295 : }
2296 : }
2297 :
2298 100418 : 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 1897991 : 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 1897991 : bits = sub( 30, norm_l( alphabet_size ) ); /* bits = floor(log2(alphabet_size)) */
2319 1897991 : tresh = (UWord16) L_sub( (UWord16) L_shl( 1U, add( bits, 1 ) ), alphabet_size );
2320 :
2321 1897991 : value = 0;
2322 1897991 : move16();
2323 7194162 : FOR( i = 0; i < bits; i++ )
2324 : {
2325 5296171 : value = (UWord16) L_add( (UWord16) L_shl( value, 1 ), bitstream[( *index )--] ); /*Q0*/
2326 : }
2327 :
2328 1897991 : IF( GE_32( value, tresh ) )
2329 : {
2330 251407 : value = (UWord16) L_add( (UWord16) L_sub( (UWord16) L_shl( value, 1 ), tresh ), bitstream[( *index )--] ); /*Q0*/
2331 : }
2332 :
2333 1897991 : 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 4251835 : 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 4251835 : msb_size = shr( add( alph_size, sub( shl( 1, gr_param ), 1 ) ), gr_param ); /* ceil division Q0*/
2357 4251835 : IF( LE_16( msb_size, 3 ) )
2358 : {
2359 372355 : value = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, alph_size ); /*Q0*/
2360 : }
2361 : ELSE
2362 : {
2363 3879480 : msb = 0;
2364 3879480 : move16();
2365 3879480 : test();
2366 6732189 : WHILE( LT_16( msb, sub( msb_size, 1 ) ) && bitstream[*index] )
2367 : {
2368 2852709 : test();
2369 2852709 : msb = add( msb, 1 );
2370 2852709 : ( *index ) = sub( ( *index ), 1 );
2371 2852709 : move16();
2372 : }
2373 :
2374 3879480 : IF( EQ_16( msb, sub( msb_size, 1 ) ) )
2375 : {
2376 14070 : lsb = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, sub( alph_size, shl( sub( msb_size, 1 ), gr_param ) ) ); /*Q0*/
2377 : }
2378 : ELSE
2379 : {
2380 3865410 : ( *index ) = sub( ( *index ), 1 );
2381 3865410 : move16();
2382 3865410 : lsb = 0;
2383 3865410 : move16();
2384 6381443 : FOR( i = 0; i < gr_param; i++ )
2385 : {
2386 2516033 : lsb = extract_l( L_add( shl( lsb, 1 ), bitstream[( *index )--] ) ); /*Q0*/
2387 : }
2388 : }
2389 :
2390 3879480 : value = (UWord16) add( shl( msb, gr_param ), lsb ); /*Q0*/
2391 : }
2392 :
2393 4251835 : 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 3089948 : 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 3089948 : dist_reorder = ivas_qmetadata_dereorder_generic_fx( elev_dist ); /*Q0*/
2413 3089948 : elev_index_reorder = add( elev_avg, dist_reorder );
2414 :
2415 3089948 : IF( elev_index_reorder < 0 )
2416 : {
2417 19269 : elev_index_reorder = add( elev_index_reorder, elev_alph );
2418 : }
2419 3070679 : ELSE IF( GE_16( elev_index_reorder, elev_alph ) )
2420 : {
2421 25846 : elev_index_reorder = sub( elev_index_reorder, elev_alph );
2422 : }
2423 :
2424 3089948 : return elev_index_reorder; /*Q0*/
2425 : }
2426 :
2427 :
2428 : /*-----------------------------------------------------------------------*
2429 : * Local functions: requentizeEC3
2430 : *-----------------------------------------------------------------------*/
2431 :
2432 : /*! r: number of bits read */
2433 8430 : 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 8430 : bit_pos = *pbit_pos;
2450 8430 : move16();
2451 :
2452 8430 : diff = 0;
2453 8430 : move16();
2454 8430 : IF( q_direction->not_in_2D )
2455 : {
2456 :
2457 8063 : IF( GT_16( coding_subbands, 1 ) )
2458 : {
2459 7994 : j = ind_order[( coding_subbands - 1 )];
2460 7994 : move16();
2461 7994 : allowed_bits = 0;
2462 7994 : move16();
2463 :
2464 30469 : FOR( k = 0; k < masa_subframes; k++ )
2465 : {
2466 22475 : allowed_bits = extract_l( L_add( allowed_bits, q_direction->band_data[j].bits_sph_idx[k] ) ); /*Q0*/
2467 : }
2468 :
2469 7994 : last_j = sub( j, (Word16) ( allowed_bits == 0 ) );
2470 :
2471 33253 : FOR( j = 0; j < last_j; j++ )
2472 : {
2473 25259 : i = ind_order[j];
2474 25259 : move16();
2475 25259 : bits_dir0 = (Word16 *) q_direction->band_data[i].bits_sph_idx; /*Q0*/
2476 :
2477 25259 : nbits = 0;
2478 25259 : move16();
2479 25259 : allowed_bits = sum16_fx( bits_dir0, q_direction->cfg.nblocks );
2480 25259 : use_vq = 0;
2481 25259 : move16();
2482 25259 : max_nb_idx = 0;
2483 25259 : move16();
2484 :
2485 93013 : FOR( k = 0; k < q_direction->cfg.nblocks; k++ )
2486 : {
2487 67754 : IF( GT_16( bits_dir0[k], use_vq ) )
2488 : {
2489 30366 : use_vq = bits_dir0[k];
2490 30366 : move16();
2491 30366 : max_nb_idx = k;
2492 30366 : move16();
2493 : }
2494 : }
2495 :
2496 25259 : IF( EQ_16( q_direction->cfg.nblocks, 1 ) )
2497 : {
2498 11094 : byteBuffer = 0;
2499 11094 : move16();
2500 : }
2501 : ELSE
2502 : {
2503 14165 : byteBuffer = 0;
2504 14165 : move16();
2505 14165 : if ( LE_16( use_vq, 1 ) )
2506 : {
2507 27 : byteBuffer = 1;
2508 27 : move16();
2509 : }
2510 14165 : test();
2511 14165 : IF( GT_16( use_vq, 1 ) && LE_16( use_vq, LIMIT_USE_COMMON ) )
2512 : {
2513 2360 : bits_dir0[max_nb_idx] = sub( bits_dir0[max_nb_idx], 1 );
2514 2360 : move16();
2515 2360 : allowed_bits = sub( allowed_bits, 1 );
2516 : /* read 1 bit to tell if joint of VQ coding */
2517 2360 : byteBuffer = bitstream[bit_pos--];
2518 2360 : move16();
2519 : }
2520 : }
2521 :
2522 93013 : FOR( k = 0; k < masa_subframes; k++ )
2523 : {
2524 67754 : q_direction->band_data[i].bits_sph_idx[k] = bits_dir0[k]; /*Q0*/
2525 67754 : move16();
2526 67754 : IF( GT_16( bits_dir0[k], 2 ) )
2527 : {
2528 64351 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2529 : {
2530 4078 : q_direction->band_data[i].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3]; /*Q0*/
2531 4078 : move16();
2532 : }
2533 : ELSE
2534 : {
2535 60273 : q_direction->band_data[i].elevation_m_alphabet[k] = shl( no_theta_masa[bits_dir0[k] - 3], 1 ) - 1;
2536 60273 : move16();
2537 : }
2538 : }
2539 : ELSE
2540 : {
2541 3403 : q_direction->band_data[i].elevation_m_alphabet[k] = 1;
2542 3403 : move16();
2543 : }
2544 : }
2545 :
2546 25259 : IF( allowed_bits > 0 )
2547 : {
2548 25259 : IF( EQ_32( byteBuffer, 1 ) )
2549 : {
2550 2332 : nbits = read_common_direction_fx( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); /*Q0*/
2551 : }
2552 : ELSE
2553 : {
2554 22927 : test();
2555 22927 : 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 5658 : fixed_rate = 1;
2559 5658 : move16();
2560 5658 : nbits = 0;
2561 5658 : move16();
2562 : }
2563 : ELSE
2564 : {
2565 : /* check if fixed_rate */
2566 17269 : fixed_rate = bitstream[bit_pos--];
2567 17269 : move16();
2568 17269 : nbits = 1;
2569 17269 : move16();
2570 : }
2571 :
2572 22927 : IF( EQ_16( fixed_rate, 1 ) )
2573 : {
2574 : /* decode_fixed_rate()*/
2575 15654 : nbits = add( nbits, decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) );
2576 : }
2577 : ELSE
2578 : {
2579 :
2580 : /* decode elevation */
2581 7273 : nbits = add( nbits, decode_elevation_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) ); /*Q0*/
2582 : /* decode azimuth */
2583 7273 : 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 25259 : diff = add( diff, sub( nbits, allowed_bits ) );
2593 :
2594 : /* update bits for next block */
2595 25259 : update_bits_next_block_fx( q_direction, &diff, ind_order[j + 1], coding_subbands, masa_subframes );
2596 : }
2597 : }
2598 : ELSE
2599 : {
2600 69 : last_j = q_direction->cfg.start_band; /*Q0*/
2601 69 : move16();
2602 : }
2603 :
2604 :
2605 20999 : FOR( j = last_j; j < coding_subbands; j++ )
2606 : {
2607 12936 : i = ind_order[j];
2608 12936 : move16();
2609 12936 : bits_dir0 = (Word16 *) q_direction->band_data[i].bits_sph_idx; /*Q0*/
2610 :
2611 12936 : nbits = 0;
2612 12936 : move16();
2613 12936 : allowed_bits = sum16_fx( bits_dir0, q_direction->cfg.nblocks ); /*Q0*/
2614 12936 : test();
2615 12936 : IF( allowed_bits > 0 && EQ_16( masa_subframes, 1 ) )
2616 : {
2617 5578 : nbits = add( nbits, decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) ); /*Q0*/
2618 : }
2619 : ELSE
2620 : {
2621 7358 : IF( allowed_bits > 0 )
2622 : {
2623 7358 : use_vq = 0;
2624 7358 : move16();
2625 7358 : max_nb_idx = 0;
2626 7358 : move16();
2627 36790 : FOR( k = 0; k < masa_subframes; k++ )
2628 : {
2629 29432 : IF( GT_16( bits_dir0[k], use_vq ) )
2630 : {
2631 10145 : use_vq = bits_dir0[k]; /*Q0*/
2632 10145 : move16();
2633 10145 : max_nb_idx = k;
2634 10145 : move16();
2635 : }
2636 : }
2637 :
2638 7358 : byteBuffer = 0;
2639 7358 : move16();
2640 :
2641 7358 : test();
2642 7358 : IF( GT_16( use_vq, 1 ) && LE_16( use_vq, LIMIT_USE_COMMON ) )
2643 : {
2644 1079 : bits_dir0[max_nb_idx] = sub( bits_dir0[max_nb_idx], 1 );
2645 1079 : move16();
2646 1079 : allowed_bits = sub( allowed_bits, 1 );
2647 :
2648 : /* read 1 bit to tell if joint of VQ coding */
2649 1079 : byteBuffer = bitstream[bit_pos--];
2650 1079 : move16();
2651 : }
2652 :
2653 7358 : IF( allowed_bits > 0 )
2654 : {
2655 7358 : test();
2656 7358 : IF( EQ_32( byteBuffer, 1 ) || LE_16( use_vq, 1 ) )
2657 : {
2658 1037 : 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 6321 : 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 1845 : FOR( j = 0; j < coding_subbands; j++ )
2682 : {
2683 5704 : FOR( k = 0; k < q_direction->cfg.nblocks; k++ )
2684 : {
2685 4226 : q_direction->band_data[j].elevation_fx[k] = 0;
2686 4226 : move32();
2687 4226 : q_direction->band_data[j].elevation_index[k] = 0;
2688 4226 : move16();
2689 : }
2690 : }
2691 :
2692 367 : nbits = decode_azimuth2D_fx( q_direction, bitstream, coding_subbands, &bit_pos, masa_subframes ); /*Q0*/
2693 : }
2694 8430 : nbits = sub( *pbit_pos, bit_pos );
2695 8430 : *pbit_pos = bit_pos;
2696 8430 : move16();
2697 :
2698 8430 : 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 7273 : 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 7273 : nbits = 0;
2722 7273 : move16();
2723 7273 : bit_pos = *pbit_pos;
2724 7273 : move16();
2725 7273 : byteBuffer = 0;
2726 7273 : move16();
2727 :
2728 7273 : j_az = 0;
2729 7273 : move16();
2730 : /* check number of valid indexes to decode */
2731 36161 : FOR( k = 0; k < masa_subframes; k++ )
2732 : {
2733 28888 : IF( LT_32( q_direction->band_data[idx_subband].azimuth_index[k], MASA_NO_INDEX ) )
2734 : {
2735 28886 : 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 7273 : IF( !j_az )
2745 : {
2746 0 : return nbits;
2747 : }
2748 :
2749 7273 : IF( !byteBuffer )
2750 : {
2751 : /* use context */
2752 7273 : use_context = 0;
2753 7273 : move16();
2754 36161 : FOR( k = 0; k < masa_subframes; k++ )
2755 : {
2756 28888 : 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 7273 : 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 7273 : byteBuffer = bitstream[bit_pos]; /*Q22*/
2801 7273 : move16();
2802 7273 : bit_pos = sub( bit_pos, 1 );
2803 7273 : IF( byteBuffer == 0 ) /* regular GR coding5 */
2804 : {
2805 : /* read GR_order */
2806 2381 : byteBuffer = bitstream[bit_pos];
2807 2381 : move16();
2808 2381 : bit_pos = sub( bit_pos, 1 );
2809 2381 : nbits = add( nbits, 1 );
2810 :
2811 11701 : FOR( k = 0; k < masa_subframes; k++ )
2812 : {
2813 9320 : IF( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 )
2814 : {
2815 9320 : 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 9318 : 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 9318 : move16();
2819 9318 : 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 9318 : 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 4892 : byteBuffer = bitstream[bit_pos]; /*Q0*/
2844 4892 : move16();
2845 4892 : bit_pos = sub( bit_pos, 1 );
2846 : /* read min index value */
2847 4892 : maximum_s( q_direction->band_data[idx_subband].azimuth_m_alphabet, masa_subframes, &max_val );
2848 4892 : min_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, max_val, MASA_GR_ORD_AZ ); /*Q0*/
2849 :
2850 24460 : FOR( k = 0; k < masa_subframes; k++ )
2851 : {
2852 19568 : IF( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 )
2853 : {
2854 19568 : 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 19568 : 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 19568 : move16();
2858 19568 : 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 19568 : move16();
2860 19568 : 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 19568 : 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 7273 : nbits = sub( *pbit_pos, bit_pos );
2884 :
2885 7273 : *pbit_pos = bit_pos;
2886 7273 : move16();
2887 :
2888 7273 : 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 7273 : 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 7273 : nr_NO_INDEX = 0;
2914 7273 : move16();
2915 7273 : nbits = 0;
2916 7273 : move16();
2917 7273 : bit_pos = *pbit_pos;
2918 7273 : move16();
2919 :
2920 36161 : FOR( k = 0; k < masa_subframes; k++ )
2921 : {
2922 28888 : q_direction->band_data[j].elevation_index[k] = 0;
2923 28888 : move16();
2924 28888 : q_direction->band_data[j].elevation_fx[k] = 0;
2925 28888 : move32();
2926 :
2927 28888 : IF( q_direction->band_data[j].bits_sph_idx[k] > 0 )
2928 : {
2929 28888 : 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 28885 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2942 : {
2943 2261 : q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[q_direction->band_data[j].bits_sph_idx[k] - 3]; /*Q0*/
2944 2261 : move16();
2945 : }
2946 : ELSE
2947 : {
2948 26624 : 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 26624 : move16();
2950 : }
2951 : }
2952 : }
2953 : ELSE
2954 : {
2955 0 : nr_NO_INDEX = add( nr_NO_INDEX, 1 );
2956 : }
2957 : }
2958 :
2959 7273 : IF( LT_16( nr_NO_INDEX, masa_subframes ) )
2960 : {
2961 : {
2962 : /* read if same or not */
2963 7273 : byteBuffer = bitstream[bit_pos];
2964 7273 : move16();
2965 7273 : bit_pos = sub( bit_pos, 1 );
2966 7273 : IF( EQ_32( byteBuffer, 1 ) ) /* same value */
2967 : {
2968 : /* read value */
2969 5622 : byteBuffer = bitstream[bit_pos]; /*Q0*/
2970 5622 : move16();
2971 5622 : bit_pos = sub( bit_pos, 1 );
2972 5622 : byteBuffer = (UWord16) L_add( L_shl( byteBuffer, 1 ), bitstream[bit_pos] );
2973 5622 : move16();
2974 5622 : bit_pos = sub( bit_pos, 1 );
2975 5622 : same_idx = byteBuffer;
2976 5622 : move16();
2977 :
2978 27906 : FOR( k = 0; k < masa_subframes; k++ )
2979 : {
2980 22284 : IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) )
2981 : {
2982 22284 : q_direction->band_data[j].elevation_index[k] = same_idx; /*Q0*/
2983 22284 : move16();
2984 22284 : 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 22284 : move32();
2986 : }
2987 : }
2988 : }
2989 : ELSE
2990 : {
2991 : /* not same; decode mean removed GR */
2992 1651 : byteBuffer = bitstream[bit_pos]; /*Q0*/
2993 1651 : bit_pos = sub( bit_pos, 1 );
2994 1651 : move16();
2995 1651 : GR_ord_elevation = extract_l( L_sub( MASA_GR_ORD_EL, byteBuffer ) ); /*Q0*/
2996 :
2997 8255 : FOR( k = 0; k < masa_subframes; k++ )
2998 : {
2999 6604 : IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) )
3000 : {
3001 6601 : 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 6601 : move16();
3003 6601 : 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 6601 : move32();
3005 : }
3006 : }
3007 : }
3008 : }
3009 : }
3010 :
3011 36161 : FOR( k = 0; k < masa_subframes; k++ )
3012 : {
3013 28888 : test();
3014 28888 : 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 28886 : q_direction->band_data[j].azimuth_index[k] = 0;
3025 28886 : move16();
3026 28886 : IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) )
3027 : {
3028 28883 : 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 28883 : 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 7273 : nbits = sub( *pbit_pos, bit_pos );
3042 7273 : *pbit_pos = bit_pos;
3043 7273 : move16();
3044 :
3045 7273 : return nbits;
3046 : }
3047 :
3048 :
3049 476608 : 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 476608 : nbits = 0;
3061 476608 : move16();
3062 :
3063 2095331 : FOR( m = 0; m < nblocks; m++ )
3064 : {
3065 1618723 : value = 0;
3066 1618723 : move16();
3067 8409297 : FOR( i = 0; i < q_direction->band_data[b].bits_sph_idx[m]; i++ )
3068 : {
3069 6790574 : value = (UWord16) L_add( L_shl( value, 1 ), bitstream[( *pbit_pos )--] ); /*Q0*/
3070 6790574 : move16();
3071 : }
3072 :
3073 1618723 : q_direction->band_data[b].spherical_index[m] = value; /*Q0*/
3074 1618723 : move16();
3075 1618723 : nbits = extract_l( L_add( nbits, q_direction->band_data[b].bits_sph_idx[m] ) ); /*Q0*/
3076 :
3077 1618723 : 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 476608 : 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 367 : 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 367 : bit_pos = *pbit_pos;
3105 367 : move16();
3106 367 : nbits = 0;
3107 367 : move16();
3108 1845 : FOR( j = 0; j < coding_subbands; j++ )
3109 : {
3110 1478 : bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx; /*Q0*/
3111 1478 : allowed_bits = sum16_fx( bits_dir0, no_frames );
3112 :
3113 1478 : IF( allowed_bits > 0 )
3114 : {
3115 1478 : use_vq = 0;
3116 1478 : move16();
3117 5704 : FOR( k = 0; k < no_frames; k++ )
3118 : {
3119 4226 : q_direction->band_data[j].elevation_fx[k] = 0;
3120 4226 : move32();
3121 4226 : q_direction->band_data[j].elevation_index[k] = 0;
3122 4226 : move16();
3123 :
3124 4226 : IF( GT_16( bits_dir0[k], use_vq ) )
3125 : {
3126 1688 : use_vq = bits_dir0[k];
3127 1688 : move16();
3128 : }
3129 : }
3130 :
3131 1478 : test();
3132 1478 : IF( LE_16( use_vq, 3 ) && LE_16( allowed_bits, 11 ) )
3133 : {
3134 230 : IF( LE_16( allowed_bits, add( no_frames, 1 ) ) )
3135 : {
3136 80 : set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_frames );
3137 373 : FOR( k = 0; k < s_min( allowed_bits, no_frames ); k++ )
3138 : {
3139 293 : q_direction->band_data[j].azimuth_fx[k] = L_shl( L_mult0( -180, bitstream[bit_pos] ), Q22 ); /*Q22*/
3140 293 : move32();
3141 293 : bit_pos = sub( bit_pos, 1 );
3142 293 : nbits = add( nbits, 1 );
3143 : }
3144 : }
3145 : ELSE
3146 : {
3147 150 : nbits = add( nbits, read_truncGR_azimuth_fx( bitstream, q_direction, j, no_frames, &bit_pos ) ); /*Q0*/
3148 : }
3149 : }
3150 : ELSE
3151 : {
3152 4782 : FOR( k = 0; k < no_frames; k++ )
3153 : {
3154 3534 : Buffer = 0;
3155 3534 : move16();
3156 20083 : FOR( i = 0; i < bits_dir0[k]; i++ )
3157 : {
3158 16549 : Buffer = (UWord16) L_add( L_shl( Buffer, 1 ), bitstream[bit_pos] ); /*Q0*/
3159 16549 : bit_pos = sub( bit_pos, 1 );
3160 : }
3161 :
3162 3534 : nbits = add( nbits, bits_dir0[k] );
3163 :
3164 3534 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
3165 : {
3166 2323 : 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 2323 : move32();
3168 4646 : 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 2323 : (Word16) GT_32( q_direction->band_data[j].elevation_fx[k], L_shl( MC_MASA_THR_ELEVATION, 22 ) ), -1 ); /*Q22*/
3170 2323 : move32();
3171 : }
3172 : ELSE
3173 : {
3174 1211 : 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 1211 : move32();
3176 : }
3177 : }
3178 : }
3179 : }
3180 : ELSE
3181 : {
3182 0 : set_zero_direction_fx( q_direction, j, no_frames );
3183 : }
3184 : }
3185 367 : *pbit_pos = bit_pos;
3186 367 : move16();
3187 :
3188 367 : return nbits;
3189 : }
3190 :
3191 : /*-------------------------------------------------------------------*
3192 : * set_zero_direction()
3193 : *
3194 : *
3195 : *-------------------------------------------------------------------*/
3196 :
3197 3369 : 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 16845 : FOR( k = 0; k < len; k++ )
3205 : {
3206 13476 : q_direction->band_data[idx_band].azimuth_fx[k] = 0;
3207 13476 : move32();
3208 13476 : q_direction->band_data[idx_band].azimuth_index[k] = 0;
3209 13476 : move16();
3210 13476 : q_direction->band_data[idx_band].elevation_fx[k] = 0;
3211 13476 : move32();
3212 13476 : q_direction->band_data[idx_band].elevation_index[k] = 0;
3213 13476 : move16();
3214 13476 : q_direction->band_data[idx_band].spherical_index[k] = 0;
3215 13476 : move16();
3216 : }
3217 :
3218 3369 : return;
3219 : }
3220 :
3221 :
3222 : /*-------------------------------------------------------------------*
3223 : * read_truncGR_azimuth()
3224 : *
3225 : *
3226 : *-------------------------------------------------------------------*/
3227 :
3228 3428 : 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 3428 : allowed_bits = sum16_fx( (Word16 *) q_direction->band_data[j].bits_sph_idx, no_subframes ); /*Q0*/
3242 3428 : nbits = 0;
3243 3428 : move16();
3244 3428 : 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 3428 : IF( NE_16( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
3266 : {
3267 467 : no_symb = 9;
3268 467 : move16();
3269 : }
3270 : ELSE
3271 : {
3272 2961 : no_symb = 8;
3273 2961 : move16();
3274 : }
3275 3428 : nbits = 0;
3276 3428 : move16();
3277 :
3278 3428 : nbits = *pbit_pos;
3279 3428 : move16();
3280 :
3281 16939 : FOR( i = 0; i < no_subframes; i++ )
3282 : {
3283 13511 : idx = ivas_qmetadata_DecodeExtendedGR( bitstream, pbit_pos, no_symb, 0 );
3284 13511 : q_direction->band_data[j].azimuth_index[i] = idx; /*Q0*/
3285 13511 : move16();
3286 13511 : IF( NE_16( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
3287 : {
3288 1862 : q_direction->band_data[j].azimuth_fx[i] = cb_azi_chan_fx[(UWord16) ( (UWord16) ( idx + 1 ) / 2 )]; /*Q22*/
3289 1862 : move32();
3290 1862 : IF( L_and( idx, 1 ) > 0 )
3291 : {
3292 720 : q_direction->band_data[j].azimuth_fx[i] = L_negate( q_direction->band_data[j].azimuth_fx[i] ); /*Q22*/
3293 720 : move32();
3294 : }
3295 : }
3296 : ELSE
3297 : {
3298 11649 : q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[idx]; /*Q22*/
3299 11649 : move32();
3300 : }
3301 : }
3302 :
3303 3428 : nbits = sub( nbits, *pbit_pos );
3304 :
3305 3428 : return nbits;
3306 : }
3307 :
3308 : /*-------------------------------------------------------------------*
3309 : * read_common_direction()
3310 : *
3311 : *
3312 : *-------------------------------------------------------------------*/
3313 :
3314 : /*! r: number of bits read */
3315 3369 : 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 3369 : bit_pos = *pbit_pos;
3331 3369 : move16();
3332 3369 : nbits = 0;
3333 3369 : move16();
3334 :
3335 3369 : set_zero_direction_fx( q_direction, j, no_subframes );
3336 3369 : IF( !bits_total )
3337 : {
3338 0 : return nbits;
3339 : }
3340 :
3341 3369 : 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 3305 : byteBuffer = bitstream[bit_pos]; /*Q0*/
3361 3305 : move16();
3362 3305 : bit_pos = sub( bit_pos, 1 );
3363 3305 : bits_el = 1;
3364 3305 : move16();
3365 3305 : nbits = add( nbits, 1 );
3366 : /* elevation is already set to 0*/
3367 3305 : IF( EQ_32( byteBuffer, 1 ) )
3368 : {
3369 1036 : byteBuffer = bitstream[bit_pos--]; /*Q0*/
3370 1036 : move16();
3371 1036 : bits_el = add( bits_el, 1 );
3372 1036 : nbits = add( nbits, 1 );
3373 1036 : IF( byteBuffer == 0 )
3374 : {
3375 3115 : FOR( i = 0; i < no_subframes; i++ )
3376 : {
3377 2492 : q_direction->band_data[j].elevation_fx[i] = delta_theta_masa_fx[2]; /*Q22*/
3378 2492 : move32();
3379 : }
3380 : }
3381 : ELSE
3382 : {
3383 413 : byteBuffer = bitstream[bit_pos--];
3384 413 : move16();
3385 413 : bits_el = add( bits_el, 1 );
3386 413 : nbits = add( nbits, 1 );
3387 413 : IF( byteBuffer == 0 )
3388 : {
3389 2020 : FOR( i = 0; i < no_subframes; i++ )
3390 : {
3391 1616 : q_direction->band_data[j].elevation_fx[i] = L_negate( delta_theta_masa_fx[2] ); /*Q22*/
3392 1616 : move32();
3393 : }
3394 : }
3395 : ELSE
3396 : {
3397 : /* theta is +/- 90; no azimuth is read */
3398 9 : byteBuffer = bitstream[bit_pos--];
3399 9 : move16();
3400 9 : nbits = add( nbits, 1 );
3401 9 : IF( byteBuffer == 0 )
3402 : {
3403 7 : set32_fx( q_direction->band_data[j].elevation_fx, ( 90 * ONE_IN_Q22 ), no_subframes ); /*Q22*/
3404 7 : set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_subframes ); /*Q22*/
3405 : }
3406 : ELSE
3407 : {
3408 2 : set32_fx( q_direction->band_data[j].elevation_fx, ( -90 * ONE_IN_Q22 ), no_subframes ); /*Q22*/
3409 2 : set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_subframes ); /*Q22*/
3410 : }
3411 9 : *pbit_pos = bit_pos;
3412 9 : move16();
3413 :
3414 9 : return nbits;
3415 : }
3416 : }
3417 : }
3418 :
3419 3296 : bits_el = sub( sum16_fx( (Word16 *) q_direction->band_data[j].bits_sph_idx, no_subframes ), bits_el ); /*Q0*/
3420 :
3421 3296 : IF( LE_16( bits_el, add( no_subframes, 1 ) ) )
3422 : {
3423 18 : nbits = add( nbits, s_min( no_subframes, bits_el ) );
3424 89 : FOR( i = 0; i < s_min( no_subframes, bits_el ); i++ )
3425 : {
3426 71 : byteBuffer = bitstream[bit_pos]; /*Q0*/
3427 71 : move16();
3428 71 : bit_pos = sub( bit_pos, 1 );
3429 : /*qdirection->azimuth_index[j][i] = (uint16_t) byteBuffer; */
3430 71 : q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[byteBuffer]; /*Q22*/
3431 71 : move32();
3432 : }
3433 : }
3434 : ELSE
3435 : {
3436 3278 : nbits = add( nbits, read_truncGR_azimuth_fx( bitstream, q_direction, j, no_subframes, &bit_pos ) );
3437 : }
3438 :
3439 3296 : *pbit_pos = bit_pos;
3440 3296 : move16();
3441 :
3442 3296 : return nbits;
3443 : }
3444 :
3445 : /*-----------------------------------------------------------------------*
3446 : * Local functions: coherence
3447 : *-----------------------------------------------------------------------*/
3448 :
3449 21931 : 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 21931 : coding_subbands_0 = hQMetaData->q_direction[0].cfg.nbands;
3466 21931 : move16();
3467 21931 : coding_subbands = hQMetaData->q_direction[idx_d].cfg.nbands;
3468 21931 : move16();
3469 21931 : IF( LE_16( coding_subbands_0, 5 ) )
3470 : {
3471 95172 : FOR( j = 0; j < 5; j++ )
3472 : {
3473 79310 : MASA_grouping[j] = j;
3474 79310 : move16();
3475 : }
3476 : }
3477 : ELSE
3478 : {
3479 6069 : IF( LE_16( coding_subbands_0, 8 ) )
3480 : {
3481 2490 : Copy( MASA_grouping_8_to_5, MASA_grouping, 8 ); /*Q0*/
3482 : }
3483 3579 : ELSE IF( LE_16( coding_subbands_0, 12 ) )
3484 : {
3485 1491 : Copy( MASA_grouping_12_to_5, MASA_grouping, 12 ); /*Q0*/
3486 : }
3487 2088 : ELSE IF( LE_16( coding_subbands_0, 18 ) )
3488 : {
3489 924 : Copy( MASA_grouping_18_to_5, MASA_grouping, 18 ); /*Q0*/
3490 : }
3491 : ELSE
3492 : {
3493 1164 : IF( LE_16( coding_subbands_0, 24 ) )
3494 : {
3495 1164 : Copy( MASA_grouping_24_to_5, MASA_grouping, 24 ); /*Q0*/
3496 : }
3497 : }
3498 : }
3499 :
3500 21931 : IF( LT_16( coding_subbands, coding_subbands_0 ) )
3501 : {
3502 3230 : d = 0;
3503 3230 : move16();
3504 26122 : FOR( j = 0; j < coding_subbands_0; j++ )
3505 : {
3506 22892 : IF( EQ_16( hQMetaData->twoDirBands[j], 1 ) )
3507 : {
3508 9229 : two_dir_band[d] = j;
3509 9229 : move16();
3510 9229 : d = add( d, 1 );
3511 : }
3512 : }
3513 : }
3514 : ELSE
3515 : {
3516 18701 : set16_fx( two_dir_band, 0, coding_subbands );
3517 : }
3518 :
3519 21931 : q_direction = &hQMetaData->q_direction[idx_d];
3520 :
3521 164670 : FOR( i = 0; i < coding_subbands; i++ )
3522 : {
3523 142739 : var_azi_fx = var_32_fx( q_direction->band_data[i].azimuth_fx, no_frames, 22 ); /*Q22*/
3524 142739 : 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 142739 : min_index = q_direction->band_data[i].energy_ratio_index[0]; /*Q0*/
3532 142739 : move16();
3533 : }
3534 :
3535 142739 : IF( LT_64( var_azi_fx, L_shl( MASA_DELTA_AZI_DCT0, 22 ) ) )
3536 : {
3537 35144 : idx_sub_cb = i_mult( MASA_NO_CV_COH, min_index ); /*Q0*/
3538 : }
3539 : ELSE
3540 : {
3541 107595 : idx_sub_cb = i_mult( MASA_NO_CV_COH, add( min_index, DIRAC_DIFFUSE_LEVELS ) ); /* NO_CV_COH = 8 */
3542 : }
3543 :
3544 142739 : dct_coh_fx[i][0] = coherence_cb0_masa_fx[idx_sub_cb + q_direction->coherence_band_data[i].spread_coherence_dct0_index];
3545 142739 : move32();
3546 :
3547 142739 : IF( LT_16( coding_subbands, coding_subbands_0 ) )
3548 : {
3549 9229 : assert( EQ_16( idx_d, 1 ) );
3550 9229 : 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 9229 : move32();
3552 : }
3553 : ELSE
3554 : {
3555 133510 : 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 133510 : move32();
3557 : }
3558 :
3559 428217 : FOR( j = 2; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
3560 : {
3561 285478 : dct_coh_fx[i][j] = 0;
3562 285478 : move32();
3563 : }
3564 :
3565 142739 : invdct4_transform_fx( dct_coh_fx[i], q_direction->coherence_band_data[i].spread_coherence, 21 );
3566 : }
3567 :
3568 21931 : return;
3569 : }
3570 :
3571 : /*-------------------------------------------------------------------*
3572 : * read_huf()
3573 : *
3574 : * Read Hufman code
3575 : *-------------------------------------------------------------------*/
3576 :
3577 : /*! r: number of bits read */
3578 21931 : 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 21931 : Word16 done = 0, end_pos;
3589 21931 : move16();
3590 : UWord16 ByteBuffer;
3591 : Word16 nbits, val;
3592 : UWord16 i;
3593 :
3594 21931 : end_pos = start_pos;
3595 21931 : move16();
3596 21931 : nbits = 0;
3597 21931 : move16();
3598 21931 : val = 0;
3599 21931 : move16();
3600 108017 : WHILE( !done && LT_16( nbits, max_len ) )
3601 : {
3602 86086 : ByteBuffer = bitstream[end_pos--]; /*Q0*/
3603 86086 : move16();
3604 86086 : val = add( shl( val, 1 ), ByteBuffer & 1 ); /*Q0*/
3605 86086 : nbits = add( nbits, 1 );
3606 407922 : FOR( i = 0; i < len; i++ )
3607 : {
3608 343767 : IF( EQ_16( val, huff_code[i] ) )
3609 : {
3610 21931 : *out = i;
3611 21931 : move16();
3612 21931 : done = 1;
3613 21931 : move16();
3614 21931 : BREAK;
3615 : }
3616 : }
3617 : }
3618 :
3619 21931 : *num_bits_read = end_pos;
3620 21931 : move16();
3621 :
3622 21931 : return IVAS_ERR_OK;
3623 : }
3624 :
3625 :
3626 : /*-------------------------------------------------------------------*
3627 : * read_GR_min_removed_data()
3628 : *
3629 : *
3630 : *-------------------------------------------------------------------*/
3631 3717 : 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 3717 : bit_pos = *p_bit_pos;
3646 3717 : move16();
3647 :
3648 : /* read GR order */
3649 3717 : byteBuffer = bitstream[bit_pos]; /*Q0*/
3650 3717 : move16();
3651 3717 : bit_pos = sub( bit_pos, 1 );
3652 3717 : nbits = 1;
3653 3717 : move16();
3654 :
3655 : /* read min index */
3656 3717 : bits_GR = bit_pos;
3657 3717 : move16();
3658 3717 : min_index = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, no_symb, 0 ); /*Q0*/
3659 3717 : nbits = add( nbits, sub( bits_GR, bit_pos ) );
3660 :
3661 : /* read GR data */
3662 41516 : FOR( j = 0; j < no_data; j++ )
3663 : {
3664 37799 : bits_GR = bit_pos;
3665 37799 : move16();
3666 37799 : IF( GT_16( no_cv_vec[j], 1 ) )
3667 : {
3668 36055 : decoded_idx[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, sub( no_cv_vec[j], min_index ), extract_l( L_and( byteBuffer, 1 ) ) ); /*Q0*/
3669 36055 : move16();
3670 36055 : nbits = add( nbits, sub( bits_GR, bit_pos ) );
3671 : }
3672 : ELSE
3673 : {
3674 1744 : decoded_idx[j] = 0;
3675 1744 : move16();
3676 : }
3677 : }
3678 :
3679 41516 : FOR( j = 0; j < no_data; j++ ){
3680 37799 : IF( GT_16( no_cv_vec[j], 1 ) ){
3681 36055 : decoded_idx[j] = add( decoded_idx[j], min_index );
3682 36055 : move16();
3683 : }
3684 : }
3685 :
3686 3717 : *p_bit_pos = bit_pos;
3687 3717 : move16();
3688 :
3689 3717 : return nbits;
3690 : }
3691 :
3692 :
3693 : /*-------------------------------------------------------------------*
3694 : * decode_fixed_rate_composed_index_coherence()
3695 : *
3696 : *
3697 : *-------------------------------------------------------------------*/
3698 :
3699 9367 : 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 9367 : bit_pos = *p_bit_pos;
3719 9367 : move16();
3720 9367 : set16_fx( (Word16 *) temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
3721 :
3722 9367 : no_cb = 1;
3723 9367 : move64();
3724 9367 : nbits = 0;
3725 9367 : move16();
3726 9367 : IF( GT_16( no_bands, MASA_LIMIT_NO_BANDS_SUR_COH ) )
3727 : {
3728 : /* read 8-max_val with GR0 */
3729 660 : bits_GR = bit_pos;
3730 660 : move16();
3731 660 : no_vals_local = sub( no_symb, ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, no_symb, 0 ) );
3732 660 : nbits = add( nbits, sub( bits_GR, bit_pos ) );
3733 12268 : FOR( j = 0; j < no_bands; j++ )
3734 : {
3735 11608 : IF( GT_16( no_cv_vec[j], no_vals_local ) )
3736 : {
3737 10371 : no_cv_vec[j] = no_vals_local; /*Q0*/
3738 10371 : move16();
3739 : }
3740 : }
3741 : }
3742 :
3743 9367 : half_no_bands = shr( no_bands, 1 ); /* no_bands / 2 */
3744 9367 : IF( GT_16( sum16_fx( no_cv_vec, no_bands ), MASA_COH_LIMIT_2IDX ) )
3745 : {
3746 127 : no_cb = 1;
3747 127 : move64();
3748 :
3749 1545 : FOR( j = 0; j < half_no_bands; j++ )
3750 : {
3751 1418 : no_cb *= no_cv_vec[j]; /*Q0*/
3752 1418 : move16();
3753 : }
3754 127 : no_bits_vec = (Word16) ceil_log_2( no_cb );
3755 127 : no_cb = 1;
3756 127 : move64();
3757 1561 : FOR( j = half_no_bands; j < no_bands; j++ )
3758 : {
3759 1434 : no_cb *= no_cv_vec[j]; /*Q0*/
3760 1434 : move16();
3761 : }
3762 127 : no_bits_vec1 = (Word16) ceil_log_2( no_cb );
3763 : }
3764 : ELSE
3765 : {
3766 9240 : no_cb = 1;
3767 9240 : move64();
3768 55744 : FOR( j = 0; j < no_bands; j++ )
3769 : {
3770 46504 : no_cb *= no_cv_vec[j]; /*Q0*/
3771 46504 : move16();
3772 : }
3773 9240 : no_bits_vec = (Word16) ceil_log_2( no_cb );
3774 9240 : no_bits_vec1 = 0;
3775 9240 : move16();
3776 : }
3777 9367 : IF( no_bits_vec1 > 0 )
3778 : {
3779 127 : idx_fr = 0;
3780 127 : move64();
3781 3885 : FOR( j = 0; j < no_bits_vec; j++ )
3782 : {
3783 3758 : idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos]; /*Q0*/
3784 3758 : bit_pos = sub( bit_pos, 1 );
3785 3758 : move64();
3786 : }
3787 :
3788 127 : nbits = add( nbits, no_bits_vec );
3789 :
3790 127 : decode_combined_index_fx( idx_fr, no_cv_vec, temp_index, half_no_bands );
3791 :
3792 127 : idx_fr = 0;
3793 127 : move64();
3794 4050 : FOR( j = 0; j < no_bits_vec1; j++ )
3795 : {
3796 3923 : idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos]; /*Q0*/
3797 3923 : bit_pos = sub( bit_pos, 1 );
3798 3923 : move64();
3799 : }
3800 127 : nbits = add( nbits, no_bits_vec1 );
3801 127 : 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 9240 : idx_fr = 0;
3806 9240 : move64();
3807 88491 : FOR( j = 0; j < no_bits_vec; j++ )
3808 : {
3809 79251 : idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos]; /*Q0*/
3810 79251 : bit_pos = sub( bit_pos, 1 );
3811 79251 : move64();
3812 : }
3813 9240 : nbits = add( nbits, no_bits_vec );
3814 9240 : decode_combined_index_fx( idx_fr, no_cv_vec, temp_index, no_bands );
3815 : }
3816 :
3817 58723 : FOR( j = 0; j < no_bands; j++ )
3818 : {
3819 49356 : decoded_index[j] = temp_index[j]; /*Q0*/
3820 49356 : move16();
3821 : }
3822 9367 : nbits = sub( *p_bit_pos, bit_pos );
3823 :
3824 9367 : *p_bit_pos = bit_pos; /*Q0*/
3825 9367 : move16();
3826 :
3827 9367 : 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 3478 : 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 3478 : nbands = hQMetaData->q_direction[idx_dir].cfg.nbands;
3852 3478 : move16();
3853 3478 : nblocks = hQMetaData->q_direction[idx_dir].cfg.nblocks;
3854 3478 : move16();
3855 :
3856 3478 : cb_size = shl( 1, nbits_coh );
3857 3478 : delta_fx = L_shl( 256, sub( 22, nbits_coh ) );
3858 3478 : nbits = *p_bit_pos;
3859 3478 : move16();
3860 16544 : FOR( k = 0; k < nblocks; k++ )
3861 : {
3862 : /* read method */
3863 13066 : IF( EQ_32( bitstream[( *p_bit_pos )--], 1 ) )
3864 : {
3865 : /* average removed */
3866 : /* read average index */
3867 140 : min_index = 0;
3868 140 : move16();
3869 582 : FOR( i = 0; i < nbits_coh; i++ )
3870 : {
3871 442 : min_index = add( shl( min_index, 1 ), bitstream[( *p_bit_pos )] ); /*Q0*/
3872 442 : ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
3873 442 : move16();
3874 : }
3875 : /* read GR param */
3876 140 : GR_param = bitstream[( *p_bit_pos )]; /*Q0*/
3877 140 : move16();
3878 140 : ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
3879 140 : move16();
3880 1948 : FOR( j = 0; j < nbands; j++ )
3881 : {
3882 1808 : decoded_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, p_bit_pos, shl( cb_size, 1 ), GR_param ); /*Q0*/
3883 1808 : IF( EQ_16( s_and( decoded_idx, 1 ), 1 ) )
3884 : {
3885 754 : decoded_idx = add( shr( add( decoded_idx, 1 ), 1 ), min_index );
3886 : }
3887 : ELSE
3888 : {
3889 1054 : decoded_idx = add( negate( shr( decoded_idx, 1 ) ), min_index );
3890 : }
3891 1808 : decoded_idx_fx = L_shl( decoded_idx, 9 );
3892 1808 : 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 1808 : move16();
3894 : }
3895 : }
3896 : ELSE
3897 : {
3898 : /* read min_index */
3899 12926 : min_index = 0;
3900 12926 : move16();
3901 56362 : FOR( i = 0; i < nbits_coh; i++ )
3902 : {
3903 43436 : min_index = add( shl( min_index, 1 ), bitstream[( *p_bit_pos )] ); /*Q0*/
3904 43436 : ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
3905 43436 : move16();
3906 : }
3907 :
3908 : /* read GR param */
3909 12926 : GR_param = bitstream[( *p_bit_pos )]; /*Q0*/
3910 12926 : move16();
3911 12926 : ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
3912 12926 : move16();
3913 279213 : FOR( j = 0; j < nbands; j++ )
3914 : {
3915 266287 : decoded_idx = add( ivas_qmetadata_DecodeExtendedGR( bitstream, p_bit_pos, cb_size - min_index, GR_param ), min_index ); /*Q0*/
3916 266287 : decoded_idx_fx = L_shl( decoded_idx, 9 ); /*Q9*/
3917 266287 : 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 266287 : move16();
3919 : }
3920 : }
3921 : }
3922 :
3923 3478 : nbits = sub( nbits, *p_bit_pos );
3924 :
3925 3478 : return nbits;
3926 : }
3927 :
3928 : /*------------------------------------------------------------------- *
3929 : * read_coherence_data()
3930 : *
3931 : * Read coherence data
3932 : *------------------------------------------------------------------- */
3933 :
3934 : /*! r: number of bits read */
3935 30043 : 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 30043 : coding_subbands = hQMetaData->q_direction[idx_dir].cfg.nbands;
3964 30043 : move16();
3965 30043 : extra_cv = idiv1616( coding_subbands, MASA_FACTOR_CV_COH ); /*Q0*/
3966 30043 : move16();
3967 30043 : q_direction = &( hQMetaData->q_direction[idx_dir] );
3968 30043 : bit_pos = *p_bit_pos;
3969 30043 : move16();
3970 30043 : nbits = 0;
3971 30043 : move16();
3972 :
3973 30043 : IF( EQ_16( q_direction->cfg.nblocks, 1 ) )
3974 : {
3975 68877 : FOR( j = 0; j < coding_subbands; j++ )
3976 : {
3977 60765 : 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 60765 : idx_ER = extract_l( L_add( L_sub( 7, q_direction->band_data[j].energy_ratio_index_mod[0] ), extra_cv ) ); /*Q0*/
3984 : }
3985 60765 : no_cv_vec[j] = add( idx_ER, 1 );
3986 60765 : move16();
3987 : }
3988 :
3989 8112 : IF( EQ_16( sum16_fx( no_cv_vec, coding_subbands ), coding_subbands ) )
3990 : {
3991 4905 : FOR( j = 0; j < coding_subbands; j++ )
3992 : {
3993 4039 : q_direction->coherence_band_data[j].spread_coherence[0] = 0;
3994 : }
3995 :
3996 866 : return 0;
3997 : }
3998 7246 : byteBuffer = bitstream[bit_pos]; /*Q0*/
3999 7246 : move16();
4000 7246 : bit_pos = sub( bit_pos, 1 );
4001 7246 : nbits = add( nbits, 1 );
4002 :
4003 7246 : IF( L_and( byteBuffer, 1 ) )
4004 : {
4005 : /* decode GR min removed */
4006 3717 : 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 41516 : FOR( j = 0; j < coding_subbands; j++ )
4008 : {
4009 37799 : IF( GT_16( no_cv_vec[j], 1 ) )
4010 : {
4011 36055 : num = i_mult( decoded_idx[j], 255 ); /*Q0*/
4012 36055 : move16();
4013 36055 : 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 36055 : q_den = norm_s( den );
4015 36055 : q_num = sub( norm_s( num ), 1 );
4016 36055 : res = div_s( shl( num, q_num ), shl( den, q_den ) ); /*Q15*/
4017 36055 : q_res = add( sub( 15, q_den ), q_num );
4018 36055 : res = L_shl( res, sub( 16, q_res ) ); /*Q16*/
4019 36055 : q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) ( round_fx( res ) ); /*Q0*/
4020 36055 : move16();
4021 : }
4022 : ELSE
4023 : {
4024 1744 : q_direction->coherence_band_data[j].spread_coherence[0] = 0;
4025 1744 : move16();
4026 : }
4027 : }
4028 : }
4029 : ELSE
4030 : {
4031 : UWord16 decoded_index[MASA_MAXIMUM_CODING_SUBBANDS];
4032 : /* decode joint index */
4033 3529 : 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 22456 : FOR( j = 0; j < coding_subbands; j++ )
4035 : {
4036 18927 : IF( GT_16( no_cv_vec[j], 1 ) )
4037 : {
4038 9213 : num = i_mult( decoded_index[j], 255 ); /*Q0*/
4039 9213 : move16();
4040 9213 : 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 9213 : q_den = norm_s( den );
4042 9213 : q_num = sub( norm_s( num ), 1 );
4043 9213 : res = div_s( shl( num, q_num ), shl( den, q_den ) ); /*Q15*/
4044 9213 : q_res = add( sub( 15, q_den ), q_num );
4045 9213 : res = L_shl( res, sub( 16, q_res ) ); /*Q16*/
4046 9213 : q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) ( round_fx( res ) ); /*Q0*/
4047 9213 : move16();
4048 : }
4049 : ELSE
4050 : {
4051 9714 : q_direction->coherence_band_data[j].spread_coherence[0] = 0;
4052 9714 : move16();
4053 : }
4054 : }
4055 : }
4056 : }
4057 : ELSE
4058 : {
4059 164670 : FOR( j = 0; j < coding_subbands; j++ )
4060 : {
4061 142739 : 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 142739 : no_cv_vec[j] = len_cb_dct0_masa[q_direction->band_data[j].energy_ratio_index[0]]; /*Q0*/
4070 142739 : move16(); /* spread coherence DCT0*/
4071 : }
4072 : }
4073 :
4074 21931 : 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 173 : no_cb = 1;
4079 173 : move64();
4080 2249 : FOR( j = 0; j < shr( coding_subbands, 1 ); j++ )
4081 : {
4082 2076 : no_cb *= no_cv_vec[j];
4083 2076 : move64();
4084 : }
4085 :
4086 173 : no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); Q0
4087 173 : no_cb = 1;
4088 173 : move64();
4089 :
4090 2249 : FOR( j = coding_subbands / 2; j < coding_subbands; j++ )
4091 : {
4092 2076 : no_cb *= no_cv_vec[j];
4093 2076 : move64();
4094 : }
4095 :
4096 173 : no_bits_vec1 = ceil_log_2( no_cb ); // (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); Q0
4097 173 : dct0_index = 0;
4098 173 : move64();
4099 :
4100 4690 : FOR( j = 0; j < no_bits_vec; j++ )
4101 : {
4102 4517 : dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos]; /*Q0*/
4103 4517 : bit_pos = sub( bit_pos, 1 );
4104 4517 : move64();
4105 : }
4106 :
4107 173 : nbits = add( nbits, no_bits_vec );
4108 173 : set_s( (Word16 *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
4109 :
4110 173 : decode_combined_index_fx( dct0_index, no_cv_vec, spr_coh_temp_index, shr( coding_subbands, 1 ) );
4111 :
4112 173 : dct0_index = 0;
4113 173 : move64();
4114 4277 : FOR( j = 0; j < no_bits_vec1; j++ )
4115 : {
4116 4104 : dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos]; /*Q0*/
4117 4104 : bit_pos = sub( bit_pos, 1 );
4118 4104 : move64();
4119 : }
4120 :
4121 173 : nbits = add( nbits, no_bits_vec1 );
4122 :
4123 173 : 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 4325 : FOR( j = 0; j < coding_subbands; j++ )
4126 : {
4127 4152 : q_direction->coherence_band_data[j].spread_coherence_dct0_index = spr_coh_temp_index[j]; /*Q0*/
4128 4152 : move16();
4129 : }
4130 : }
4131 : ELSE
4132 : {
4133 : /* spread coherence */
4134 : UWord16 spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
4135 :
4136 21758 : no_cb = 1;
4137 21758 : move64();
4138 :
4139 160345 : FOR( j = 0; j < coding_subbands; j++ )
4140 : {
4141 138587 : no_cb *= no_cv_vec[j];
4142 138587 : move64();
4143 : }
4144 :
4145 21758 : 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 21758 : no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); Q0
4149 21758 : dct0_index = 0;
4150 21758 : move64();
4151 :
4152 256373 : FOR( j = 0; j < no_bits_vec; j++ )
4153 : {
4154 234615 : dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos]; /*Q0*/
4155 234615 : bit_pos = sub( bit_pos, 1 );
4156 234615 : move64();
4157 : }
4158 :
4159 21758 : nbits = add( nbits, no_bits_vec );
4160 :
4161 21758 : set16_fx( (Word16 *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
4162 :
4163 21758 : decode_combined_index_fx( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands );
4164 :
4165 160345 : FOR( j = 0; j < coding_subbands; j++ )
4166 : {
4167 138587 : q_direction->coherence_band_data[j].spread_coherence_dct0_index = spr_coh_temp_index[j]; /*Q0*/
4168 138587 : move16();
4169 : }
4170 : }
4171 :
4172 : /* read GR data for DCT1 */
4173 164670 : FOR( j = 0; j < coding_subbands; j++ )
4174 : {
4175 142739 : bits_GR = bit_pos;
4176 142739 : idx_dct1[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, shl( MASA_NO_CV_COH1, 1 ), 0 ); /*Q0*/
4177 142739 : move16();
4178 142739 : nbits = add( nbits, sub( bits_GR, bit_pos ) );
4179 : }
4180 21931 : bits_GR = bit_pos;
4181 21931 : move16(); /* just to store the data */
4182 :
4183 : /* read average index */
4184 21931 : read_huf( &bit_pos, bitstream, &av_index, bit_pos, MASA_NO_CV_COH1, huff_code_av_masa, 10 ); /* 10 is MAX_LEN*/
4185 21931 : nbits = add( nbits, sub( bits_GR, bit_pos ) );
4186 :
4187 : /* write indexes in metadata structure */
4188 164670 : FOR( j = 0; j < coding_subbands; j++ )
4189 : {
4190 142739 : IF( L_and( idx_dct1[j], 1 ) )
4191 : {
4192 3232 : 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 3232 : move16();
4194 : }
4195 : ELSE
4196 : {
4197 139507 : 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 139507 : move16();
4199 : }
4200 : }
4201 : }
4202 29177 : nbits = sub( *p_bit_pos, bit_pos );
4203 :
4204 29177 : *p_bit_pos = bit_pos;
4205 29177 : move16();
4206 :
4207 29177 : return nbits;
4208 : }
4209 :
4210 : /*-------------------------------------------------------------------*
4211 : * read_surround_coherence()
4212 : *
4213 : *
4214 : *-------------------------------------------------------------------*/
4215 :
4216 25838 : 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 25838 : coding_subbands = hQMetaData->q_direction[0].cfg.nbands;
4235 25838 : q_direction = hQMetaData->q_direction;
4236 :
4237 25838 : bits_sur_coherence = 0;
4238 25838 : move16();
4239 25838 : bit_pos = *p_bit_pos;
4240 25838 : move16();
4241 :
4242 25838 : d = 0;
4243 25838 : move16();
4244 216380 : FOR( j = 0; j < coding_subbands; j++ )
4245 : {
4246 190542 : error_ratio_surr = ONE_IN_Q30;
4247 190542 : move32();
4248 :
4249 190542 : IF( EQ_16( hQMetaData->no_directions, 2 ) )
4250 : {
4251 36488 : d = add( d, hQMetaData->twoDirBands[j] );
4252 36488 : idx = s_max( sub( d, 1 ), 0 );
4253 36488 : IF( EQ_16( hQMetaData->twoDirBands[j], 1 ) )
4254 : {
4255 12202 : 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 24286 : 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 154054 : error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ); /*Q30*/
4265 : }
4266 :
4267 190542 : IF( error_ratio_surr <= 0 )
4268 : {
4269 155 : error_ratio_surr = 0;
4270 155 : move32();
4271 155 : no_cv_vec[j] = 1;
4272 155 : move16();
4273 155 : idx_ER[j] = masa_sq_fx( 0, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
4274 155 : move16();
4275 : }
4276 : ELSE
4277 : {
4278 190387 : idx_ER[j] = masa_sq_fx( error_ratio_surr, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
4279 190387 : move16();
4280 190387 : no_cv_vec[j] = add( idx_cb_sur_coh_masa[idx_ER[j]], 2 );
4281 190387 : move16();
4282 : }
4283 : }
4284 :
4285 25838 : 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 25838 : byteBuffer = bitstream[bit_pos]; /*Q0*/
4305 25838 : bit_pos = sub( bit_pos, 1 );
4306 25838 : move16();
4307 25838 : bits_sur_coherence = add( bits_sur_coherence, 1 );
4308 :
4309 25838 : IF( L_and( byteBuffer, 1 ) )
4310 : {
4311 : /* GR decoding */
4312 : /* read GR order */
4313 20173 : byteBuffer = bitstream[bit_pos]; /*Q0*/
4314 20173 : bit_pos = sub( bit_pos, 1 );
4315 20173 : bits_sur_coherence = add( bits_sur_coherence, 1 );
4316 :
4317 : /* read min index */
4318 20173 : bits_GR = bit_pos;
4319 20173 : move16();
4320 20173 : min_index = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, MASA_MAX_NO_CV_SUR_COH, 0 ); /*Q0*/
4321 20173 : bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
4322 :
4323 : /* read GR data */
4324 184388 : FOR( j = 0; j < coding_subbands; j++ )
4325 : {
4326 164215 : bits_GR = bit_pos;
4327 164215 : move16();
4328 : /* decoding for min removed */
4329 164215 : IF( GT_16( no_cv_vec[j], 1 ) )
4330 : {
4331 164076 : idx_sur_coh[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, sub( no_cv_vec[j], min_index ), ( byteBuffer & 1 ) ); /*Q30*/
4332 164076 : move16();
4333 164076 : bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
4334 : }
4335 : ELSE
4336 : {
4337 139 : idx_sur_coh[j] = 0;
4338 139 : move16();
4339 : }
4340 : }
4341 :
4342 184388 : FOR( j = 0; j < coding_subbands; j++ )
4343 : {
4344 164215 : IF( GT_16( no_cv_vec[j], 1 ) )
4345 : {
4346 164076 : hQMetaData->surcoh_band_data[j].sur_coherence_index = add( idx_sur_coh[j], min_index ); /*Q0*/
4347 164076 : move16();
4348 : }
4349 : ELSE
4350 : {
4351 139 : hQMetaData->surcoh_band_data[j].sur_coherence_index = idx_sur_coh[j]; /*Q0*/
4352 139 : move16();
4353 : }
4354 :
4355 164215 : 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 164215 : move16();
4357 : }
4358 : }
4359 : ELSE
4360 : {
4361 : /* fixed rate */
4362 : UWord16 sur_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
4363 5665 : set16_fx( (Word16 *) sur_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
4364 :
4365 5665 : 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 31992 : FOR( j = 0; j < coding_subbands; j++ )
4368 : {
4369 26327 : hQMetaData->surcoh_band_data[j].sur_coherence_index = sur_coh_temp_index[j]; /*Q0*/
4370 26327 : move16();
4371 : }
4372 :
4373 : /* deindex surround coherence */
4374 31992 : FOR( j = 0; j < coding_subbands; j++ )
4375 : {
4376 26327 : IF( GT_16( no_cv_vec[j], 1 ) )
4377 : {
4378 23627 : 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 23627 : move16();
4380 : }
4381 : ELSE
4382 : {
4383 2700 : hQMetaData->surcoh_band_data[j].surround_coherence[0] = 0;
4384 2700 : move16();
4385 : }
4386 : }
4387 : }
4388 :
4389 216380 : FOR( j = 0; j < coding_subbands; j++ )
4390 : {
4391 762168 : FOR( k = 1; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ )
4392 : {
4393 571626 : hQMetaData->surcoh_band_data[j].surround_coherence[k] = hQMetaData->surcoh_band_data[j].surround_coherence[0]; /*Q0*/
4394 571626 : move16();
4395 : }
4396 : }
4397 :
4398 : /* Replace return value with the actual read bits. bits_sur_coherence might show wrong count at this point. */
4399 25838 : bits_sur_coherence = sub( *p_bit_pos, bit_pos );
4400 25838 : *p_bit_pos = bit_pos;
4401 25838 : move16();
4402 :
4403 25838 : return bits_sur_coherence;
4404 : }
4405 :
4406 :
4407 : /*-------------------------------------------------------------------*
4408 : * read_surround_coherence_hr()
4409 : *
4410 : *
4411 : *-------------------------------------------------------------------*/
4412 2239 : 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 2239 : coding_subbands = hQMetaData->q_direction[0].cfg.nbands;
4431 : // q_direction = hQMetaData->q_direction;
4432 :
4433 2239 : bits_sur_coherence = 0;
4434 2239 : move16();
4435 2239 : bit_pos = *p_bit_pos;
4436 2239 : move16();
4437 :
4438 10772 : FOR( sf = 0; sf < hQMetaData->q_direction[0].cfg.nblocks; sf++ )
4439 : {
4440 8533 : d = 0;
4441 8533 : move16();
4442 :
4443 212608 : FOR( j = 0; j < coding_subbands; j++ )
4444 : {
4445 204075 : error_ratio_surr_fx = ONE_IN_Q62;
4446 204075 : IF( EQ_32( hQMetaData->no_directions, 2 ) )
4447 : {
4448 108075 : d = add( d, hQMetaData->twoDirBands[j] ); /*Q0*/
4449 108075 : idx = s_max( sub( d, 1 ), 0 );
4450 108075 : error_ratio_surr_fx = W_sub(
4451 : W_sub( ONE_IN_Q62, energy_ratio[0][j][sf] ),
4452 108075 : energy_ratio[1][idx][sf] * hQMetaData->twoDirBands[j] ); /*Q62*/
4453 : }
4454 : ELSE
4455 : {
4456 96000 : error_ratio_surr_fx = W_sub( ONE_IN_Q62, energy_ratio[0][j][sf] ); /*Q62*/
4457 : }
4458 :
4459 204075 : IF( LE_64( error_ratio_surr_fx, ( 461168601842 ) ) ) // 1e-7 in Q62
4460 : {
4461 1642 : error_ratio_surr_fx = 0;
4462 1642 : move64();
4463 1642 : no_cv_vec[j] = 1;
4464 1642 : move16();
4465 1642 : idx_ER[j] = 0;
4466 1642 : move16();
4467 : }
4468 : ELSE
4469 : {
4470 202433 : idx_ER[j] = 7; // masa_sq( error_ratio_surr, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
4471 202433 : no_cv_vec[j] = add( idx_cb_sur_coh_masa[idx_ER[j]], 2 ); /*Q0*/
4472 202433 : move16();
4473 202433 : move16();
4474 : }
4475 : }
4476 :
4477 8533 : 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 8533 : byteBuffer = bitstream[bit_pos]; /*Q0*/
4496 8533 : move16();
4497 8533 : bit_pos = sub( bit_pos, 1 );
4498 8533 : bits_sur_coherence = add( bits_sur_coherence, 1 );
4499 :
4500 8533 : IF( byteBuffer & 1 )
4501 : {
4502 : /* GR decoding */
4503 : /* read GR order */
4504 8360 : byteBuffer = bitstream[bit_pos]; /*Q0*/
4505 8360 : move16();
4506 8360 : bit_pos = sub( bit_pos, 1 );
4507 8360 : bits_sur_coherence = add( bits_sur_coherence, 1 );
4508 :
4509 : /* read min index */
4510 8360 : bits_GR = bit_pos;
4511 8360 : min_index = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, MASA_MAX_NO_CV_SUR_COH, 0 ); /*Q0*/
4512 8360 : bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
4513 :
4514 : /* read GR data */
4515 208333 : FOR( j = 0; j < coding_subbands; j++ )
4516 : {
4517 199973 : bits_GR = bit_pos;
4518 199973 : move16();
4519 : /* decoding for min removed */
4520 199973 : IF( GT_16( no_cv_vec[j], 1 ) )
4521 : {
4522 198355 : idx_sur_coh[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, sub( no_cv_vec[j], min_index ), ( byteBuffer & 1 ) ); /*Q0*/
4523 198355 : move16();
4524 198355 : bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
4525 : }
4526 : ELSE
4527 : {
4528 1618 : idx_sur_coh[j] = 0;
4529 1618 : move16();
4530 : }
4531 : }
4532 :
4533 208333 : FOR( j = 0; j < coding_subbands; j++ )
4534 : {
4535 199973 : IF( GT_16( no_cv_vec[j], 1 ) )
4536 : {
4537 198355 : hQMetaData->surcoh_band_data[j].sur_coherence_index = (UWord16) L_add( (Word32) idx_sur_coh[j], L_deposit_l( min_index ) ); /*Q0*/
4538 198355 : move16();
4539 198355 : 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 198355 : move16();
4541 : }
4542 : ELSE
4543 : {
4544 1618 : hQMetaData->surcoh_band_data[j].sur_coherence_index = idx_sur_coh[j]; /*Q0*/
4545 1618 : move16();
4546 1618 : hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0;
4547 1618 : move16();
4548 : }
4549 : }
4550 : }
4551 : ELSE
4552 : {
4553 : /* fixed rate */
4554 : UWord16 sur_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
4555 173 : set16_fx( (Word16 *) sur_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
4556 :
4557 173 : 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 4275 : FOR( j = 0; j < coding_subbands; j++ )
4560 : {
4561 4102 : hQMetaData->surcoh_band_data[j].sur_coherence_index = sur_coh_temp_index[j]; /*Q0*/
4562 4102 : move16();
4563 : }
4564 :
4565 : /* deindex surround coherence */
4566 4275 : FOR( j = 0; j < coding_subbands; j++ )
4567 : {
4568 4102 : IF( GT_16( no_cv_vec[j], 1 ) )
4569 : {
4570 4007 : 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 4007 : move16();
4572 : }
4573 : ELSE
4574 : {
4575 95 : hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0;
4576 95 : 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 2239 : bits_sur_coherence = sub( *p_bit_pos, bit_pos );
4585 2239 : *p_bit_pos = bit_pos;
4586 2239 : move16();
4587 :
4588 2239 : return bits_sur_coherence;
4589 : }
4590 :
4591 :
4592 : /*-------------------------------------------------------------------*
4593 : * decode_combined_index()
4594 : *
4595 : * Decode combined index into several indexes
4596 : *-------------------------------------------------------------------*/
4597 :
4598 31598 : 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 31598 : base[0] = 1;
4609 31598 : move64();
4610 192079 : FOR( i = 1; i < len; i++ )
4611 : {
4612 160481 : base[i] = base[i - 1] * no_cv_vec[i - 1];
4613 : }
4614 :
4615 192079 : FOR( i = len - 1; i > 0; i-- )
4616 : {
4617 160481 : index[i] = (UWord16) ( comb_index / base[i] );
4618 160481 : comb_index -= index[i] * base[i];
4619 : }
4620 :
4621 31598 : index[0] = (UWord16) comb_index;
4622 31598 : move16();
4623 :
4624 31598 : return;
4625 : }
4626 :
4627 :
4628 1634 : 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 1634 : step = STEP_M2T_FX;
4642 1634 : move32();
4643 1634 : move16();
4644 1634 : sign = 1;
4645 1634 : move16();
4646 1634 : 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 1634 : set16_fx( q_idx, 0, len_stream );
4659 : /* read DCT 0 component */
4660 11438 : FOR( i = 0; i < BITS_MASA2TOTTAL_DCT0; i++ )
4661 : {
4662 9804 : q_idx[0] = add( shl( q_idx[0], 1 ), bit_stream[( *index )--] ); /*Q0*/
4663 9804 : move16();
4664 : }
4665 1634 : q_idx[0] = i_mult( q_idx[0], sign ); /*Q0*/
4666 1634 : move16();
4667 :
4668 1634 : IF( q_idx[0] != 0 )
4669 : {
4670 1634 : IF( GE_16( len_stream, 8 ) )
4671 : {
4672 : /* read index of last index encoded with GR2 */
4673 1440 : i_min = 0;
4674 1440 : move16();
4675 1440 : j = 4;
4676 1440 : move16();
4677 7200 : FOR( i = 0; i < j; i++ )
4678 : {
4679 5760 : i_min = extract_l( L_add( shl( i_min, 1 ), bit_stream[( *index )--] ) ); /*Q0*/
4680 : }
4681 :
4682 : /* read GR orders */
4683 1440 : GR1 = extract_l( L_add( bit_stream[( *index )--], 1 ) ); /*Q0*/
4684 1440 : IF( EQ_16( GR1, 2 ) )
4685 : {
4686 1096 : GR2 = bit_stream[( *index )--]; /*Q0*/
4687 1096 : move16();
4688 : }
4689 : ELSE
4690 : {
4691 344 : GR2 = 0;
4692 344 : move16();
4693 : }
4694 :
4695 : /* read GR data */
4696 8286 : FOR( i = 1; i <= i_min; i++ )
4697 : {
4698 6846 : q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 ); /*Q0*/
4699 6846 : move16();
4700 : }
4701 19074 : FOR( i = ( i_min + 1 ); i < len_stream; i++ )
4702 : {
4703 17634 : q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR2 ); /*Q0*/
4704 17634 : move16();
4705 : }
4706 : }
4707 : ELSE
4708 : {
4709 : /* read GR order (only one) */
4710 194 : GR1 = bit_stream[( *index )]; /*Q0*/
4711 194 : move16();
4712 194 : ( *index ) = sub( ( *index ), 1 );
4713 194 : move16();
4714 950 : FOR( i = 1; i < len_stream; i++ )
4715 : {
4716 756 : q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 ); /*Q0*/
4717 756 : move16();
4718 : }
4719 : }
4720 : }
4721 :
4722 : /* deindex */
4723 1634 : q_dct_data_fx[0] = L_shl( Mpy_32_16_1( step, shl( q_idx[0], 7 ) ), 2 ); // q = 25
4724 1634 : move32();
4725 26870 : FOR( i = 1; i < len_stream; i++ )
4726 : {
4727 25236 : IF( s_and( q_idx[i], 1 ) == 0 )
4728 : {
4729 17577 : q_dct_data_fx[i] = L_shl( Mpy_32_16_1( step, negate( shl( q_idx[i], 6 ) ) ), 2 ); /*Q25*/
4730 17577 : move32();
4731 : }
4732 : ELSE
4733 : {
4734 7659 : q_dct_data_fx[i] = L_shl( Mpy_32_16_1( step, shl( q_idx[i] + 1, 6 ) ), 2 ); /*Q25*/
4735 7659 : move32();
4736 : }
4737 : }
4738 :
4739 1634 : return;
4740 : }
4741 :
4742 :
4743 : /*-------------------------------------------------------------------------
4744 : * ivas_omasa_decode_masa_to_total()
4745 : *
4746 : *------------------------------------------------------------------------*/
4747 :
4748 1634 : 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 1634 : n_streams = 1;
4763 1634 : move16();
4764 1634 : len_stream = i_mult( nbands, nblocks );
4765 1634 : 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 1634 : set16_fx( q_idx, 0, i_mult( nbands, nblocks ) );
4774 3268 : FOR( i = 0; i < n_streams; i++ )
4775 : {
4776 1634 : 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 1634 : SWITCH( len_stream )
4781 : {
4782 20 : case 4:
4783 20 : matrix_product_q30_fx( dct4_fx, nblocks, nblocks, 1, q_dct_data_fx, nblocks, 1, 0, dct_data_tmp_fx );
4784 20 : Copy32( dct_data_tmp_fx, q_dct_data_fx, nblocks ); /*Q30*/
4785 20 : BREAK;
4786 174 : case 5:
4787 174 : matrix_product_q30_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
4788 174 : Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
4789 174 : 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 360 : case 12:
4795 360 : matrix_product_q30_fx( dct12_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
4796 360 : Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
4797 360 : BREAK;
4798 1080 : case 20:
4799 1080 : matrix_product_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx );
4800 1080 : matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx ); /* reuse of variable*/
4801 1080 : 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 1634 : k = 0;
4811 1634 : move16();
4812 6568 : FOR( i = 0; i < nblocks; i++ )
4813 : {
4814 31804 : FOR( j = 0; j < nbands; j++ )
4815 : {
4816 26870 : masa_to_total_energy_ratio_fx[i][j] = L_max( 0, q_dct_data_fx[k] ); // Q30
4817 26870 : move32();
4818 26870 : masa_to_total_energy_ratio_fx[i][j] = L_min( ONE_IN_Q30, masa_to_total_energy_ratio_fx[i][j] ); /*Q30*/
4819 26870 : move32();
4820 26870 : k = add( k, 1 );
4821 : }
4822 : }
4823 :
4824 1634 : IF( EQ_16( nblocks, 1 ) )
4825 : {
4826 2136 : FOR( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
4827 : {
4828 17172 : FOR( j = 0; j < nbands; j++ )
4829 : {
4830 15570 : masa_to_total_energy_ratio_fx[i][j] = masa_to_total_energy_ratio_fx[0][j]; /*Q30*/
4831 15570 : move32();
4832 : }
4833 : }
4834 : }
4835 :
4836 1634 : IF( EQ_16( nbands, 1 ) )
4837 : {
4838 100 : FOR( j = 1; j < 5; j++ )
4839 : {
4840 400 : FOR( i = 0; i < nblocks; i++ )
4841 : {
4842 320 : masa_to_total_energy_ratio_fx[i][j] = masa_to_total_energy_ratio_fx[i][0]; /*Q30*/
4843 320 : move32();
4844 : }
4845 : }
4846 : }
4847 :
4848 1634 : return;
4849 : }
|