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