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