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