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 "prot_fx.h"
39 : #include "ivas_prot_fx.h"
40 : #include "ivas_rom_com.h"
41 : #include "ivas_stat_enc.h"
42 : #include "wmc_auto.h"
43 :
44 : #include "basop_util.h"
45 : #include "ivas_rom_com_fx.h"
46 :
47 : /*-----------------------------------------------------------------------*
48 : * Local function prototypes
49 : *-----------------------------------------------------------------------*/
50 :
51 : static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_fx( IVAS_QMETADATA_HANDLE hQMetaData, Word16 *needed_bits, Word16 *nbits_diff, Word16 *dfRatioBits, const Word16 hodirac_flag );
52 :
53 : static Word16 ivas_qmetadata_entropy_encode_diffuseness_fx(
54 : BSTR_ENC_HANDLE hMetaData,
55 : IVAS_QDIRECTION *q_direction,
56 : UWord16 *diffuseness_index_max_ec_frame );
57 :
58 : static void ivas_qmetadata_reorder_2dir_bands_fx( IVAS_QMETADATA_HANDLE hQMetaData );
59 :
60 : static Word16 ivas_qmetadata_entropy_encode_df_ratio_fx(
61 : BSTR_ENC_HANDLE hMetaData,
62 : IVAS_QDIRECTION *q_direction,
63 : Word16 *df_ratio_bits );
64 :
65 : static Word16 ivas_qmetadata_entropy_encode_dir_fx(
66 : BSTR_ENC_HANDLE hMetaData,
67 : IVAS_QDIRECTION *q_direction,
68 : const UWord16 diffuseness_index_max_ec_frame,
69 : const Word16 nbands,
70 : const Word16 start_band,
71 : const Word16 direction_bits_raw,
72 : Word16 max_bits,
73 : const Word16 hrmasa_flag );
74 :
75 : static Word16 ivas_qmetadata_raw_encode_dir_fx(
76 : BSTR_ENC_HANDLE hMetaData,
77 : IVAS_QDIRECTION *q_direction,
78 : const Word16 nbands,
79 : const Word16 start_band );
80 :
81 :
82 : static Word16 ivas_qmetadata_get_optimal_gr_param_fx(
83 : UWord16 *unsigned_data,
84 : const Word16 count,
85 : const Word16 gr_param_count,
86 : Word16 *opt_gr_size );
87 :
88 : Word16 ivas_qmetadata_encode_extended_gr_length_fx( const UWord16 value, const UWord16 alphabet_size, const Word16 gr_param );
89 :
90 : static Word16 ivas_qmetadata_encode_quasi_uniform_length_fx( const UWord16 value, const UWord16 alphabet_size );
91 :
92 : static void ivas_qmetadata_encode_quasi_uniform_fx( BSTR_ENC_HANDLE hMetaData, const UWord16 value, const UWord16 alphabet_size );
93 :
94 : static Word16 ivas_qmetadata_reorder_elevation_index_fx(
95 : const Word16 elevation_index,
96 : const Word16 avg_elevation_index,
97 : const Word16 elevation_alphabet );
98 :
99 : static Word16 ivas_qmetadata_reorder_azimuth_index_fx(
100 : const Word16 azimuth_index,
101 : const Word16 avg_azimuth_index,
102 : const Word16 azimuth_alphabet );
103 : static ivas_error requantize_direction_EC_3_fx( Word16 *extra_bits, IVAS_QDIRECTION *q_direction, const Word16 coding_subbands, BSTR_ENC_HANDLE hMetaData, Word32 elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], Word32 azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], Word16 *ind_order );
104 :
105 :
106 : static void calculate_two_distances_fx(
107 : Word32 *el_fx, /* i : elevation values */
108 : Word16 *bits, /* i : number of bits for each tile */
109 : const Word16 total_bits, /* i : total number of bits for subband */
110 : const Word16 len, /* i : number of tiles */
111 : Word32 *p_d1, /* o : first distortion */
112 : Word32 *p_d2, /* o : second distortion */
113 : Word16 *Q_out );
114 :
115 : static void joint_encoding_fx( IVAS_QDIRECTION *q_direction, const Word16 j, const Word16 next_j, const Word16 coding_subbands, Word16 *bits_dir0, const Word16 allowed_bits, BSTR_ENC_HANDLE hMetaData, Word16 *diff );
116 : static ivas_error write_ec_direction_fx( Word16 *num_bits_written, BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const Word16 j_idx, const Word16 len, const Word16 GR_ord_elevation, const Word16 GR_ord_azimuth, const Word16 use_context, const Word16 same );
117 : static Word16 write_fixed_rate_direction_fx( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const Word16 j_idx, const Word16 len );
118 :
119 :
120 : static Word16 ivas_qmetadata_quantize_coherence_fx(
121 : IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata */
122 : const Word16 idx_d, /* i : current direction index */
123 : const Word16 all_coherence_zero, /* i : all coherence is zero - flag */
124 : BSTR_ENC_HANDLE hMetaData, /* i : metadata handle */
125 : const Word16 write_flag, /* i : flag to actually write the data or not */
126 : Word16 *indice_coherence,
127 : const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */
128 : );
129 :
130 : static void dct4_transform_fx(
131 : UWord8 *v, /* i : input 4D vector */
132 : Word32 *dct_v /* o : output transformed vector Q31 */
133 : );
134 :
135 : static Word32 quantize_DCT_0_coh_fx( // o:Q21
136 : const Word16 x, /* i : input value Q14 */
137 : const Word16 j, /* i : subband index */
138 : const Word16 *coherence_cb, /* i : coherence codebook Q14 */
139 : const Word16 delta_var, /* i : azimuth variance threshold Q6 */
140 : const Word16 no_cb, /* i : maximum number of codewords */
141 : IVAS_QDIRECTION *q_direction, /* i : quantized metadata */
142 : UWord16 *idx_x, /* o : codewords index */
143 : Word16 *p_no_cb, /* o : actual number of codewords dependent on energy ratio value */
144 : const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */
145 : );
146 :
147 : static Word16 encode_coherence_indexesDCT0_fx(
148 : UWord16 *idx_dct, /* i : indexes to be encoded */
149 : const Word16 len, /* i : number of indexes */
150 : Word16 *no_cb_vec, /* i : number of codewords for each position */
151 : BSTR_ENC_HANDLE hMetaData,
152 : const Word16 indice_coherence,
153 : const Word16 nbits,
154 : const Word16 nbits1 );
155 :
156 : static Word16 encode_coherence_indexesDCT1_fx(
157 : UWord16 *idx_dct, /* i : data to be encoded */
158 : const Word16 len, /* i : number of data */
159 : BSTR_ENC_HANDLE hMetaData /* i : metadata handle */
160 : );
161 :
162 : static UWord64 create_combined_index_fx( UWord16 *idx_dct, const Word16 len, const Word16 *no_cb_vec );
163 :
164 : static Word16 encode_surround_coherence_fx(
165 : IVAS_QMETADATA *hQMetaData, /* i : quantized metadata */
166 : BSTR_ENC_HANDLE hMetaData /* i/o: metadata bitstream handle */
167 : );
168 : static Word16 common_direction_fx(
169 : IVAS_QDIRECTION *q_direction,
170 : const Word16 band_idx,
171 : const Word16 len,
172 : const Word16 bits_allowed,
173 : BSTR_ENC_HANDLE hMetaData,
174 : Word32 *elevation_orig_fx,
175 : Word32 *azimuth_orig_fx );
176 : static Word16 ivas_diffuseness_huff_ec_encode_fx(
177 : BSTR_ENC_HANDLE hMetaData,
178 : const UWord16 idx );
179 :
180 : static void ivas_diffuseness_huff_ec_prepare_fx(
181 : IVAS_QDIRECTION *q_direction,
182 : Word16 *best_av,
183 : UWord16 *avr_idx,
184 : Word16 *diffuseness_bits_huff );
185 :
186 : static Word16 coherence_coding_length( const UWord16 *idx_sur_coh_shift, const UWord8 idx_shift_len, const Word16 coding_subbands, const Word16 *no_cv, UWord16 *mr_idx, Word16 *no_cv_shift, Word16 *p_min_idx, Word16 *GR_ord, Word16 *nbits_fr, Word16 *nbits_fr1 );
187 :
188 : static Word16 write_2dir_info( BSTR_ENC_HANDLE hMetaData, UWord8 *twoDirBands, const Word16 n, const Word16 k );
189 :
190 : static void transform_azimuth_dir2_fx(
191 : IVAS_QMETADATA_HANDLE hQMetaData,
192 : Word16 *dir2_bands );
193 :
194 : static Word16 ivas_qmetadata_quantize_coherence_hr_512_fx( IVAS_QMETADATA *hQMetaData, const Word16 idx_d, const Word16 all_coherence_zero, BSTR_ENC_HANDLE hMetaData, const Word16 bits_coh );
195 :
196 : static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512_fx( IVAS_QMETADATA_HANDLE hQMetaData, Word16 *needed_bits, const Word16 bits_dir_hr, BSTR_ENC_HANDLE hMetaData );
197 :
198 : static Word16 calc_var_azi_fx( const IVAS_QDIRECTION *q_direction, const Word16 diffuseness_index_max_ec_frame, const Word32 avg_azimuth, Word32 *avg_azimuth_out );
199 :
200 : static Word16 encode_surround_coherence_hr_fx( IVAS_QMETADATA *hQMetaData, BSTR_ENC_HANDLE hMetaData );
201 :
202 : static Word16 write_stream_dct_coeffs_omasa_fx( Word16 *q_idx, const Word16 len_stream, BSTR_ENC_HANDLE hMetaData, const Word16 first_line, const Word16 low_bitrate_mode );
203 :
204 : static Word16 find_optimal_GR_order_fx( const Word16 *q_idx, const Word16 len, Word16 *GR );
205 :
206 : static Word16 find_optimal_GR_orders_fx( const Word16 *q_idx, const Word16 len, const Word16 len_max_GR1, Word16 *GR1, Word16 *GR2, Word16 *i_min );
207 :
208 :
209 : /*-----------------------------------------------------------------------*
210 : * ivas_qmetadata_enc_encode()
211 : *
212 : * Main function for quantizing and coding Spatial Metadata
213 : *-----------------------------------------------------------------------*/
214 :
215 202957 : ivas_error ivas_qmetadata_enc_encode_fx(
216 : BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */
217 : IVAS_QMETADATA *hQMetaData, /* i/o: metadata handle */
218 : const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */
219 : )
220 : {
221 : Word16 i, bit_pos_start, bit_pos_start_coh;
222 : Word16 next_ind_start;
223 : UWord16 diffuseness_index_max_ec_frame;
224 : UWord16 diffuseness_index_max_ec_frame_pre[QMETADATA_MAX_NO_DIRECTIONS];
225 : Word16 bits_dir_raw_pre[QMETADATA_MAX_NO_DIRECTIONS];
226 : Word16 bits_diff_sum;
227 : Word16 bits_diff[QMETADATA_MAX_NO_DIRECTIONS], bits_coherence[QMETADATA_MAX_NO_DIRECTIONS];
228 : Word16 bits_dir[QMETADATA_MAX_NO_DIRECTIONS], bits_dir_raw;
229 : Word16 extra_bits;
230 : IVAS_QDIRECTION *q_direction;
231 : Word16 nbands, nblocks, start_band;
232 : Word16 ndirections, d;
233 : Word32 azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
234 : Word16 all_coherence_zero;
235 : Word16 bit_pos_0, total_bits_1dir, bits_no_dirs_coh;
236 : Word16 bits_signaling[QMETADATA_MAX_NO_DIRECTIONS];
237 : Word16 indice_coherence;
238 : Word16 bits_dir_bands[MASA_MAXIMUM_CODING_SUBBANDS], raw_flag[MASA_MAXIMUM_CODING_SUBBANDS];
239 : Word16 diff_bits, bits_ec, next_ind_raw_flag;
240 : Word16 dfRatio_bits[MASA_MAXIMUM_CODING_SUBBANDS];
241 : Word16 bits_surround_coh, no_TF;
242 : Word16 dir2_bands[MASA_MAXIMUM_TWO_DIR_BANDS];
243 : Word16 ind_order[MASA_MAXIMUM_CODING_SUBBANDS];
244 : Word16 reduce_bits;
245 : ivas_error error;
246 :
247 202957 : error = IVAS_ERR_OK;
248 202957 : move32();
249 :
250 : /* Save initial position in bitstream */
251 202957 : bit_pos_0 = hMetaData->nb_bits_tot;
252 202957 : move16();
253 202957 : bit_pos_start = bit_pos_0;
254 202957 : move16();
255 :
256 202957 : ndirections = hQMetaData->no_directions;
257 202957 : move16();
258 202957 : extra_bits = 0;
259 202957 : move16();
260 :
261 : /* Check if coherence should be encoded */
262 202957 : all_coherence_zero = 1;
263 202957 : move16();
264 202957 : bits_no_dirs_coh = 0;
265 202957 : move16();
266 :
267 202957 : IF( hQMetaData->coherence_flag )
268 : {
269 27866 : all_coherence_zero = hQMetaData->all_coherence_zero;
270 27866 : move16();
271 :
272 27866 : push_next_indice( hMetaData, all_coherence_zero, 1 ); /* signal coherence */
273 27866 : bits_no_dirs_coh = add( bits_no_dirs_coh, 1 );
274 : }
275 :
276 202957 : IF( GT_16( ndirections, 1 ) )
277 : {
278 : /* Reorder 2dir bands for more efficient encoding. */
279 20820 : IF( !hodirac_flag )
280 : {
281 4580 : ivas_qmetadata_reorder_2dir_bands_fx( hQMetaData );
282 : }
283 20820 : d = 0;
284 20820 : move16();
285 255252 : FOR( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ )
286 : {
287 234432 : IF( EQ_16( hQMetaData->twoDirBands[i], 1 ) )
288 : {
289 208080 : Copy32( hQMetaData->q_direction[1].band_data[i].azimuth_fx, hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q22
290 208080 : Copy32( hQMetaData->q_direction[1].band_data[i].elevation_fx, hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q22
291 208080 : Copy32( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q30
292 :
293 208080 : dir2_bands[d] = i;
294 208080 : move16();
295 :
296 208080 : IF( hQMetaData->coherence_flag )
297 : {
298 13200 : mvc2c( hQMetaData->q_direction[1].coherence_band_data[i].spread_coherence, hQMetaData->q_direction[1].coherence_band_data[d].spread_coherence, hQMetaData->q_direction[1].cfg.nblocks );
299 : }
300 208080 : d = add( d, 1 );
301 : }
302 : }
303 :
304 20820 : bits_no_dirs_coh = add( bits_no_dirs_coh, write_2dir_info( hMetaData, hQMetaData->twoDirBands, hQMetaData->q_direction[0].cfg.nbands, hQMetaData->numTwoDirBands ) );
305 :
306 47172 : FOR( i = d; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
307 : {
308 26352 : set32_fx( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, 0, hQMetaData->q_direction[1].cfg.nblocks );
309 : }
310 :
311 20820 : hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands;
312 20820 : move16();
313 : }
314 :
315 : /*Quantization of the Diffuseness */
316 202957 : ivas_qmetadata_quantize_diffuseness_nrg_ratios_fx( hQMetaData, bits_dir_raw_pre, bits_diff, dfRatio_bits, hodirac_flag );
317 :
318 202957 : bits_diff_sum = 0;
319 202957 : move16();
320 :
321 202957 : bits_diff[0] = ivas_qmetadata_entropy_encode_diffuseness_fx( hMetaData, &( hQMetaData->q_direction[0] ), &diffuseness_index_max_ec_frame_pre[0] );
322 202957 : move16();
323 202957 : bits_diff_sum = add( bits_diff_sum, bits_diff[0] );
324 :
325 202957 : IF( EQ_16( ndirections, 2 ) )
326 : {
327 20820 : bits_diff[1] = ivas_qmetadata_entropy_encode_df_ratio_fx( hMetaData, &( hQMetaData->q_direction[1] ), dfRatio_bits );
328 20820 : move16();
329 20820 : bits_diff_sum = add( bits_diff_sum, bits_diff[1] );
330 : }
331 :
332 : /* 2dir energy ratio encoding reuses index memory. Now that diffRatio and dFRatio have been encoded,
333 : * we retrieve index_dirRatio1Inv and index_dirRatio1Inv for further parameter encoding. This is
334 : * necessary only for bands that have two concurrent directions. */
335 202957 : IF( EQ_16( hQMetaData->no_directions, 2 ) )
336 : {
337 : Word16 j, k, dir2band, index_dirRatio1Inv, index_dirRatio2Inv;
338 :
339 20820 : dir2band = 0;
340 20820 : move16();
341 255252 : FOR( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j )
342 : {
343 234432 : IF( EQ_16( hQMetaData->twoDirBands[j], 1 ) )
344 : {
345 208080 : index_dirRatio1Inv = masa_sq_fx( L_sub( ONE_IN_Q30, hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0] ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS );
346 208080 : index_dirRatio2Inv = masa_sq_fx( L_sub( ONE_IN_Q30, hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[0] ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS );
347 :
348 1031268 : FOR( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ )
349 : {
350 823188 : hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index_dirRatio1Inv;
351 823188 : move16();
352 : }
353 :
354 1031268 : FOR( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
355 : {
356 823188 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[k] = index_dirRatio2Inv;
357 823188 : move16();
358 : }
359 :
360 208080 : dir2band = add( dir2band, 1 );
361 : }
362 : }
363 : }
364 :
365 : /* Encode surround coherence */
366 202957 : IF( EQ_16( ndirections, 2 ) )
367 : {
368 20820 : no_TF = add( imult1616( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ), imult1616( hQMetaData->q_direction[1].cfg.nbands, hQMetaData->q_direction[1].cfg.nblocks ) );
369 20820 : test();
370 20820 : IF( EQ_16( all_coherence_zero, 0 ) && GE_16( sub( sub( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), idiv1616( imult1616( 43, no_TF ), 10 ) ), sum16_fx( bits_diff, ndirections ) ), MASA_MIN_BITS_SURR_COH ) )
371 : {
372 4580 : bits_surround_coh = encode_surround_coherence_fx( hQMetaData, hMetaData );
373 : }
374 : ELSE
375 : {
376 16240 : bits_surround_coh = 0;
377 16240 : move16();
378 211120 : FOR( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
379 : {
380 194880 : IF( hQMetaData->surcoh_band_data != NULL )
381 : {
382 0 : set8_fx( (Word8 *) hQMetaData->surcoh_band_data[i].surround_coherence, 0, hQMetaData->q_direction[0].cfg.nblocks );
383 : }
384 : }
385 : }
386 20820 : bits_no_dirs_coh = add( bits_no_dirs_coh, bits_surround_coh );
387 : // total_bits_1dir = ( ( hQMetaData->metadata_max_bits - bits_no_dirs_coh ) * hQMetaData->q_direction[0].cfg.nbands * hQMetaData->q_direction[0].cfg.nblocks ) / no_TF;
388 : Word32 tmp_quo, tmp_mod;
389 20820 : iDiv_and_mod_32( imult3216( L_mult0( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), hQMetaData->q_direction[0].cfg.nbands ), hQMetaData->q_direction[0].cfg.nblocks ), no_TF, &tmp_quo, &tmp_mod, 0 );
390 20820 : total_bits_1dir = extract_l( tmp_quo );
391 : }
392 : ELSE
393 : {
394 182137 : no_TF = imult1616( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks );
395 182137 : test();
396 182137 : IF( EQ_16( all_coherence_zero, 0 ) && GE_16( sub( sub( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), idiv1616( imult1616( 43, no_TF ), 10 ) ), bits_diff[0] ), MASA_MIN_BITS_SURR_COH ) )
397 : {
398 21939 : bits_surround_coh = encode_surround_coherence_fx( hQMetaData, hMetaData );
399 : }
400 : ELSE
401 : {
402 160198 : bits_surround_coh = 0;
403 160198 : move16();
404 673421 : FOR( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
405 : {
406 513223 : IF( hQMetaData->surcoh_band_data != NULL )
407 : {
408 14934 : set8_fx( (Word8 *) hQMetaData->surcoh_band_data[i].surround_coherence, 0, hQMetaData->q_direction[0].cfg.nblocks );
409 : }
410 : }
411 : }
412 182137 : total_bits_1dir = sub( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), bits_surround_coh );
413 : }
414 :
415 : /* Loop over number of directions*/
416 426734 : FOR( d = 0; d < ndirections; d++ )
417 : {
418 223777 : q_direction = &( hQMetaData->q_direction[d] );
419 :
420 223777 : IF( EQ_16( d, 1 ) )
421 : {
422 20820 : transform_azimuth_dir2_fx( hQMetaData, dir2_bands );
423 : }
424 :
425 223777 : nbands = q_direction->cfg.nbands;
426 223777 : move16();
427 223777 : nblocks = q_direction->cfg.nblocks;
428 223777 : move16();
429 223777 : start_band = q_direction->cfg.start_band;
430 223777 : move16();
431 223777 : diffuseness_index_max_ec_frame = diffuseness_index_max_ec_frame_pre[0];
432 223777 : move16();
433 223777 : bits_dir_raw = bits_dir_raw_pre[d];
434 223777 : move16();
435 :
436 : /* This sets bit budget correctly for the second direction */
437 223777 : IF( d == 0 )
438 : {
439 202957 : bits_diff[d] = bits_diff_sum;
440 202957 : move16();
441 : }
442 : ELSE
443 : {
444 20820 : bits_diff[d] = 0;
445 20820 : move16();
446 : }
447 :
448 223777 : bits_signaling[d] = 0;
449 223777 : move16();
450 :
451 : /*Coherence */
452 223777 : bits_coherence[d] = 0;
453 223777 : move16();
454 223777 : bit_pos_start_coh = hMetaData->nb_bits_tot;
455 223777 : move16();
456 :
457 223777 : IF( all_coherence_zero == 0 )
458 : {
459 31263 : bits_coherence[d] = ivas_qmetadata_quantize_coherence_fx( hQMetaData, d, all_coherence_zero, hMetaData, 0, &indice_coherence, 0 );
460 31263 : move16();
461 : }
462 :
463 223777 : test();
464 223777 : IF( EQ_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_5_1 ) || EQ_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_7_1 ) )
465 : {
466 9940 : q_direction->not_in_2D = 0;
467 9940 : move16();
468 : /* Quantize directions*/
469 9940 : quantize_direction_frame2D_fx( q_direction, azimuth_orig, elevation_orig );
470 : }
471 : ELSE
472 : {
473 : /* Quantize directions*/
474 213837 : quantize_direction_frame_fx( q_direction, azimuth_orig, elevation_orig, 0 );
475 : }
476 :
477 : /* Signalling 2D*/
478 223777 : push_next_indice( hMetaData, ( q_direction->not_in_2D > 0 ), 1 ); /*2D flag*/
479 223777 : bits_signaling[d] = 1;
480 223777 : move16();
481 :
482 : /* Save state of metadata bitstream buffer after writing energy ratios, number of dirs and save space for coherence*/
483 223777 : bit_pos_start = hMetaData->nb_bits_tot;
484 223777 : move16();
485 223777 : next_ind_start = hMetaData->nb_ind_tot;
486 223777 : move16();
487 :
488 : /* Encode quantized directions with EC frame-wise*/
489 223777 : IF( LE_16( add( total_bits_1dir, bits_surround_coh ), hQMetaData->qmetadata_max_bit_req ) )
490 : {
491 156446 : push_next_indice( hMetaData, 0, 1 ); /*Write 1 bit to signal EC frame-wise (EC1)*/
492 156446 : bits_signaling[d] = add( bits_signaling[d], 1 );
493 156446 : move16();
494 : }
495 :
496 223777 : next_ind_raw_flag = hMetaData->nb_ind_tot;
497 223777 : move16();
498 223777 : push_next_indice( hMetaData, 0, 1 ); /* Raw coding flag*/
499 :
500 223777 : bits_dir_bands[0] = ivas_qmetadata_raw_encode_dir_fx( NULL, q_direction, q_direction->cfg.nbands, q_direction->cfg.start_band );
501 223777 : move16();
502 :
503 : // reduce_bits = hQMetaData->is_masa_ivas_format ? ( total_bits_1dir - ( bits_diff[d] + bits_coherence[d] + bits_signaling[d] ) - 1 ) : MASA_MAX_BITS;
504 223777 : IF( hQMetaData->is_masa_ivas_format )
505 : {
506 53400 : reduce_bits = sub( sub( total_bits_1dir, add( add( bits_diff[d], bits_coherence[d] ), bits_signaling[d] ) ), 1 );
507 : }
508 : ELSE
509 : {
510 170377 : reduce_bits = MASA_MAX_BITS;
511 170377 : move16();
512 : }
513 223777 : bits_ec = ivas_qmetadata_entropy_encode_dir_fx( hMetaData, q_direction, diffuseness_index_max_ec_frame, q_direction->cfg.nbands, q_direction->cfg.start_band, bits_dir_bands[0], reduce_bits, 0 );
514 :
515 223777 : IF( bits_ec < 0 )
516 : {
517 106484 : hMetaData->ind_list[next_ind_raw_flag].value = 1; /*rewrite flag*/
518 106484 : move16();
519 106484 : bits_ec = ivas_qmetadata_raw_encode_dir_fx( hMetaData, q_direction, q_direction->cfg.nbands, q_direction->cfg.start_band );
520 : }
521 223777 : bits_dir[d] = add( bits_ec, 1 );
522 223777 : move16();
523 223777 : extra_bits = sub( hQMetaData->metadata_max_bits, sub( hMetaData->nb_bits_tot, bit_pos_0 ) );
524 :
525 : /* Encode quantized directions with EC band-wise */
526 223777 : test();
527 223777 : test();
528 223777 : IF( LE_16( add( total_bits_1dir, bits_surround_coh ), hQMetaData->qmetadata_max_bit_req ) && GT_16( add( add( add( bits_dir[d], bits_diff[d] ), bits_coherence[d] ), bits_signaling[d] ), total_bits_1dir ) && GT_16( q_direction->cfg.nblocks, 1 ) )
529 : {
530 8024 : restore_metadata_buffer_fx( hMetaData, next_ind_start, bit_pos_start );
531 :
532 : /* Write signaling */
533 8024 : push_next_indice( hMetaData, 1, 1 ); /*Write 1 bit to signal no EC frame-wise (EC1)*/
534 8024 : push_next_indice( hMetaData, 0, 1 ); /*Write 1 bit to signal EC band-wise (EC2)*/
535 8024 : bits_signaling[d] = 3;
536 8024 : move16();
537 :
538 : /* Write raw flags */
539 8024 : next_ind_raw_flag = hMetaData->nb_ind_tot;
540 8024 : move16();
541 41307 : FOR( i = start_band; i < nbands; i++ )
542 : {
543 33283 : push_next_indice( hMetaData, 0, 1 ); /* Raw coding flag*/
544 : }
545 :
546 8024 : bits_dir[d] = 0;
547 8024 : move16();
548 8024 : diff_bits = sub( add( add( bits_diff[d], bits_coherence[d] ), bits_signaling[d] ), total_bits_1dir );
549 41307 : FOR( i = start_band; i < nbands; i++ )
550 : {
551 33283 : bits_dir_bands[i] = ivas_qmetadata_raw_encode_dir_fx( NULL, q_direction, add( i, 1 ), i );
552 33283 : move16();
553 :
554 : /* Write ec bits */
555 33283 : bits_ec = ivas_qmetadata_entropy_encode_dir_fx( hMetaData, q_direction, diffuseness_index_max_ec_frame, add( i, 1 ), i, bits_dir_bands[i], MASA_MAX_BITS, 0 );
556 :
557 33283 : IF( bits_ec >= 0 )
558 : {
559 17766 : bits_dir_bands[i] = bits_ec;
560 17766 : move16();
561 17766 : raw_flag[i] = 0;
562 17766 : move16();
563 : }
564 : ELSE
565 : {
566 15517 : raw_flag[i] = 1;
567 15517 : move16();
568 : }
569 33283 : diff_bits = add( diff_bits, add( bits_dir_bands[i], 1 ) );
570 : }
571 :
572 8024 : small_requantize_direction_frame_fx( q_direction, azimuth_orig, elevation_orig, raw_flag, bits_dir_bands, &diff_bits );
573 :
574 41307 : FOR( i = start_band; i < nbands; i++ )
575 : {
576 33283 : IF( raw_flag[i] )
577 : {
578 : /* Rewrite raw flag value */
579 15517 : hMetaData->ind_list[next_ind_raw_flag + i - start_band].value = 1;
580 15517 : move16();
581 :
582 : /* Write ec bits */
583 15517 : bits_ec = ivas_qmetadata_raw_encode_dir_fx( hMetaData, q_direction, add( i, 1 ), i );
584 : }
585 33283 : bits_dir[d] = add( bits_dir[d], add( bits_dir_bands[i], 1 ) );
586 33283 : move16();
587 : }
588 :
589 8024 : extra_bits = sub( hQMetaData->metadata_max_bits, sub( hMetaData->nb_bits_tot, bit_pos_0 ) );
590 : }
591 :
592 : /* Requantized directions */
593 223777 : test();
594 223777 : IF( LE_16( add( total_bits_1dir, bits_surround_coh ), hQMetaData->qmetadata_max_bit_req ) && GT_16( add( add( add( bits_dir[d], bits_diff[d] ), bits_coherence[d] ), bits_signaling[d] ), total_bits_1dir ) )
595 : {
596 :
597 : /*Bit budget exceeded, bit reduction strategy?*/
598 9338 : extra_bits = 0;
599 9338 : move16();
600 :
601 9338 : restore_metadata_buffer_fx( hMetaData, next_ind_start, bit_pos_start );
602 :
603 9338 : push_next_indice( hMetaData, 1, 1 ); /*Write 1 bit to signal no EC frame-wise (EC1)*/
604 9338 : IF( GT_16( nblocks, 1 ) )
605 : {
606 5619 : push_next_indice( hMetaData, 1, 1 ); /*Write 1 bit to signal requantization stage (EC3)*/
607 5619 : bits_signaling[d] = 3;
608 5619 : move16();
609 : }
610 : ELSE
611 : {
612 3719 : bits_signaling[d] = 2;
613 3719 : move16();
614 : }
615 :
616 9338 : IF( hQMetaData->is_masa_ivas_format == 0 )
617 : {
618 3136 : reduce_bits = sub( bits_dir_raw, sub( sub( sub( total_bits_1dir, bits_diff[d] ), bits_coherence[d] ), bits_signaling[d] ) );
619 3136 : ind_order[0] = -1;
620 3136 : move16();
621 : }
622 : ELSE
623 : {
624 6202 : ind_order[0] = 0;
625 6202 : move16();
626 6202 : reduce_bits = s_min( add( imult1616( nbands, nblocks ), MASA_BIT_REDUCT_PARAM ), sub( bits_dir_raw, sub( sub( sub( total_bits_1dir, bits_diff[d] ), bits_coherence[d] ), bits_signaling[d] ) ) );
627 :
628 6202 : IF( GT_16( reduce_bits, sub( bits_dir_raw, imult1616( nbands, nblocks ) ) ) )
629 : {
630 150 : reduce_bits = sub( bits_dir_raw, imult1616( nbands, nblocks ) );
631 : }
632 : }
633 :
634 9338 : only_reduce_bits_direction_fx( &extra_bits, q_direction, reduce_bits, nbands, nblocks, ind_order );
635 9338 : bits_dir[d] = hMetaData->nb_bits_tot;
636 9338 : move16();
637 :
638 9338 : requantize_direction_EC_3_fx( &extra_bits, q_direction, nbands, hMetaData, elevation_orig, azimuth_orig, ind_order );
639 9338 : bits_dir[d] = sub( hMetaData->nb_bits_tot, bits_dir[d] );
640 9338 : move16();
641 : }
642 :
643 : /* finalize writing coherence */
644 223777 : test();
645 223777 : test();
646 223777 : IF( ( bits_coherence[d] > 0 ) && ( all_coherence_zero == 0 ) && GT_16( nblocks, 1 ) )
647 : {
648 23095 : bit_pos_start = hMetaData->nb_bits_tot;
649 23095 : hMetaData->nb_bits_tot = bit_pos_start_coh;
650 23095 : ivas_qmetadata_quantize_coherence_fx( hQMetaData, d, all_coherence_zero, hMetaData, 1, &indice_coherence, 0 );
651 23095 : hMetaData->nb_bits_tot = bit_pos_start;
652 23095 : move16();
653 23095 : move16();
654 23095 : move16();
655 : }
656 :
657 223777 : IF( d == 0 )
658 : {
659 202957 : total_bits_1dir = sub( hQMetaData->metadata_max_bits, sub( hMetaData->nb_bits_tot, bit_pos_0 ) );
660 : }
661 :
662 : /* Save quantized DOAs */
663 1335070 : FOR( i = start_band; i < nbands; i++ )
664 : {
665 1111293 : Copy32( q_direction->band_data[i].azimuth_fx, q_direction->band_data[i].q_azimuth_fx, nblocks );
666 1111293 : Copy32( q_direction->band_data[i].elevation_fx, q_direction->band_data[i].q_elevation_fx, nblocks );
667 : }
668 :
669 : /* Copy original DOAs back to q_direction*/
670 1335070 : FOR( i = start_band; i < nbands; i++ )
671 : {
672 1111293 : Copy32( azimuth_orig[i], q_direction->band_data[i].azimuth_fx, nblocks );
673 1111293 : Copy32( elevation_orig[i], q_direction->band_data[i].elevation_fx, nblocks );
674 : }
675 : }
676 :
677 202957 : return error;
678 : }
679 :
680 :
681 : /*-----------------------------------------------------------------------*
682 : * ivas_qmetadata_enc_encode_hr_384_512()
683 : *
684 : * Main function for quantizing and coding Spatial Metadata at HRs
685 : *-----------------------------------------------------------------------*/
686 2276 : ivas_error ivas_qmetadata_enc_encode_hr_384_512_fx(
687 : BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */
688 : IVAS_QMETADATA *hQMetaData, /* i/o: metadata handle */
689 : const Word16 bits_sph_idx,
690 : const Word16 bits_sp_coh )
691 : {
692 : Word16 i, j;
693 : Word16 bits_diff[QMETADATA_MAX_NO_DIRECTIONS];
694 : IVAS_QDIRECTION *q_direction;
695 : Word16 nbands, nblocks, start_band;
696 : Word16 ndirections, d;
697 : Word16 all_coherence_zero;
698 : Word16 bits_ec;
699 : Word32 azimuth_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; // Q22
700 : ivas_error error;
701 :
702 2276 : error = IVAS_ERR_OK;
703 2276 : move32();
704 :
705 :
706 2276 : ndirections = hQMetaData->no_directions;
707 2276 : move16();
708 :
709 : /* Check if coherence should be encoded */
710 2276 : all_coherence_zero = 1;
711 2276 : move16();
712 2276 : IF( hQMetaData->q_direction->cfg.inactiveBands > 0 )
713 : {
714 300 : push_next_indice( hMetaData, 1, 1 );
715 : /* write the number of inactive higher bands */
716 300 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( hQMetaData->q_direction->cfg.inactiveBands, 1 ), MASA_MAXIMUM_CODING_SUBBANDS, 1 );
717 : }
718 : ELSE
719 : {
720 : /* no change */
721 1976 : push_next_indice( hMetaData, 0, 1 );
722 : }
723 2276 : IF( hQMetaData->coherence_flag )
724 : {
725 2276 : all_coherence_zero = hQMetaData->all_coherence_zero;
726 2276 : move16();
727 2276 : push_next_indice( hMetaData, all_coherence_zero, 1 ); /* signal coherence */
728 : }
729 :
730 : /* encode 2 direction subbands position */
731 2276 : test();
732 2276 : IF( EQ_16( ndirections, 2 ) && EQ_16( bits_sph_idx, 11 ) )
733 : {
734 876 : write_2dir_info( hMetaData, hQMetaData->twoDirBands, hQMetaData->q_direction[0].cfg.nbands, hQMetaData->numTwoDirBands );
735 876 : d = 0;
736 876 : move16();
737 21600 : FOR( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ )
738 : {
739 20724 : IF( EQ_16( hQMetaData->twoDirBands[i], 1 ) )
740 : {
741 8334 : Copy32( hQMetaData->q_direction[1].band_data[i].azimuth_fx, hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q22
742 8334 : Copy32( hQMetaData->q_direction[1].band_data[i].elevation_fx, hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q22
743 8334 : Copy32( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q30
744 :
745 8334 : IF( hQMetaData->coherence_flag )
746 : {
747 8334 : mvc2c( hQMetaData->q_direction[1].coherence_band_data[i].spread_coherence, hQMetaData->q_direction[1].coherence_band_data[d].spread_coherence, hQMetaData->q_direction[1].cfg.nblocks );
748 : }
749 8334 : d = add( d, 1 );
750 : }
751 : }
752 13266 : FOR( i = hQMetaData->numTwoDirBands; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
753 : {
754 12390 : set32_fx( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, 0, hQMetaData->q_direction[1].cfg.nblocks );
755 : }
756 :
757 876 : hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands;
758 876 : move16();
759 : }
760 :
761 : /*Quantization and encoding of the Diffuseness */
762 2276 : ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512_fx( hQMetaData, bits_diff, bits_sph_idx, hMetaData );
763 :
764 :
765 : /* Encode surround coherence */
766 2276 : IF( all_coherence_zero == 0 )
767 : {
768 2276 : encode_surround_coherence_hr_fx( hQMetaData, hMetaData );
769 : }
770 : ELSE
771 : {
772 0 : FOR( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
773 : {
774 0 : IF( hQMetaData->surcoh_band_data != NULL )
775 : {
776 0 : set8_fx( (Word8 *) hQMetaData->surcoh_band_data[i].surround_coherence, 0, hQMetaData->q_direction[0].cfg.nblocks );
777 : }
778 : }
779 : }
780 :
781 : /* Loop over number of directions*/
782 5808 : FOR( d = 0; d < ndirections; d++ )
783 : {
784 3532 : q_direction = &( hQMetaData->q_direction[d] );
785 :
786 3532 : nbands = q_direction->cfg.nbands;
787 3532 : nblocks = q_direction->cfg.nblocks;
788 3532 : start_band = q_direction->cfg.start_band;
789 3532 : move16();
790 3532 : move16();
791 3532 : move16();
792 :
793 3532 : q_direction->not_in_2D = 0;
794 3532 : move16();
795 :
796 : /*Coherence */
797 3532 : IF( all_coherence_zero == 0 )
798 : {
799 3532 : ivas_qmetadata_quantize_coherence_hr_512_fx( hQMetaData, d, all_coherence_zero, hMetaData, bits_sp_coh );
800 : }
801 :
802 : /* write the spherical indexes */
803 3532 : bits_ec = hMetaData->nb_bits_tot;
804 3532 : move16();
805 :
806 3532 : IF( EQ_16( bits_sph_idx, 11 ) )
807 : {
808 : /* do the quantization */
809 2352 : quantize_direction_frame_fx( q_direction, azimuth_orig_fx, elevation_orig_fx, 1 );
810 : }
811 :
812 75310 : FOR( i = start_band; i < nbands; i++ )
813 : {
814 343140 : FOR( j = 0; j < nblocks; j++ )
815 : {
816 271362 : push_next_indice( hMetaData, q_direction->band_data[i].spherical_index[j], bits_sph_idx );
817 : }
818 : }
819 3532 : bits_ec = sub( hMetaData->nb_bits_tot, bits_ec );
820 :
821 :
822 : /* Save quantized DOAs */
823 3532 : IF( EQ_16( bits_sph_idx, 11 ) )
824 : {
825 45810 : FOR( i = start_band; i < nbands; i++ )
826 : {
827 43458 : Copy32( azimuth_orig_fx[i], q_direction->band_data[i].azimuth_fx, nblocks ); // Q22
828 43458 : Copy32( elevation_orig_fx[i], q_direction->band_data[i].elevation_fx, nblocks ); // Q22
829 : }
830 : }
831 : ELSE
832 : {
833 29500 : FOR( i = start_band; i < nbands; i++ )
834 : {
835 28320 : Copy32( q_direction->band_data[i].azimuth_fx, q_direction->band_data[i].q_azimuth_fx, nblocks ); // Q22
836 28320 : Copy32( q_direction->band_data[i].elevation_fx, q_direction->band_data[i].q_elevation_fx, nblocks ); // Q22
837 : }
838 : }
839 : }
840 :
841 2276 : IF( hQMetaData->q_direction->cfg.inactiveBands > 0 )
842 : {
843 300 : hQMetaData->q_direction[0].cfg.nbands = add( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction->cfg.inactiveBands );
844 300 : move16();
845 300 : IF( GT_16( ndirections, 1 ) )
846 : {
847 300 : hQMetaData->q_direction[1].cfg.nbands = add( hQMetaData->q_direction[1].cfg.nbands, hQMetaData->q_direction->cfg.inactiveBands );
848 300 : move16();
849 : }
850 : }
851 :
852 2276 : return error;
853 : }
854 :
855 :
856 : /*-----------------------------------------------------------------------*
857 : * ivas_qmetadata_enc_sid_encode()
858 : *
859 : * Main function for coding SID for Spatial Metadata
860 : *-----------------------------------------------------------------------*/
861 :
862 : /*! r: number of bits written */
863 10391 : void ivas_qmetadata_enc_sid_encode_fx(
864 : BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */
865 : IVAS_QMETADATA *q_metadata, /* i/o: metadata handle */
866 : const Word16 masa_sid_descriptor, /* i : description of MASA SID coding structure */
867 : const Word16 ivas_format /* i : IVAS format */
868 : )
869 : {
870 : Word16 b, m;
871 : Word16 bit_pos_start;
872 : IVAS_QDIRECTION *q_direction;
873 : Word16 nbands, nblocks, start_band;
874 : Word32 avg_direction_vector_fx[3];
875 : Word32 avg_elevation_fx[MASA_MAXIMUM_CODING_SUBBANDS];
876 : Word32 direction_vector_fx[3];
877 : Word32 avg_azimuth_fx[MASA_MAXIMUM_CODING_SUBBANDS];
878 : Word16 bits_dir, bits_diff, bits_delta;
879 : Word16 metadata_sid_bits; /* bits allocated to SID for metadata */
880 :
881 10391 : IF( EQ_16( ivas_format, SBA_FORMAT ) )
882 : {
883 3363 : 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*/
884 3363 : move16();
885 : }
886 : ELSE
887 : {
888 7028 : metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS;
889 7028 : move16();
890 : }
891 :
892 :
893 : /* Save initial position in bitstream */
894 10391 : bit_pos_start = hMetaData->nb_bits_tot;
895 10391 : move16();
896 :
897 : /* write for MASA the number of transport channels used at coding and the CPE mode DFT/MDCT */
898 10391 : IF( GT_16( masa_sid_descriptor, negate( 1 ) ) )
899 : {
900 4016 : push_next_indice( hMetaData, masa_sid_descriptor, 1 );
901 : }
902 :
903 : /* Code for one direction: diffuseness and average DOA(s)*/
904 10391 : q_direction = &( q_metadata->q_direction[0] );
905 10391 : nbands = q_direction->cfg.nbands;
906 10391 : nblocks = q_direction->cfg.nblocks;
907 10391 : move16();
908 10391 : move16();
909 10391 : start_band = 0; /*Start always with band 0 for SID*/
910 10391 : move16();
911 :
912 : /* sanity checks*/
913 10391 : assert( q_metadata->no_directions == 1 && "Qmetadata SID: only one direction supported!" );
914 10391 : IF( EQ_16( ivas_format, SBA_FORMAT ) )
915 : {
916 3363 : assert( ( q_direction->cfg.nbands == DIRAC_DTX_BANDS ) && "Qmetadata SID: only 2 bands supported!" );
917 : }
918 : ELSE
919 : {
920 7028 : assert( ( q_direction->cfg.nbands == 5 ) && "Qmetadata SID: only 5 bands supported!" );
921 : }
922 :
923 10391 : IF( NE_16( ivas_format, SBA_FORMAT ) )
924 : {
925 : /* Signalling 2D*/
926 7028 : push_next_indice( hMetaData, ( q_direction->not_in_2D > 0 ), 1 ); /*2D flag*/
927 : }
928 : ELSE
929 : {
930 3363 : q_direction->not_in_2D = 1; /* force for merged modes */
931 3363 : move16();
932 : }
933 :
934 : /*Encode the quantized diffuseness in raw coding*/
935 10391 : bits_dir = 0;
936 10391 : bits_diff = 0;
937 10391 : move16();
938 10391 : move16();
939 10391 : IF( NE_16( ivas_format, SBA_FORMAT ) )
940 : {
941 42168 : FOR( b = start_band; b < nbands; b++ )
942 : {
943 35140 : q_direction->band_data[b].energy_ratio_index[0] = s_max( q_direction->band_data[b].energy_ratio_index[0], 4 );
944 35140 : move16();
945 35140 : bits_diff = add( bits_diff, ivas_qmetadata_encode_quasi_uniform_length_fx( sub( q_direction->band_data[b].energy_ratio_index[0], 4 ), DIRAC_DIFFUSE_LEVELS - 4 ) );
946 35140 : q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[q_direction->band_data[b].energy_ratio_index[0]];
947 35140 : move16();
948 :
949 35140 : IF( q_direction->not_in_2D == 0 )
950 : {
951 625 : q_direction->band_data[b].azimuth_m_alphabet[0] = 1 << ( s_min( 8, q_direction->band_data[b].bits_sph_idx[0] ) );
952 625 : move16();
953 625 : bits_dir = add( bits_dir, ivas_qmetadata_encode_quasi_uniform_length_fx( sub( q_direction->band_data[b].azimuth_m_alphabet[0], 1 ), q_direction->band_data[b].azimuth_m_alphabet[0] ) );
954 : }
955 : ELSE
956 : {
957 34515 : bits_dir = add( bits_dir, q_direction->band_data[b].bits_sph_idx[0] );
958 : }
959 : }
960 :
961 : /* Reduce bit demand by increasing diffuseness*/
962 7028 : bits_delta = sub( sub( sub( metadata_sid_bits, sub( hMetaData->nb_bits_tot, bit_pos_start ) ), bits_diff ), bits_dir );
963 7028 : IF( bits_delta > 0 )
964 : {
965 32504 : WHILE( bits_delta > 0 )
966 : {
967 25476 : test();
968 139244 : FOR( b = start_band; b < nbands && ( bits_delta > 0 ); b++ )
969 : {
970 113768 : test();
971 113768 : IF( LT_16( q_direction->band_data[b].bits_sph_idx[0], 11 ) )
972 : {
973 113766 : bits_delta = sub( bits_delta, 1 );
974 113766 : q_direction->band_data[b].bits_sph_idx[0] = add( q_direction->band_data[b].bits_sph_idx[0], 1 );
975 113766 : move16();
976 : }
977 : }
978 : }
979 :
980 7028 : IF( q_direction->not_in_2D == 0 )
981 : {
982 750 : FOR( b = start_band; b < nbands; b++ )
983 : {
984 625 : q_direction->band_data[b].azimuth_m_alphabet[0] = shl( 1, ( s_min( 8, q_direction->band_data[b].bits_sph_idx[0] ) ) );
985 625 : move16();
986 : }
987 : }
988 : }
989 : ELSE
990 : {
991 0 : WHILE( bits_delta < 0 )
992 : {
993 0 : test();
994 0 : FOR( b = nbands - 1; b >= start_band && ( bits_delta < 0 ); b-- )
995 : {
996 0 : test();
997 0 : IF( GE_16( q_direction->band_data[b].bits_sph_idx[0], 4 ) )
998 : {
999 0 : bits_delta = add( bits_delta, 1 );
1000 0 : q_direction->band_data[b].bits_sph_idx[0] = sub( q_direction->band_data[b].bits_sph_idx[0], 1 );
1001 0 : IF( q_direction->not_in_2D == 0 )
1002 : {
1003 0 : q_direction->band_data[b].azimuth_m_alphabet[0] = shl( 1, ( s_min( 8, q_direction->band_data[b].bits_sph_idx[0] ) ) );
1004 0 : move16();
1005 : }
1006 : }
1007 : }
1008 : }
1009 : }
1010 : }
1011 : ELSE
1012 : {
1013 10089 : FOR( b = start_band; b < nbands; b++ )
1014 : {
1015 6726 : q_direction->band_data[b].energy_ratio_index[0] = s_max( q_direction->band_data[b].energy_ratio_index[0], 4 );
1016 6726 : bits_diff = add( bits_diff, ivas_qmetadata_encode_quasi_uniform_length_fx( sub( q_direction->band_data[b].energy_ratio_index[0], 4 ), DIRAC_DIFFUSE_LEVELS - 4 ) );
1017 6726 : q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[q_direction->band_data[b].energy_ratio_index[0]];
1018 6726 : move16();
1019 6726 : move16();
1020 :
1021 6726 : IF( q_direction->not_in_2D == 0 )
1022 : {
1023 0 : q_direction->band_data[b].azimuth_m_alphabet[0] = shl( 1, ( s_min( 5, q_direction->band_data[b].bits_sph_idx[0] ) ) );
1024 0 : move16();
1025 0 : bits_dir = add( bits_dir, ivas_qmetadata_encode_quasi_uniform_length_fx( sub( q_direction->band_data[b].azimuth_m_alphabet[0], 1 ), q_direction->band_data[b].azimuth_m_alphabet[0] ) );
1026 : }
1027 : ELSE
1028 : {
1029 6726 : bits_dir = add( bits_dir, q_direction->band_data[b].bits_sph_idx[0] );
1030 : }
1031 : }
1032 :
1033 : /* Reduce bit demand by increasing diffuseness*/
1034 3363 : bits_delta = sub( sub( sub( metadata_sid_bits, sub( hMetaData->nb_bits_tot, bit_pos_start ) ), bits_diff ), bits_dir );
1035 :
1036 3363 : test();
1037 3367 : WHILE( bits_delta < 0 && ( q_direction->not_in_2D > 0 ) )
1038 : {
1039 4 : test();
1040 4 : test();
1041 10 : FOR( b = nbands - 1; b >= start_band && ( bits_delta < 0 ); b-- )
1042 : {
1043 6 : test();
1044 6 : IF( LT_16( q_direction->band_data[b].energy_ratio_index[0], ( DIRAC_DIFFUSE_LEVELS - 1 ) ) )
1045 : {
1046 6 : bits_delta = add( bits_delta, q_direction->band_data[b].bits_sph_idx[0] );
1047 6 : q_direction->band_data[b].energy_ratio_index[0] = add( q_direction->band_data[b].energy_ratio_index[0], 1 );
1048 6 : move16();
1049 6 : q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[q_direction->band_data[b].energy_ratio_index[0]];
1050 6 : move16();
1051 6 : bits_delta = sub( bits_delta, q_direction->band_data[b].bits_sph_idx[0] );
1052 : }
1053 : }
1054 : }
1055 : }
1056 10391 : assert( ( bits_delta >= 0 ) && "Bit budget in Qmetadata SID is violated!!!" );
1057 :
1058 : /*Code diffuseness*/
1059 52257 : FOR( b = start_band; b < nbands; b++ )
1060 : {
1061 41866 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, sub( q_direction->band_data[b].energy_ratio_index[0], 4 ), DIRAC_DIFFUSE_LEVELS - 4 );
1062 : }
1063 :
1064 : /* Compute and Quantize an average direction per band*/
1065 52257 : FOR( b = start_band; b < nbands; b++ )
1066 : {
1067 41866 : set32_fx( avg_direction_vector_fx, 0, 3 );
1068 133541 : FOR( m = 0; m < nblocks; m++ )
1069 : {
1070 : /*compute the average direction */
1071 91675 : 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 );
1072 91675 : scale_sig32( direction_vector_fx, 3, Q22 - Q30 ); // Q30 -> Q22
1073 : #ifdef VEC_ARITH_OPT_v1
1074 91675 : v_add_fixed_no_hdrm( avg_direction_vector_fx, direction_vector_fx, avg_direction_vector_fx, 3 ); // Q22
1075 : #else /* VEC_ARITH_OPT_v1 */
1076 : v_add_fixed( avg_direction_vector_fx, direction_vector_fx, avg_direction_vector_fx, 3, 0 ); // Q22
1077 : #endif /* VEC_ARITH_OPT_v1 */
1078 : }
1079 :
1080 41866 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_fx, Q22, &avg_azimuth_fx[b], &avg_elevation_fx[b] );
1081 :
1082 : /* Quantize the average direction */
1083 41866 : IF( q_direction->not_in_2D == 0 )
1084 : {
1085 1250 : q_direction->band_data[b].spherical_index[0] = quantize_direction2D_fx( avg_azimuth_fx[b], q_direction->band_data[b].azimuth_m_alphabet[0], &avg_azimuth_fx[b],
1086 625 : &q_direction->band_data[b].azimuth_index[0], q_direction->cfg.mc_ls_setup );
1087 625 : move16();
1088 : }
1089 : ELSE
1090 : {
1091 82482 : q_direction->band_data[b].spherical_index[0] = quantize_direction_fx( avg_elevation_fx[b], avg_azimuth_fx[b], q_direction->band_data[b].bits_sph_idx[0], &avg_elevation_fx[b], &avg_azimuth_fx[b],
1092 41241 : &q_direction->band_data[b].elevation_index[0], &q_direction->band_data[b].azimuth_index[0], q_direction->cfg.mc_ls_setup );
1093 41241 : move16();
1094 : }
1095 :
1096 : /* Save quantized DOAs */
1097 41866 : q_direction->band_data[b].q_azimuth_fx[0] = avg_azimuth_fx[b];
1098 41866 : q_direction->band_data[b].q_elevation_fx[0] = avg_elevation_fx[b];
1099 41866 : move32();
1100 41866 : move32();
1101 :
1102 41866 : IF( EQ_16( q_direction->band_data[b].azimuth_index[0], MASA_NO_INDEX ) )
1103 : {
1104 125 : q_direction->band_data[b].azimuth_index[0] = 0;
1105 125 : move16();
1106 : }
1107 : }
1108 :
1109 : /* quantize average elevation and azimuth angles */
1110 10391 : IF( q_direction->not_in_2D > 0 )
1111 : {
1112 51507 : FOR( b = start_band; b < nbands; b++ )
1113 : {
1114 41241 : push_next_indice( hMetaData, q_direction->band_data[b].spherical_index[0], q_direction->band_data[b].bits_sph_idx[0] );
1115 : }
1116 : }
1117 : ELSE
1118 : {
1119 750 : FOR( b = start_band; b < nbands; b++ )
1120 : {
1121 625 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[b].azimuth_index[0], q_direction->band_data[b].azimuth_m_alphabet[0] );
1122 : }
1123 : }
1124 :
1125 :
1126 : /* fill bits*/
1127 10391 : assert( ( hMetaData->nb_bits_tot - bit_pos_start ) <= metadata_sid_bits && "Too many written bits!" );
1128 26849 : WHILE( ( ( ( hMetaData->nb_bits_tot - bit_pos_start ) ) < metadata_sid_bits ) )
1129 : {
1130 16458 : push_next_indice( hMetaData, 0, 1 ); /*fill bit*/
1131 : }
1132 :
1133 10391 : return;
1134 : }
1135 :
1136 :
1137 : /*-------------------------------------------------------------------------
1138 : * reset_metadata_spatial()
1139 : *
1140 : * Reset metadata in spatial formats
1141 : *------------------------------------------------------------------------*/
1142 81539 : void reset_metadata_spatial_fx(
1143 : const IVAS_FORMAT ivas_format, /* i : IVAS format */
1144 : BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */
1145 : const Word32 element_brate, /* i : element bitrate */
1146 : Word32 *total_brate, /* o : total bitrate */
1147 : const Word32 core_brate, /* i : core bitrate */
1148 : const Word16 nb_bits_metadata /* i : number of meatdata bits */
1149 : )
1150 : {
1151 : Word16 i, next_ind_sid, last_ind_sid;
1152 : Word16 j;
1153 : Word16 metadata_sid_bits;
1154 :
1155 81539 : test();
1156 81539 : IF( EQ_32( core_brate, SID_2k40 ) || core_brate == FRAME_NO_DATA )
1157 : {
1158 3932 : test();
1159 3932 : test();
1160 3932 : IF( ( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, MASA_FORMAT ) ) && core_brate != FRAME_NO_DATA )
1161 : {
1162 541 : IF( EQ_32( ivas_format, SBA_FORMAT ) )
1163 : {
1164 350 : hMetaData->ind_list[0].value = 1;
1165 350 : move16();
1166 350 : metadata_sid_bits = (Word16) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS;
1167 350 : move16();
1168 :
1169 700 : WHILE( ( hMetaData->nb_bits_tot < metadata_sid_bits ) )
1170 : {
1171 350 : push_next_indice( hMetaData, 0, 1 ); /*fill bit*/
1172 : }
1173 : }
1174 : ELSE
1175 : {
1176 : /* Reset metadata and keep only SID metadata*/
1177 191 : last_ind_sid = hMetaData->nb_ind_tot;
1178 191 : next_ind_sid = hMetaData->nb_ind_tot;
1179 191 : move16();
1180 191 : move16();
1181 2366 : WHILE( ( hMetaData->nb_bits_tot > nb_bits_metadata ) )
1182 : {
1183 2175 : next_ind_sid = sub( next_ind_sid, 1 );
1184 2175 : hMetaData->nb_bits_tot = sub( hMetaData->nb_bits_tot, hMetaData->ind_list[next_ind_sid].nb_bits );
1185 2175 : move16();
1186 : }
1187 :
1188 191 : hMetaData->nb_bits_tot = 0;
1189 191 : move16();
1190 :
1191 3964 : FOR( i = 0; i < next_ind_sid; i++ )
1192 : {
1193 3773 : hMetaData->ind_list[i].nb_bits = -1;
1194 3773 : move16();
1195 : }
1196 :
1197 2366 : FOR( ( j = 0, i = next_ind_sid ); i < last_ind_sid; ( i++, j++ ) )
1198 : {
1199 2175 : hMetaData->ind_list[j].value = hMetaData->ind_list[i].value;
1200 2175 : hMetaData->ind_list[j].nb_bits = hMetaData->ind_list[i].nb_bits;
1201 2175 : hMetaData->nb_bits_tot = add( hMetaData->nb_bits_tot, hMetaData->ind_list[j].nb_bits );
1202 2175 : hMetaData->ind_list[i].nb_bits = -1;
1203 2175 : move16();
1204 2175 : move16();
1205 2175 : move16();
1206 2175 : move16();
1207 : }
1208 :
1209 191 : hMetaData->nb_ind_tot = j;
1210 191 : move16();
1211 : }
1212 : }
1213 : ELSE
1214 : {
1215 : /*Reset metadata*/
1216 3391 : reset_indices_enc_fx( hMetaData, hMetaData->nb_ind_tot );
1217 : }
1218 :
1219 3932 : *total_brate = element_brate;
1220 3932 : move32();
1221 : }
1222 77607 : ELSE IF( NE_32( ivas_format, SBA_FORMAT ) )
1223 : {
1224 : /* Reset SID metadata bits*/
1225 101935 : WHILE( ( hMetaData->nb_bits_tot > nb_bits_metadata ) )
1226 : {
1227 65708 : hMetaData->nb_ind_tot = sub( hMetaData->nb_ind_tot, 1 );
1228 65708 : hMetaData->nb_bits_tot = sub( hMetaData->nb_bits_tot, hMetaData->ind_list[hMetaData->nb_ind_tot].nb_bits );
1229 65708 : hMetaData->ind_list[hMetaData->nb_ind_tot].nb_bits = -1;
1230 65708 : move16();
1231 65708 : move16();
1232 65708 : move16();
1233 : }
1234 : }
1235 :
1236 81539 : return;
1237 : }
1238 :
1239 :
1240 : /*-------------------------------------------------------------------------
1241 : * quantize_direction2D()
1242 : *
1243 : *
1244 : *------------------------------------------------------------------------*/
1245 : /*! r: quantized spherical index */
1246 85849 : Word16 quantize_direction2D_fx(
1247 : Word32 phi, /* i : input azimuth value Q22 */
1248 : const Word16 no_cw, /* i : number of bits */
1249 : Word32 *phi_q, /* o : quantized azimuth value Q22 */
1250 : UWord16 *index_phi, /* o : quantized azimuth index */
1251 : const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */
1252 : )
1253 : {
1254 : Word16 idx_sph;
1255 : UWord16 id_phi;
1256 85849 : IF( LT_16( no_cw, 2 ) )
1257 : {
1258 0 : *phi_q = 0;
1259 0 : move32();
1260 :
1261 0 : return 0;
1262 : }
1263 :
1264 85849 : IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) )
1265 : {
1266 83843 : id_phi = quantize_phi_chan_compand_fx( L_add( phi, DEGREE_180_Q_22 ), phi_q, no_cw, 0, mc_format );
1267 : }
1268 : ELSE
1269 : {
1270 2006 : id_phi = quantize_phi_enc_fx( L_add( phi, DEGREE_180_Q_22 ), 0, phi_q, no_cw );
1271 : }
1272 85849 : *phi_q = L_sub( *phi_q, DEGREE_180_Q_22 );
1273 85849 : move32();
1274 :
1275 85849 : *index_phi = ivas_qmetadata_reorder_generic_fx( sub( id_phi, shr( no_cw, 1 ) ) );
1276 85849 : move16();
1277 :
1278 85849 : idx_sph = id_phi;
1279 85849 : move16();
1280 :
1281 85849 : return idx_sph;
1282 : }
1283 :
1284 2276 : static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512_fx(
1285 : IVAS_QMETADATA_HANDLE hQMetaData,
1286 : Word16 *needed_bits,
1287 : const Word16 bits_dir_hr,
1288 : BSTR_ENC_HANDLE hMetaData )
1289 : {
1290 : Word16 j, k;
1291 : Word16 index;
1292 :
1293 2276 : needed_bits[0] = 0;
1294 2276 : needed_bits[1] = 0;
1295 2276 : move16();
1296 2276 : move16();
1297 :
1298 56600 : FOR( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j )
1299 : {
1300 261270 : FOR( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ )
1301 : {
1302 206946 : index = masa_sq_fx( L_sub( ONE_IN_Q30, hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] ), diffuseness_thresholds_hr_fx, HR_MASA_ER_LEVELS );
1303 :
1304 206946 : push_next_indice( hMetaData, index, MASA_BITS_ER_HR );
1305 206946 : hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index;
1306 206946 : hQMetaData->q_direction[0].band_data[j].energy_ratio_index_mod[k] = index;
1307 206946 : hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] = W_extract_h( W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[index] ) ); // Q30
1308 206946 : needed_bits[0] = add( needed_bits[0], MASA_BITS_ER_HR );
1309 206946 : hQMetaData->q_direction[0].band_data[j].bits_sph_idx[k] = bits_dir_hr;
1310 206946 : move16();
1311 206946 : move16();
1312 206946 : move32();
1313 206946 : move16();
1314 206946 : move16();
1315 : }
1316 : }
1317 :
1318 2276 : IF( EQ_16( hQMetaData->no_directions, 2 ) )
1319 : {
1320 : Word32 ratioSum;
1321 : Word16 div_e;
1322 1256 : IF( EQ_16( bits_dir_hr, 16 ) )
1323 : {
1324 9500 : FOR( j = hQMetaData->q_direction[1].cfg.start_band; j < hQMetaData->q_direction[1].cfg.nbands; j++ )
1325 : {
1326 45600 : FOR( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
1327 : {
1328 36480 : index = masa_sq_fx( L_sub( ONE_IN_Q30, hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] ), diffuseness_thresholds_hr_fx, HR_MASA_ER_LEVELS );
1329 :
1330 36480 : push_next_indice( hMetaData, index, MASA_BITS_ER_HR );
1331 36480 : hQMetaData->q_direction[1].band_data[j].energy_ratio_index[k] = index;
1332 36480 : move16();
1333 36480 : hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = W_extract_h( W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[index] ) );
1334 36480 : move32();
1335 :
1336 36480 : ratioSum = L_add( hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k], hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] );
1337 36480 : IF( GT_32( ratioSum, ONE_IN_Q30 /*1.0f*/ ) )
1338 : {
1339 1294 : hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_newton( hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k], ratioSum, &div_e );
1340 1294 : hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] = L_shl( hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k], sub( div_e, 1 ) );
1341 1294 : move32();
1342 1294 : move32();
1343 :
1344 1294 : hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_newton( hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k], ratioSum, &div_e );
1345 1294 : hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = L_shl( hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k], sub( div_e, 1 ) );
1346 1294 : move32();
1347 1294 : move32();
1348 : }
1349 :
1350 36480 : needed_bits[1] = add( needed_bits[1], MASA_BITS_ER_HR );
1351 36480 : move16();
1352 36480 : hQMetaData->q_direction[1].band_data[j].bits_sph_idx[k] = bits_dir_hr;
1353 36480 : move16();
1354 : }
1355 : }
1356 : }
1357 : ELSE
1358 : {
1359 : Word16 pos_2dir_band[MASA_MAXIMUM_CODING_SUBBANDS];
1360 876 : k = 0;
1361 876 : move16();
1362 21600 : FOR( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; j++ )
1363 : {
1364 20724 : IF( EQ_16( hQMetaData->twoDirBands[j], 1 ) )
1365 : {
1366 8334 : pos_2dir_band[k] = j;
1367 8334 : move16();
1368 8334 : k = add( k, 1 );
1369 : }
1370 : ELSE
1371 : {
1372 12390 : pos_2dir_band[k] = 0;
1373 12390 : move16();
1374 : }
1375 : }
1376 9210 : FOR( j = hQMetaData->q_direction[1].cfg.start_band; j < hQMetaData->q_direction[1].cfg.nbands; j++ )
1377 : {
1378 36270 : FOR( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
1379 : {
1380 27936 : index = masa_sq_fx( L_sub( ONE_IN_Q30, hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] ), diffuseness_thresholds_hr_fx, HR_MASA_ER_LEVELS );
1381 :
1382 27936 : push_next_indice( hMetaData, index, MASA_BITS_ER_HR );
1383 27936 : hQMetaData->q_direction[1].band_data[j].energy_ratio_index[k] = index;
1384 27936 : move16();
1385 27936 : hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = W_extract_h( W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[index] ) ); // Q30
1386 27936 : move32();
1387 :
1388 27936 : ratioSum = L_add( hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k], hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] ); // Q30
1389 :
1390 27936 : IF( GT_32( ratioSum, ONE_IN_Q30 /*1.0f*/ ) )
1391 : {
1392 326 : hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_newton( hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k], ratioSum, &div_e );
1393 326 : hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k] = L_shl( hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k], sub( div_e, 1 ) );
1394 326 : move32();
1395 326 : move32();
1396 :
1397 326 : hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_newton( hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k], ratioSum, &div_e );
1398 326 : hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = L_shl( hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k], sub( div_e, 1 ) );
1399 326 : move32();
1400 326 : move32();
1401 : }
1402 :
1403 27936 : needed_bits[1] = add( needed_bits[1], MASA_BITS_ER_HR );
1404 27936 : move16();
1405 27936 : hQMetaData->q_direction[1].band_data[j].bits_sph_idx[k] = bits_dir_hr;
1406 27936 : move16();
1407 : }
1408 : }
1409 : }
1410 : }
1411 :
1412 2276 : return;
1413 : }
1414 :
1415 :
1416 : /*-------------------------------------------------------------------------
1417 : * ivas_qmetadata_quantize_diffuseness_nrg_ratios()
1418 : *
1419 : * Quantize diffuseness
1420 : *------------------------------------------------------------------------*/
1421 :
1422 202957 : static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_fx(
1423 : IVAS_QMETADATA_HANDLE hQMetaData,
1424 : Word16 *needed_bits,
1425 : Word16 *nbits_diff,
1426 : Word16 *dfRatioBits,
1427 : const Word16 hodirac_flag )
1428 : {
1429 : Word16 j, k, dir2band;
1430 : Word16 index_dirRatio1Inv, index_dirRatio2Inv, index_dirRatio1Inv_mod, index_dirRatio2Inv_mod;
1431 : Word16 index_diff;
1432 :
1433 202957 : nbits_diff[0] = 0;
1434 202957 : nbits_diff[1] = 0;
1435 202957 : needed_bits[0] = 0;
1436 202957 : needed_bits[1] = 0;
1437 202957 : dir2band = 0;
1438 202957 : move16();
1439 202957 : move16();
1440 202957 : move16();
1441 202957 : move16();
1442 202957 : move16();
1443 :
1444 1106170 : FOR( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j )
1445 : {
1446 903213 : test();
1447 903213 : IF( EQ_32( hQMetaData->no_directions, 2 ) && EQ_16( hQMetaData->twoDirBands[j], 1 ) )
1448 208080 : {
1449 : Word32 diffRatio, dfRatio, dfRatioQ, diffRatioQ, dirRatio1Q, dirRatio2Q; /* Q30 */
1450 : Word32 dirRatio1, dirRatio2, sumRatio; /* Q30 */
1451 : Word16 dfRatio_index, dfRatio_qsteps, dfRatio_bits;
1452 :
1453 : /* With 2dir metadata, we quantize and transmit diffuse-to-total ratio (diffRatio) and
1454 : * distribution factor of direct-to-total ratios (dFRatio). This is more efficient and
1455 : * accurate than simple separate quantization of each direct-to-total ratio or their
1456 : * separate inverses. */
1457 208080 : IF( hodirac_flag )
1458 : {
1459 : /* already encoded as total and ratios in HO-DirAC */
1460 194880 : diffRatio = L_sub( ONE_IN_Q30, hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0] ); // Q30
1461 194880 : dfRatio = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[0]; // Q30
1462 194880 : move32();
1463 : }
1464 : ELSE
1465 : {
1466 13200 : dirRatio1 = hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0]; // Q30
1467 13200 : move32();
1468 13200 : dirRatio2 = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[0]; // Q30
1469 13200 : move32();
1470 13200 : sumRatio = L_add( dirRatio1, dirRatio2 ); // Q30
1471 13200 : diffRatio = L_sub( ONE_IN_Q30, sumRatio ); // Q30
1472 13200 : IF( LT_32( sumRatio, EPSILON_FIX ) )
1473 : {
1474 0 : dfRatio = ONE_IN_Q29 /* 0.5f in Q30*/; // Q30
1475 0 : move32();
1476 : }
1477 : ELSE
1478 : {
1479 : Word16 exp_diff;
1480 13200 : dfRatio = L_deposit_h( BASOP_Util_Divide3232_Scale( dirRatio1, sumRatio, &exp_diff ) );
1481 13200 : dfRatio = L_shl( dfRatio, sub( exp_diff, Q1 ) ); // Q30
1482 : }
1483 : }
1484 :
1485 :
1486 208080 : index_diff = masa_sq_fx( diffRatio, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS );
1487 208080 : diffRatioQ = diffuseness_reconstructions_fx[index_diff]; // Q30
1488 208080 : move32();
1489 :
1490 208080 : IF( hodirac_flag )
1491 : {
1492 194880 : dfRatio_bits = ivas_get_df_ratio_bits_hodirac_fx( index_diff );
1493 : }
1494 : ELSE
1495 : {
1496 13200 : dfRatio_bits = ivas_get_df_ratio_bits_fx( index_diff );
1497 : }
1498 :
1499 208080 : dfRatioBits[dir2band] = dfRatio_bits;
1500 208080 : move16();
1501 :
1502 208080 : dfRatio_qsteps = shl( 1, dfRatio_bits );
1503 208080 : IF( hodirac_flag )
1504 : {
1505 : Word16 dfRatioQ16; /* Q14 */
1506 194880 : dfRatio_index = usquant_fx( extract_h( dfRatio ), &dfRatioQ16 /* Q14 */, 0, shr( div_s( 1, sub( dfRatio_qsteps, 1 ) ), 2 ), dfRatio_qsteps );
1507 194880 : dfRatioQ = L_deposit_h( dfRatioQ16 ); // Q30
1508 194880 : dirRatio1Q = L_sub( ONE_IN_Q30, diffRatioQ ); // Q30
1509 194880 : dirRatio2Q = dfRatioQ; // Q30
1510 194880 : move32();
1511 : }
1512 : ELSE
1513 : {
1514 : Word16 dfRatioQ16; /* Q14 */
1515 13200 : dfRatio_index = usquant_fx( extract_h( dfRatio ), &dfRatioQ16 /* Q14 */, ONE_IN_Q13 /* 0.5f in Q14 */, shr( div_s( 1, sub( dfRatio_qsteps, 1 ) ), 3 ), dfRatio_qsteps );
1516 :
1517 : /* Direction quantization requires also separately quantized direct-to-total ratios. Thus, we calculate them. */
1518 13200 : dirRatio1Q = L_shl( Mpy_32_16_1( L_sub( ONE_IN_Q30, diffRatioQ ), dfRatioQ16 ), 1 ); // Q30
1519 13200 : dirRatio2Q = L_sub( L_sub( ONE_IN_Q30, diffRatioQ ), dirRatio1Q ); // Q30
1520 : }
1521 :
1522 208080 : index_dirRatio1Inv = masa_sq_fx( L_sub( ONE_IN_Q30, dirRatio1Q ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS );
1523 :
1524 : /* Note: To save memory, we store temporarily index_diff and dfRatio_index into first and second direction
1525 : * energy ratio index variables until they have been encoded. index_dirRatio1Inv and index_dirRatio2Inv are
1526 : * then later retrieved for further use in encoding. */
1527 1031268 : FOR( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ )
1528 : {
1529 823188 : hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index_diff; // Q0
1530 823188 : move16();
1531 823188 : hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] = dirRatio1Q; // Q30
1532 823188 : move32();
1533 : }
1534 208080 : nbits_diff[0] = add( nbits_diff[0], MASA_BITS_ER );
1535 208080 : move16();
1536 :
1537 208080 : IF( hodirac_flag )
1538 : {
1539 : Word16 tmp; /* Q14 */
1540 194880 : index_dirRatio2Inv = usquant_fx( extract_h( dirRatio2Q ), &tmp /* Q14 */, 0, shr( div_s( 1, sub( DIRAC_DIFFUSE_LEVELS, 1 ) ), 2 ), DIRAC_DIFFUSE_LEVELS );
1541 : }
1542 : ELSE
1543 : {
1544 13200 : index_dirRatio2Inv = masa_sq_fx( L_sub( ONE_IN_Q30, dirRatio2Q ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS );
1545 : }
1546 :
1547 1031268 : FOR( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
1548 : {
1549 823188 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[k] = dfRatio_index; // Q0
1550 823188 : move16();
1551 823188 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[k] = dirRatio2Q; // Q30
1552 823188 : move32();
1553 : }
1554 208080 : nbits_diff[1] = add( nbits_diff[1], dfRatio_bits );
1555 208080 : move16();
1556 :
1557 : /* Obtain compensated direct-to-total ratios for direction quantization. This compensates for the
1558 : * fact that with 2dir data, it is harder to achieve separate high direct-to-total ratio values
1559 : * which are assumed by the direction quantization system. In practice, this improves direction
1560 : * accuracy when it is perceptual meaningful. */
1561 208080 : masa_compensate_two_dir_energy_ratio_index_fx( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod, hodirac_flag );
1562 :
1563 1031268 : FOR( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ )
1564 : {
1565 823188 : hQMetaData->q_direction[0].band_data[j].energy_ratio_index_mod[k] = index_dirRatio1Inv_mod;
1566 823188 : move16();
1567 823188 : hQMetaData->q_direction[0].band_data[j].bits_sph_idx[k] = bits_direction_masa[index_dirRatio1Inv_mod];
1568 823188 : move16();
1569 : }
1570 208080 : needed_bits[0] = add( needed_bits[0], imult1616( hQMetaData->q_direction[0].cfg.nblocks, bits_direction_masa[index_dirRatio1Inv_mod] ) );
1571 208080 : move16();
1572 :
1573 1031268 : FOR( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
1574 : {
1575 823188 : hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index_mod[k] = index_dirRatio2Inv_mod;
1576 823188 : move16();
1577 823188 : hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[k] = bits_direction_masa[index_dirRatio2Inv_mod];
1578 823188 : move16();
1579 : }
1580 208080 : needed_bits[1] = add( needed_bits[1], imult1616( hQMetaData->q_direction[1].cfg.nblocks, bits_direction_masa[index_dirRatio2Inv_mod] ) );
1581 208080 : move16();
1582 :
1583 208080 : dir2band = add( dir2band, 1 );
1584 : }
1585 : ELSE
1586 : {
1587 695133 : index_dirRatio1Inv = masa_sq_fx( L_sub( ONE_IN_Q30, hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0] ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS );
1588 :
1589 2915733 : FOR( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ )
1590 : {
1591 2220600 : hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index_dirRatio1Inv;
1592 2220600 : move16();
1593 2220600 : hQMetaData->q_direction[0].band_data[j].energy_ratio_index_mod[k] = index_dirRatio1Inv;
1594 2220600 : move16();
1595 2220600 : hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[index_dirRatio1Inv] ); // Q30
1596 2220600 : move32();
1597 2220600 : hQMetaData->q_direction[0].band_data[j].bits_sph_idx[k] = bits_direction_masa[index_dirRatio1Inv];
1598 2220600 : move16();
1599 : }
1600 :
1601 695133 : nbits_diff[0] = add( nbits_diff[0], MASA_BITS_ER );
1602 695133 : move16();
1603 :
1604 695133 : needed_bits[0] = add( needed_bits[0], imult1616( hQMetaData->q_direction[0].cfg.nblocks, bits_direction_masa[index_dirRatio1Inv] ) );
1605 695133 : move16();
1606 : }
1607 : }
1608 :
1609 202957 : return;
1610 : }
1611 :
1612 :
1613 : /*-------------------------------------------------------------------------
1614 : * ivas_diffuseness_huff_ec_encode()
1615 : *
1616 : *
1617 : *------------------------------------------------------------------------*/
1618 144052 : static Word16 ivas_diffuseness_huff_ec_encode_fx(
1619 : BSTR_ENC_HANDLE hMetaData,
1620 : const UWord16 idx )
1621 : {
1622 : Word16 nbits;
1623 144052 : nbits = 0;
1624 144052 : move16();
1625 144052 : IF( LE_16( idx, DIFF_EC_HUFF_GR0_LIMIT ) )
1626 : {
1627 140957 : IF( idx > 0 )
1628 : {
1629 79097 : push_next_indice( hMetaData, (UWord16) L_sub( L_shl( 1, idx ), 1 ), idx );
1630 79097 : nbits = add( nbits, idx );
1631 : }
1632 140957 : push_next_indice( hMetaData, 0, 1 );
1633 140957 : nbits = add( nbits, 1 );
1634 : }
1635 : ELSE
1636 : {
1637 3095 : push_next_indice( hMetaData, 511, DIFF_EC_HUFF_GR0_LIMIT + 1 );
1638 3095 : push_next_indice( hMetaData, (UWord16) L_sub( idx, DIFF_EC_HUFF_GR0_LIMIT + 1 ), 2 );
1639 3095 : nbits = add( nbits, DIFF_EC_HUFF_GR0_LIMIT + 3 );
1640 : }
1641 144052 : return nbits;
1642 : }
1643 :
1644 : /*-------------------------------------------------------------------------
1645 : * ivas_diffuseness_huff_ec_prepare()
1646 : *
1647 : *
1648 : *------------------------------------------------------------------------*/
1649 25294 : static void ivas_diffuseness_huff_ec_prepare_fx(
1650 : IVAS_QDIRECTION *q_direction,
1651 : Word16 *best_av,
1652 : UWord16 *avr_idx,
1653 : Word16 *diffuseness_bits_huff )
1654 : {
1655 : Word16 bits;
1656 : Word16 av_crt;
1657 : Word16 av;
1658 : Word16 av_e;
1659 : Word16 sh_idx;
1660 : UWord16 ui_sh_idx[MASA_MAXIMUM_CODING_SUBBANDS];
1661 : Word16 b, start_band, nbands;
1662 :
1663 25294 : start_band = q_direction->cfg.start_band;
1664 25294 : move16();
1665 25294 : nbands = q_direction->cfg.nbands;
1666 25294 : move16();
1667 :
1668 25294 : *diffuseness_bits_huff = 0;
1669 25294 : move16();
1670 25294 : av = 0;
1671 25294 : move16();
1672 344582 : FOR( b = start_band; b < nbands; b++ )
1673 : {
1674 319288 : av = add( av, q_direction->band_data[b].energy_ratio_index[0] );
1675 : }
1676 : // av = (Word16) ( 0.5f + av / (float) nbands );
1677 25294 : av = BASOP_Util_Divide1616_Scale( av, nbands, &av_e );
1678 25294 : av = shr_r( av, sub( 15, av_e ) ); // Q0
1679 25294 : *best_av = av;
1680 25294 : move16();
1681 :
1682 25294 : *diffuseness_bits_huff = MAX16B;
1683 25294 : move16();
1684 101176 : FOR( av_crt = av - 1; av_crt <= av + 1; av_crt++ )
1685 : {
1686 75882 : bits = 0;
1687 75882 : move16();
1688 1033746 : FOR( b = start_band; b < nbands; b++ )
1689 : {
1690 957864 : sh_idx = sub( q_direction->band_data[b].energy_ratio_index[0], av_crt );
1691 : // ui_sh_idx[b] = ( sh_idx <= 0 ) ? ( -2 * sh_idx ) : sh_idx * 2 - 1;
1692 957864 : IF( sh_idx <= 0 )
1693 : {
1694 568203 : ui_sh_idx[b] = negate( shl( sh_idx, 1 ) );
1695 : }
1696 : ELSE
1697 : {
1698 389661 : ui_sh_idx[b] = sub( shl( sh_idx, 1 ), 1 );
1699 : }
1700 957864 : move16();
1701 957864 : if ( GE_32( ui_sh_idx[b], 2 * DIRAC_DIFFUSE_LEVELS - 3 ) )
1702 : {
1703 3840 : bits = 100; /* to avoid difference larger than 6 in absolute value */
1704 3840 : move16();
1705 : }
1706 :
1707 : // bits += ( ui_sh_idx[b] <= DIFF_EC_HUFF_GR0_LIMIT ) ? ( ui_sh_idx[b] + 1 ) : 11;
1708 957864 : IF( LE_32( ui_sh_idx[b], DIFF_EC_HUFF_GR0_LIMIT ) )
1709 : {
1710 923595 : bits = add( bits, add( ui_sh_idx[b], 1 ) );
1711 : }
1712 : ELSE
1713 : {
1714 34269 : bits = add( bits, 11 );
1715 : }
1716 : }
1717 :
1718 75882 : IF( LT_16( bits, *diffuseness_bits_huff ) )
1719 : {
1720 47109 : *diffuseness_bits_huff = bits;
1721 47109 : move16();
1722 47109 : Copy( (Word16 *) ui_sh_idx, (Word16 *) avr_idx, nbands );
1723 47109 : *best_av = av_crt;
1724 47109 : move16();
1725 : }
1726 : }
1727 :
1728 25294 : *diffuseness_bits_huff = add( *diffuseness_bits_huff, MASA_BITS_ER ); /* for the average */
1729 25294 : move16();
1730 :
1731 25294 : return;
1732 : }
1733 :
1734 : /*-------------------------------------------------------------------------
1735 : * ivas_qmetadata_entropy_encode_diffuseness()
1736 : *
1737 : * encode diffuseness
1738 : *------------------------------------------------------------------------*/
1739 202957 : static Word16 ivas_qmetadata_entropy_encode_diffuseness_fx(
1740 : BSTR_ENC_HANDLE hMetaData,
1741 : IVAS_QDIRECTION *q_direction,
1742 : UWord16 *diffuseness_index_max_ec_frame )
1743 : {
1744 : Word16 start_bit_pos;
1745 : Word16 diffuseness_bits_raw;
1746 : Word16 b;
1747 : Word16 min_diffuseness_m_index, max_diffuseness_m_index;
1748 : Word16 nbands;
1749 : Word16 start_band;
1750 :
1751 202957 : nbands = q_direction->cfg.nbands;
1752 202957 : move16();
1753 202957 : start_band = q_direction->cfg.start_band;
1754 202957 : move16();
1755 :
1756 202957 : start_bit_pos = hMetaData->nb_bits_tot;
1757 202957 : move16();
1758 :
1759 202957 : IF( EQ_16( nbands, 1 ) )
1760 : {
1761 : /* If there is only one band, diffuseness should be coded directly as raw with no signaling. */
1762 3973 : push_next_indice( hMetaData, q_direction->band_data[0].energy_ratio_index[0], MASA_BITS_ER );
1763 3973 : *diffuseness_index_max_ec_frame = 5;
1764 3973 : move16();
1765 3973 : return sub( hMetaData->nb_bits_tot, start_bit_pos );
1766 : }
1767 :
1768 : /* compute the number of raw coding bits */
1769 198984 : diffuseness_bits_raw = 0;
1770 198984 : move16();
1771 1098224 : FOR( b = start_band; b < nbands; b++ )
1772 : {
1773 899240 : diffuseness_bits_raw = add( diffuseness_bits_raw, ivas_qmetadata_encode_quasi_uniform_length_fx( q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ) );
1774 : }
1775 :
1776 198984 : min_diffuseness_m_index = q_direction->band_data[start_band].energy_ratio_index[0];
1777 198984 : move16();
1778 198984 : max_diffuseness_m_index = q_direction->band_data[start_band].energy_ratio_index[0];
1779 198984 : move16();
1780 :
1781 1098224 : FOR( b = start_band; b < nbands; b++ )
1782 : {
1783 899240 : if ( LT_16( q_direction->band_data[b].energy_ratio_index[0], min_diffuseness_m_index ) )
1784 : {
1785 118363 : min_diffuseness_m_index = q_direction->band_data[b].energy_ratio_index[0];
1786 118363 : move16();
1787 : }
1788 :
1789 899240 : if ( GT_16( q_direction->band_data[b].energy_ratio_index[0], max_diffuseness_m_index ) )
1790 : {
1791 129862 : max_diffuseness_m_index = q_direction->band_data[b].energy_ratio_index[0];
1792 129862 : move16();
1793 : }
1794 : }
1795 :
1796 198984 : IF( LT_16( nbands, DIFF_EC_HUFF_BAND_LIMIT ) )
1797 : {
1798 : /* Use similarity coding approach or raw coding when there is a low number of bands. */
1799 : /* one bit is used to indicate whether diffuseness values are entropy coded or coded raw */
1800 173690 : IF( EQ_16( min_diffuseness_m_index, max_diffuseness_m_index ) ) /* all values are equal */
1801 : {
1802 52525 : push_next_indice( hMetaData, 0, 1 ); /* dif_use_raw_coding */
1803 52525 : push_next_indice( hMetaData, 1, 1 ); /* dif_have_unique_value */
1804 52525 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, min_diffuseness_m_index, DIRAC_DIFFUSE_LEVELS ); /* dif_unique_value */
1805 : }
1806 121165 : ELSE IF( EQ_16( add( min_diffuseness_m_index, 1 ), max_diffuseness_m_index ) ) /* only two consecutive values are present */
1807 : {
1808 38348 : push_next_indice( hMetaData, 0, 1 ); /* dif_use_raw_coding */
1809 38348 : push_next_indice( hMetaData, 0, 1 ); /* dif_have_unique_value */
1810 38348 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, min_diffuseness_m_index, DIRAC_DIFFUSE_LEVELS - 1 ); /* dif_min_value */
1811 :
1812 167986 : FOR( b = start_band; b < nbands; b++ )
1813 : {
1814 129638 : push_next_indice( hMetaData, sub( q_direction->band_data[b].energy_ratio_index[0], min_diffuseness_m_index ), 1 ); /* dif_bit_offset_values */
1815 : }
1816 : }
1817 : ELSE /* raw coding */
1818 : {
1819 82817 : push_next_indice( hMetaData, 1, 1 ); /* dif_use_raw_coding */
1820 :
1821 379174 : FOR( b = start_band; b < nbands; b++ )
1822 : {
1823 296357 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ); /* dif_values */
1824 : }
1825 : }
1826 : }
1827 : ELSE
1828 : {
1829 : /* Use Huffman-coding approach or raw coding when there is a high number of bands. */
1830 : Word16 diffuseness_bits_huff;
1831 : Word16 best_av;
1832 : UWord16 avr_idx[MASA_MAXIMUM_CODING_SUBBANDS];
1833 :
1834 : /* First, obtain average indices and bit usage for Huffman-coding. */
1835 25294 : ivas_diffuseness_huff_ec_prepare_fx( q_direction, &best_av, avr_idx, &diffuseness_bits_huff );
1836 :
1837 : /* If there is benefit, use Huffman-coding. Otherwise, use raw coding. */
1838 25294 : IF( LT_16( diffuseness_bits_huff, diffuseness_bits_raw ) )
1839 : {
1840 : /* Signal Huffman EC */
1841 11241 : push_next_indice( hMetaData, 0, 1 );
1842 11241 : push_next_indice( hMetaData, best_av, MASA_BITS_ER );
1843 155293 : FOR( b = start_band; b < nbands; b++ )
1844 : {
1845 144052 : ivas_diffuseness_huff_ec_encode_fx( hMetaData, avr_idx[b] );
1846 : }
1847 : }
1848 : ELSE
1849 : {
1850 : /* Signal raw */
1851 14053 : push_next_indice( hMetaData, 1, 1 );
1852 189289 : FOR( b = start_band; b < nbands; b++ )
1853 : {
1854 175236 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ); /* dif_values */
1855 : }
1856 : }
1857 : }
1858 :
1859 198984 : *diffuseness_index_max_ec_frame = 5;
1860 198984 : move16();
1861 : /* adaptively select the diffuseness_index_max_ec threshold */
1862 198984 : IF( GT_16( min_diffuseness_m_index, 5 ) )
1863 : {
1864 71096 : *diffuseness_index_max_ec_frame = DIRAC_DIFFUSE_LEVELS - 1;
1865 71096 : move16();
1866 : }
1867 :
1868 :
1869 198984 : return sub( hMetaData->nb_bits_tot, start_bit_pos );
1870 : }
1871 :
1872 : /*-------------------------------------------------------------------------
1873 : * ivas_qmetadata_entropy_encode_df_ratio()
1874 : *
1875 : * encode dfRatio
1876 : *------------------------------------------------------------------------*/
1877 20820 : static Word16 ivas_qmetadata_entropy_encode_df_ratio_fx(
1878 : BSTR_ENC_HANDLE hMetaData,
1879 : IVAS_QDIRECTION *q_direction,
1880 : Word16 *df_ratio_bits )
1881 : {
1882 : Word16 start_bit_pos;
1883 : Word16 bits_raw;
1884 : Word16 b;
1885 : Word16 min_index, max_index;
1886 : Word16 nbands, start_band;
1887 : Word16 max_df_ratio_bits;
1888 20820 : Word16 ec_mode = 0;
1889 20820 : move16();
1890 : Word16 max_alphabet_size;
1891 :
1892 20820 : nbands = q_direction->cfg.nbands;
1893 20820 : move16();
1894 20820 : start_band = q_direction->cfg.start_band;
1895 20820 : move16();
1896 :
1897 20820 : start_bit_pos = hMetaData->nb_bits_tot;
1898 20820 : move16();
1899 :
1900 20820 : IF( EQ_16( nbands, 1 ) )
1901 : {
1902 : /* If there is only one band, ratio should be coded directly as raw with no signaling. */
1903 1732 : push_next_indice( hMetaData, q_direction->band_data[0].energy_ratio_index[0], df_ratio_bits[0] );
1904 :
1905 1732 : return sub( hMetaData->nb_bits_tot, start_bit_pos );
1906 : }
1907 :
1908 : /* compute the number of raw coding bits */
1909 19088 : bits_raw = 0;
1910 19088 : move16();
1911 19088 : max_df_ratio_bits = 0;
1912 19088 : move16();
1913 225436 : FOR( b = start_band; b < nbands; b++ )
1914 : {
1915 206348 : bits_raw = add( bits_raw, df_ratio_bits[b] );
1916 206348 : max_df_ratio_bits = s_max( df_ratio_bits[b], max_df_ratio_bits );
1917 : }
1918 :
1919 19088 : min_index = q_direction->band_data[start_band].energy_ratio_index[0];
1920 19088 : move16();
1921 19088 : max_index = q_direction->band_data[start_band].energy_ratio_index[0];
1922 19088 : move16();
1923 225436 : FOR( b = start_band; b < nbands; b++ )
1924 : {
1925 206348 : if ( LT_16( q_direction->band_data[b].energy_ratio_index[0], min_index ) )
1926 : {
1927 16386 : min_index = q_direction->band_data[b].energy_ratio_index[0];
1928 16386 : move16();
1929 : }
1930 :
1931 206348 : if ( GT_16( q_direction->band_data[b].energy_ratio_index[0], max_index ) )
1932 : {
1933 23295 : max_index = q_direction->band_data[b].energy_ratio_index[0];
1934 23295 : move16();
1935 : }
1936 : }
1937 :
1938 : /* Decide what modes are possible */
1939 19088 : IF( GE_16( bits_raw, add( add( max_df_ratio_bits, 2 ), nbands ) ) )
1940 : {
1941 14574 : ec_mode = 2;
1942 : }
1943 4514 : ELSE IF( GE_16( bits_raw, add( max_df_ratio_bits, 1 ) ) )
1944 : {
1945 4514 : ec_mode = 1;
1946 : }
1947 : ELSE
1948 : {
1949 0 : ec_mode = 0;
1950 : }
1951 19088 : move16();
1952 19088 : max_alphabet_size = shl( 1, max_df_ratio_bits );
1953 :
1954 19088 : test();
1955 19088 : test();
1956 19088 : IF( EQ_16( min_index, max_index ) && ec_mode > 0 ) /* all values are equal */
1957 : {
1958 344 : push_next_indice( hMetaData, 0, 1 ); /* Signal between EC and raw */
1959 344 : IF( GT_16( ec_mode, 1 ) )
1960 : {
1961 : /* Only use bit for signaling if necessary */
1962 101 : push_next_indice( hMetaData, 0, 1 ); /* Signal between one value or bandwise diff mode */
1963 : }
1964 :
1965 344 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, min_index, max_alphabet_size );
1966 : }
1967 18744 : ELSE IF( EQ_16( add( min_index, 1 ), max_index ) && GT_16( ec_mode, 1 ) ) /* only two consecutive values are present */
1968 : {
1969 1181 : push_next_indice( hMetaData, 0, 1 );
1970 1181 : push_next_indice( hMetaData, 1, 1 );
1971 1181 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, min_index, sub( max_alphabet_size, 1 ) );
1972 :
1973 12132 : FOR( b = start_band; b < nbands; b++ )
1974 : {
1975 10951 : push_next_indice( hMetaData, sub( q_direction->band_data[b].energy_ratio_index[0], min_index ), 1 ); /* Band-wise offset values */
1976 : }
1977 : }
1978 : ELSE /* raw coding */
1979 : {
1980 17563 : IF( ec_mode > 0 )
1981 : {
1982 17563 : push_next_indice( hMetaData, 1, 1 ); /* Only signal raw mode if not implicitly using it */
1983 : }
1984 :
1985 211668 : FOR( b = start_band; b < nbands; b++ )
1986 : {
1987 194105 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[b].energy_ratio_index[0], shl( 1, df_ratio_bits[b] ) ); /* dif_values */
1988 : }
1989 : }
1990 :
1991 19088 : return sub( hMetaData->nb_bits_tot, start_bit_pos );
1992 : }
1993 :
1994 : /*-------------------------------------------------------------------------
1995 : * restore_metadata_buffer()
1996 : *
1997 : * Restore metadata buffer
1998 : *------------------------------------------------------------------------*/
1999 248691 : void restore_metadata_buffer_fx(
2000 : BSTR_ENC_HANDLE hMetaData,
2001 : const Word16 next_ind_start,
2002 : const Word16 bit_pos_start )
2003 : {
2004 : Word16 i;
2005 :
2006 11198879 : FOR( i = next_ind_start; i < hMetaData->nb_ind_tot; i++ )
2007 : {
2008 10950188 : hMetaData->ind_list[i].nb_bits = -1;
2009 10950188 : move16();
2010 : }
2011 248691 : hMetaData->nb_bits_tot = bit_pos_start;
2012 248691 : move16();
2013 248691 : hMetaData->nb_ind_tot = next_ind_start;
2014 248691 : move16();
2015 :
2016 248691 : return;
2017 : }
2018 :
2019 : /*-------------------------------------------------------------------------
2020 : * ivas_qmetadata_encode_quasi_uniform_fx()
2021 : *
2022 : * encode value using a quasi-uniform code of b or b + 1 bits, where b = floor(log2(alphabet_size))
2023 : *------------------------------------------------------------------------*/
2024 1895061 : static void ivas_qmetadata_encode_quasi_uniform_fx(
2025 : BSTR_ENC_HANDLE hMetaData,
2026 : const UWord16 value,
2027 : const UWord16 alphabet_size )
2028 : {
2029 : Word16 bits;
2030 : UWord16 tresh;
2031 :
2032 1895061 : bits = sub( 30, norm_l( alphabet_size ) ); /* bits = floor(log2(alphabet_size)) */
2033 1895061 : tresh = (UWord16) L_sub( L_shl( 1U, add( bits, 1 ) ), alphabet_size );
2034 :
2035 1895061 : IF( LT_32( value, tresh ) )
2036 : {
2037 1581694 : push_next_indice( hMetaData, value, bits );
2038 : }
2039 : ELSE /* value >= tresh */
2040 : {
2041 313367 : push_next_indice( hMetaData, (UWord16) L_add( value, tresh ), add( bits, 1 ) );
2042 : }
2043 :
2044 1895061 : return;
2045 : }
2046 :
2047 :
2048 : /*-----------------------------------------------------------------------*
2049 : * GR encoder function definitions
2050 : *-----------------------------------------------------------------------*/
2051 : /*-------------------------------------------------------------------------
2052 : * GR_bits_new_fx()
2053 : *
2054 : *
2055 : *------------------------------------------------------------------------*/
2056 : /*! r: number of bits using Golomb Rice code */
2057 135554 : static Word16 GR_bits_new_fx(
2058 : UWord16 *data, /* i : data to encode with GR */
2059 : Word16 *no_symb, /* i : number of symbols for each component*/
2060 : const Word16 no_data, /* i : number of input data */
2061 : const Word16 GR_order, /* i : GR order to be used */
2062 : const Word16 check_two_orders, /* i : check also coding with GR_order-1 */
2063 : Word16 *real_GR_ord /* o : the GR order that has been used */
2064 : )
2065 : {
2066 135554 : Word16 nbits = 0, i;
2067 135554 : Word16 nbits1 = 0;
2068 : Word16 nb;
2069 135554 : move16();
2070 135554 : move16();
2071 :
2072 1183094 : FOR( i = 0; i < no_data; i++ )
2073 : {
2074 1047540 : nb = ivas_qmetadata_encode_extended_gr_length_fx( data[i], no_symb[i], GR_order );
2075 1047540 : nbits = add( nbits, nb );
2076 : }
2077 :
2078 135554 : IF( EQ_16( check_two_orders, 1 ) )
2079 : {
2080 1012277 : FOR( i = 0; i < no_data; i++ )
2081 : {
2082 899818 : nb = ivas_qmetadata_encode_extended_gr_length_fx( data[i], no_symb[i], GR_order - 1 );
2083 899818 : nbits1 = add( nbits1, nb );
2084 : }
2085 :
2086 112459 : IF( nbits1 < nbits )
2087 : {
2088 69777 : nbits = add( nbits1, 1 );
2089 69777 : *real_GR_ord = sub( GR_order, 1 );
2090 69777 : move16();
2091 : }
2092 : ELSE
2093 : {
2094 42682 : nbits = add( nbits, 1 );
2095 42682 : *real_GR_ord = GR_order;
2096 42682 : move16();
2097 : }
2098 : }
2099 : ELSE
2100 : {
2101 23095 : *real_GR_ord = GR_order;
2102 23095 : move16();
2103 : }
2104 :
2105 135554 : return nbits;
2106 : }
2107 :
2108 :
2109 : /*-------------------------------------------------------------------------
2110 : * GR_bits_azimuth_context()
2111 : *
2112 : * Encoding azimuth indexes with GR code using context
2113 : *------------------------------------------------------------------------*/
2114 : /*! r: numer of bits used for coding */
2115 18841 : static Word16 GR_bits_azimuth_context_fx(
2116 : UWord16 *data_in, /* i : data to be encoded Qx*/
2117 : Word16 *no_symb, /* i : number of symbols for each component */
2118 : const Word16 no_data_in, /* i : number of input data */
2119 : const Word16 GR_order, /* i : GR order (GR_order or GR_order-1 are used ) */
2120 : const UWord16 *bits_dir, /* i : bits for encoding the direction for each TF tile */
2121 : Word16 *real_GR_ord, /* o : which GR order has been used Q0 */
2122 : Word16 *p_use_context /* o : flag telling if context has been used or not Q0 */
2123 : )
2124 : {
2125 : Word16 i, nbits, nbits1, use_context;
2126 : UWord16 cdata[MAX_PARAM_SPATIAL_SUBFRAMES];
2127 : UWord16 data[MAX_PARAM_SPATIAL_SUBFRAMES];
2128 : Word16 min_val, max_val;
2129 : Word16 real_GR_ord1;
2130 : Word16 no_symb_local[MAX_PARAM_SPATIAL_SUBFRAMES];
2131 18841 : Word16 no_data = 0;
2132 18841 : move16();
2133 75527 : FOR( i = 0; i < no_data_in; i++ )
2134 : {
2135 56686 : IF( LT_32( data_in[i], MASA_NO_INDEX ) )
2136 : {
2137 56673 : no_symb_local[no_data] = no_symb[i];
2138 56673 : move16();
2139 56673 : data[no_data++] = data_in[i]; // Qx
2140 56673 : move16();
2141 : }
2142 : }
2143 :
2144 18841 : IF( no_data == 0 )
2145 : {
2146 6 : *p_use_context = -3; /* corresponding to nothing to be written */
2147 6 : move16();
2148 6 : return 0;
2149 : }
2150 :
2151 18835 : nbits = 0;
2152 18835 : move16();
2153 18835 : use_context = 0;
2154 18835 : move16();
2155 75508 : FOR( i = 0; i < no_data; i++ )
2156 : {
2157 56673 : IF( LE_16( bits_dir[i], 1 ) )
2158 : {
2159 0 : nbits = add( nbits, bits_dir[i] );
2160 0 : use_context = 1;
2161 0 : move16();
2162 : }
2163 : ELSE
2164 : {
2165 56673 : *real_GR_ord = sub( GR_order, (Word16) EQ_16( bits_dir[i], 2 ) );
2166 56673 : move16();
2167 56673 : nbits = add( nbits, ivas_qmetadata_encode_extended_gr_length_fx( data[i], no_symb_local[i], *real_GR_ord ) );
2168 : }
2169 : }
2170 :
2171 18835 : real_GR_ord1 = 0;
2172 18835 : move16();
2173 18835 : IF( use_context == 0 )
2174 : {
2175 18835 : nbits = GR_bits_new_fx( data, no_symb_local, no_data, GR_order, 1, real_GR_ord );
2176 18835 : nbits1 = nbits;
2177 18835 : move16();
2178 18835 : min_val = data[0]; // Qx
2179 18835 : move16();
2180 56673 : FOR( i = 1; i < no_data; i++ )
2181 : {
2182 37838 : if ( LT_32( data[i], min_val ) )
2183 : {
2184 5320 : min_val = data[i]; // Qx
2185 5320 : move16();
2186 : }
2187 : }
2188 75508 : FOR( i = 0; i < no_data; i++ )
2189 : {
2190 56673 : cdata[i] = (UWord16) L_sub( data[i], min_val ); // Qx
2191 56673 : move16();
2192 : }
2193 :
2194 18835 : maximum_s( no_symb_local, no_data, &max_val );
2195 18835 : nbits1 = add( GR_bits_new_fx( cdata, no_symb_local, no_data, sub( GR_order, 1 ), 1, &real_GR_ord1 ), ivas_qmetadata_encode_extended_gr_length_fx( min_val, max_val, MASA_GR_ORD_AZ ) );
2196 :
2197 18835 : IF( LT_16( nbits1, nbits ) )
2198 : {
2199 6533 : nbits = add( nbits1, 1 );
2200 6533 : use_context = -2;
2201 6533 : move16();
2202 6533 : *real_GR_ord = real_GR_ord1;
2203 6533 : move16();
2204 : }
2205 : ELSE
2206 : {
2207 12302 : nbits = add( nbits, 1 );
2208 12302 : use_context = -1;
2209 12302 : move16();
2210 : }
2211 : }
2212 :
2213 18835 : *p_use_context = use_context;
2214 18835 : move16();
2215 18835 : return nbits;
2216 : }
2217 :
2218 : /*-------------------------------------------------------------------------
2219 : * mean_removed_GR_new()
2220 : *
2221 : * Golomb Rice encoding with mean removing
2222 : *------------------------------------------------------------------------*/
2223 : /*! r: number of bits used */
2224 36323 : static Word16 mean_removed_GR_new_fx(
2225 : const UWord16 *idx, /* i : data to encode */
2226 : const Word16 max_no_symb,
2227 : const Word16 len, /* i : number of data */
2228 : const Word16 adapt_GR, /* i : flag for telling to use or nor two GR order values */
2229 : Word16 *GR_ord, /* i/o: GR order */
2230 : UWord16 *p_av, /* o : average index */
2231 : UWord16 *mr_idx /* o : mean removed indexes */
2232 : )
2233 : {
2234 : Word16 av, i, nbits;
2235 : Word16 sh_idx[MASA_MAXIMUM_CODING_SUBBANDS];
2236 : Word16 max_ns[MASA_MAXIMUM_CODING_SUBBANDS];
2237 :
2238 : /* av = (Word16) ( 0.5f + sum_s( (const Word16 *) idx, len ) / (float) len ); */
2239 36323 : av = shr( add( 1, idiv1616U( shl( sum16_fx( (const Word16 *) idx, len ), 1 ), len ) ), 1 ); // Q0
2240 :
2241 36323 : *p_av = av;
2242 36323 : move16();
2243 455407 : FOR( i = 0; i < len; i++ )
2244 : {
2245 419084 : max_ns[i] = shl( max_no_symb, 1 );
2246 419084 : sh_idx[i] = sub( idx[i], av );
2247 419084 : move16();
2248 419084 : move16();
2249 : }
2250 :
2251 455407 : FOR( i = 0; i < len; i++ )
2252 : {
2253 419084 : IF( sh_idx[i] < 0 )
2254 : {
2255 51221 : sh_idx[i] = imult1616( -2, sh_idx[i] );
2256 : }
2257 367863 : ELSE IF( sh_idx[i] > 0 )
2258 : {
2259 49652 : sh_idx[i] = sub( shl( sh_idx[i], 1 ), 1 );
2260 49652 : move16();
2261 : }
2262 : ELSE
2263 : {
2264 318211 : sh_idx[i] = 0;
2265 318211 : move16();
2266 : }
2267 419084 : mr_idx[i] = (UWord16) sh_idx[i];
2268 419084 : move16();
2269 : }
2270 :
2271 36323 : nbits = GR_bits_new_fx( mr_idx, max_ns, len, *GR_ord, adapt_GR, GR_ord );
2272 :
2273 36323 : return nbits;
2274 : }
2275 :
2276 : /*-------------------------------------------------------------------------
2277 : * ivas_qmetadata_encode_quasi_uniform_length_fx()
2278 : *
2279 : *------------------------------------------------------------------------*/
2280 8689190 : static Word16 ivas_qmetadata_encode_quasi_uniform_length_fx(
2281 : const UWord16 value,
2282 : const UWord16 alphabet_size )
2283 : {
2284 : Word16 bits;
2285 : UWord16 tresh;
2286 :
2287 8689190 : bits = sub( 30, norm_l( alphabet_size ) ); /* bits = floor(log2(alphabet_size)) */
2288 8689190 : tresh = (UWord16) L_sub( L_shl( 1U, add( bits, 1 ) ), alphabet_size );
2289 :
2290 8689190 : IF( GE_32( value, tresh ) )
2291 : {
2292 2280955 : bits = add( bits, 1 );
2293 : }
2294 :
2295 8689190 : return bits;
2296 : }
2297 :
2298 : /*-------------------------------------------------------------------------
2299 : * ivas_qmetadata_entropy_encode_dir()
2300 : *
2301 : * Main function for entropy coding of the directions
2302 : *------------------------------------------------------------------------*/
2303 :
2304 257060 : static Word16 ivas_qmetadata_entropy_encode_dir_fx(
2305 : BSTR_ENC_HANDLE hMetaData,
2306 : IVAS_QDIRECTION *q_direction,
2307 : const UWord16 diffuseness_index_max_ec_frame,
2308 : const Word16 nbands,
2309 : const Word16 start_band,
2310 : const Word16 direction_bits_raw,
2311 : Word16 max_bits,
2312 : const Word16 hrmasa_flag )
2313 : {
2314 : UWord16 diff_idx_min;
2315 : Word16 i, j;
2316 : Word16 nblocks;
2317 :
2318 : Word32 avg_direction_vector[3], direction_vector[3], avg_azimuth, avg_elevation;
2319 : Word16 avg_azimuth_alphabet, avg_elevation_alphabet;
2320 : UWord16 avg_azimuth_index, avg_elevation_index;
2321 : Word16 avg_elevation_index_projected;
2322 : Word16 avg_azimuth_index_projected;
2323 : UWord16 avg_elevation_index_initial, avg_elevation_offset;
2324 : UWord16 avg_azimuth_index_initial, avg_azimuth_offset;
2325 : Word16 elevation_bits_ec_best, azimuth_bits_ec_best;
2326 :
2327 257060 : Word16 gr_param_elevation_best = 0, avg_elevation_index_best = 0;
2328 257060 : move16();
2329 257060 : move16();
2330 : UWord16 dist_elevation_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
2331 : Word16 gr_param_azimuth_best, avg_azimuth_index_best;
2332 : UWord16 dist_azimuth_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
2333 :
2334 : UWord16 idx, dist_count;
2335 : Word16 direction_bits_ec;
2336 :
2337 : UWord16 dist_elevation_indexes[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
2338 : UWord16 dist_elevation_alphabets[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
2339 : UWord16 dist_azimuth_indexes[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
2340 : UWord16 dist_azimuth_alphabets[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
2341 257060 : Word16 all_zero_dist_elevation_indexes = 1, all_zero_dist_azimuth_indexes = 1;
2342 257060 : move16();
2343 257060 : move16();
2344 : Word16 gr_param_elevation, gr_size_elevation, egr_size_elevation, gr_param_azimuth, gr_size_azimuth;
2345 : Word16 egr_size_azimuth, elevation_bits_ec, azimuth_bits_ec;
2346 :
2347 : Word32 abs_theta;
2348 : Word16 theta_cb[MAX_NO_THETA]; // Q22-Q16 = Q6
2349 : Word16 sign_th, no_th;
2350 257060 : Word16 avg_azimuth_index_upd = 0, use_adapt_avg;
2351 257060 : move16();
2352 257060 : Word16 make_gain = 0;
2353 257060 : move16();
2354 257060 : Word16 bits_gained = 0;
2355 257060 : move16();
2356 257060 : nblocks = q_direction->cfg.nblocks;
2357 257060 : move16();
2358 :
2359 : /* estimate the number of bits for entropy coding of the direction values */
2360 257060 : direction_bits_ec = 0;
2361 257060 : move16();
2362 257060 : diff_idx_min = DIRAC_DIFFUSE_LEVELS;
2363 257060 : move16();
2364 257060 : idx = 0;
2365 257060 : move16();
2366 257060 : dist_count = 0;
2367 257060 : move16();
2368 257060 : set_zero_fx( avg_direction_vector, 3 );
2369 :
2370 1401636 : FOR( i = start_band; i < nbands; i++ )
2371 : {
2372 1144576 : IF( hrmasa_flag )
2373 : {
2374 0 : diff_idx_min = 0; // min( q_direction->band_data[i].energy_ratio_index_mod[0]>>1, diff_idx_min );
2375 0 : move16();
2376 : }
2377 : ELSE
2378 : {
2379 1144576 : diff_idx_min = s_min( q_direction->band_data[i].energy_ratio_index_mod[0], diff_idx_min );
2380 : }
2381 :
2382 1144576 : IF( GT_32( q_direction->band_data[i].energy_ratio_index_mod[0], diffuseness_index_max_ec_frame ) )
2383 : {
2384 : /* estimate the raw part */
2385 315998 : IF( q_direction->not_in_2D > 0 )
2386 : {
2387 1212111 : FOR( j = 0; j < nblocks; j++ )
2388 : {
2389 939696 : direction_bits_ec = add( direction_bits_ec, q_direction->band_data[i].bits_sph_idx[j] );
2390 : }
2391 : }
2392 : ELSE
2393 : {
2394 173029 : FOR( j = 0; j < nblocks; j++ )
2395 : {
2396 129446 : direction_bits_ec = add( direction_bits_ec, ivas_qmetadata_encode_quasi_uniform_length_fx( q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] ) );
2397 : }
2398 : }
2399 : }
2400 : ELSE
2401 : {
2402 828578 : dist_count = add( dist_count, nblocks );
2403 :
2404 3759544 : FOR( j = 0; j < nblocks; j++ )
2405 : {
2406 : /*compute the average direction */
2407 2930966 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[i].azimuth_fx[j], q_direction->band_data[i].elevation_fx[j], direction_vector );
2408 2930966 : scale_sig32( direction_vector, 3, -8 ); // Q30 -> Q22
2409 : #ifdef VEC_ARITH_OPT_v1
2410 2930966 : v_add_fixed_no_hdrm( avg_direction_vector, direction_vector, avg_direction_vector, 3 );
2411 : #else /* VEC_ARITH_OPT_v1 */
2412 : v_add_fixed( avg_direction_vector, direction_vector, avg_direction_vector, 3, 0 );
2413 : #endif /* VEC_ARITH_OPT_v1 */
2414 : }
2415 : }
2416 : }
2417 :
2418 : /* quantize average elevation and azimuth angles using the best angle spacing and equatorial precision */
2419 257060 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector, Q22, &avg_azimuth, &avg_elevation );
2420 :
2421 257060 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2422 : {
2423 15130 : avg_elevation_alphabet = no_theta_masa[bits_direction_masa[diff_idx_min] - 3]; // Q0
2424 15130 : move16();
2425 15130 : avg_azimuth_alphabet = no_phi_masa[bits_direction_masa[diff_idx_min] - 1][0]; /* average azimuth is quantized on the equatorial plane Q0*/
2426 15130 : move16();
2427 : }
2428 : ELSE
2429 : {
2430 241930 : avg_elevation_alphabet = sub( shl( no_theta_masa[bits_direction_masa[diff_idx_min] - 3], 1 ), 1 ); // Q0
2431 241930 : avg_azimuth_alphabet = no_phi_masa[bits_direction_masa[diff_idx_min] - 1][0]; /* average azimuth is quantized on the equatorial plane Q0*/
2432 241930 : move16();
2433 : }
2434 :
2435 257060 : no_th = no_theta_masa[bits_direction_masa[diff_idx_min] - 3]; // Q0
2436 257060 : move16();
2437 :
2438 2551612 : FOR( i = 0; i < no_th; i++ )
2439 : {
2440 2294552 : theta_cb[i] = imult1616( i, round_fx( delta_theta_masa_fx[bits_direction_masa[diff_idx_min] - 3] ) ); // Q6
2441 2294552 : move16();
2442 : }
2443 :
2444 257060 : if ( GT_32( theta_cb[i - 1], 90 << Q6 ) )
2445 : {
2446 132088 : theta_cb[i - 1] = 90 << Q6;
2447 132088 : move16();
2448 : }
2449 :
2450 257060 : IF( avg_elevation < 0 )
2451 : {
2452 109204 : abs_theta = L_negate( avg_elevation ); // Q22
2453 109204 : sign_th = -1;
2454 109204 : move16();
2455 : }
2456 : ELSE
2457 : {
2458 147856 : abs_theta = avg_elevation; // Q22
2459 147856 : move32();
2460 147856 : sign_th = 1;
2461 147856 : move16();
2462 : }
2463 :
2464 : Word16 tmp;
2465 257060 : avg_elevation_index = squant_fx( round_fx( abs_theta ), &tmp, theta_cb, no_th );
2466 257060 : avg_elevation = L_deposit_h( tmp ); // Q22
2467 :
2468 257060 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2469 : {
2470 15130 : assert( avg_elevation >= 0 );
2471 : }
2472 : ELSE
2473 : {
2474 241930 : IF( sign_th < 0 )
2475 : {
2476 109204 : avg_elevation_index = sub( shr( avg_elevation_alphabet, 1 ), avg_elevation_index );
2477 : }
2478 : ELSE
2479 : {
2480 132726 : avg_elevation_index = add( avg_elevation_index, shr( avg_elevation_alphabet, 1 ) );
2481 : }
2482 : // avg_elevation *= sign_th;
2483 241930 : if ( sign_th < 0 )
2484 : {
2485 109204 : avg_elevation = L_negate( avg_elevation ); // Q22
2486 : }
2487 : }
2488 :
2489 257060 : avg_azimuth_index = (UWord16) ( quantize_phi_enc_fx( L_add( avg_azimuth, DEGREE_180_Q_22 ), 0, &avg_azimuth, avg_azimuth_alphabet ) );
2490 :
2491 : /* Elevation only if not 2D */
2492 257060 : IF( q_direction->not_in_2D > 0 )
2493 : {
2494 220304 : avg_elevation_index_initial = avg_elevation_index;
2495 220304 : move16();
2496 220304 : elevation_bits_ec_best = MAX16B;
2497 220304 : move16();
2498 220304 : avg_elevation_index_best = -1; /* out of range value */
2499 220304 : move16();
2500 220304 : gr_param_elevation_best = -1; /* out of range value */
2501 220304 : move16();
2502 :
2503 881216 : FOR( avg_elevation_offset = 0; avg_elevation_offset < q_direction->cfg.search_effort; avg_elevation_offset++ )
2504 : {
2505 660912 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2506 : {
2507 12990 : avg_elevation_index = u_extract_l( UL_addNsD( avg_elevation_index_initial, avg_elevation_offset ) );
2508 : }
2509 : ELSE
2510 : {
2511 647922 : avg_elevation_index = (UWord16) L_add( avg_elevation_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_elevation_offset ) );
2512 : }
2513 : // avg_elevation_index = (uint16_t) ( ( avg_elevation_index + avg_elevation_alphabet ) % avg_elevation_alphabet );
2514 660912 : avg_elevation_index = u_extract_l( UL_addNsD( avg_elevation_index, avg_elevation_alphabet ) % avg_elevation_alphabet );
2515 :
2516 660912 : all_zero_dist_elevation_indexes = 1;
2517 660912 : move16();
2518 660912 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2519 : {
2520 12990 : elevation_bits_ec = ivas_qmetadata_encode_quasi_uniform_length_fx( avg_elevation_index, avg_elevation_alphabet );
2521 : }
2522 : ELSE
2523 : {
2524 647922 : elevation_bits_ec = ivas_qmetadata_encode_quasi_uniform_length_fx( ivas_qmetadata_reorder_generic_fx( sub( avg_elevation_index, shr( avg_elevation_alphabet, 1 ) ) ), avg_elevation_alphabet );
2525 : }
2526 660912 : idx = 0;
2527 660912 : move16();
2528 3609462 : FOR( i = start_band; i < nbands; i++ )
2529 : {
2530 2948550 : IF( LE_16( q_direction->band_data[i].energy_ratio_index_mod[0], diffuseness_index_max_ec_frame ) )
2531 : {
2532 9837183 : FOR( j = 0; j < nblocks; j++ )
2533 : {
2534 : /* project the quantized average elevation to the same grid as the current sample */
2535 7705878 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2536 : {
2537 77232 : avg_elevation_index_projected = ivas_chan_project_elevation_index_fx( avg_elevation_index, avg_elevation_alphabet, q_direction->band_data[i].elevation_m_alphabet[j] ); // Q0
2538 : }
2539 : ELSE
2540 : {
2541 7628646 : avg_elevation_index_projected = ivas_dirac_project_elevation_index_fx( avg_elevation_index, avg_elevation_alphabet, q_direction->band_data[i].elevation_m_alphabet[j] ); // Q0
2542 : }
2543 :
2544 7705878 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2545 : {
2546 77232 : IF( L_sub( q_direction->band_data[i].elevation_index[j], avg_elevation_index_projected ) > 0 )
2547 : {
2548 : // dist_elevation_indexes[idx] = 2 * ( q_direction->band_data[i].elevation_index[j] - avg_elevation_index_projected ) - 1;
2549 3868 : dist_elevation_indexes[idx] = sub( shl( sub( q_direction->band_data[i].elevation_index[j], avg_elevation_index_projected ), 1 ), 1 );
2550 3868 : move16();
2551 : }
2552 : ELSE
2553 : {
2554 : // dist_elevation_indexes[idx] = -2 * ( q_direction->band_data[i].elevation_index[j] - avg_elevation_index_projected );
2555 73364 : dist_elevation_indexes[idx] = imult1616( -2, sub( q_direction->band_data[i].elevation_index[j], avg_elevation_index_projected ) );
2556 73364 : move16();
2557 : }
2558 : }
2559 : ELSE
2560 : {
2561 7628646 : dist_elevation_indexes[idx] = ivas_qmetadata_reorder_elevation_index_fx( q_direction->band_data[i].elevation_index[j], avg_elevation_index_projected, q_direction->band_data[i].elevation_m_alphabet[j] );
2562 7628646 : move16();
2563 : }
2564 7705878 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2565 : {
2566 77232 : dist_elevation_alphabets[idx] = sub( shl( q_direction->band_data[i].elevation_m_alphabet[j], 1 ), 1 );
2567 77232 : move16();
2568 : }
2569 : ELSE
2570 : {
2571 7628646 : dist_elevation_alphabets[idx] = q_direction->band_data[i].elevation_m_alphabet[j];
2572 7628646 : move16();
2573 : }
2574 :
2575 7705878 : if ( dist_elevation_indexes[idx] != 0 )
2576 : {
2577 5224400 : all_zero_dist_elevation_indexes = 0;
2578 5224400 : move16();
2579 : }
2580 7705878 : idx = add( idx, 1 );
2581 : }
2582 : }
2583 : }
2584 :
2585 660912 : IF( all_zero_dist_elevation_indexes )
2586 : {
2587 57827 : egr_size_elevation = 0;
2588 57827 : move16();
2589 57827 : gr_param_elevation = 4;
2590 57827 : move16();
2591 : }
2592 : ELSE
2593 : {
2594 603085 : gr_param_elevation = ivas_qmetadata_get_optimal_gr_param_fx( dist_elevation_indexes, idx, 4, &gr_size_elevation ); // Q0
2595 603085 : egr_size_elevation = 0;
2596 603085 : move16();
2597 8193868 : FOR( i = 0; i < idx; i++ )
2598 : {
2599 7590783 : egr_size_elevation = add( egr_size_elevation, ivas_qmetadata_encode_extended_gr_length_fx( dist_elevation_indexes[i], dist_elevation_alphabets[i], gr_param_elevation ) ); // Q0
2600 : }
2601 : }
2602 660912 : elevation_bits_ec = add( elevation_bits_ec, add( ivas_qmetadata_encode_quasi_uniform_length_fx( gr_param_elevation, 4 + 1 ), egr_size_elevation ) ); // Q0
2603 :
2604 660912 : IF( LT_16( elevation_bits_ec, elevation_bits_ec_best ) )
2605 : {
2606 300917 : elevation_bits_ec_best = elevation_bits_ec; // Q0
2607 300917 : move16();
2608 300917 : avg_elevation_index_best = avg_elevation_index; // Q0
2609 300917 : move16();
2610 300917 : gr_param_elevation_best = gr_param_elevation; // Q0
2611 300917 : move16();
2612 4171363 : FOR( idx = 0; idx < dist_count; idx++ )
2613 : {
2614 3870446 : dist_elevation_indexes_best[idx] = dist_elevation_indexes[idx];
2615 3870446 : move16();
2616 : }
2617 : }
2618 : }
2619 :
2620 220304 : direction_bits_ec = add( direction_bits_ec, elevation_bits_ec_best );
2621 : }
2622 :
2623 : /*Azimuth*/
2624 257060 : use_adapt_avg = 0;
2625 257060 : move16();
2626 257060 : test();
2627 257060 : test();
2628 257060 : IF( GE_16( sub( nbands, start_band ), 5 ) && NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && GT_16( nblocks, 1 ) )
2629 : {
2630 3415 : use_adapt_avg = calc_var_azi_fx( q_direction, diffuseness_index_max_ec_frame, L_sub( avg_azimuth, DEGREE_180_Q_22 ), &avg_azimuth ); // 180.Q22
2631 :
2632 3415 : avg_azimuth_index = (UWord16) ( quantize_phi_enc_fx( L_add( avg_azimuth, DEGREE_180_Q_22 ), 0, &avg_azimuth, avg_azimuth_alphabet ) );
2633 : }
2634 257060 : avg_azimuth_index_initial = avg_azimuth_index; /* avg_azimuth_index;*/
2635 257060 : move16();
2636 257060 : azimuth_bits_ec_best = MAX16B;
2637 257060 : move16();
2638 257060 : avg_azimuth_index_best = -1; /* out of range value */
2639 257060 : move16();
2640 257060 : gr_param_azimuth_best = -1; /* out of range value */
2641 257060 : move16();
2642 :
2643 1028240 : FOR( avg_azimuth_offset = 0; avg_azimuth_offset < q_direction->cfg.search_effort; avg_azimuth_offset++ )
2644 : {
2645 771180 : set_zero_fx( avg_direction_vector, 3 );
2646 771180 : avg_azimuth_index = (UWord16) L_add( avg_azimuth_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_azimuth_offset ) );
2647 771180 : avg_azimuth_index = (UWord16) ( L_add( avg_azimuth_index, avg_azimuth_alphabet ) % avg_azimuth_alphabet );
2648 771180 : all_zero_dist_azimuth_indexes = 1;
2649 771180 : move16();
2650 771180 : azimuth_bits_ec = ivas_qmetadata_encode_quasi_uniform_length_fx( ivas_qmetadata_reorder_generic_fx( sub( avg_azimuth_index, shr( avg_azimuth_alphabet, 1 ) ) ), avg_azimuth_alphabet );
2651 :
2652 771180 : idx = 0;
2653 771180 : move16();
2654 4204908 : FOR( i = start_band; i < nbands; i++ )
2655 : {
2656 3433728 : IF( LE_16( q_direction->band_data[i].energy_ratio_index_mod[0], diffuseness_index_max_ec_frame ) )
2657 : {
2658 11278632 : FOR( j = 0; j < nblocks; j++ )
2659 : {
2660 8792898 : test();
2661 8792898 : test();
2662 8792898 : IF( GT_16( idx, MASA_LIMIT_IDX_AVG_AZI ) && NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && EQ_16( use_adapt_avg, 1 ) )
2663 : {
2664 52437 : avg_azimuth_index_projected = ivas_dirac_project_azimuth_index_fx( avg_azimuth_index_upd, avg_azimuth_alphabet, q_direction->band_data[i].azimuth_m_alphabet[j] );
2665 : }
2666 : ELSE
2667 : {
2668 8740461 : test();
2669 8740461 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && ( use_adapt_avg == 1 ) )
2670 : {
2671 34935 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[i].azimuth_fx[j], q_direction->band_data[i].elevation_fx[j], direction_vector );
2672 34935 : scale_sig32( direction_vector, 3, -8 ); // Q30 -> Q22
2673 :
2674 34935 : IF( LT_16( idx, 4 ) )
2675 : {
2676 : #ifdef VEC_ARITH_OPT_v1
2677 29220 : v_add_fixed_no_hdrm( avg_direction_vector, direction_vector, avg_direction_vector, 3 );
2678 : #else /* VEC_ARITH_OPT_v1 */
2679 : v_add_fixed( avg_direction_vector, direction_vector, avg_direction_vector, 3, 0 );
2680 : #endif /* VEC_ARITH_OPT_v1 */
2681 : }
2682 : }
2683 : /* project the quantized average azimuth angle to the same grid as the current sample */
2684 8740461 : avg_azimuth_index_projected = ivas_dirac_project_azimuth_index_fx( avg_azimuth_index, avg_azimuth_alphabet, q_direction->band_data[i].azimuth_m_alphabet[j] );
2685 : }
2686 8792898 : dist_azimuth_indexes[idx] = ivas_qmetadata_reorder_azimuth_index_fx( add( ivas_qmetadata_dereorder_generic_fx( q_direction->band_data[i].azimuth_index[j] ), shr( q_direction->band_data[i].azimuth_m_alphabet[j], 1 ) ), avg_azimuth_index_projected, q_direction->band_data[i].azimuth_m_alphabet[j] );
2687 8792898 : move16();
2688 8792898 : dist_azimuth_alphabets[idx] = q_direction->band_data[i].azimuth_m_alphabet[j];
2689 8792898 : move16();
2690 :
2691 8792898 : if ( dist_azimuth_indexes[idx] != 0 )
2692 : {
2693 6727084 : all_zero_dist_azimuth_indexes = 0;
2694 6727084 : move16();
2695 : }
2696 :
2697 8792898 : test();
2698 8792898 : test();
2699 8792898 : IF( GE_16( idx, MASA_LIMIT_IDX_AVG_AZI ) && NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && EQ_16( use_adapt_avg, 1 ) )
2700 : {
2701 58152 : IF( idx % nblocks == 0 )
2702 : {
2703 : // v_multc( avg_direction_vector, 0.5f, avg_direction_vector, 3 );
2704 14538 : scale_sig32( avg_direction_vector, 3, -1 );
2705 : }
2706 :
2707 : /*compute the average direction per already coded subband */
2708 58152 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[i].azimuth_fx[j], q_direction->band_data[i].elevation_fx[j], direction_vector );
2709 58152 : scale_sig32( direction_vector, 3, -8 ); // Q30 -> Q22
2710 :
2711 : #ifdef VEC_ARITH_OPT_v1
2712 58152 : v_add_fixed_no_hdrm( avg_direction_vector, direction_vector, avg_direction_vector, 3 );
2713 : #else /* VEC_ARITH_OPT_v1 */
2714 : v_add_fixed( avg_direction_vector, direction_vector, avg_direction_vector, 3, 0 );
2715 : #endif /* VEC_ARITH_OPT_v1 */
2716 58152 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector, Q22, &avg_azimuth, &avg_elevation );
2717 :
2718 58152 : avg_azimuth_index_upd = quantize_phi_enc_fx( L_add( avg_azimuth, 180 << Q22 ), 0, &avg_azimuth, avg_azimuth_alphabet );
2719 : }
2720 8792898 : idx = add( idx, 1 );
2721 : }
2722 : }
2723 : }
2724 :
2725 771180 : IF( all_zero_dist_azimuth_indexes )
2726 : {
2727 67684 : egr_size_azimuth = 0;
2728 67684 : move16();
2729 67684 : gr_param_azimuth = 5;
2730 67684 : move16();
2731 : }
2732 : ELSE
2733 : {
2734 : /* estimate the ExtendedGR part for azimuth */
2735 703496 : gr_param_azimuth = ivas_qmetadata_get_optimal_gr_param_fx( dist_azimuth_indexes, idx, 5, &gr_size_azimuth );
2736 703496 : egr_size_azimuth = 0;
2737 703496 : move16();
2738 9377664 : FOR( i = 0; i < idx; i++ )
2739 : {
2740 8674168 : egr_size_azimuth = add( egr_size_azimuth, ivas_qmetadata_encode_extended_gr_length_fx( dist_azimuth_indexes[i], dist_azimuth_alphabets[i], gr_param_azimuth ) );
2741 : }
2742 : }
2743 :
2744 771180 : azimuth_bits_ec = add( azimuth_bits_ec, add( ivas_qmetadata_encode_quasi_uniform_length_fx( gr_param_azimuth, 5 + 1 ), egr_size_azimuth ) );
2745 :
2746 771180 : IF( LT_16( azimuth_bits_ec, azimuth_bits_ec_best ) )
2747 : {
2748 369332 : azimuth_bits_ec_best = azimuth_bits_ec;
2749 369332 : move16();
2750 369332 : avg_azimuth_index_best = avg_azimuth_index;
2751 369332 : move16();
2752 369332 : gr_param_azimuth_best = gr_param_azimuth;
2753 369332 : move16();
2754 :
2755 4871216 : FOR( idx = 0; idx < dist_count; idx++ )
2756 : {
2757 4501884 : dist_azimuth_indexes_best[idx] = dist_azimuth_indexes[idx];
2758 4501884 : move16();
2759 : }
2760 : }
2761 : }
2762 :
2763 257060 : test();
2764 257060 : test();
2765 257060 : test();
2766 257060 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && GT_16( dist_count, 4 ) && NE_16( gr_param_azimuth_best, 5 ) && GT_16( nblocks, 1 ) )
2767 : {
2768 2711 : azimuth_bits_ec_best = add( azimuth_bits_ec_best, 1 );
2769 : }
2770 :
2771 257060 : direction_bits_ec = add( direction_bits_ec, azimuth_bits_ec_best );
2772 :
2773 : /*Decision raw or EC*/
2774 : /* one bit is used to indicate whether the direction values are entropy coded or coded raw */
2775 257060 : IF( LT_16( direction_bits_ec, direction_bits_raw ) ) /* entropy coding is better */
2776 : {
2777 :
2778 : /* encode the raw part first */
2779 842280 : FOR( i = start_band; i < nbands; i++ )
2780 : {
2781 707221 : IF( GT_16( q_direction->band_data[i].energy_ratio_index_mod[0], diffuseness_index_max_ec_frame ) )
2782 : {
2783 190455 : IF( q_direction->not_in_2D > 0 )
2784 : {
2785 817213 : FOR( j = 0; j < nblocks; j++ )
2786 : {
2787 645599 : push_next_indice( hMetaData, q_direction->band_data[i].spherical_index[j], q_direction->band_data[i].bits_sph_idx[j] );
2788 : }
2789 : }
2790 : ELSE
2791 : {
2792 87173 : FOR( j = 0; j < nblocks; j++ )
2793 : {
2794 68332 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] );
2795 : }
2796 : }
2797 : }
2798 : }
2799 :
2800 135059 : test();
2801 135059 : test();
2802 135059 : if ( GT_16( nbands, 1 ) && sub( direction_bits_ec, max_bits ) > 0 && LT_16( sub( direction_bits_ec, max_bits ), imult1616( nblocks, nbands ) ) )
2803 : {
2804 2207 : make_gain = 1;
2805 2207 : move16();
2806 : }
2807 :
2808 135059 : IF( q_direction->not_in_2D > 0 )
2809 : {
2810 : /* encode the ExtendedGR part for elevation */
2811 116175 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
2812 : {
2813 2553 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, avg_elevation_index_best, avg_elevation_alphabet );
2814 : }
2815 : ELSE
2816 : {
2817 113622 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, ivas_qmetadata_reorder_generic_fx( sub( avg_elevation_index_best, shr( avg_elevation_alphabet, 1 ) ) ), avg_elevation_alphabet );
2818 : }
2819 :
2820 116175 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, gr_param_elevation_best, 4 + 1 );
2821 :
2822 116175 : IF( NE_16( gr_param_elevation_best, 4 ) ) /* not all zero */
2823 : {
2824 1660758 : FOR( idx = 0; idx < dist_count; idx++ )
2825 : {
2826 1566553 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, dist_elevation_indexes_best[idx], dist_elevation_alphabets[idx], gr_param_elevation_best );
2827 : }
2828 : }
2829 : }
2830 :
2831 : /* encode the ExtendedGR part for azimuth */
2832 135059 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, ivas_qmetadata_reorder_generic_fx( sub( avg_azimuth_index_best, shr( avg_azimuth_alphabet, 1 ) ) ), avg_azimuth_alphabet );
2833 :
2834 135059 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, gr_param_azimuth_best, 5 + 1 );
2835 :
2836 135059 : IF( NE_16( gr_param_azimuth_best, 5 ) ) /* not all zero */
2837 : {
2838 561000 : FOR( idx = 0; idx < s_min( nblocks, dist_count ); idx++ )
2839 : {
2840 444627 : test();
2841 444627 : test();
2842 444627 : IF( EQ_16( make_gain, 1 ) && LT_16( bits_gained, sub( direction_bits_ec, max_bits ) ) && GT_16( dist_azimuth_alphabets[idx], 40 ) )
2843 : {
2844 1569 : IF( GT_16( dist_azimuth_indexes_best[idx], 1 ) )
2845 : {
2846 1032 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best );
2847 1032 : bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length_fx( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ),
2848 1032 : ivas_qmetadata_encode_extended_gr_length_fx( sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) );
2849 : }
2850 537 : ELSE IF( EQ_16( dist_azimuth_indexes_best[idx], 1 ) )
2851 : {
2852 226 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best );
2853 226 : bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length_fx( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ),
2854 226 : ivas_qmetadata_encode_extended_gr_length_fx( sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) );
2855 : }
2856 : ELSE
2857 : {
2858 311 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best );
2859 : }
2860 : }
2861 : ELSE
2862 : {
2863 443058 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best );
2864 : }
2865 : }
2866 :
2867 116373 : IF( GT_16( dist_count, nblocks ) )
2868 : {
2869 90748 : test();
2870 90748 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && GT_16( nblocks, 1 ) )
2871 : {
2872 2267 : push_next_indice( hMetaData, use_adapt_avg, 1 );
2873 : }
2874 1447749 : FOR( idx = nblocks; idx < dist_count; idx++ )
2875 : {
2876 1357001 : test();
2877 1357001 : test();
2878 1357001 : IF( EQ_16( make_gain, 1 ) && LT_16( bits_gained, sub( direction_bits_ec, max_bits ) ) && GT_16( dist_azimuth_alphabets[idx], 40 ) )
2879 : {
2880 10009 : IF( GT_16( dist_azimuth_indexes_best[idx], 1 ) )
2881 : {
2882 7116 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best );
2883 7116 : bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length_fx( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ),
2884 7116 : ivas_qmetadata_encode_extended_gr_length_fx( sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) );
2885 : }
2886 2893 : ELSE IF( EQ_16( dist_azimuth_indexes_best[idx], 1 ) )
2887 : {
2888 1246 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best );
2889 1246 : bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length_fx( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ),
2890 1246 : ivas_qmetadata_encode_extended_gr_length_fx( sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) );
2891 : }
2892 : ELSE
2893 : {
2894 1647 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best );
2895 : }
2896 : }
2897 : ELSE
2898 : {
2899 1346992 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best );
2900 : }
2901 : }
2902 : }
2903 : }
2904 :
2905 135059 : direction_bits_ec = sub( direction_bits_ec, bits_gained );
2906 : }
2907 : ELSE
2908 : {
2909 122001 : direction_bits_ec = -1;
2910 122001 : move16();
2911 : }
2912 :
2913 257060 : return direction_bits_ec;
2914 : }
2915 :
2916 :
2917 : /*-------------------------------------------------------------------------
2918 : * ivas_qmetadata_raw_encode_dir()
2919 : *
2920 : * Main function for raw coding of the directions (writing and bit estimation)
2921 : *------------------------------------------------------------------------*/
2922 379061 : static Word16 ivas_qmetadata_raw_encode_dir_fx(
2923 : BSTR_ENC_HANDLE hMetaData,
2924 : IVAS_QDIRECTION *q_direction,
2925 : const Word16 nbands,
2926 : const Word16 start_band )
2927 : {
2928 : Word16 i, j;
2929 : Word16 direction_bits_raw;
2930 379061 : Word16 start_bits = 0; /*To avoid compiler warning*/
2931 379061 : move16();
2932 :
2933 379061 : direction_bits_raw = 0;
2934 379061 : move16();
2935 379061 : if ( hMetaData != NULL )
2936 : {
2937 122001 : start_bits = hMetaData->nb_bits_tot;
2938 122001 : move16();
2939 : }
2940 :
2941 379061 : IF( q_direction->not_in_2D > 0 )
2942 : {
2943 1671705 : FOR( i = start_band; i < nbands; i++ )
2944 : {
2945 1347272 : IF( hMetaData != NULL )
2946 : {
2947 1559103 : FOR( j = 0; j < q_direction->cfg.nblocks; j++ )
2948 : {
2949 1194681 : push_next_indice( hMetaData, q_direction->band_data[i].spherical_index[j], q_direction->band_data[i].bits_sph_idx[j] );
2950 : }
2951 : }
2952 : ELSE
2953 : {
2954 982850 : direction_bits_raw = add( direction_bits_raw, imult1616( q_direction->cfg.nblocks, q_direction->band_data[i].bits_sph_idx[0] ) );
2955 : }
2956 : }
2957 : }
2958 : ELSE
2959 : {
2960 289287 : FOR( i = start_band; i < nbands; i++ )
2961 : {
2962 918580 : FOR( j = 0; j < q_direction->cfg.nblocks; j++ )
2963 : {
2964 683921 : IF( hMetaData != NULL )
2965 : {
2966 192135 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] );
2967 : }
2968 : ELSE
2969 : {
2970 491786 : direction_bits_raw = add( direction_bits_raw,
2971 491786 : ivas_qmetadata_encode_quasi_uniform_length_fx( q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] ) );
2972 : }
2973 : }
2974 : }
2975 : }
2976 :
2977 379061 : IF( hMetaData != NULL )
2978 : {
2979 122001 : direction_bits_raw = sub( hMetaData->nb_bits_tot, start_bits );
2980 : }
2981 :
2982 379061 : return direction_bits_raw;
2983 : }
2984 :
2985 : /*-------------------------------------------------------------------------
2986 : * ivas_qmetadata_get_optimal_gr_param()
2987 : *
2988 : *
2989 : *------------------------------------------------------------------------*/
2990 1306581 : static Word16 ivas_qmetadata_get_optimal_gr_param_fx(
2991 : UWord16 *unsigned_data,
2992 : const Word16 count,
2993 : const Word16 gr_param_count,
2994 : Word16 *opt_gr_size )
2995 : {
2996 : Word16 opt_bits, bits, idx;
2997 : Word16 opt_gr_param;
2998 : Word16 p;
2999 :
3000 1306581 : opt_bits = MAX16B;
3001 1306581 : move16();
3002 1306581 : opt_gr_param = -1;
3003 1306581 : move16();
3004 :
3005 7236401 : FOR( p = 0; p < gr_param_count; p++ )
3006 : {
3007 5929820 : bits = imult1616( count, add( 1, p ) ); /* terminating zero bit and the lsb bits */
3008 79663792 : FOR( idx = 0; idx < count; idx++ )
3009 : {
3010 73733972 : bits = add( bits, extract_l( L_shr( unsigned_data[idx], p ) ) ); /* leading one bits */
3011 : }
3012 :
3013 5929820 : IF( LT_16( bits, opt_bits ) )
3014 : {
3015 2187612 : opt_gr_param = p;
3016 2187612 : move16();
3017 2187612 : opt_bits = bits;
3018 2187612 : move16();
3019 : }
3020 : }
3021 :
3022 1306581 : *opt_gr_size = opt_bits;
3023 1306581 : move16();
3024 :
3025 1306581 : return opt_gr_param;
3026 : }
3027 :
3028 : /*-------------------------------------------------------------------------
3029 : * ivas_qmetadata_encode_extended_gr_length_fx()
3030 : *
3031 : *
3032 : *------------------------------------------------------------------------*/
3033 : Word16
3034 20226824 : ivas_qmetadata_encode_extended_gr_length_fx(
3035 : const UWord16 value,
3036 : const UWord16 alphabet_size,
3037 : const Word16 gr_param )
3038 : {
3039 : UWord16 msb_alphabet_size;
3040 : Word16 bits;
3041 : UWord16 msb, lsb;
3042 :
3043 :
3044 20226824 : msb_alphabet_size = (UWord16) L_shr( L_add( alphabet_size, L_sub( L_shl( 1U, gr_param ), 1 ) ), gr_param );
3045 :
3046 20226824 : IF( LE_32( msb_alphabet_size, 3 ) )
3047 : {
3048 : /* EncodeQuasiUniform is always equal or better than Limited GR with up to 3 msb values */
3049 4031549 : bits = ivas_qmetadata_encode_quasi_uniform_length_fx( value, alphabet_size );
3050 : }
3051 : ELSE
3052 : {
3053 16195275 : msb = (UWord16) L_shr( value, gr_param );
3054 :
3055 16195275 : bits = msb; /* leading one bits */
3056 16195275 : move16();
3057 16195275 : IF( LT_32( msb, L_sub( msb_alphabet_size, 1 ) ) )
3058 : {
3059 15964781 : bits = add( bits, add( 1, gr_param ) ); /* terminating zero bit, if not the largest msb (Limited GR), and the lsb bits */
3060 : }
3061 : ELSE
3062 : {
3063 230494 : lsb = (UWord16) L_and( value, L_sub( L_shl( 1U, gr_param ), 1 ) );
3064 230494 : bits = add( bits, ivas_qmetadata_encode_quasi_uniform_length_fx( lsb, (UWord16) L_sub( alphabet_size, L_shl( L_sub( msb_alphabet_size, 1 ), gr_param ) ) ) );
3065 : }
3066 : }
3067 :
3068 20226824 : return bits;
3069 : }
3070 :
3071 : /*-------------------------------------------------------------------------
3072 : * ivas_qmetadata_reorder_elevation_index()
3073 : *
3074 : *
3075 : *------------------------------------------------------------------------*/
3076 11276265 : static Word16 ivas_qmetadata_reorder_elevation_index_fx(
3077 : const Word16 elevation_index,
3078 : const Word16 avg_elevation_index,
3079 : const Word16 elevation_alphabet )
3080 : {
3081 : Word16 elevation_alphabet_half;
3082 : Word16 elevation_index_reordered;
3083 :
3084 11276265 : elevation_alphabet_half = shr( elevation_alphabet, 1 );
3085 11276265 : elevation_index_reordered = sub( elevation_index, avg_elevation_index );
3086 :
3087 : /* reduce the distance for the index elevation to the range [-elevation_alphabet_half, elevation_alphabet_half] */
3088 11276265 : IF( LT_16( elevation_index_reordered, negate( elevation_alphabet_half ) ) )
3089 : {
3090 230148 : elevation_index_reordered = add( elevation_index_reordered, elevation_alphabet );
3091 : }
3092 11046117 : ELSE IF( GT_16( elevation_index_reordered, elevation_alphabet_half ) )
3093 : {
3094 193084 : elevation_index_reordered = sub( elevation_index_reordered, elevation_alphabet );
3095 : }
3096 :
3097 : /* fold reduced signed distance value for converting to unsigned */
3098 11276265 : elevation_index_reordered = ivas_qmetadata_reorder_generic_fx( elevation_index_reordered );
3099 :
3100 11276265 : return elevation_index_reordered;
3101 : }
3102 :
3103 : /*-------------------------------------------------------------------------
3104 : * ivas_qmetadata_reorder_azimuth_index()
3105 : *
3106 : *
3107 : *------------------------------------------------------------------------*/
3108 8792898 : static Word16 ivas_qmetadata_reorder_azimuth_index_fx(
3109 : const Word16 azimuth_index,
3110 : const Word16 avg_azimuth_index,
3111 : const Word16 azimuth_alphabet )
3112 : {
3113 : Word16 azimuth_alphabet_half;
3114 : Word16 azimuth_index_reordered;
3115 :
3116 8792898 : azimuth_index_reordered = sub( azimuth_index, avg_azimuth_index );
3117 :
3118 8792898 : test();
3119 8792898 : IF( NE_16( azimuth_alphabet, 1 ) && EQ_16( s_and( azimuth_alphabet, 0x01 ), 1 ) )
3120 : {
3121 3647619 : return ( ivas_qmetadata_reorder_elevation_index_fx( azimuth_index, avg_azimuth_index, azimuth_alphabet ) );
3122 : }
3123 5145279 : ELSE IF( NE_16( azimuth_alphabet, 1 ) )
3124 : {
3125 5140548 : azimuth_alphabet_half = shr( azimuth_alphabet, 1 );
3126 : /* reduce the distance for the index azimuth to the range [-azimuth_alphabet_half, azimuth_alphabet_half - 1] */
3127 5140548 : IF( LT_16( azimuth_index_reordered, negate( azimuth_alphabet_half ) ) )
3128 : {
3129 108410 : azimuth_index_reordered = add( azimuth_index_reordered, azimuth_alphabet );
3130 : }
3131 5032138 : ELSE IF( GT_16( azimuth_index_reordered, sub( azimuth_alphabet_half, 1 ) ) )
3132 : {
3133 358549 : azimuth_index_reordered = sub( azimuth_index_reordered, azimuth_alphabet );
3134 : }
3135 : /* fold reduced signed distance value for converting to unsigned */
3136 5140548 : azimuth_index_reordered = ivas_qmetadata_reorder_generic_fx( azimuth_index_reordered );
3137 : }
3138 : ELSE
3139 : {
3140 : /* for North and South poles, a single azimuth direction exists */
3141 4731 : azimuth_index_reordered = 0;
3142 4731 : move16();
3143 : }
3144 :
3145 5145279 : return azimuth_index_reordered;
3146 : }
3147 :
3148 : /*-------------------------------------------------------------------------
3149 : * ivas_qmetadata_encode_extended_gr_fx()
3150 : *
3151 : *
3152 : *------------------------------------------------------------------------*/
3153 4565381 : void ivas_qmetadata_encode_extended_gr_fx(
3154 : BSTR_ENC_HANDLE hMetaData,
3155 : const UWord16 value,
3156 : const UWord16 alphabet_size,
3157 : const Word16 gr_param )
3158 : {
3159 : UWord16 msb_alphabet_size;
3160 : UWord16 msb, lsb, cnt;
3161 :
3162 :
3163 4565381 : msb_alphabet_size = (UWord16) L_shr( L_add( alphabet_size, L_sub( L_shl( 1U, gr_param ), 1 ) ), gr_param );
3164 :
3165 4565381 : IF( LE_32( msb_alphabet_size, 3 ) )
3166 : {
3167 : /* EncodeQuasiUniform is always equal or better than Limited GR with up to 3 msb values */
3168 307684 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, value, alphabet_size );
3169 : }
3170 : ELSE
3171 : {
3172 4257697 : msb = (UWord16) L_shr( value, gr_param );
3173 4257697 : lsb = (UWord16) L_and( value, L_sub( L_shl( 1U, gr_param ), 1 ) );
3174 :
3175 7527045 : FOR( cnt = 0; cnt < msb; cnt++ )
3176 : {
3177 : /* leading one bits */
3178 3269348 : push_next_indice( hMetaData, 1, 1 );
3179 : }
3180 :
3181 4257697 : IF( LT_32( msb, L_sub( msb_alphabet_size, 1 ) ) )
3182 : {
3183 4233842 : push_next_indice( hMetaData, 0, 1 ); /* terminating zero bit, if not the largest msb (Limited GR) */
3184 4233842 : IF( gr_param > 0 )
3185 : {
3186 1587182 : push_next_indice( hMetaData, lsb, gr_param );
3187 : }
3188 : }
3189 : ELSE
3190 : {
3191 23855 : ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, lsb, (UWord16) L_sub( alphabet_size, L_shl( L_sub( msb_alphabet_size, 1 ), gr_param ) ) );
3192 : }
3193 : }
3194 :
3195 4565381 : return;
3196 : }
3197 :
3198 : /*-----------------------------------------------------------------------*
3199 : * Local functions (EC3, requantize directions)
3200 : *-----------------------------------------------------------------------*/
3201 3265 : static Word16 truncGR0_fx(
3202 : Word32 *data_fx, // Q22
3203 : Word32 *data_hat_fx, // Q22
3204 : UWord16 *data_idx,
3205 : const Word16 len,
3206 : const Word16 bits_allowed,
3207 : Word32 *st_fx, // Q31
3208 : Word32 *ct_fx // Q31
3209 : )
3210 : {
3211 : Word16 i;
3212 : Word16 bits;
3213 3265 : const Word16 remap3b[8] = { 1, 6, 2, 4, 0, 5, 3, 7 };
3214 3265 : const Word16 remap2b[4] = { 1, 2, 0, 3 };
3215 : Word32 diff_fx[MAX_PARAM_SPATIAL_SUBFRAMES];
3216 : Word16 indx[MAX_PARAM_SPATIAL_SUBFRAMES];
3217 : Word32 L_temp;
3218 3265 : move16();
3219 3265 : move16();
3220 3265 : move16();
3221 3265 : move16();
3222 3265 : move16();
3223 3265 : move16();
3224 3265 : move16();
3225 3265 : move16();
3226 3265 : move16();
3227 3265 : move16();
3228 3265 : move16();
3229 3265 : move16();
3230 3265 : bits = 0;
3231 3265 : move16();
3232 3265 : set_val_Word32( data_hat_fx, 0, len );
3233 3265 : set_val_Word32( diff_fx, 10000, len );
3234 :
3235 3265 : IF( LE_16( bits_allowed, add( len, 1 ) ) )
3236 : {
3237 246 : bits = s_min( bits_allowed, len );
3238 246 : set_val_Word32( data_hat_fx, 0, len );
3239 :
3240 1190 : FOR( i = 0; i < bits; i++ )
3241 : {
3242 944 : IF( LE_32( L_abs( data_fx[i] ), 377487360 ) ) // 90 in Q22
3243 : {
3244 861 : data_idx[i] = 0;
3245 861 : move16();
3246 861 : data_hat_fx[i] = 0;
3247 861 : move32();
3248 : }
3249 : ELSE
3250 : {
3251 83 : data_idx[i] = 1;
3252 83 : move16();
3253 83 : data_hat_fx[i] = -754974720; //-180 in Q22
3254 83 : move32();
3255 : }
3256 : }
3257 :
3258 246 : return bits;
3259 : }
3260 :
3261 14891 : FOR( i = 0; i < len; i++ )
3262 : {
3263 11872 : data_idx[i] = quantize_phi_enc_fx( L_add( data_fx[i], DEGREE_180_Q_22 ), 0, &data_hat_fx[i], 8 );
3264 11872 : move16();
3265 11872 : data_hat_fx[i] = L_sub( data_hat_fx[i], DEGREE_180_Q_22 );
3266 11872 : move32();
3267 11872 : data_idx[i] = remap3b[data_idx[i]];
3268 11872 : move16();
3269 11872 : bits = add( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[i], 8, 0 ) );
3270 : // diff[i] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[i] - data_hat[i] ) ); /*(data[i] - data_hat[i])*(data[i] - data_hat[i]);*/
3271 11872 : L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[i], data_hat_fx[i] ), 91 ), 7 ) ) ) ); // Q31
3272 11872 : diff_fx[i] = L_negate( L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ) ); // Q30
3273 11872 : move32();
3274 : }
3275 :
3276 3019 : i = 0;
3277 3019 : move16();
3278 3019 : IF( GT_16( bits, bits_allowed ) )
3279 : {
3280 2706 : sort_desc_ind_32_fx( diff_fx, len, indx );
3281 11330 : FOR( i = len - 1; i >= 0; i-- )
3282 : {
3283 9723 : IF( GT_32( data_idx[indx[i]], 3 ) )
3284 : {
3285 5400 : bits = sub( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[indx[i]], 8, 0 ) );
3286 : // data_idx[indx[i]] = quantize_phi( data[indx[i]] + 180, 0, &data_hat[indx[i]], 4 );
3287 5400 : data_idx[indx[i]] = quantize_phi_enc_fx( L_add( data_fx[indx[i]], DEGREE_180_Q_22 ), 0, &data_hat_fx[indx[i]], 4 );
3288 5400 : move16();
3289 : // data_hat[indx[i]] -= 180;
3290 5400 : data_hat_fx[indx[i]] = L_sub( data_hat_fx[indx[i]], DEGREE_180_Q_22 );
3291 5400 : move32();
3292 5400 : data_idx[indx[i]] = remap2b[data_idx[indx[i]]];
3293 5400 : move16();
3294 5400 : bits = add( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[indx[i]], 8, 0 ) );
3295 : // diff[indx[i]] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[indx[i]] - data_hat[indx[i]] ) );
3296 5400 : L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[indx[i]], data_hat_fx[indx[i]] ), 91 ), 7 ) ) ) ); // Q31
3297 :
3298 5400 : diff_fx[indx[i]] = L_negate( L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ) ); // Q30
3299 5400 : move32();
3300 : }
3301 9723 : IF( LE_16( bits, bits_allowed ) )
3302 : {
3303 1099 : BREAK;
3304 : }
3305 : }
3306 : }
3307 :
3308 3019 : IF( GT_16( bits, bits_allowed ) )
3309 : {
3310 1607 : sort_desc_ind_32_fx( diff_fx, len, indx );
3311 3380 : FOR( i = len - 1; i >= 0; i-- )
3312 : {
3313 :
3314 3347 : IF( GT_16( data_idx[indx[i]], 1 ) )
3315 : {
3316 2874 : bits = sub( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[indx[i]], 8, 0 ) );
3317 :
3318 2874 : IF( LE_32( L_abs( data_fx[indx[i]] ), 377487360 ) ) // 90 in Q22
3319 : {
3320 1830 : data_idx[indx[i]] = 0;
3321 1830 : move16();
3322 : // data_hat[i] = 0.0f;
3323 1830 : data_hat_fx[indx[i]] = 0;
3324 1830 : move32();
3325 : }
3326 : ELSE
3327 : {
3328 1044 : data_idx[indx[i]] = 1;
3329 1044 : move16();
3330 : // data_hat[i] = -180.0f;
3331 1044 : data_hat_fx[indx[i]] = -754974720; //-180 in Q22
3332 1044 : move32();
3333 : }
3334 :
3335 2874 : bits = add( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[indx[i]], 8, 0 ) );
3336 : // diff[indx[i]] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[indx[i]] - data_hat[indx[i]] ) );
3337 2874 : L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[indx[i]], data_hat_fx[indx[i]] ), 91 ), 7 ) ) ) ); // Q31
3338 :
3339 2874 : diff_fx[indx[i]] = L_negate( L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ) ); // Q30
3340 2874 : move32();
3341 : }
3342 :
3343 3347 : IF( LE_16( bits, bits_allowed ) )
3344 : {
3345 1574 : BREAK;
3346 : }
3347 : }
3348 : }
3349 :
3350 3019 : IF( GT_16( bits, bits_allowed ) )
3351 : {
3352 :
3353 33 : sort_desc_ind_32_fx( diff_fx, len, indx );
3354 34 : FOR( i = len - 1; i >= 0; i-- )
3355 : {
3356 :
3357 34 : IF( data_idx[indx[i]] > 0 )
3358 : {
3359 33 : bits = sub( bits, data_idx[indx[i]] );
3360 33 : data_idx[indx[i]] = 0;
3361 33 : move16();
3362 33 : data_hat_fx[indx[i]] = 0;
3363 33 : move32();
3364 : }
3365 34 : IF( LE_16( bits, bits_allowed ) )
3366 : {
3367 33 : BREAK;
3368 : }
3369 : }
3370 : }
3371 :
3372 3019 : return bits;
3373 : }
3374 : /*-------------------------------------------------------------------*
3375 : * truncGR0_chan()
3376 : *
3377 : *
3378 : *-------------------------------------------------------------------*/
3379 526 : static Word16 truncGR0_chan_fx(
3380 : const Word32 *data_fx, // Q22
3381 : Word32 *data_hat_fx, // Q22
3382 : UWord16 *data_idx,
3383 : const Word16 len,
3384 : const Word16 bits_allowed,
3385 : Word32 *st_fx, // Q31
3386 : Word32 *ct_fx ) // Q31
3387 : {
3388 : Word16 i, idx_crt;
3389 : Word16 bits;
3390 : Word32 diff_fx[MAX_PARAM_SPATIAL_SUBFRAMES], sort_diff_fx[MAX_PARAM_SPATIAL_SUBFRAMES], min_diff_fx, sum_diff_fx;
3391 : Word16 indx[MAX_PARAM_SPATIAL_SUBFRAMES];
3392 : Word32 L_temp;
3393 526 : bits = 0;
3394 526 : move16();
3395 526 : set_val_Word32( data_hat_fx, 0, len );
3396 526 : set_val_Word32( diff_fx, 10000, len );
3397 526 : Word16 gb = find_guarded_bits_fx( len );
3398 526 : IF( LE_16( bits_allowed, add( len, 1 ) ) )
3399 : {
3400 0 : bits = s_min( bits_allowed, len );
3401 0 : set_val_Word32( data_hat_fx, 0, len );
3402 :
3403 0 : FOR( i = 0; i < bits; i++ )
3404 : {
3405 0 : IF( LE_32( L_abs( data_fx[i] ), 377487360 ) ) // 90 in Q22
3406 : {
3407 0 : data_idx[i] = 0;
3408 0 : move16();
3409 0 : data_hat_fx[i] = 0;
3410 0 : move32();
3411 : }
3412 : ELSE
3413 : {
3414 0 : data_idx[i] = 1;
3415 0 : move16();
3416 : // data_hat[i] = -180.0f;
3417 0 : data_hat_fx[i] = -754974720; //-180 in Q22
3418 0 : move32();
3419 : }
3420 : }
3421 0 : return bits;
3422 : }
3423 :
3424 2618 : FOR( i = 0; i < len; i++ )
3425 : {
3426 2092 : data_idx[i] = quantize_phi_chan_lbr_fx( data_fx[i], &data_hat_fx[i], 9 );
3427 2092 : move16();
3428 2092 : bits = add( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[i], 9, 0 ) );
3429 : // diff[i] = -st[i] - ct[i] * cosf( ( data[i] - data_hat[i] ) * PI_OVER_180 );
3430 2092 : L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[i], data_hat_fx[i] ), 91 ), 7 ) ) ) ); // Q31
3431 2092 : diff_fx[i] = L_negate( L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ) ); // Q30
3432 2092 : move32();
3433 : }
3434 :
3435 744 : WHILE( ( bits > bits_allowed ) )
3436 : {
3437 : // min_diff = 1000.0f;
3438 218 : min_diff_fx = 2097152000; // 1000 in Q21
3439 218 : move32();
3440 218 : Word16 min_diff_e = Q31 - Q21;
3441 218 : move16();
3442 218 : idx_crt = -1;
3443 218 : move16();
3444 218 : Copy32( diff_fx, sort_diff_fx, len );
3445 1078 : FOR( i = 0; i < len; i++ )
3446 : {
3447 860 : IF( data_idx[i] > 0 )
3448 : {
3449 : // sort_diff[i] = -st[i] - ct[i] * cosf( ( fabsf( data[i] ) - cb_azi_chan[( ( data_idx[i] + 1 ) >> 1 ) - 1] ) * PI_OVER_180 );
3450 701 : L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( L_abs( data_fx[i] ), cb_azi_chan_fx[( ( data_idx[i] + 1 ) >> 1 ) - 1] ), 91 ), 7 ) ) ) ); // Q31
3451 701 : sort_diff_fx[i] = L_negate( L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ) ); // Q30
3452 701 : move32();
3453 701 : sum_diff_fx = sum2_f_32_fx( sort_diff_fx, len, gb ); // Q(2*Q30-31-gb)= Q(Q29-gb)
3454 701 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( sum_diff_fx, sub( Q31, sub( Q29, gb ) ), min_diff_fx, min_diff_e );
3455 701 : IF( EQ_16( flag, -1 ) )
3456 : {
3457 423 : min_diff_fx = sum_diff_fx;
3458 423 : move32();
3459 423 : min_diff_e = sub( Q31, sub( Q29, gb ) );
3460 423 : idx_crt = i;
3461 423 : move16();
3462 : }
3463 701 : sort_diff_fx[i] = diff_fx[i]; // Q30
3464 701 : move32();
3465 : }
3466 : }
3467 :
3468 218 : IF( GT_16( idx_crt, -1 ) )
3469 : {
3470 218 : bits = sub( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[idx_crt], 9, 0 ) );
3471 218 : data_idx[idx_crt] = quantize_phi_chan_lbr_fx( data_fx[idx_crt], &data_hat_fx[idx_crt], add( data_idx[idx_crt], 1 ) );
3472 218 : move16();
3473 218 : bits = add( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[idx_crt], 9, 0 ) );
3474 : // diff[idx_crt] = -st[idx_crt] - ct[idx_crt] * cosf( ( data[idx_crt] - data_hat[idx_crt] ) * PI_OVER_180 );
3475 218 : L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[idx_crt], data_hat_fx[idx_crt] ), 91 ), 7 ) ) ) ); // Q31
3476 :
3477 218 : diff_fx[idx_crt] = L_negate( L_add( L_shr( st_fx[idx_crt], 1 ), L_shr( Mpy_32_32( ct_fx[idx_crt], L_temp ), 1 ) ) ); // Q30
3478 218 : move32();
3479 : }
3480 : ELSE
3481 : {
3482 0 : BREAK;
3483 : }
3484 : }
3485 :
3486 526 : IF( GT_16( bits, bits_allowed ) )
3487 : {
3488 0 : Copy32( diff_fx, sort_diff_fx, len );
3489 0 : sort_desc_ind_32_fx( sort_diff_fx, len, indx );
3490 :
3491 0 : FOR( i = len - 1; i >= 0; i-- )
3492 : {
3493 0 : idx_crt = indx[i];
3494 0 : move16();
3495 0 : IF( data_idx[idx_crt] > 0 )
3496 : {
3497 0 : bits = sub( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[idx_crt], 9, 0 ) );
3498 0 : data_idx[idx_crt] = 0;
3499 0 : move16();
3500 0 : data_hat_fx[idx_crt] = 0;
3501 0 : move32();
3502 0 : bits = add( bits, 1 );
3503 : }
3504 :
3505 0 : IF( LE_16( bits, bits_allowed ) )
3506 : {
3507 0 : BREAK;
3508 : }
3509 : }
3510 : }
3511 :
3512 526 : return bits;
3513 : }
3514 :
3515 : /*-------------------------------------------------------------------*
3516 : * common_direction()
3517 : *
3518 : *
3519 : *-------------------------------------------------------------------*/
3520 3481 : static Word16 common_direction_fx(
3521 : IVAS_QDIRECTION *q_direction,
3522 : const Word16 band_idx,
3523 : const Word16 len,
3524 : const Word16 bits_allowed,
3525 : BSTR_ENC_HANDLE hMetaData,
3526 : Word32 *elevation_orig_fx, // Q22
3527 : Word32 *azimuth_orig_fx // Q22
3528 : )
3529 : {
3530 : Word16 nbits;
3531 : Word16 no_th, i, id_th, k;
3532 : Word32 theta_cb_fx[5];
3533 : Word32 dist_fx, best_dist_fx;
3534 : Word32 ct_fx[MAX_PARAM_SPATIAL_SUBFRAMES], st_fx[MAX_PARAM_SPATIAL_SUBFRAMES];
3535 :
3536 3481 : nbits = 0;
3537 3481 : move16();
3538 3481 : IF( bits_allowed == 0 )
3539 : {
3540 0 : FOR( i = 0; i < len; i++ )
3541 : {
3542 0 : q_direction->band_data[band_idx].elevation_fx[i] = 0;
3543 0 : move32();
3544 0 : q_direction->band_data[band_idx].azimuth_fx[i] = 0;
3545 0 : move32();
3546 : }
3547 :
3548 0 : return 0;
3549 : }
3550 :
3551 3481 : IF( LE_16( bits_allowed, add( len, 1 ) ) )
3552 : {
3553 80 : set_val_Word32( q_direction->band_data[band_idx].elevation_fx, 0, len );
3554 80 : set_val_Word32( st_fx, 0, len );
3555 :
3556 400 : FOR( i = 0; i < len; i++ )
3557 : {
3558 : // ct[i] = cosf( elevation_orig[i] * PI_OVER_180 );
3559 320 : ct_fx[i] = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( elevation_orig_fx[i], 91 ), 7 ) ) ) ); // Q31
3560 320 : move32();
3561 : }
3562 :
3563 80 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
3564 : {
3565 0 : nbits = truncGR0_chan_fx( azimuth_orig_fx, q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed, st_fx, ct_fx );
3566 : }
3567 : ELSE
3568 : {
3569 80 : nbits = truncGR0_fx( azimuth_orig_fx, q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed, st_fx, ct_fx );
3570 : }
3571 :
3572 400 : FOR( i = 0; i < nbits; i++ )
3573 : {
3574 320 : push_next_indice( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 1 );
3575 : }
3576 :
3577 80 : return nbits;
3578 : }
3579 :
3580 3401 : no_th = add( no_theta_masa[0], 3 ); /* only 5 values for theta; the lat 2 are +/-90 */
3581 :
3582 3401 : theta_cb_fx[0] = 0;
3583 3401 : move32();
3584 3401 : theta_cb_fx[1] = delta_theta_masa_fx[2];
3585 3401 : move32();
3586 3401 : theta_cb_fx[2] = -theta_cb_fx[1];
3587 3401 : move32();
3588 : // theta_cb[3] = 90.0f;
3589 3401 : theta_cb_fx[3] = 377487360; // 90.0f in Q22
3590 3401 : move32();
3591 : // theta_cb[4] = -90.0f;
3592 3401 : theta_cb_fx[4] = -377487360; //-90.0f in Q22
3593 3401 : move32();
3594 : // best_dist = 900000.0f;
3595 3401 : best_dist_fx = 1843200000; // 900000.0f in Q11
3596 3401 : move32();
3597 3401 : Word16 best_dist_q = Q11;
3598 3401 : move16();
3599 3401 : id_th = 0;
3600 3401 : move16();
3601 3401 : Word16 gb = find_guarded_bits_fx( len );
3602 20406 : FOR( i = 0; i < no_th; i++ )
3603 : {
3604 : // dist = 0.0f;
3605 17005 : dist_fx = 0;
3606 17005 : move32();
3607 85025 : FOR( k = 0; k < len; k++ )
3608 : {
3609 : // dist += ( elevation_orig[k] - theta_cb[i] ) * ( elevation_orig[k] - theta_cb[i] );
3610 68020 : dist_fx = L_add( dist_fx, L_shr( Mpy_32_32( L_sub( elevation_orig_fx[k], theta_cb_fx[i] ), L_sub( elevation_orig_fx[k], theta_cb_fx[i] ) ), gb ) ); // Q(2*Q22-31) = Q13-gb
3611 : }
3612 17005 : IF( LT_32( L_shr( dist_fx, sub( sub( Q13, gb ), best_dist_q ) ), best_dist_fx ) )
3613 : {
3614 4479 : id_th = i;
3615 4479 : move16();
3616 4479 : best_dist_fx = dist_fx;
3617 4479 : move32();
3618 4479 : best_dist_q = sub( Q13, gb );
3619 : }
3620 : }
3621 :
3622 3401 : set_val_Word32( q_direction->band_data[band_idx].elevation_fx, theta_cb_fx[id_th], len );
3623 :
3624 17005 : FOR( i = 0; i < len; i++ )
3625 : {
3626 13604 : q_direction->band_data[band_idx].elevation_index[i] = id_th;
3627 13604 : move16();
3628 : }
3629 :
3630 3401 : IF( id_th == 0 )
3631 : {
3632 2331 : push_next_indice( hMetaData, 0, 1 ); /* average theta index */
3633 : // set_f( st, 0.0f, len );
3634 2331 : set_val_Word32( st_fx, 0, len );
3635 :
3636 11655 : FOR( i = 0; i < len; i++ )
3637 : {
3638 : // ct[i] = cosf( elevation_orig[i] * PI_OVER_180 );
3639 9324 : ct_fx[i] = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( elevation_orig_fx[i], 91 ), 7 ) ) ) ); // Q31
3640 9324 : move32();
3641 : }
3642 :
3643 2331 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
3644 : {
3645 181 : nbits = truncGR0_chan_fx( /*azimuth_orig,*/ azimuth_orig_fx, /*q_direction->band_data[band_idx].azimuth,*/ q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, sub( bits_allowed, 1 ), /* st,*/ st_fx, /*ct,*/ ct_fx ) + 1;
3646 : }
3647 : ELSE
3648 : {
3649 :
3650 2150 : nbits = truncGR0_fx( azimuth_orig_fx, q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed - 1, st_fx, ct_fx ) + 1;
3651 : }
3652 : }
3653 : ELSE
3654 : {
3655 1070 : IF( GE_16( id_th, 3 ) )
3656 : {
3657 : /* theta is 90 or -90; only theta is sent */
3658 8 : push_next_indice( hMetaData, add( id_th, 11 ), 4 ); /* average theta index */
3659 :
3660 8 : set_val_Word32( q_direction->band_data[band_idx].azimuth_fx, 0, len );
3661 40 : FOR( i = 0; i < len; i++ )
3662 : {
3663 32 : q_direction->band_data[band_idx].azimuth_index[i] = 0;
3664 32 : move16();
3665 : }
3666 8 : nbits = 4;
3667 8 : move16();
3668 8 : return nbits;
3669 : }
3670 :
3671 1062 : set_val_Word32( st_fx, L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( theta_cb_fx[id_th], 91 ), 7 ) ) ) ), len );
3672 1062 : set_val_Word32( ct_fx, L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( theta_cb_fx[id_th], 91 ), 7 ) ) ) ), len );
3673 :
3674 5310 : FOR( i = 0; i < len; i++ )
3675 : {
3676 : // st[i] *= sinf( elevation_orig[i] * PI_OVER_180 );
3677 4248 : st_fx[i] = Mpy_32_32( st_fx[i], L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( elevation_orig_fx[i], 91 ), 7 ) ) ) ) ); // Q31;
3678 4248 : move32();
3679 : // ct[i] *= cosf( elevation_orig[i] * PI_OVER_180 );
3680 4248 : ct_fx[i] = Mpy_32_32( ct_fx[i], L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( elevation_orig_fx[i], 91 ), 7 ) ) ) ) ); // Q31;
3681 4248 : move32();
3682 4248 : q_direction->band_data[band_idx].azimuth_index[i] = 0;
3683 4248 : move16();
3684 : }
3685 :
3686 1062 : IF( EQ_16( id_th, 1 ) )
3687 : {
3688 646 : push_next_indice( hMetaData, 2, 2 ); /* average theta index */
3689 : }
3690 : ELSE
3691 : {
3692 416 : assert( id_th == 2 );
3693 416 : push_next_indice( hMetaData, 6, 3 ); /* average theta index */
3694 : }
3695 :
3696 1062 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
3697 : {
3698 337 : nbits = add( truncGR0_chan_fx( azimuth_orig_fx, q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, sub( bits_allowed, add( id_th, 1 ) ), st_fx, ct_fx ), add( id_th, 1 ) );
3699 : }
3700 : ELSE
3701 : {
3702 :
3703 725 : nbits = add( truncGR0_fx( azimuth_orig_fx, q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, sub( bits_allowed, add( id_th, 1 ) ), st_fx, ct_fx ), add( id_th, 1 ) );
3704 : }
3705 : }
3706 :
3707 3393 : IF( LE_16( sub( bits_allowed, add( id_th, 1 ) ), add( len, 1 ) ) )
3708 : {
3709 :
3710 89 : FOR( i = 0; i < s_min( len, sub( bits_allowed, add( id_th, 1 ) ) ); i++ )
3711 : {
3712 71 : push_next_indice( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 1 );
3713 : }
3714 : }
3715 : ELSE
3716 : {
3717 3375 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
3718 : {
3719 2590 : FOR( i = 0; i < len; i++ )
3720 : {
3721 2072 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 9, 0 );
3722 : }
3723 : }
3724 : ELSE
3725 : {
3726 14285 : FOR( i = 0; i < len; i++ )
3727 : {
3728 11428 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 8, 0 );
3729 : }
3730 : }
3731 : }
3732 :
3733 3393 : return nbits;
3734 : }
3735 :
3736 : /*-------------------------------------------------------------------*
3737 : * encode_directions_subband()
3738 : *
3739 : *
3740 : *-------------------------------------------------------------------*/
3741 42006 : static Word16 encode_directions_subband_fx(
3742 : IVAS_QDIRECTION *q_direction,
3743 : Word16 coding_subbands,
3744 : BSTR_ENC_HANDLE hMetaData,
3745 : const Word16 j,
3746 : const Word16 next_j,
3747 : const Word16 no_subframes,
3748 : const Word16 last_subband,
3749 : Word16 *p_diff,
3750 : Word32 *elevation_orig_fx, // Q22
3751 : Word32 *azimuth_orig_fx // Q22
3752 : )
3753 : {
3754 : Word16 allowed_bits, use_vq, max_nb_idx, k;
3755 : Word16 diff;
3756 : Word32 d1_fx, d2_fx;
3757 : Word16 nbits;
3758 : Word16 *bits_dir0;
3759 :
3760 42006 : nbits = 0;
3761 42006 : move16();
3762 42006 : diff = *p_diff;
3763 42006 : move16();
3764 42006 : bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx;
3765 42006 : move16();
3766 42006 : allowed_bits = sum16_fx( bits_dir0, no_subframes );
3767 :
3768 42006 : IF( allowed_bits > 0 )
3769 : {
3770 42006 : use_vq = 0;
3771 42006 : move16();
3772 42006 : max_nb_idx = 0;
3773 42006 : move16();
3774 152820 : FOR( k = 0; k < no_subframes; k++ )
3775 : {
3776 110814 : IF( GT_16( bits_dir0[k], use_vq ) )
3777 : {
3778 50391 : use_vq = bits_dir0[k];
3779 50391 : move16();
3780 50391 : max_nb_idx = k;
3781 50391 : move16();
3782 : }
3783 : }
3784 :
3785 42006 : IF( GT_16( no_subframes, 1 ) )
3786 : {
3787 22936 : test();
3788 22936 : IF( GT_16( use_vq, 1 ) && LE_16( use_vq, LIMIT_USE_COMMON ) )
3789 : {
3790 3539 : bits_dir0[max_nb_idx] = sub( bits_dir0[max_nb_idx], 1 );
3791 3539 : move16();
3792 3539 : allowed_bits = sub( allowed_bits, 1 );
3793 : }
3794 : }
3795 42006 : IF( GT_16( no_subframes, 1 ) )
3796 : {
3797 22936 : IF( LE_16( use_vq, LIMIT_USE_COMMON ) )
3798 : {
3799 : /* calculate the two distances */
3800 : Word16 Q_out;
3801 3593 : calculate_two_distances_fx( q_direction->band_data[j].elevation_fx, bits_dir0, allowed_bits, no_subframes, &d1_fx, &d2_fx, &Q_out );
3802 3593 : test();
3803 3593 : test();
3804 3593 : IF( ( GT_16( use_vq, 1 ) && LE_32( d2_fx, d1_fx ) ) || LE_16( use_vq, 1 ) )
3805 : {
3806 3481 : IF( GT_16( use_vq, 1 ) )
3807 : {
3808 3427 : push_next_indice( hMetaData, 1, 1 ); /* signal VQ */
3809 : }
3810 :
3811 3481 : diff = add( diff, sub( common_direction_fx( q_direction, j, no_subframes, allowed_bits, hMetaData, /*elevation_orig,*/ elevation_orig_fx, /*azimuth_orig,*/ azimuth_orig_fx ), allowed_bits ) );
3812 :
3813 3481 : IF( last_subband == 0 )
3814 : {
3815 2403 : update_bits_next_block_fx( q_direction, &diff, next_j, coding_subbands, no_subframes );
3816 : }
3817 : }
3818 : ELSE
3819 : {
3820 112 : push_next_indice( hMetaData, 0, 1 );
3821 :
3822 112 : IF( last_subband == 0 )
3823 : {
3824 57 : Copy32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); // Q22
3825 57 : Copy32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); // Q22
3826 57 : joint_encoding_fx( q_direction, j, next_j, coding_subbands, bits_dir0, allowed_bits, hMetaData, &diff );
3827 : }
3828 : ELSE
3829 : {
3830 275 : FOR( k = 0; k < no_subframes; k++ )
3831 : {
3832 : /* requantize the direction */
3833 440 : q_direction->band_data[j].spherical_index[k] = quantize_direction_fx( elevation_orig_fx[k], azimuth_orig_fx[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation_fx[k], &q_direction->band_data[j].azimuth_fx[k],
3834 220 : &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup );
3835 220 : move16();
3836 : }
3837 :
3838 55 : IF( allowed_bits > 0 )
3839 : {
3840 55 : nbits = write_fixed_rate_direction_fx( hMetaData, q_direction, j, no_subframes );
3841 : }
3842 : }
3843 : }
3844 : }
3845 : ELSE
3846 : {
3847 : /* there is only joint coding */
3848 19343 : Copy32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); // Q22
3849 19343 : Copy32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); // Q22
3850 :
3851 19343 : IF( last_subband == 0 )
3852 : {
3853 12558 : joint_encoding_fx( q_direction, j, next_j, coding_subbands, bits_dir0, allowed_bits, hMetaData, &diff );
3854 : }
3855 : ELSE
3856 : {
3857 33925 : FOR( k = 0; k < no_subframes; k++ )
3858 : {
3859 : /* requantize the direction */
3860 54280 : q_direction->band_data[j].spherical_index[k] = quantize_direction_fx( elevation_orig_fx[k], azimuth_orig_fx[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation_fx[k], &q_direction->band_data[j].azimuth_fx[k],
3861 27140 : &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup );
3862 27140 : move16();
3863 : }
3864 :
3865 6785 : IF( allowed_bits > 0 )
3866 : {
3867 6785 : nbits = write_fixed_rate_direction_fx( hMetaData, q_direction, j, no_subframes );
3868 : }
3869 : }
3870 : }
3871 : }
3872 : ELSE
3873 : {
3874 : /* 1 subframe case */
3875 : /* there is only joint coding */
3876 19070 : Copy32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); // Q22
3877 19070 : Copy32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); // Q22
3878 :
3879 19070 : IF( last_subband == 0 )
3880 : {
3881 12780 : joint_encoding_fx( q_direction, j, next_j, coding_subbands, bits_dir0, allowed_bits, hMetaData, &diff );
3882 : }
3883 : ELSE
3884 : {
3885 12580 : FOR( k = 0; k < no_subframes; k++ )
3886 : {
3887 : /* requantize the direction */
3888 12580 : q_direction->band_data[j].spherical_index[k] = quantize_direction_fx( elevation_orig_fx[k], azimuth_orig_fx[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation_fx[k], &q_direction->band_data[j].azimuth_fx[k],
3889 6290 : &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup );
3890 6290 : move16();
3891 : }
3892 :
3893 6290 : IF( allowed_bits > 0 )
3894 : {
3895 6290 : nbits = write_fixed_rate_direction_fx( hMetaData, q_direction, j, no_subframes );
3896 : }
3897 : }
3898 : }
3899 : }
3900 : ELSE
3901 : {
3902 0 : set_val_Word32( q_direction->band_data[j].elevation_fx, 0, no_subframes );
3903 0 : set_val_Word32( q_direction->band_data[j].azimuth_fx, 0, no_subframes );
3904 : }
3905 :
3906 42006 : *p_diff = diff;
3907 42006 : move16();
3908 42006 : return nbits;
3909 : }
3910 :
3911 : /*-------------------------------------------------------------------*
3912 : * calc_var_azi()
3913 : *
3914 : *
3915 : *-------------------------------------------------------------------*/
3916 :
3917 3415 : static Word16 calc_var_azi_fx(
3918 : const IVAS_QDIRECTION *q_direction,
3919 : const Word16 diffuseness_index_max_ec_frame,
3920 : const Word32 avg_azimuth, /* Q22 */
3921 : Word32 *avg_azimuth_out /* Q22 */ )
3922 : {
3923 : Word32 var_band, dif; /* Q22 */
3924 : Word32 avg_direction_vector_band[3], direction_vector[3]; /* Q25 */
3925 : Word32 avg_azimuth_band[24]; /* Q22 */
3926 : Word32 avg_elevation; /* Q22 */
3927 : Word16 i, j, idx;
3928 :
3929 3415 : idx = 0;
3930 3415 : move16();
3931 3415 : set32_fx( avg_azimuth_band, 0, 24 );
3932 :
3933 20490 : FOR( i = 0; i < q_direction->cfg.nbands; i++ )
3934 : {
3935 17075 : set32_fx( avg_direction_vector_band, 0, 3 );
3936 17075 : IF( LE_16( q_direction->band_data[i].energy_ratio_index_mod[0], diffuseness_index_max_ec_frame ) )
3937 : {
3938 57560 : FOR( j = 0; j < q_direction->cfg.nblocks; j++ )
3939 : {
3940 : /*compute the average direction */
3941 46048 : ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[i].azimuth_fx[j], q_direction->band_data[i].elevation_fx[j], direction_vector );
3942 46048 : v_shr_32( direction_vector, direction_vector, 3, 5 ); // Q30 -> Q25
3943 46048 : v_add_32( avg_direction_vector_band, direction_vector, avg_direction_vector_band, 3 );
3944 : }
3945 11512 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_band, 30 - 5, &avg_azimuth_band[idx], &avg_elevation );
3946 11512 : idx += 1;
3947 : }
3948 : }
3949 :
3950 3415 : var_band = 0; /* Q11 */
3951 3415 : move32();
3952 :
3953 14927 : FOR( i = 0; i < idx; i++ )
3954 : {
3955 11512 : dif = L_sub( avg_azimuth_band[idx], avg_azimuth );
3956 11512 : if ( dif < 0 )
3957 : {
3958 2831 : dif = L_negate( dif );
3959 : }
3960 11512 : if ( GT_32( dif, DEGREE_180_Q_22 ) )
3961 : {
3962 0 : dif = L_sub( DEGREE_360_Q_22, dif );
3963 : }
3964 :
3965 11512 : var_band = Madd_32_32( var_band, dif, dif ); /* Q11 */
3966 : }
3967 :
3968 3415 : IF( idx > 0 )
3969 : {
3970 3415 : Word16 mul = div_s( 1, idx );
3971 3415 : var_band = Mpy_32_16_1( var_band, mul ); /* Q11 */
3972 3415 : var_band = L_shr_r( var_band, 11 ); /* Q0 */
3973 : }
3974 :
3975 3415 : IF( LE_32( var_band, VAR_AZI_THRESH ) )
3976 : {
3977 980 : *avg_azimuth_out = avg_azimuth;
3978 980 : move32();
3979 980 : return 0;
3980 : }
3981 : ELSE
3982 : {
3983 2435 : *avg_azimuth_out = avg_azimuth_band[0];
3984 2435 : move32();
3985 2435 : return 1;
3986 : }
3987 : }
3988 :
3989 :
3990 : /*-------------------------------------------------------------------*
3991 : * requantize_direction_EC_3()
3992 : *
3993 : *
3994 : *-------------------------------------------------------------------*/
3995 9338 : static ivas_error requantize_direction_EC_3_fx(
3996 : Word16 *extra_bits,
3997 : IVAS_QDIRECTION *q_direction,
3998 : const Word16 coding_subbands,
3999 : BSTR_ENC_HANDLE hMetaData,
4000 : Word32 elevation_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22
4001 : Word32 azimuth_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22
4002 : Word16 *ind_order )
4003 : {
4004 : /* gradually increase the bits following the performance of the EC layer*/
4005 : Word16 j, k;
4006 : Word16 use_vq;
4007 : Word16 diff, allowed_bits, nbits, last_j;
4008 : Word16 no_subframes, start_band;
4009 : Word32 st_fx[MAX_PARAM_SPATIAL_SUBFRAMES], ct_fx[MAX_PARAM_SPATIAL_SUBFRAMES];
4010 :
4011 : Word16 *bits_dir0;
4012 :
4013 9338 : nbits = 0;
4014 9338 : move16();
4015 9338 : no_subframes = q_direction->cfg.nblocks;
4016 9338 : move16();
4017 9338 : start_band = q_direction->cfg.start_band;
4018 9338 : move16();
4019 :
4020 :
4021 9338 : IF( GT_16( q_direction->not_in_2D, MASA_LIMIT_2D ) )
4022 : {
4023 8838 : j = ind_order[coding_subbands - 1];
4024 8838 : move16();
4025 8838 : bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx;
4026 8838 : allowed_bits = sum_s( bits_dir0, no_subframes );
4027 8838 : last_j = sub( j, ( allowed_bits == 0 ) );
4028 8838 : diff = 0;
4029 8838 : move16();
4030 8838 : IF( EQ_16( coding_subbands, 1 ) )
4031 : {
4032 143 : last_j = start_band;
4033 143 : move16();
4034 : }
4035 36636 : FOR( j = 0; j < last_j; j++ )
4036 : {
4037 27798 : k = ind_order[j];
4038 27798 : move16();
4039 27798 : encode_directions_subband_fx( q_direction, coding_subbands, hMetaData, k, ind_order[j + 1], no_subframes, 0, &diff, elevation_orig_fx[k], azimuth_orig_fx[k] );
4040 : }
4041 :
4042 : /* last subbands to be written in fixed rate */
4043 23046 : FOR( j = last_j; j < coding_subbands; j++ )
4044 : {
4045 14208 : k = ind_order[j];
4046 14208 : move16();
4047 14208 : encode_directions_subband_fx( q_direction, coding_subbands, hMetaData, k, 0, no_subframes, 1, &diff, elevation_orig_fx[k], azimuth_orig_fx[k] );
4048 : }
4049 : }
4050 : ELSE /* 2D */
4051 : {
4052 500 : diff = 0;
4053 500 : nbits = 0;
4054 500 : move16();
4055 500 : move16();
4056 2199 : FOR( j = start_band; j < coding_subbands; j++ )
4057 : {
4058 1699 : bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx;
4059 1699 : move16();
4060 1699 : allowed_bits = sum_s( bits_dir0, no_subframes );
4061 1699 : move16();
4062 1699 : use_vq = 0;
4063 1699 : move16();
4064 6947 : FOR( k = 0; k < no_subframes; k++ )
4065 : {
4066 5248 : IF( GT_16( bits_dir0[k], use_vq ) )
4067 : {
4068 1988 : use_vq = bits_dir0[k];
4069 1988 : move16();
4070 : }
4071 : }
4072 :
4073 1699 : test();
4074 1699 : IF( LE_16( use_vq, 3 ) && LE_16( allowed_bits, 11 ) )
4075 : {
4076 :
4077 318 : set_val_Word32( st_fx, 0, no_subframes );
4078 :
4079 1335 : FOR( k = 0; k < no_subframes; k++ )
4080 : {
4081 : // ct[k] = cosf( elevation_orig[j][k] * PI_OVER_180 );
4082 1017 : ct_fx[k] = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( elevation_orig_fx[j][k], 91 ), 7 ) ) ) ); // Q31
4083 1017 : move32();
4084 : }
4085 :
4086 318 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
4087 : {
4088 : // nbits += truncGR0_chan( azimuth_orig[j], q_direction->band_data[j].azimuth, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st, ct );
4089 8 : nbits = add( nbits, truncGR0_chan_fx( /*azimuth_orig,*/ azimuth_orig_fx[j], /*q_direction->band_data[j].azimuth,*/ q_direction->band_data[j].azimuth_fx, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, /*st,*/ st_fx, /*ct,*/ ct_fx ) );
4090 : }
4091 : ELSE
4092 : {
4093 310 : nbits = add( nbits, truncGR0_fx( azimuth_orig_fx[j], q_direction->band_data[j].azimuth_fx, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st_fx, ct_fx ) );
4094 : }
4095 :
4096 318 : IF( LE_16( allowed_bits, add( no_subframes, 1 ) ) )
4097 : {
4098 148 : Word16 len = s_min( no_subframes, allowed_bits );
4099 701 : FOR( k = 0; k < len; k++ )
4100 : {
4101 553 : push_next_indice( hMetaData, q_direction->band_data[j].azimuth_index[k], 1 );
4102 : }
4103 : }
4104 : ELSE
4105 : {
4106 634 : FOR( k = 0; k < no_subframes; k++ )
4107 : {
4108 464 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ? 9 : 8, 0 );
4109 : }
4110 : }
4111 : }
4112 : ELSE
4113 : {
4114 5612 : FOR( k = 0; k < no_subframes; k++ )
4115 : {
4116 : /* requantize the direction */
4117 8462 : q_direction->band_data[j].spherical_index[k] = quantize_direction2D_fx( azimuth_orig_fx[j][k], 1 << q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].azimuth_fx[k],
4118 4231 : &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup );
4119 4231 : move16();
4120 4231 : q_direction->band_data[j].elevation_index[k] = 0;
4121 4231 : move16();
4122 : }
4123 1381 : nbits = add( nbits, write_fixed_rate_direction_fx( hMetaData, q_direction, j, no_subframes ) );
4124 : }
4125 : }
4126 : }
4127 :
4128 9338 : *extra_bits = -diff;
4129 9338 : move16();
4130 9338 : return IVAS_ERR_OK;
4131 : }
4132 :
4133 : /*-------------------------------------------------------------------*
4134 : * write_fixed_rate_direction()
4135 : *
4136 : * writing of the spherical indexes
4137 : *-------------------------------------------------------------------*/
4138 : /*! r: number of bits written */
4139 32147 : static Word16 write_fixed_rate_direction_fx(
4140 : BSTR_ENC_HANDLE hMetaData, /* i : MASA metadata structure */
4141 : IVAS_QDIRECTION *qdirection, /* i/o: quantized directional parameters */
4142 : const Word16 j_idx, /* i : index of subband for which the data is written */
4143 : const Word16 len /* i : number of data */
4144 : )
4145 : {
4146 : Word16 nbits, i;
4147 :
4148 32147 : nbits = 0;
4149 32147 : move16();
4150 102490 : FOR( i = 0; i < len; i++ )
4151 : {
4152 70343 : push_next_indice( hMetaData, qdirection->band_data[j_idx].spherical_index[i], qdirection->band_data[j_idx].bits_sph_idx[i] );
4153 70343 : nbits = extract_l( L_add( nbits, qdirection->band_data[j_idx].bits_sph_idx[i] ) );
4154 : }
4155 :
4156 32147 : return nbits;
4157 : }
4158 :
4159 : /*-------------------------------------------------------------------*
4160 : * joint_encoding()
4161 : *
4162 : * joint encoding of elevation and azimuth
4163 : *-------------------------------------------------------------------*/
4164 25395 : static void joint_encoding_fx(
4165 : IVAS_QDIRECTION *q_direction, /* i/o: quantized directional parameters */
4166 : const Word16 j, /* i : subband index */
4167 : const Word16 next_j, /* i : next subband index */
4168 : const Word16 coding_subbands, /* i : total number of subband */
4169 : Word16 *bits_dir0, /* i/o: number of bits for each tile in each subband */
4170 : const Word16 allowed_bits, /* i : maximum number of bits available for the current subband */
4171 : BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */
4172 : Word16 *diff /* o : bits to be given/taken to next subband */
4173 : )
4174 : {
4175 : Word16 k;
4176 : Word16 GR_ord_azimuth, use_context, GR_ord_elevation;
4177 : UWord8 method;
4178 : Word16 nbits;
4179 : Word16 same;
4180 : UWord16 data[MAX_PARAM_SPATIAL_SUBFRAMES];
4181 25395 : Word16 len_data = 0;
4182 25395 : move16();
4183 : Word16 no_symb_ele[MAX_PARAM_SPATIAL_SUBFRAMES];
4184 :
4185 88635 : FOR( k = 0; k < q_direction->cfg.nblocks; k++ )
4186 : {
4187 63240 : q_direction->band_data[j].bits_sph_idx[k] = bits_dir0[k];
4188 63240 : move16();
4189 :
4190 : /* requantize the direction */
4191 126480 : q_direction->band_data[j].spherical_index[k] = quantize_direction_fx( q_direction->band_data[j].elevation_fx[k], q_direction->band_data[j].azimuth_fx[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation_fx[k],
4192 63240 : &q_direction->band_data[j].azimuth_fx[k], &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup );
4193 :
4194 63240 : move16();
4195 63240 : IF( GE_32( bits_dir0[k], 3 ) )
4196 : {
4197 62976 : IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
4198 : {
4199 3619 : q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3];
4200 3619 : move16();
4201 3619 : q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[bits_dir0[k] - 1][q_direction->band_data[j].elevation_index[k]];
4202 3619 : move16();
4203 : }
4204 : ELSE
4205 : {
4206 59357 : q_direction->band_data[j].elevation_m_alphabet[k] = sub( shl( no_theta_masa[bits_dir0[k] - 3], 1 ), 1 );
4207 59357 : move16();
4208 59357 : q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[bits_dir0[k] - 1][( q_direction->band_data[j].elevation_index[k] + 1 ) >> 1];
4209 59357 : move16();
4210 : }
4211 62976 : assert( q_direction->band_data[j].elevation_index[k] != MASA_NO_INDEX );
4212 : }
4213 264 : ELSE IF( bits_dir0[k] > 0 )
4214 : {
4215 264 : q_direction->band_data[j].elevation_m_alphabet[k] = 1;
4216 264 : move16();
4217 264 : q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[bits_dir0[k] - 1][0];
4218 264 : move16();
4219 : }
4220 : ELSE
4221 : {
4222 0 : q_direction->band_data[j].elevation_m_alphabet[k] = 1;
4223 0 : move16();
4224 0 : q_direction->band_data[j].azimuth_m_alphabet[k] = 1;
4225 0 : move16();
4226 : }
4227 : }
4228 :
4229 88635 : FOR( k = 0; k < q_direction->cfg.nblocks; k++ )
4230 : {
4231 63240 : IF( LE_32( q_direction->band_data[j].bits_sph_idx[k], 2 ) )
4232 : {
4233 264 : q_direction->band_data[j].elevation_index[k] = MASA_NO_INDEX;
4234 264 : move16();
4235 : }
4236 : ELSE
4237 : {
4238 62976 : no_symb_ele[len_data] = q_direction->band_data[j].elevation_m_alphabet[k];
4239 62976 : move16();
4240 62976 : data[len_data++] = q_direction->band_data[j].elevation_index[k];
4241 62976 : move16();
4242 : }
4243 : }
4244 :
4245 :
4246 : /* encode indexes for current subband and count the number of bits */
4247 25395 : test();
4248 25395 : IF( EQ_16( q_direction->cfg.nblocks, 1 ) && LE_32( q_direction->band_data[j].bits_sph_idx[0], MASA_MIN_BITS_TF + 1 ) )
4249 : {
4250 : /* encode with fixed rate only if only one subframe and very low number of bits */
4251 6554 : nbits = write_fixed_rate_direction_fx( hMetaData, q_direction, j, q_direction->cfg.nblocks );
4252 : }
4253 : ELSE
4254 : {
4255 :
4256 18841 : IF( len_data > 0 )
4257 : {
4258 18841 : nbits = GR_bits_new_fx( data, no_symb_ele, len_data, MASA_GR_ORD_EL, 1, &GR_ord_elevation );
4259 : }
4260 : ELSE
4261 : {
4262 0 : nbits = 0;
4263 0 : move16();
4264 0 : GR_ord_elevation = MASA_GR_ORD_EL;
4265 0 : move16();
4266 : }
4267 :
4268 18841 : same = 1;
4269 18841 : move16();
4270 56686 : FOR( k = 1; k < q_direction->cfg.nblocks; k++ )
4271 : {
4272 37845 : if ( NE_32( q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].elevation_index[0] ) )
4273 : {
4274 9424 : same = 0;
4275 9424 : move16();
4276 : }
4277 : }
4278 18841 : test();
4279 18841 : IF( EQ_16( same, 1 ) && LT_32( q_direction->band_data[j].elevation_index[0], 4 ) )
4280 : {
4281 12574 : nbits = 3;
4282 12574 : move16();
4283 : }
4284 : ELSE
4285 : {
4286 6267 : same = 0;
4287 6267 : move16();
4288 6267 : nbits = add( nbits, 1 );
4289 : }
4290 :
4291 18841 : nbits = add( nbits, GR_bits_azimuth_context_fx( q_direction->band_data[j].azimuth_index,
4292 18841 : q_direction->band_data[j].azimuth_m_alphabet, q_direction->cfg.nblocks, MASA_GR_ORD_AZ,
4293 18841 : q_direction->band_data[j].bits_sph_idx, &GR_ord_azimuth, &use_context ) );
4294 :
4295 18841 : IF( allowed_bits == 0 )
4296 : {
4297 0 : nbits = 0;
4298 0 : move16();
4299 : }
4300 : ELSE
4301 : {
4302 18841 : IF( GE_16( nbits, allowed_bits ) )
4303 : {
4304 11082 : nbits = add( allowed_bits, 1 ); /* fixed rate encoding */
4305 11082 : method = 1;
4306 11082 : move16();
4307 11082 : push_next_indice( hMetaData, method, 1 );
4308 :
4309 : /* write current subband data */
4310 11082 : nbits = add( 1, write_fixed_rate_direction_fx( hMetaData, q_direction, j, q_direction->cfg.nblocks ) );
4311 : }
4312 : ELSE
4313 : {
4314 7759 : nbits = add( nbits, 1 ); /* EC coding */
4315 7759 : method = 0;
4316 7759 : move16();
4317 7759 : push_next_indice( hMetaData, method, 1 );
4318 :
4319 : /* write current subband data */
4320 7759 : write_ec_direction_fx( &nbits, hMetaData, q_direction, j, q_direction->cfg.nblocks, GR_ord_elevation, GR_ord_azimuth, use_context, same );
4321 7759 : nbits = add( nbits, 1 );
4322 : }
4323 : }
4324 : }
4325 25395 : *diff = add( *diff, sub( nbits, allowed_bits ) );
4326 25395 : move16();
4327 25395 : update_bits_next_block_fx( q_direction, diff, next_j, coding_subbands, q_direction->cfg.nblocks );
4328 :
4329 25395 : return;
4330 : }
4331 :
4332 : /*-------------------------------------------------------------------*
4333 : * calculate_two_distances()
4334 : *
4335 : * calculate estimated distortions if encoding with VQ or not
4336 : *-------------------------------------------------------------------*/
4337 3593 : static void calculate_two_distances_fx(
4338 : Word32 *el_fx, /* i : elevation values Q22 */
4339 : Word16 *bits, /* i : number of bits for each tile */
4340 : const Word16 total_bits, /* i : total number of bits for subband */
4341 : const Word16 len, /* i : number of tiles */
4342 : Word32 *p_d1, /* o : first distortion Q_out */
4343 : Word32 *p_d2, /* o : second distortion Q_out */
4344 : Word16 *Q_out )
4345 : {
4346 : Word16 i;
4347 : Word32 d1_fx, d2_fx, el_av_fx;
4348 3593 : const Word32 cos_delta_phi_cb_fx[] = { // Q31
4349 : 1821066112,
4350 : 1930158336,
4351 : 1991146880,
4352 : 2053638656,
4353 : 2092508032,
4354 : 2107969920,
4355 : 2121069568,
4356 : 2131377536
4357 : };
4358 3593 : move32();
4359 3593 : move32();
4360 3593 : move32();
4361 3593 : move32();
4362 3593 : move32();
4363 3593 : move32();
4364 3593 : move32();
4365 3593 : move32();
4366 : Word32 var_el_fx;
4367 3593 : d1_fx = 0;
4368 3593 : move32();
4369 3593 : d2_fx = 0;
4370 3593 : move32();
4371 : Word16 temp, temp1;
4372 : Word32 L_temp, L_temp1, L_temp2, L_temp3;
4373 3593 : Word16 gb = find_guarded_bits_fx( len );
4374 3593 : el_av_fx = L_shl( mean_no_sat_Word32_fx( el_fx, len, gb ), gb ); // Q22-gb
4375 3593 : IF( GT_16( total_bits, 9 ) )
4376 : {
4377 16510 : FOR( i = 0; i < len; i++ )
4378 : {
4379 13208 : IF( GT_16( bits[i], 2 ) )
4380 : {
4381 9173 : IF( LT_32( L_abs( el_fx[i] ), L_abs( ( L_sub( L_abs( el_fx[i] ), 188743680 ) ) ) ) ) // 188743680 = 45 in Q22
4382 : {
4383 : /* el_hat = 0*/
4384 6046 : IF( EQ_16( bits[i], 3 ) )
4385 : {
4386 : // d1 += 1 - 0.7f * cosf( el[i] * PI_OVER_180 );
4387 6046 : temp = getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ); // Q15
4388 6046 : d1_fx = L_add( d1_fx, L_shr( L_sub( ONE_IN_Q30, L_shr( Mpy_32_16_1( 1503238554, temp ), 1 ) ), gb ) ); // 1503238554 = 0.7 in Q31
4389 : // Q30-gb
4390 : }
4391 : ELSE
4392 : {
4393 : // d1 += 1 - 0.92f * cosf( el[i] * PI_OVER_180 );
4394 0 : temp = getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ); // Q15
4395 0 : d1_fx = L_add( d1_fx, L_shr( L_sub( ONE_IN_Q30, L_shr( Mpy_32_16_1( 1975684956, temp ), 1 ) ), gb ) ); // 1975684956 = 0.92 in Q31
4396 : // Q30-gb
4397 : }
4398 : }
4399 : ELSE
4400 : {
4401 3127 : IF( EQ_16( bits[i], 3 ) )
4402 : {
4403 : // d1 += 1 - sinf( el[i] * PI_OVER_180 ) * 0.7f * sign( el[i] );
4404 3127 : temp = getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ); // Q15
4405 3127 : d1_fx = L_add( d1_fx, L_shr( L_sub( ONE_IN_Q30, L_shr( Mpy_32_16_1( imult3216( 1503238554, sign_fx( el_fx[i] ) ), temp ), 1 ) ), gb ) ); // 1503238554 = 0.7 in Q31
4406 : // Q30-gb
4407 : }
4408 : ELSE
4409 : {
4410 : // d1 += 1 - 0.7f * 0.92f * cosf( el[i] * PI_OVER_180 ) - sinf( fabsf( el[i] * PI_OVER_180 ) ) * 0.7f;
4411 0 : temp = getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ); // Q15
4412 0 : temp1 = getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( L_abs( el_fx[i] ), 91 ), 7 ) ) ); // Q15
4413 0 : d1_fx = L_add( d1_fx, L_shr( L_sub( L_sub( ONE_IN_Q30, L_shr( Mpy_32_16_1( 1422493168, temp ), 1 ) ), L_shr( Mpy_32_16_1( 1503238554, temp1 ), 1 ) ), gb ) ); // 1422493168 = 0.92* 0.7 in Q31 ;1503238554 = 0.7 in Q31
4414 : // Q30-gb
4415 : }
4416 : }
4417 : }
4418 : ELSE
4419 : {
4420 4035 : IF( EQ_16( bits[i], 2 ) )
4421 : {
4422 : // d1 += 1 - cosf( el[i] * PI_OVER_180 ) * 0.7f;
4423 4035 : temp = getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ); // Q15
4424 4035 : d1_fx = L_add( d1_fx, L_shr( L_sub( ONE_IN_Q30, L_shr( Mpy_32_16_1( 1503238554, temp ), 1 ) ), gb ) ); // 1503238554 = 0.7 in Q31
4425 : // Q31-gb
4426 : }
4427 : ELSE
4428 : {
4429 : // d1 += 1;
4430 0 : d1_fx = L_add( d1_fx, L_shr( ONE_IN_Q30, gb ) );
4431 : }
4432 : }
4433 : // d2 += 1 - sinf( el_av * PI_OVER_180 ) * sinf( el[i] * PI_OVER_180 ) - cosf( el[i] * PI_OVER_180 ) * cosf( el_av * PI_OVER_180 ) * cos_delta_phi_cb[total_bits - 9];
4434 13208 : L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ) ); //*91/7 to convert angle in Q22 to radians
4435 : // Q15
4436 13208 : L_temp1 = L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ) );
4437 13208 : L_temp2 = L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( el_av_fx, 91 ), 7 ) ) ) );
4438 13208 : L_temp3 = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_av_fx, 91 ), 7 ) ) ) );
4439 : // temp1f = sinf( el_av * PI_OVER_180 ) * sinf( el[i] * PI_OVER_180 );
4440 : // L_temp4 = Mpy_32_32( L_temp2, L_temp1 );
4441 13208 : d2_fx = L_add( d2_fx, L_shr( L_sub( L_sub( ONE_IN_Q30, L_shr( Mpy_32_32( L_temp2, L_temp1 ), 1 ) ), L_shr( Mpy_32_32( Mpy_32_32( L_temp, L_temp3 ), cos_delta_phi_cb_fx[total_bits - 9] ), 1 ) ), gb ) ); // Q30-gb
4442 : }
4443 : }
4444 3593 : Word16 Qin = Q22;
4445 3593 : move16();
4446 : // var_el = var( el, len );
4447 3593 : var_el_fx = var_fx_32in_32out( el_fx, &Qin, len, gb );
4448 3593 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( var_el_fx, sub( 31, Qin ), 1300, 31 );
4449 3593 : if ( EQ_16( flag, 1 ) )
4450 : {
4451 : // d2 = d1 + 0.1f;
4452 112 : d2_fx = L_add( d1_fx, L_shr( 214748365, sub( Q31, sub( Q30, gb ) ) ) ); // 214748365 = 0.1f in Q31
4453 : }
4454 :
4455 3593 : *p_d1 = d1_fx;
4456 3593 : move32();
4457 3593 : *p_d2 = d2_fx;
4458 3593 : move32();
4459 3593 : *Q_out = sub( Q30, gb );
4460 3593 : move16();
4461 3593 : return;
4462 : }
4463 :
4464 : /*-------------------------------------------------------------------*
4465 : * write_ec_direction()
4466 : *
4467 : * write metadata using entropy encoding
4468 : *-------------------------------------------------------------------*/
4469 : /*! r: number of bits written */
4470 7759 : static ivas_error write_ec_direction_fx(
4471 : Word16 *num_bits_written, /* o : Number of bits written */
4472 : BSTR_ENC_HANDLE hMetaData, /* i : MASA metadata structure */
4473 : IVAS_QDIRECTION *qdirection, /* i : quantized directional info */
4474 : const Word16 j_idx, /* i : index of subband to encode and write */
4475 : const Word16 len, /* i : number of tiles */
4476 : const Word16 GR_ord_elevation, /* i : GR order for elevation encoding */
4477 : const Word16 GR_ord_azimuth, /* i : GR order for azimuth encoding */
4478 : const Word16 use_context, /* i : flag for context usiage in azimuth encoding */
4479 : const Word16 same /* i : flag if elevation indexes are the same or not */
4480 : )
4481 : {
4482 : Word16 i, nbits, bits_crt, nr_NO_INDEX;
4483 : UWord16 data;
4484 : Word16 min_val, max_val;
4485 :
4486 7759 : nr_NO_INDEX = 0;
4487 7759 : move16();
4488 7759 : nbits = 0;
4489 7759 : move16();
4490 : /* write elevation */
4491 38537 : FOR( i = 0; i < len; i++ )
4492 : {
4493 30778 : data = qdirection->band_data[j_idx].elevation_index[i];
4494 30778 : test();
4495 30778 : if ( EQ_32( data, MASA_NO_INDEX ) || ( qdirection->band_data[j_idx].bits_sph_idx[i] == 0 ) )
4496 : {
4497 3 : nr_NO_INDEX = add( nr_NO_INDEX, 1 );
4498 : }
4499 : }
4500 :
4501 7759 : IF( LT_16( nr_NO_INDEX, len ) )
4502 : {
4503 7759 : IF( EQ_16( same, 1 ) )
4504 : {
4505 6021 : push_next_indice( hMetaData, 1, 1 );
4506 6021 : nbits = add( nbits, 1 );
4507 6021 : push_next_indice( hMetaData, qdirection->band_data[j_idx].elevation_index[0], 2 );
4508 6021 : nbits = add( nbits, 2 );
4509 : }
4510 : ELSE
4511 : {
4512 1738 : push_next_indice( hMetaData, 0, 1 );
4513 1738 : nbits = add( nbits, 1 );
4514 :
4515 1738 : push_next_indice( hMetaData, sub( 1, (Word16) EQ_16( GR_ord_elevation, MASA_GR_ORD_EL ) ), 1 );
4516 1738 : nbits = add( nbits, 1 );
4517 :
4518 8690 : FOR( i = 0; i < len; i++ )
4519 : {
4520 6952 : data = qdirection->band_data[j_idx].elevation_index[i];
4521 6952 : IF( LT_32( data, MASA_NO_INDEX ) )
4522 : {
4523 6949 : bits_crt = hMetaData->nb_bits_tot;
4524 6949 : move16();
4525 6949 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, data, qdirection->band_data[j_idx].elevation_m_alphabet[i], GR_ord_elevation );
4526 6949 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) );
4527 : }
4528 : }
4529 : }
4530 : }
4531 :
4532 : /* write azimuth */
4533 7759 : IF( use_context < 0 )
4534 : {
4535 7759 : IF( EQ_16( use_context, -1 ) )
4536 : {
4537 : /* regular GR coding */
4538 2530 : push_next_indice( hMetaData, 0, 1 );
4539 2530 : nbits = add( nbits, 1 );
4540 2530 : push_next_indice( hMetaData, sub( 1, (Word16) EQ_16( GR_ord_azimuth, MASA_GR_ORD_AZ ) ), 1 );
4541 2530 : nbits = add( nbits, 1 );
4542 :
4543 12392 : FOR( i = 0; i < len; i++ )
4544 : {
4545 9862 : data = qdirection->band_data[j_idx].azimuth_index[i];
4546 9862 : IF( LT_32( data, MASA_NO_INDEX ) )
4547 : {
4548 9860 : bits_crt = hMetaData->nb_bits_tot;
4549 9860 : move16();
4550 9860 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], GR_ord_azimuth );
4551 9860 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) );
4552 : }
4553 : }
4554 : }
4555 5229 : ELSE IF( EQ_16( use_context, -2 ) )
4556 : {
4557 : /* min removed GR coding */
4558 5229 : push_next_indice( hMetaData, 1, 1 );
4559 5229 : nbits = add( nbits, 1 );
4560 5229 : push_next_indice( hMetaData, sub( 1, (Word16) EQ_16( GR_ord_azimuth, sub( MASA_GR_ORD_AZ, 1 ) ) ), 1 );
4561 5229 : nbits = add( nbits, 1 );
4562 :
4563 : /* find min */
4564 5229 : min_val = MASA_NO_INDEX;
4565 5229 : move16();
4566 26145 : FOR( i = 0; i < len; i++ )
4567 : {
4568 20916 : if ( LT_32( qdirection->band_data[j_idx].azimuth_index[i], min_val ) )
4569 : {
4570 6733 : min_val = qdirection->band_data[j_idx].azimuth_index[i];
4571 6733 : move16();
4572 : }
4573 : }
4574 :
4575 :
4576 : /* write min*/
4577 5229 : bits_crt = hMetaData->nb_bits_tot;
4578 5229 : move16();
4579 5229 : maximum_s( qdirection->band_data[j_idx].azimuth_m_alphabet, len, &max_val );
4580 5229 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, min_val, max_val, MASA_GR_ORD_AZ );
4581 5229 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) );
4582 :
4583 26145 : FOR( i = 0; i < len; i++ )
4584 : {
4585 20916 : data = (UWord16) L_sub( qdirection->band_data[j_idx].azimuth_index[i], min_val );
4586 20916 : IF( LT_32( data, sub( MASA_NO_INDEX, min_val ) ) )
4587 : {
4588 20916 : bits_crt = hMetaData->nb_bits_tot;
4589 20916 : move16();
4590 20916 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], GR_ord_azimuth );
4591 20916 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) );
4592 : }
4593 : }
4594 : }
4595 : }
4596 : ELSE
4597 : {
4598 0 : FOR( i = 0; i < len; i++ )
4599 : {
4600 0 : data = qdirection->band_data[j_idx].azimuth_index[i];
4601 0 : IF( LT_32( data, MASA_NO_INDEX ) )
4602 : {
4603 0 : SWITCH( qdirection->band_data[j_idx].bits_sph_idx[i] )
4604 : {
4605 0 : case 0:
4606 0 : BREAK;
4607 0 : case 1:
4608 0 : nbits = add( nbits, 1 );
4609 0 : push_next_indice( hMetaData, data, 1 );
4610 0 : BREAK;
4611 0 : case 2:
4612 0 : bits_crt = hMetaData->nb_bits_tot;
4613 0 : move16();
4614 0 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], MASA_GR_ORD_AZ - 1 );
4615 0 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) );
4616 0 : BREAK;
4617 0 : default:
4618 0 : bits_crt = hMetaData->nb_bits_tot;
4619 0 : move16();
4620 0 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], MASA_GR_ORD_AZ );
4621 0 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) );
4622 0 : BREAK;
4623 : }
4624 0 : }
4625 : }
4626 : }
4627 :
4628 7759 : *num_bits_written = nbits;
4629 7759 : move16();
4630 7759 : return IVAS_ERR_OK;
4631 : }
4632 :
4633 : /*-----------------------------------------------------------------------*
4634 : * Local functions (coherence Q and coding)
4635 : *-----------------------------------------------------------------------*/
4636 : /*! r: index */
4637 34134 : static UWord64 create_combined_index_fx(
4638 : UWord16 *idx_dct, /* i : indexes to combine */
4639 : const Word16 len, /* i : number of indexes */
4640 : const Word16 *no_cb_vec /* i : how many codewords for each position */
4641 : )
4642 : {
4643 : Word16 i;
4644 : UWord64 idx, base;
4645 :
4646 34134 : base = 1;
4647 34134 : move64();
4648 34134 : idx = 0;
4649 34134 : move64();
4650 238281 : FOR( i = 0; i < len; i++ )
4651 : {
4652 204147 : idx = W_add( idx, base * idx_dct[i] );
4653 204147 : base *= no_cb_vec[i];
4654 : }
4655 :
4656 34134 : return idx;
4657 : }
4658 :
4659 : /*-----------------------------------------------------------------------*
4660 : * encoding DCT0 coeffs with joint index
4661 : *-----------------------------------------------------------------------*/
4662 : /*! r: number of bits written */
4663 23095 : static Word16 encode_coherence_indexesDCT0_fx(
4664 : UWord16 *idx_dct, /* i : indexes to be encoded */
4665 : const Word16 len, /* i : number of indexes */
4666 : Word16 *no_cb_vec, /* i : number of codewords for each position */
4667 : BSTR_ENC_HANDLE hMetaData,
4668 : const Word16 indice_coherence,
4669 : const Word16 nbits,
4670 : const Word16 nbits1 )
4671 : {
4672 : Word16 i;
4673 : UWord64 idx;
4674 : Word16 no_idx16;
4675 : Word16 k;
4676 : Word16 half_len, j;
4677 : UWord64 idx1;
4678 :
4679 : /* calculate bits for dct0 components with joint encoding */
4680 23095 : IF( nbits1 > 0 )
4681 : {
4682 174 : half_len = shr( len, 1 );
4683 174 : idx = create_combined_index_fx( idx_dct, half_len, no_cb_vec );
4684 174 : idx1 = create_combined_index_fx( &idx_dct[half_len], half_len, &no_cb_vec[half_len] );
4685 : }
4686 : ELSE
4687 : {
4688 22921 : idx = create_combined_index_fx( idx_dct, len, no_cb_vec );
4689 22921 : idx1 = 0;
4690 22921 : move16();
4691 : }
4692 :
4693 : // if ( nbits % 16 == 0 )
4694 23095 : IF( s_and( nbits, 15 ) == 0 )
4695 : {
4696 310 : no_idx16 = shr( nbits, 4 );
4697 : }
4698 : ELSE
4699 : {
4700 : // no_idx16 = (Word16) round_f( ( nbits / 16.0f + 0.5f ) );
4701 22785 : no_idx16 = shr_r( add( nbits, ONE_IN_Q3 ), 4 );
4702 : }
4703 :
4704 23095 : k = nbits;
4705 23095 : move16();
4706 23095 : i = 0;
4707 23095 : move16();
4708 27206 : FOR( i = 0; i < no_idx16 - 1; i++ )
4709 : {
4710 4111 : k = sub( k, 16 );
4711 4111 : hMetaData->ind_list[indice_coherence + i].value = ( ( idx >> k ) & 65535 ); /* 16 bits */
4712 4111 : move16();
4713 : }
4714 23095 : hMetaData->ind_list[indice_coherence + i].value = ( idx & ( ( 1 << k ) - 1 ) );
4715 23095 : move16();
4716 :
4717 23095 : IF( nbits1 > 0 )
4718 : {
4719 : // if ( nbits1 % 16 == 0 )
4720 174 : IF( s_and( nbits1, 15 ) == 0 )
4721 : {
4722 0 : no_idx16 = shr( nbits1, 4 );
4723 : }
4724 : ELSE
4725 : {
4726 : // no_idx16 = (Word16) round_f( ( nbits1 / 16.0f + 0.5f ) );
4727 174 : no_idx16 = shr_r( add( nbits1, ONE_IN_Q3 ), 4 );
4728 : }
4729 :
4730 174 : k = nbits1;
4731 174 : move16();
4732 :
4733 348 : FOR( j = i + 1; j < no_idx16 + i; j++ )
4734 : {
4735 174 : k = sub( k, 16 );
4736 174 : hMetaData->ind_list[indice_coherence + j].value = ( ( idx1 >> k ) & 65535 ); /* 16 bits */
4737 174 : move16();
4738 : }
4739 174 : hMetaData->ind_list[indice_coherence + j].value = ( idx1 & ( ( 1 << k ) - 1 ) );
4740 174 : move16();
4741 : }
4742 :
4743 23095 : return add( nbits, nbits1 );
4744 : }
4745 :
4746 : /*-------------------------------------------------------------------*
4747 : * coherence_coding_length()
4748 : *
4749 : *
4750 : *-------------------------------------------------------------------*/
4751 42720 : static Word16 coherence_coding_length(
4752 : const UWord16 *idx_sur_coh_shift,
4753 : const UWord8 idx_shift_len,
4754 : const Word16 coding_subbands,
4755 : const Word16 *no_cv,
4756 : UWord16 *mr_idx,
4757 : Word16 *no_cv_shift,
4758 : Word16 *p_min_idx,
4759 : Word16 *GR_ord,
4760 : Word16 *nbits_fr,
4761 : Word16 *nbits_fr1 )
4762 : {
4763 : Word16 half_coding_subbands;
4764 : Word16 j;
4765 : Word16 nbits;
4766 : UWord64 no_cb;
4767 : Word16 min_idx;
4768 :
4769 42720 : half_coding_subbands = 0;
4770 42720 : move16();
4771 :
4772 42720 : IF( GT_16( sum16_fx( no_cv, coding_subbands ), MASA_COH_LIMIT_2IDX ) )
4773 : {
4774 :
4775 2745 : no_cb = 1;
4776 2745 : move16();
4777 2745 : half_coding_subbands = shr( coding_subbands, 1 );
4778 2745 : move16();
4779 35042 : FOR( j = 0; j < half_coding_subbands; j++ )
4780 : {
4781 32297 : no_cb = no_cb * no_cv[j];
4782 : }
4783 : //*nbits_fr = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
4784 2745 : IF( LE_64( no_cb, 1 ) )
4785 : {
4786 0 : *nbits_fr = 0;
4787 : }
4788 : ELSE
4789 : {
4790 2745 : *nbits_fr = sub( 63, W_norm( W_sub( no_cb, 1 ) ) );
4791 : }
4792 2745 : move16();
4793 2745 : no_cb = 1;
4794 2745 : move16();
4795 35166 : FOR( j = half_coding_subbands; j < coding_subbands; j++ )
4796 : {
4797 32421 : no_cb = no_cb * no_cv[j];
4798 : }
4799 : //*nbits_fr1 = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
4800 2745 : IF( LE_64( no_cb, 1 ) )
4801 : {
4802 0 : *nbits_fr1 = 0;
4803 : }
4804 : ELSE
4805 : {
4806 2745 : *nbits_fr1 = sub( 63, W_norm( W_sub( no_cb, 1 ) ) );
4807 : }
4808 2745 : move16();
4809 : }
4810 : ELSE
4811 : {
4812 39975 : no_cb = 1;
4813 435931 : FOR( j = 0; j < coding_subbands; j++ )
4814 : {
4815 395956 : no_cb = no_cb * no_cv[j];
4816 : }
4817 : //*nbits_fr = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
4818 39975 : IF( LE_64( no_cb, 1 ) )
4819 : {
4820 292 : *nbits_fr = 0;
4821 : }
4822 : ELSE
4823 : {
4824 39683 : *nbits_fr = sub( 63, W_norm( W_sub( no_cb, 1 ) ) );
4825 : }
4826 39975 : move16();
4827 39975 : *nbits_fr1 = 0;
4828 39975 : move16();
4829 : }
4830 :
4831 :
4832 42720 : minimum_s( (const Word16 *) idx_sur_coh_shift, (Word16) idx_shift_len, &min_idx );
4833 501293 : FOR( j = 0; j < idx_shift_len; j++ )
4834 : {
4835 458573 : mr_idx[j] = sub( idx_sur_coh_shift[j], min_idx );
4836 458573 : move16();
4837 458573 : no_cv_shift[j] = sub( no_cv_shift[j], min_idx );
4838 458573 : move16();
4839 : }
4840 42720 : nbits = add( add( min_idx, 1 ), GR_bits_new_fx( mr_idx, no_cv_shift, idx_shift_len, *GR_ord, 1, GR_ord ) );
4841 42720 : *p_min_idx = min_idx;
4842 42720 : move16();
4843 :
4844 42720 : return nbits;
4845 : }
4846 :
4847 : /*-------------------------------------------------------------------*
4848 : * encode_spread_coherence_1sf()
4849 : *
4850 : * Encoding spread coherence for 1 subframe bands
4851 : *-------------------------------------------------------------------*/
4852 : /*! r: number of bits written */
4853 8168 : static Word16 encode_spread_coherence_1sf_fx(
4854 : IVAS_QMETADATA *q_metadata, /* i : quantized metadata */
4855 : const Word16 idx_d, /* i : current direction index */
4856 : BSTR_ENC_HANDLE hMasaMetaData, /* i/o: metadata bitstream handle */
4857 : const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */
4858 : )
4859 : {
4860 : Word16 i, j, k;
4861 : Word16 idx_ER;
4862 : Word16 nbits, nbits_fr;
4863 : UWord16 idx_sp_coh[MASA_MAXIMUM_CODING_SUBBANDS]; // Q15
4864 : UWord16 mr_idx_sp_coh[MASA_MAXIMUM_CODING_SUBBANDS];
4865 : Word16 GR_ord, bits_GR;
4866 : UWord64 idx, idx1;
4867 : Word16 no_idx16;
4868 : Word16 no_cv[MASA_MAXIMUM_CODING_SUBBANDS];
4869 : IVAS_QDIRECTION *q_direction;
4870 : Word16 half_coding_subbands, nbits_fr1, coding_subbands;
4871 : UWord16 idx_sp_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS];
4872 : UWord8 idx_shift;
4873 8168 : Word16 max_val = 0, nbits_max;
4874 8168 : move16();
4875 : Word16 extra_cv;
4876 : Word16 no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx;
4877 :
4878 8168 : coding_subbands = q_metadata->q_direction[idx_d].cfg.nbands;
4879 8168 : move16();
4880 8168 : q_direction = &( q_metadata->q_direction[idx_d] );
4881 8168 : nbits = 0;
4882 8168 : move16();
4883 8168 : GR_ord = 1;
4884 8168 : move16();
4885 8168 : idx_shift = 0;
4886 8168 : move16();
4887 :
4888 : /* number of codevectors added dependent on number of subbands */
4889 : // extra_cv = coding_subbands / MASA_FACTOR_CV_COH;
4890 8168 : Word16 tmp = 0;
4891 8168 : move16();
4892 8168 : extra_cv = -1;
4893 8168 : move16();
4894 21610 : WHILE( ( tmp <= coding_subbands ) )
4895 : {
4896 13442 : tmp = add( tmp, 6 );
4897 13442 : extra_cv = add( extra_cv, 1 );
4898 : }
4899 69576 : FOR( j = 0; j < coding_subbands; j++ )
4900 : {
4901 61408 : IF( hrmasa_flag )
4902 : {
4903 0 : idx_ER = add( sub( 7, shr( q_direction->band_data[j].energy_ratio_index_mod[0], 1 ) ), extra_cv );
4904 : }
4905 : ELSE
4906 : {
4907 61408 : idx_ER = add( sub( 7, q_direction->band_data[j].energy_ratio_index_mod[0] ), extra_cv );
4908 : }
4909 :
4910 61408 : IF( idx_ER > 0 )
4911 : {
4912 : // idx_sp_coh[j] = (uint16_t) roundf( q_direction->coherence_band_data[j].spread_coherence[0] / ( 255.0f / (float) idx_ER ) );
4913 48297 : idx_sp_coh[j] = extract_l( Mpy_32_32_r( imult1616( q_direction->coherence_band_data[j].spread_coherence[0], idx_ER ), 8421505 /* 1/255.f in Q31 */ ) );
4914 48297 : move16();
4915 : // q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) roundf( idx_sp_coh[j] * ( 255.0f / (float) idx_ER ) );
4916 48297 : IF( idx_sp_coh[j] )
4917 : {
4918 22753 : q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) idiv1616( imult1616( idx_sp_coh[j], 255 ), idx_ER );
4919 22753 : move16();
4920 : }
4921 : ELSE
4922 : {
4923 25544 : q_direction->coherence_band_data[j].spread_coherence[0] = 0;
4924 25544 : move16();
4925 : }
4926 : }
4927 : ELSE
4928 : {
4929 13111 : idx_sp_coh[j] = 0;
4930 13111 : move16();
4931 13111 : q_direction->coherence_band_data[j].spread_coherence[0] = 0;
4932 13111 : move16();
4933 : }
4934 61408 : no_cv[j] = add( idx_ER, 1 );
4935 61408 : move16();
4936 :
4937 61408 : no_cv_shift[idx_shift] = no_cv[j];
4938 61408 : move16();
4939 61408 : idx_sp_coh_shift[idx_shift++] = idx_sp_coh[j];
4940 61408 : move16();
4941 : }
4942 :
4943 8168 : IF( EQ_16( sum16_fx( no_cv, coding_subbands ), coding_subbands ) )
4944 : {
4945 621 : return 0;
4946 : }
4947 :
4948 7547 : nbits_max = 0;
4949 7547 : move16();
4950 7547 : IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) )
4951 : {
4952 1962 : j = maximum_s( (Word16 *) idx_sp_coh, coding_subbands, &max_val );
4953 33582 : FOR( j = 0; j < coding_subbands; j++ )
4954 : {
4955 31620 : IF( GT_16( no_cv[j], add( max_val, 1 ) ) )
4956 : {
4957 30477 : no_cv[j] = add( max_val, 1 );
4958 30477 : move16();
4959 : }
4960 : }
4961 1962 : nbits_max = add( sub( MASA_MAX_NO_CV_SUR_COH, max_val ), extra_cv );
4962 : }
4963 :
4964 7547 : nbits = coherence_coding_length( idx_sp_coh_shift, idx_shift, coding_subbands, no_cv,
4965 : mr_idx_sp_coh, no_cv_shift, &min_idx, &GR_ord, &nbits_fr, &nbits_fr1 );
4966 7547 : half_coding_subbands = 0;
4967 7547 : move16();
4968 7547 : idx1 = 0;
4969 7547 : move16();
4970 :
4971 7547 : IF( LT_16( add( add( nbits_fr, nbits_fr1 ), nbits_max ), nbits ) )
4972 : {
4973 : /* write flag*/
4974 4976 : push_next_indice( hMasaMetaData, 0, 1 );
4975 :
4976 : /* create combined index */
4977 4976 : nbits = add( add( nbits_fr, nbits_fr1 ), 1 );
4978 :
4979 4976 : IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) )
4980 : {
4981 : /* write max value*/
4982 179 : bits_GR = hMasaMetaData->nb_bits_tot;
4983 179 : move16();
4984 179 : ivas_qmetadata_encode_extended_gr_fx( hMasaMetaData, add( sub( sub( MASA_MAX_NO_CV_SUR_COH, max_val ), 1 ), extra_cv ), add( MASA_MAX_NO_CV_SUR_COH, extra_cv ), 0 );
4985 179 : nbits = add( nbits, sub( hMasaMetaData->nb_bits_tot, bits_GR ) );
4986 : }
4987 :
4988 4976 : IF( nbits_fr1 > 0 )
4989 : {
4990 24 : half_coding_subbands = shr( coding_subbands, 1 );
4991 24 : idx = create_combined_index_fx( idx_sp_coh, half_coding_subbands, no_cv );
4992 24 : idx1 = create_combined_index_fx( &idx_sp_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] );
4993 : }
4994 : ELSE
4995 : {
4996 4952 : idx = create_combined_index_fx( idx_sp_coh, coding_subbands, no_cv );
4997 : }
4998 :
4999 : // if ( nbits_fr % 16 == 0 )
5000 4976 : IF( s_and( nbits_fr, 15 ) == 0 )
5001 : {
5002 88 : no_idx16 = shr( nbits_fr, 4 );
5003 : }
5004 : ELSE
5005 : {
5006 : // no_idx16 = (Word16) round_f( ( nbits_fr / 16.0f + 0.5f ) );
5007 4888 : no_idx16 = shr_r( add( nbits_fr, ONE_IN_Q3 ), 4 );
5008 : }
5009 :
5010 : /* write combined index */
5011 4976 : k = nbits_fr;
5012 4976 : move16();
5013 5093 : FOR( i = 0; i < no_idx16 - 1; i++ )
5014 : {
5015 117 : k = sub( k, 16 );
5016 117 : push_next_indice( hMasaMetaData, ( ( idx >> k ) & 65535 ), 16 ); /* 16 bits */
5017 : }
5018 :
5019 4976 : push_next_indice( hMasaMetaData, ( idx & ( ( 1 << k ) - 1 ) ), k );
5020 :
5021 4976 : IF( nbits_fr1 > 0 )
5022 : {
5023 : // if ( nbits_fr1 % 16 == 0 )
5024 24 : IF( s_and( nbits_fr1, 15 ) == 0 )
5025 : {
5026 0 : no_idx16 = shr( nbits_fr1, 4 );
5027 : }
5028 : ELSE
5029 : {
5030 : // no_idx16 = (Word16) round_f( ( nbits_fr1 / 16.0f + 0.5f ) );
5031 24 : no_idx16 = shr_r( add( nbits_fr1, ONE_IN_Q3 ), 4 );
5032 : }
5033 :
5034 24 : assert( no_idx16 <= 4 );
5035 :
5036 24 : k = nbits_fr1;
5037 24 : move16();
5038 56 : FOR( i = 0; i < no_idx16 - 1; i++ )
5039 : {
5040 32 : k = sub( k, 16 );
5041 32 : push_next_indice( hMasaMetaData, ( ( idx1 >> k ) & 65535 ), 16 ); /* 16 bits */
5042 : }
5043 24 : push_next_indice( hMasaMetaData, ( idx1 & ( ( 1 << k ) - 1 ) ), k );
5044 : }
5045 : }
5046 : ELSE
5047 : {
5048 : /* write flag */
5049 2571 : nbits = 1;
5050 2571 : move16();
5051 :
5052 : /* write flag*/
5053 2571 : push_next_indice( hMasaMetaData, 1, 1 );
5054 :
5055 : /* write GR_ord */
5056 2571 : push_next_indice( hMasaMetaData, GR_ord, 1 );
5057 2571 : nbits = add( nbits, 1 );
5058 :
5059 : /* write the min */
5060 2571 : bits_GR = hMasaMetaData->nb_bits_tot;
5061 2571 : move16();
5062 2571 : ivas_qmetadata_encode_extended_gr_fx( hMasaMetaData, min_idx, add( MASA_MAX_NO_CV_SUR_COH, extra_cv ), 0 );
5063 2571 : nbits = add( nbits, sub( hMasaMetaData->nb_bits_tot, bits_GR ) );
5064 :
5065 : /* write GR data */
5066 35032 : FOR( j = 0; j < idx_shift; j++ )
5067 : {
5068 32461 : bits_GR = hMasaMetaData->nb_bits_tot;
5069 32461 : move16();
5070 32461 : ivas_qmetadata_encode_extended_gr_fx( hMasaMetaData, mr_idx_sp_coh[j], no_cv_shift[j], GR_ord );
5071 32461 : nbits = add( nbits, sub( hMasaMetaData->nb_bits_tot, bits_GR ) );
5072 : }
5073 : }
5074 :
5075 7547 : return nbits;
5076 : }
5077 :
5078 : /*-------------------------------------------------------------------*
5079 : * encode_surround_coherence()
5080 : *
5081 : * encoding surround coherence
5082 : *-------------------------------------------------------------------*/
5083 :
5084 : /*! r: number of bits written */
5085 26519 : static Word16 encode_surround_coherence_fx(
5086 : IVAS_QMETADATA *hQMetaData, /* i : quantized metadata */
5087 : BSTR_ENC_HANDLE hMetaData /* i/o: metadata bitstream handle */
5088 : )
5089 : {
5090 : Word16 i, j, k;
5091 : Word16 idx_ER, idx16;
5092 : Word16 nbits, nbits_fr;
5093 : UWord16 idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
5094 : UWord16 mr_idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
5095 : Word16 GR_ord, bits_GR;
5096 : UWord64 idx, idx1;
5097 : Word16 no_idx16;
5098 : Word16 no_cv[MASA_MAXIMUM_CODING_SUBBANDS];
5099 : Word32 error_ratio_surr; // Q30
5100 : IVAS_QDIRECTION *q_direction;
5101 : Word16 half_coding_subbands, nbits_fr1, coding_subbands;
5102 : Word16 all_coherence_zero;
5103 : UWord16 idx_sur_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS];
5104 : UWord8 idx_shift;
5105 26519 : Word16 max_val = 0, nbits_max;
5106 26519 : move16();
5107 : Word16 no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx;
5108 :
5109 26519 : coding_subbands = hQMetaData->q_direction[0].cfg.nbands;
5110 26519 : move16();
5111 26519 : all_coherence_zero = hQMetaData->all_coherence_zero;
5112 26519 : move16();
5113 26519 : q_direction = &( hQMetaData->q_direction[0] );
5114 26519 : nbits = 0;
5115 26519 : move16();
5116 :
5117 26519 : IF( EQ_16( all_coherence_zero, 1 ) )
5118 : {
5119 0 : nbits = 0;
5120 0 : move16();
5121 : }
5122 : ELSE
5123 : {
5124 26519 : GR_ord = 1;
5125 26519 : move16();
5126 26519 : k = 0;
5127 26519 : move16();
5128 26519 : idx_shift = 0;
5129 26519 : move16();
5130 221629 : FOR( j = 0; j < coding_subbands; j++ )
5131 : {
5132 195110 : IF( EQ_16( hQMetaData->no_directions, 2 ) )
5133 : {
5134 39552 : k = add( k, hQMetaData->twoDirBands[j] );
5135 39552 : idx16 = s_max( sub( k, 1 ), 0 );
5136 39552 : error_ratio_surr = W_sat_l( W_sub( W_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ), W_mult0_32_32( q_direction[1].band_data[idx16].energy_ratio_fx[0], hQMetaData->twoDirBands[j] ) ) ); // Q30
5137 : }
5138 : ELSE
5139 : {
5140 155558 : error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ); // Q30
5141 : }
5142 :
5143 195110 : IF( error_ratio_surr <= 0 )
5144 : {
5145 457 : error_ratio_surr = 0;
5146 457 : move16();
5147 457 : idx_sur_coh[j] = 0;
5148 457 : move16();
5149 457 : no_cv[j] = 1;
5150 457 : move16();
5151 457 : hQMetaData->surcoh_band_data[j].surround_coherence[0] = 0; /* sur_coherence_cb_masa[idx_cb_sur_coh_masa[DIRAC_DIFFUSE_LEVELS - 1] * MASA_MAX_NO_CV_SUR_COH]; */
5152 457 : move16();
5153 : }
5154 : ELSE
5155 : {
5156 194653 : idx_ER = masa_sq_fx( error_ratio_surr, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS );
5157 :
5158 389306 : idx_sur_coh[j] = squant_int_fx( hQMetaData->surcoh_band_data[j].surround_coherence[0], &hQMetaData->surcoh_band_data[j].surround_coherence[0],
5159 194653 : &sur_coherence_cb_masa[idx_cb_sur_coh_masa[idx_ER] * MASA_MAX_NO_CV_SUR_COH], add( idx_cb_sur_coh_masa[idx_ER], 2 ) );
5160 194653 : move16();
5161 :
5162 194653 : no_cv[j] = add( idx_cb_sur_coh_masa[idx_ER], 2 );
5163 194653 : move16();
5164 194653 : no_cv_shift[idx_shift] = no_cv[j];
5165 194653 : move16();
5166 194653 : idx_sur_coh_shift[idx_shift++] = idx_sur_coh[j];
5167 194653 : move16();
5168 : }
5169 : }
5170 :
5171 26519 : IF( EQ_16( sum16_fx( no_cv, coding_subbands ), coding_subbands ) )
5172 : {
5173 0 : return 0;
5174 : }
5175 :
5176 26519 : nbits_max = 0;
5177 26519 : move16();
5178 26519 : IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) )
5179 : {
5180 4855 : j = maximum_s( (Word16 *) idx_sur_coh, coding_subbands, &max_val );
5181 89707 : FOR( j = 0; j < coding_subbands; j++ )
5182 : {
5183 84852 : IF( GT_16( no_cv[j], add( max_val, 1 ) ) )
5184 : {
5185 70940 : no_cv[j] = add( max_val, 1 );
5186 70940 : move16();
5187 : }
5188 : }
5189 4855 : nbits_max = sub( MASA_MAX_NO_CV_SUR_COH, max_val ); /* encoded with GR0 as max_no_vals - no_vals*/
5190 : }
5191 :
5192 26519 : nbits = coherence_coding_length( idx_sur_coh_shift, idx_shift, coding_subbands, no_cv,
5193 : mr_idx_sur_coh, no_cv_shift, &min_idx, &GR_ord, &nbits_fr, &nbits_fr1 );
5194 26519 : half_coding_subbands = shr( coding_subbands, 1 );
5195 26519 : idx1 = 0;
5196 26519 : move16();
5197 :
5198 : /* should check how to encode the average - check distribution */
5199 26519 : IF( LT_16( add( add( nbits_fr, nbits_fr1 ), nbits_max ), nbits ) )
5200 : {
5201 : /* write flag*/
5202 5580 : push_next_indice( hMetaData, 0, 1 );
5203 :
5204 : /* create combined index */
5205 5580 : nbits = add( add( nbits_fr, nbits_fr1 ), 1 );
5206 5580 : IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) )
5207 : {
5208 : /* write max value*/
5209 321 : bits_GR = hMetaData->nb_bits_tot;
5210 321 : move16();
5211 321 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( MASA_MAX_NO_CV_SUR_COH - 1, max_val ), MASA_MAX_NO_CV_SUR_COH, 0 );
5212 321 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) );
5213 : }
5214 :
5215 5580 : IF( nbits_fr1 > 0 )
5216 : {
5217 40 : idx = create_combined_index_fx( idx_sur_coh, half_coding_subbands, no_cv );
5218 40 : idx1 = create_combined_index_fx( &idx_sur_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] );
5219 : }
5220 : ELSE
5221 : {
5222 5540 : idx = create_combined_index_fx( idx_sur_coh, coding_subbands, no_cv );
5223 : }
5224 :
5225 : // if ( nbits_fr % 16 == 0 )
5226 5580 : IF( s_and( nbits_fr, 15 ) == 0 )
5227 : {
5228 207 : no_idx16 = shr( nbits_fr, 4 );
5229 : }
5230 : ELSE
5231 : {
5232 : // no_idx16 = (Word16) round_f( ( nbits_fr / 16.0f + 0.5f ) );
5233 5373 : no_idx16 = shr_r( add( nbits_fr, ONE_IN_Q3 ), 4 );
5234 : }
5235 :
5236 : /* write combined index */
5237 5580 : k = nbits_fr;
5238 5580 : move16();
5239 5739 : FOR( i = 0; i < no_idx16 - 1; i++ )
5240 : {
5241 159 : k = sub( k, 16 );
5242 159 : push_next_indice( hMetaData, ( ( idx >> k ) & 65535 ), 16 ); /* 16 bits */
5243 : }
5244 :
5245 5580 : push_next_indice( hMetaData, ( idx & ( ( 1 << k ) - 1 ) ), k );
5246 :
5247 5580 : IF( nbits_fr1 > 0 )
5248 : {
5249 : // if ( nbits_fr1 % 16 == 0 )
5250 40 : IF( s_and( nbits_fr1, 15 ) == 0 )
5251 : {
5252 0 : no_idx16 = shr( nbits_fr1, 4 );
5253 : }
5254 : ELSE
5255 : {
5256 : // no_idx16 = (Word16) round_f( ( nbits_fr1 / 16.0f + 0.5f ) );
5257 40 : no_idx16 = shr_r( add( nbits_fr1, ONE_IN_Q3 ), 4 );
5258 : }
5259 :
5260 40 : assert( no_idx16 <= 4 );
5261 :
5262 40 : k = nbits_fr1;
5263 40 : move16();
5264 106 : FOR( i = 0; i < no_idx16 - 1; i++ )
5265 : {
5266 66 : k = sub( k, 16 );
5267 66 : push_next_indice( hMetaData, ( ( idx1 >> k ) & 65535 ), 16 ); /* 16 bits */
5268 : }
5269 :
5270 40 : push_next_indice( hMetaData, ( idx1 & ( ( 1 << k ) - 1 ) ), k );
5271 : }
5272 : }
5273 : ELSE
5274 : {
5275 : /* write flag */
5276 20939 : nbits = 1;
5277 20939 : move16();
5278 :
5279 : /* write flag*/
5280 20939 : push_next_indice( hMetaData, 1, 1 );
5281 :
5282 : /* write GR_ord */
5283 20939 : push_next_indice( hMetaData, GR_ord, 1 );
5284 20939 : nbits = add( nbits, 1 );
5285 :
5286 : /* write the min */
5287 20939 : bits_GR = hMetaData->nb_bits_tot;
5288 20939 : move16();
5289 20939 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH, 0 );
5290 20939 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) );
5291 :
5292 : /* write GR data */
5293 189695 : FOR( j = 0; j < idx_shift; j++ )
5294 : {
5295 168756 : bits_GR = hMetaData->nb_bits_tot;
5296 168756 : move16();
5297 :
5298 168756 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, mr_idx_sur_coh[j], no_cv_shift[j], GR_ord );
5299 :
5300 168756 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) );
5301 : }
5302 : }
5303 : }
5304 :
5305 26519 : return nbits;
5306 : }
5307 :
5308 2276 : static Word16 encode_surround_coherence_hr_fx(
5309 : IVAS_QMETADATA *hQMetaData, /* i : quantized metadata */
5310 : BSTR_ENC_HANDLE hMetaData /* i/o: metadata bitstream handle */
5311 : )
5312 : {
5313 : Word16 i, j, k, sf;
5314 : Word16 nbits, nbits_fr, nbits_sf;
5315 : UWord16 idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
5316 : UWord16 mr_idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
5317 : Word16 GR_ord, bits_GR;
5318 : UWord64 idx, idx1;
5319 : Word16 no_idx16;
5320 : Word16 no_cv[MASA_MAXIMUM_CODING_SUBBANDS];
5321 : Word32 error_ratio_surr; // Q30
5322 : IVAS_QDIRECTION *q_direction;
5323 : Word16 half_coding_subbands, nbits_fr1, coding_subbands;
5324 : Word16 all_coherence_zero;
5325 : UWord16 idx_sur_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS];
5326 : UWord8 idx_shift;
5327 2276 : Word16 max_val = 0, nbits_max;
5328 : Word16 no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx;
5329 : Word16 idx16;
5330 2276 : move16();
5331 :
5332 2276 : coding_subbands = hQMetaData->q_direction[0].cfg.nbands;
5333 2276 : all_coherence_zero = hQMetaData->all_coherence_zero;
5334 2276 : q_direction = &( hQMetaData->q_direction[0] );
5335 2276 : nbits = 0;
5336 2276 : move16();
5337 2276 : move16();
5338 2276 : move16();
5339 :
5340 2276 : IF( EQ_16( all_coherence_zero, 1 ) )
5341 : {
5342 0 : nbits = 0;
5343 0 : move16();
5344 : }
5345 : ELSE
5346 : {
5347 10930 : FOR( sf = 0; sf < hQMetaData->q_direction[0].cfg.nblocks; sf++ )
5348 : {
5349 8654 : GR_ord = 1;
5350 8654 : k = 0;
5351 8654 : idx_shift = 0;
5352 8654 : move16();
5353 8654 : move16();
5354 8654 : move16();
5355 215600 : FOR( j = 0; j < coding_subbands; j++ )
5356 : {
5357 206946 : IF( EQ_16( hQMetaData->no_directions, 2 ) )
5358 : {
5359 109026 : k = add( k, hQMetaData->twoDirBands[j] );
5360 109026 : idx16 = s_max( sub( k, 1 ), 0 );
5361 109026 : error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[sf] ); // Q30
5362 109026 : IF( hQMetaData->twoDirBands[j] )
5363 : {
5364 64416 : error_ratio_surr = L_sub( error_ratio_surr, q_direction[1].band_data[idx16].energy_ratio_fx[sf] ); // Q30
5365 : }
5366 : }
5367 : ELSE
5368 : {
5369 97920 : error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[sf] ); // Q30
5370 : }
5371 :
5372 : /* if ( error_ratio_surr <= 0 ) Restricting precision to 7 decimal places */
5373 206946 : IF( LE_32( error_ratio_surr, 107 /* 1e-7 in Q30 */ ) )
5374 : {
5375 1644 : error_ratio_surr = 0;
5376 1644 : idx_sur_coh[j] = 0;
5377 1644 : no_cv[j] = 1;
5378 1644 : hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0; /* sur_coherence_cb_masa[idx_cb_sur_coh_masa[DIRAC_DIFFUSE_LEVELS - 1] * MASA_MAX_NO_CV_SUR_COH]; */
5379 1644 : move32();
5380 1644 : move16();
5381 1644 : move16();
5382 1644 : move16();
5383 : }
5384 : ELSE
5385 : {
5386 410604 : idx_sur_coh[j] = squant_int_fx( hQMetaData->surcoh_band_data[j].surround_coherence[sf], &hQMetaData->surcoh_band_data[j].surround_coherence[sf],
5387 205302 : &sur_coherence_cb_masa[idx_cb_sur_coh_masa[7] * MASA_MAX_NO_CV_SUR_COH], idx_cb_sur_coh_masa[7] + 2 );
5388 205302 : no_cv[j] = add( idx_cb_sur_coh_masa[7], 2 );
5389 205302 : no_cv_shift[idx_shift] = no_cv[j];
5390 205302 : idx_sur_coh_shift[idx_shift++] = idx_sur_coh[j];
5391 205302 : move16();
5392 205302 : move16();
5393 205302 : move16();
5394 205302 : move16();
5395 : }
5396 : }
5397 :
5398 8654 : IF( NE_16( sum16_fx( no_cv, coding_subbands ), coding_subbands ) )
5399 : {
5400 8654 : nbits_max = 0;
5401 8654 : move16();
5402 8654 : IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) )
5403 : {
5404 8654 : j = maximum_s( (Word16 *) idx_sur_coh, coding_subbands, &max_val );
5405 215600 : FOR( j = 0; j < coding_subbands; j++ )
5406 : {
5407 206946 : IF( GT_16( no_cv[j], add( max_val, 1 ) ) )
5408 : {
5409 205302 : no_cv[j] = add( max_val, 1 );
5410 205302 : move16();
5411 : }
5412 : }
5413 8654 : nbits_max = sub( MASA_MAX_NO_CV_SUR_COH, max_val ); /* encoded with GR0 as max_no_vals - no_vals*/
5414 : }
5415 8654 : IF( max_val == 0 )
5416 : {
5417 74 : FOR( j = 0; j < coding_subbands; j++ )
5418 : {
5419 71 : hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0;
5420 71 : move16();
5421 : }
5422 : }
5423 8654 : nbits_sf = coherence_coding_length( idx_sur_coh_shift, idx_shift, coding_subbands, no_cv,
5424 : mr_idx_sur_coh, no_cv_shift, &min_idx, &GR_ord, &nbits_fr, &nbits_fr1 );
5425 8654 : half_coding_subbands = shr( coding_subbands, 1 );
5426 8654 : idx1 = 0;
5427 8654 : move16();
5428 :
5429 : /* should check how to encode the average - check distribution */
5430 8654 : IF( LT_16( add( add( nbits_fr, nbits_fr1 ), nbits_max ), nbits_sf ) )
5431 : {
5432 : /* write flag*/
5433 177 : push_next_indice( hMetaData, 0, 1 );
5434 :
5435 : /* create combined index */
5436 177 : nbits = add( nbits, add( nbits_fr, add( nbits_fr1, 1 ) ) );
5437 177 : IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) )
5438 : {
5439 : /* write max value*/
5440 177 : bits_GR = hMetaData->nb_bits_tot;
5441 177 : move16();
5442 177 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( MASA_MAX_NO_CV_SUR_COH - 1, max_val ), MASA_MAX_NO_CV_SUR_COH, 0 );
5443 177 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) );
5444 : }
5445 :
5446 177 : IF( nbits_fr1 > 0 )
5447 : {
5448 68 : idx = create_combined_index_fx( idx_sur_coh, half_coding_subbands, no_cv );
5449 68 : idx1 = create_combined_index_fx( &idx_sur_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] );
5450 : }
5451 : ELSE
5452 : {
5453 109 : idx = create_combined_index_fx( idx_sur_coh, coding_subbands, no_cv );
5454 : }
5455 :
5456 177 : IF( nbits_fr % 16 == 0 )
5457 : {
5458 23 : no_idx16 = shr( nbits_fr, 4 );
5459 : }
5460 : ELSE
5461 : {
5462 154 : no_idx16 = add( shr( nbits_fr, 4 ), 1 );
5463 : }
5464 :
5465 : /* write combined index */
5466 177 : k = nbits_fr;
5467 177 : move16();
5468 376 : FOR( i = 0; i < no_idx16 - 1; i++ )
5469 : {
5470 199 : k = sub( k, 16 );
5471 199 : push_next_indice( hMetaData, ( ( idx >> k ) & 65535 ), 16 ); /* 16 bits */
5472 : }
5473 :
5474 177 : push_next_indice( hMetaData, ( idx & ( ( 1 << k ) - 1 ) ), k );
5475 :
5476 177 : IF( nbits_fr1 > 0 )
5477 : {
5478 68 : IF( nbits_fr1 % 16 == 0 )
5479 : {
5480 34 : no_idx16 = shr( nbits_fr1, 4 );
5481 : }
5482 : ELSE
5483 : {
5484 34 : no_idx16 = add( shr( nbits_fr1, 4 ), 1 );
5485 : }
5486 :
5487 68 : assert( no_idx16 <= 4 );
5488 :
5489 68 : k = nbits_fr1;
5490 68 : move16();
5491 163 : FOR( i = 0; i < no_idx16 - 1; i++ )
5492 : {
5493 95 : k = sub( k, 16 );
5494 95 : push_next_indice( hMetaData, ( ( idx1 >> k ) & 65535 ), 16 ); /* 16 bits */
5495 : }
5496 :
5497 68 : push_next_indice( hMetaData, ( idx1 & ( ( 1 << k ) - 1 ) ), k );
5498 : }
5499 : }
5500 : ELSE
5501 : {
5502 : /* write flag */
5503 8477 : nbits = add( nbits, 1 );
5504 :
5505 : /* write flag*/
5506 8477 : push_next_indice( hMetaData, 1, 1 );
5507 :
5508 : /* write GR_ord */
5509 8477 : push_next_indice( hMetaData, GR_ord, 1 );
5510 8477 : nbits = add( nbits, 1 );
5511 :
5512 : /* write the min */
5513 8477 : bits_GR = hMetaData->nb_bits_tot;
5514 8477 : move16();
5515 8477 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH, 0 );
5516 8477 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) );
5517 :
5518 : /* write GR data */
5519 209609 : FOR( j = 0; j < idx_shift; j++ )
5520 : {
5521 201132 : bits_GR = hMetaData->nb_bits_tot;
5522 201132 : move16();
5523 :
5524 201132 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, mr_idx_sur_coh[j], no_cv_shift[j], GR_ord );
5525 :
5526 201132 : nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) );
5527 : }
5528 : }
5529 : }
5530 : }
5531 : }
5532 :
5533 2276 : return nbits;
5534 : }
5535 :
5536 :
5537 : /*-------------------------------------------------------------------*
5538 : * quantize_DCT_0_coh()
5539 : *
5540 : * quanization of DCT component of order zero for transformed coherence vector
5541 : *-------------------------------------------------------------------*/
5542 : /*! r: quantized value */
5543 147722 : static Word32 quantize_DCT_0_coh_fx( // o:Q21
5544 : const Word16 x, /* i : input value Q14 */
5545 : const Word16 j, /* i : subband index */
5546 : const Word16 *coherence_cb, /* i : coherence codebook Q14 */
5547 : const Word16 delta_var, /* i : azimuth variance threshold Q6 */
5548 : const Word16 no_cb, /* i : maximum number of codewords */
5549 : IVAS_QDIRECTION *q_direction, /* i : quantized metadata */
5550 : UWord16 *idx_x, /* o : codewords index */
5551 : Word16 *p_no_cb, /* o : actual number of codewords dependent on energy ratio value */
5552 : const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */
5553 : )
5554 : {
5555 : Word16 var_azi /*Q6*/, xhat;
5556 : Word16 idx_sub_cb, idx;
5557 : Word16 min_index;
5558 : Word16 azimuth_16[MAX_PARAM_SPATIAL_SUBFRAMES]; // Q6
5559 147722 : Copy_Scale_sig_32_16( q_direction->band_data[j].azimuth_fx, azimuth_16, MAX_PARAM_SPATIAL_SUBFRAMES, -16 ); // Q22->Q6
5560 : /* quantize first DCT component */
5561 147722 : var_azi = var_fx( azimuth_16, Q6, q_direction->cfg.nblocks );
5562 :
5563 147722 : IF( hrmasa_flag )
5564 : {
5565 0 : minimum_s( (Word16 *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index );
5566 0 : min_index = shr( min_index, 1 );
5567 : }
5568 : ELSE
5569 : {
5570 147722 : min_index = q_direction->band_data[j].energy_ratio_index[0];
5571 147722 : move16();
5572 : }
5573 :
5574 147722 : IF( LT_16( var_azi, delta_var ) )
5575 : {
5576 36005 : idx_sub_cb = imult1616( no_cb, min_index );
5577 : }
5578 : ELSE
5579 : {
5580 111717 : idx_sub_cb = imult1616( no_cb, add( min_index, DIRAC_DIFFUSE_LEVELS ) );
5581 : }
5582 :
5583 147722 : idx = squant_fx( x, &xhat, &coherence_cb[idx_sub_cb], len_cb_dct0_masa[min_index] );
5584 :
5585 147722 : *p_no_cb = len_cb_dct0_masa[min_index];
5586 147722 : move16();
5587 147722 : *idx_x = idx;
5588 147722 : move16();
5589 :
5590 147722 : return L_shl( xhat, 7 ); // Q21
5591 : }
5592 :
5593 : /*-------------------------------------------------------------------*
5594 : * encode_coherence_indexesDCT1()
5595 : *
5596 : * Encoding DCT1 coeffs with joint index or EC
5597 : *-------------------------------------------------------------------*/
5598 : /*! r: number of bits written */
5599 23095 : static Word16 encode_coherence_indexesDCT1_fx(
5600 : UWord16 *idx_dct, /* i : data to be encoded */
5601 : const Word16 len, /* i : number of data */
5602 : BSTR_ENC_HANDLE hMetaData /* i : metadata handle */
5603 : )
5604 : {
5605 : Word16 i, nbits, GR_ord;
5606 : UWord16 av;
5607 : UWord16 mr_idx_dct[MASA_MAXIMUM_CODING_SUBBANDS];
5608 :
5609 23095 : GR_ord = 0;
5610 23095 : move16();
5611 23095 : nbits = 0;
5612 23095 : move16();
5613 :
5614 23095 : nbits = mean_removed_GR_new_fx( idx_dct, MASA_NO_CV_COH1, len, 0, &GR_ord, &av, mr_idx_dct );
5615 :
5616 170817 : FOR( i = 0; i < len; i++ )
5617 : {
5618 147722 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, mr_idx_dct[i], 2 * MASA_NO_CV_COH1, GR_ord );
5619 : }
5620 :
5621 23095 : nbits = add( nbits, len_huf_masa[av] );
5622 :
5623 23095 : push_next_indice( hMetaData, huff_code_av_masa[av], len_huf_masa[av] );
5624 :
5625 23095 : return nbits;
5626 : }
5627 :
5628 : /*-------------------------------------------------------------------*
5629 : * dct4_transform()
5630 : *
5631 : * 4D implementation of DCT transform
5632 : *-------------------------------------------------------------------*/
5633 295444 : static void dct4_transform_fx(
5634 : UWord8 *v, /* i : input 4D vector */
5635 : Word32 *dct_v /* o : output transformed vector Q21 */
5636 : )
5637 : {
5638 : Word32 a, b, c, d;
5639 :
5640 295444 : a = L_shl( L_add( v[0], v[3] ), Q12 ); //*0.5f / 256.0f;
5641 295444 : b = L_shl( L_add( v[1], v[2] ), Q12 ); //*0.5f / 256.0f;
5642 295444 : c = L_shl( L_sub( v[0], v[3] ), Q13 ); // / 256.0f;
5643 295444 : d = L_shl( L_sub( v[1], v[2] ), Q13 ); // / 256.0f;
5644 :
5645 295444 : dct_v[0] = L_add( a, b ); // 0.5f * (a + b);
5646 295444 : move32();
5647 295444 : dct_v[1] = L_add( Mpy_32_32_r( 1402911301 /*0.653281482438188f.Q31*/, c ), Mpy_32_32_r( 581104888 /*0.270598050073099f.Q31*/, d ) );
5648 295444 : move32();
5649 295444 : dct_v[2] = L_sub( a, b ); // 0.5f * (a - b);
5650 295444 : move32();
5651 295444 : dct_v[3] = L_sub( Mpy_32_32_r( 581104888 /*0.270598050073099f.Q31*/, c ), Mpy_32_32_r( 1402911301 /*0.653281482438188f.Q31*/, d ) );
5652 295444 : move32();
5653 :
5654 295444 : return;
5655 : }
5656 :
5657 : /*-------------------------------------------------------------------*
5658 : * ivas_qmetadata_quantize_coherence_hr_512()
5659 : *
5660 : *
5661 : *-------------------------------------------------------------------*/
5662 3532 : static Word16 ivas_qmetadata_quantize_coherence_hr_512_fx(
5663 : IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata */
5664 : const Word16 idx_d, /* i : current direction index */
5665 : const Word16 all_coherence_zero, /* i : all coherence is zero - flag */
5666 : BSTR_ENC_HANDLE hMetaData, /* i : metadata handle */
5667 : const Word16 bits_coh )
5668 : {
5669 : Word16 j, k;
5670 : Word16 nbands, nblocks;
5671 : Word16 nbits;
5672 : Word16 nbits1, nbits0, nbits_av;
5673 : UWord16 idx_coh[MASA_MAXIMUM_CODING_SUBBANDS];
5674 : IVAS_QDIRECTION *q_direction;
5675 : Word16 cbsize;
5676 : Word16 delta, tmp;
5677 : Word16 min_idx, GR_param, GR_param_av;
5678 : UWord16 av, mr_idx[MASA_MAXIMUM_CODING_SUBBANDS];
5679 :
5680 3532 : q_direction = &( hQMetaData->q_direction[idx_d] );
5681 3532 : nbands = q_direction->cfg.nbands;
5682 3532 : nblocks = q_direction->cfg.nblocks;
5683 3532 : nbits = 0;
5684 3532 : move16();
5685 3532 : move16();
5686 3532 : move16();
5687 :
5688 3532 : IF( EQ_16( all_coherence_zero, 1 ) )
5689 : {
5690 0 : return nbits;
5691 : }
5692 3532 : nbits = hMetaData->nb_bits_tot;
5693 3532 : move16();
5694 :
5695 3532 : cbsize = shl( 1, bits_coh );
5696 : // delta = 256.0f / cbsize;
5697 3532 : delta = div_l( 256, shr( cbsize, 1 ) ); // Q15
5698 :
5699 16760 : FOR( k = 0; k < nblocks; k++ )
5700 : {
5701 13228 : min_idx = 0;
5702 13228 : move16();
5703 284590 : FOR( j = 0; j < nbands; j++ )
5704 : {
5705 271362 : idx_coh[j] = usquant_fx( (Word16) ( q_direction->coherence_band_data[j].spread_coherence[k] ), &tmp, shr( delta, 1 ), shr( delta, 1 ) /* Q-1 */, cbsize );
5706 271362 : move16();
5707 271362 : q_direction->coherence_band_data[j].spread_coherence[k] = (UWord8) add( imult1616( idx_coh[j], delta ), shr( delta, 1 ) /*delta/2*/ ); // Q15
5708 271362 : if ( LT_16( idx_coh[j], min_idx ) )
5709 : {
5710 0 : min_idx = idx_coh[j];
5711 0 : move16();
5712 : }
5713 : }
5714 :
5715 13228 : nbits0 = 0;
5716 13228 : nbits1 = 0;
5717 13228 : move16();
5718 13228 : move16();
5719 :
5720 284590 : FOR( j = 0; j < nbands; j++ )
5721 : {
5722 271362 : idx_coh[j] = sub( idx_coh[j], min_idx );
5723 271362 : move16();
5724 271362 : nbits0 = add( nbits0, ivas_qmetadata_encode_extended_gr_length_fx( idx_coh[j], sub( cbsize, min_idx ), 0 ) );
5725 271362 : nbits1 = add( nbits1, ivas_qmetadata_encode_extended_gr_length_fx( idx_coh[j], sub( cbsize, min_idx ), 1 ) );
5726 : }
5727 13228 : IF( nbits0 < nbits1 )
5728 : {
5729 12746 : GR_param = 0;
5730 12746 : nbits1 = nbits0;
5731 12746 : move16();
5732 12746 : move16();
5733 : }
5734 : ELSE
5735 : {
5736 482 : GR_param = 1;
5737 482 : move16();
5738 : }
5739 :
5740 13228 : GR_param_av = 1;
5741 13228 : move16();
5742 13228 : nbits_av = mean_removed_GR_new_fx( idx_coh, cbsize, nbands, 1, &GR_param_av, &av, mr_idx );
5743 :
5744 13228 : IF( LT_16( nbits_av, nbits1 ) )
5745 : {
5746 146 : nbits1 = nbits_av;
5747 146 : GR_param = GR_param_av;
5748 146 : move16();
5749 146 : move16();
5750 :
5751 : /* use average removed */
5752 146 : push_next_indice( hMetaData, 1, 1 );
5753 :
5754 : /* write average */
5755 146 : push_next_indice( hMetaData, av, bits_coh );
5756 :
5757 : /* write GR param */
5758 146 : push_next_indice( hMetaData, GR_param, 1 );
5759 :
5760 2050 : FOR( j = 0; j < nbands; j++ )
5761 : {
5762 1904 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, mr_idx[j], imult1616( 2, cbsize ), GR_param );
5763 : }
5764 : }
5765 : ELSE
5766 : {
5767 : /* use min removed */
5768 13082 : push_next_indice( hMetaData, 0, 1 );
5769 :
5770 : /* write min index */
5771 13082 : push_next_indice( hMetaData, min_idx, bits_coh );
5772 :
5773 : /* write GR param */
5774 13082 : push_next_indice( hMetaData, GR_param, 1 );
5775 :
5776 282540 : FOR( j = 0; j < nbands; j++ )
5777 : {
5778 269458 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, idx_coh[j], sub( cbsize, min_idx ), GR_param );
5779 : }
5780 : }
5781 : }
5782 :
5783 3532 : nbits = sub( hMetaData->nb_bits_tot, nbits );
5784 3532 : return nbits;
5785 : }
5786 :
5787 : /*-------------------------------------------------------------------*
5788 : * ivas_qmetadata_quantize_coherence()
5789 : *
5790 : *
5791 : *-------------------------------------------------------------------*/
5792 :
5793 : /*! r: number of bits written */
5794 54358 : static Word16 ivas_qmetadata_quantize_coherence_fx(
5795 : IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata */
5796 : const Word16 idx_d, /* i : current direction index */
5797 : const Word16 all_coherence_zero, /* i : all coherence is zero - flag */
5798 : BSTR_ENC_HANDLE hMetaData, /* i : metadata handle */
5799 : const Word16 write_flag, /* i : flag to actually write the data or not */
5800 : Word16 *indice_coherence,
5801 : const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */
5802 : )
5803 : {
5804 : Word16 j, k;
5805 : Word32 dct_coh[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; // Q21
5806 : UWord16 idx_dct[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
5807 : Word16 coding_subbands;
5808 : Word16 nbits;
5809 : UWord64 no_cb;
5810 : Word16 MASA_grouping[MASA_MAXIMUM_CODING_SUBBANDS];
5811 : Word16 nbits1;
5812 : Word16 coding_subbands_0, d;
5813 : Word16 two_dir_band[MASA_MAXIMUM_CODING_SUBBANDS];
5814 : Word16 no_cb_vec[MASA_MAXIMUM_CODING_SUBBANDS];
5815 : IVAS_QDIRECTION *q_direction;
5816 : Word16 min_index;
5817 : Word16 tmp16;
5818 54358 : min_index = 0;
5819 54358 : move16();
5820 54358 : q_direction = &( hQMetaData->q_direction[idx_d] );
5821 54358 : coding_subbands = q_direction->cfg.nbands;
5822 54358 : move16();
5823 54358 : nbits = 0;
5824 54358 : move16();
5825 :
5826 54358 : IF( EQ_16( all_coherence_zero, 1 ) )
5827 : {
5828 0 : return nbits;
5829 : }
5830 :
5831 54358 : IF( EQ_16( hQMetaData->q_direction[idx_d].cfg.nblocks, 1 ) )
5832 : {
5833 8168 : nbits = encode_spread_coherence_1sf_fx( hQMetaData, idx_d, hMetaData, hrmasa_flag );
5834 :
5835 8168 : return nbits;
5836 : }
5837 : ELSE
5838 : {
5839 46190 : k = 0;
5840 46190 : move16();
5841 46190 : no_cb = 1;
5842 46190 : move64();
5843 46190 : coding_subbands_0 = hQMetaData->q_direction[0].cfg.nbands;
5844 46190 : move16();
5845 46190 : IF( LE_16( coding_subbands_0, 5 ) )
5846 : {
5847 202968 : FOR( j = 0; j < 5; j++ )
5848 : {
5849 169140 : MASA_grouping[j] = j;
5850 169140 : move16();
5851 : }
5852 : }
5853 : ELSE
5854 : {
5855 12362 : IF( LE_16( coding_subbands_0, 8 ) )
5856 : {
5857 5092 : Copy( MASA_grouping_8_to_5, MASA_grouping, 8 );
5858 : }
5859 7270 : ELSE IF( LE_16( coding_subbands_0, 12 ) )
5860 : {
5861 3022 : Copy( MASA_grouping_12_to_5, MASA_grouping, 12 );
5862 : }
5863 4248 : ELSE IF( LE_16( coding_subbands_0, 18 ) )
5864 : {
5865 1880 : Copy( MASA_grouping_18_to_5, MASA_grouping, 18 );
5866 : }
5867 : ELSE
5868 : {
5869 2368 : IF( LE_16( coding_subbands_0, 24 ) )
5870 : {
5871 2368 : Copy( MASA_grouping_24_to_5, MASA_grouping, 24 );
5872 : }
5873 : }
5874 : }
5875 :
5876 46190 : IF( LT_16( coding_subbands, coding_subbands_0 ) )
5877 : {
5878 7468 : d = 0;
5879 7468 : move16();
5880 58684 : FOR( j = 0; j < coding_subbands_0; j++ )
5881 : {
5882 51216 : IF( EQ_16( hQMetaData->twoDirBands[j], 1 ) )
5883 : {
5884 20312 : two_dir_band[d] = j;
5885 20312 : move16();
5886 20312 : d = add( d, 1 );
5887 : }
5888 : }
5889 : }
5890 :
5891 341634 : FOR( j = 0; j < coding_subbands; j++ )
5892 : {
5893 : /* DCT transform */
5894 295444 : dct4_transform_fx( hQMetaData->q_direction[idx_d].coherence_band_data[j].spread_coherence, dct_coh[j] );
5895 :
5896 295444 : IF( hrmasa_flag )
5897 : {
5898 0 : minimum_s( (Word16 *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index );
5899 0 : no_cb_vec[j] = len_cb_dct0_masa[min_index >> 1];
5900 0 : move16();
5901 : }
5902 : ELSE
5903 : {
5904 295444 : no_cb_vec[j] = len_cb_dct0_masa[q_direction->band_data[j].energy_ratio_index[0]];
5905 295444 : move16();
5906 : }
5907 :
5908 295444 : IF( write_flag )
5909 : {
5910 : /* quantize first DCT parameter */
5911 147722 : dct_coh[j][0] = quantize_DCT_0_coh_fx( extract_l( L_shr_r( dct_coh[j][0], 7 ) ), j, coherence_cb0_masa_Q14, MASA_DELTA_AZI_DCT0 << Q6, MASA_NO_CV_COH, q_direction, &idx_dct[k], &no_cb_vec[j], hrmasa_flag ); // Q21
5912 147722 : move32();
5913 : }
5914 :
5915 295444 : IF( LT_16( coding_subbands, coding_subbands_0 ) )
5916 : {
5917 20312 : idx_dct[k + coding_subbands] = squant_fx( extract_l( L_shr_r( dct_coh[j][1], 6 ) ), &tmp16, &coherence_cb1_masa_Q15[MASA_grouping[two_dir_band[j]] * MASA_NO_CV_COH1], MASA_NO_CV_COH1 );
5918 20312 : move16();
5919 : }
5920 : ELSE
5921 : {
5922 275132 : idx_dct[k + coding_subbands] = squant_fx( extract_l( L_shr_r( dct_coh[j][1], 6 ) ), &tmp16, &coherence_cb1_masa_Q15[MASA_grouping[j] * MASA_NO_CV_COH1], MASA_NO_CV_COH1 );
5923 275132 : move16();
5924 : }
5925 295444 : dct_coh[j][1] = L_shl( tmp16, 6 );
5926 295444 : k = add( k, 1 );
5927 295444 : move16();
5928 :
5929 295444 : dct_coh[j][2] = 0;
5930 295444 : move32();
5931 295444 : dct_coh[j][3] = 0;
5932 295444 : move32();
5933 : }
5934 :
5935 46190 : nbits1 = 0;
5936 46190 : move16();
5937 46190 : IF( GT_16( sum_s( no_cb_vec, coding_subbands ), MASA_COH_LIMIT_2IDX ) )
5938 : {
5939 : /* make two indxes */
5940 348 : no_cb = 1;
5941 348 : move64();
5942 :
5943 4524 : FOR( j = 0; j < coding_subbands / 2; j++ )
5944 : {
5945 4176 : no_cb = no_cb * no_cb_vec[j];
5946 : }
5947 :
5948 : // nbits = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
5949 348 : IF( LE_64( no_cb, 1 ) )
5950 : {
5951 0 : nbits = 0;
5952 0 : move16();
5953 : }
5954 : ELSE
5955 : {
5956 348 : nbits = sub( 63, W_norm( W_sub( no_cb, 1 ) ) );
5957 : }
5958 348 : no_cb = 1;
5959 348 : move64();
5960 :
5961 4524 : FOR( j = coding_subbands / 2; j < coding_subbands; j++ )
5962 : {
5963 4176 : no_cb = no_cb * no_cb_vec[j];
5964 : }
5965 : // nbits1 = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
5966 348 : IF( LE_64( no_cb, 1 ) )
5967 : {
5968 0 : nbits1 = 0;
5969 0 : move16();
5970 : }
5971 : ELSE
5972 : {
5973 348 : nbits1 = sub( 63, W_norm( W_sub( no_cb, 1 ) ) );
5974 : }
5975 : }
5976 : ELSE
5977 : {
5978 45842 : no_cb = 1;
5979 45842 : move64();
5980 :
5981 332934 : FOR( j = 0; j < coding_subbands; j++ )
5982 : {
5983 287092 : no_cb = no_cb * no_cb_vec[j];
5984 : }
5985 :
5986 : // nbits = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
5987 45842 : IF( LE_64( no_cb, 1 ) )
5988 : {
5989 0 : nbits = 0;
5990 0 : move16();
5991 : }
5992 : ELSE
5993 : {
5994 45842 : nbits = sub( 63, W_norm( W_sub( no_cb, 1 ) ) );
5995 : }
5996 : }
5997 :
5998 46190 : IF( write_flag )
5999 : {
6000 170817 : FOR( j = 0; j < coding_subbands; j++ )
6001 : {
6002 : /* inverse DCT transform */
6003 147722 : invdct4_transform_fx( dct_coh[j], q_direction->coherence_band_data[j].spread_coherence, Q21 );
6004 : }
6005 :
6006 23095 : nbits = encode_coherence_indexesDCT0_fx( idx_dct, coding_subbands, no_cb_vec, hMetaData, *indice_coherence, nbits, nbits1 );
6007 : }
6008 : ELSE
6009 : {
6010 : /* write dummy data now and save the position */
6011 23095 : *indice_coherence = hMetaData->nb_ind_tot;
6012 23095 : move16();
6013 23095 : k = nbits;
6014 23095 : move16();
6015 50301 : WHILE( k > 0 )
6016 : {
6017 27206 : push_next_indice( hMetaData, 0, s_min( 16, k ) );
6018 27206 : k = sub( k, 16 );
6019 : }
6020 :
6021 23095 : IF( nbits1 > 0 )
6022 : {
6023 174 : k = nbits1;
6024 174 : move16();
6025 522 : WHILE( k > 0 )
6026 : {
6027 348 : push_next_indice( hMetaData, 0, s_min( 16, k ) );
6028 348 : k = sub( k, 16 );
6029 : }
6030 : }
6031 23095 : nbits = add( nbits, nbits1 );
6032 23095 : set16_fx( no_cb_vec, MASA_NO_CV_COH1, coding_subbands );
6033 23095 : nbits = add( nbits, encode_coherence_indexesDCT1_fx( &idx_dct[coding_subbands], coding_subbands, hMetaData ) );
6034 :
6035 23095 : return nbits;
6036 : }
6037 : }
6038 23095 : return nbits;
6039 : }
6040 :
6041 :
6042 : /*-------------------------------------------------------------------*
6043 : * ivas_qmetadata_reorder_2dir_bands()
6044 : *
6045 : * Reorders metadata on 2dir bands such that direct-to-total ratio of first direction is
6046 : * always larger or equal to direct-to-total ratio of second direction.
6047 : *-------------------------------------------------------------------*/
6048 4580 : static void ivas_qmetadata_reorder_2dir_bands_fx(
6049 : IVAS_QMETADATA_HANDLE hQMetaData )
6050 : {
6051 : Word16 nbands;
6052 : Word16 nsubframes;
6053 : Word16 band, sf;
6054 :
6055 4580 : nbands = hQMetaData->q_direction[0].cfg.nbands;
6056 4580 : move16();
6057 4580 : nsubframes = hQMetaData->q_direction[0].cfg.nblocks;
6058 4580 : move16();
6059 :
6060 44132 : FOR( band = 0; band < nbands; band++ )
6061 : {
6062 39552 : IF( EQ_16( hQMetaData->twoDirBands[band], 1 ) )
6063 : {
6064 13200 : IF( LT_32( hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0], hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[0] ) )
6065 : {
6066 5424 : UWord16 uint16_tmp = 0;
6067 5424 : move16();
6068 5424 : Word32 fx_tmp = 0;
6069 5424 : move32();
6070 5424 : UWord8 uint8_tmp = 0;
6071 5424 : move16();
6072 :
6073 23454 : FOR( sf = 0; sf < nsubframes; sf++ )
6074 : {
6075 18030 : uint16_tmp = hQMetaData->q_direction[0].band_data[band].spherical_index[sf];
6076 18030 : move16();
6077 18030 : hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[1].band_data[band].spherical_index[sf];
6078 18030 : move16();
6079 18030 : hQMetaData->q_direction[1].band_data[band].spherical_index[sf] = uint16_tmp;
6080 18030 : move16();
6081 :
6082 18030 : fx_tmp = hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf]; // Q22
6083 18030 : move32();
6084 18030 : hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[1].band_data[band].azimuth_fx[sf];
6085 18030 : move32();
6086 18030 : hQMetaData->q_direction[1].band_data[band].azimuth_fx[sf] = fx_tmp;
6087 18030 : move32();
6088 :
6089 18030 : fx_tmp = hQMetaData->q_direction[0].band_data[band].elevation_fx[sf];
6090 18030 : move32();
6091 18030 : hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[1].band_data[band].elevation_fx[sf]; // Q22
6092 18030 : move32();
6093 18030 : hQMetaData->q_direction[1].band_data[band].elevation_fx[sf] = fx_tmp;
6094 18030 : move32();
6095 :
6096 18030 : uint8_tmp = hQMetaData->q_direction[0].band_data[band].distance[sf];
6097 18030 : move16();
6098 18030 : hQMetaData->q_direction[0].band_data[band].distance[sf] = hQMetaData->q_direction[1].band_data[band].distance[sf];
6099 18030 : move16();
6100 18030 : hQMetaData->q_direction[1].band_data[band].distance[sf] = uint8_tmp;
6101 18030 : move16();
6102 :
6103 18030 : IF( hQMetaData->coherence_flag )
6104 : {
6105 18030 : uint8_tmp = hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf];
6106 18030 : move16();
6107 18030 : hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf];
6108 18030 : move16();
6109 18030 : hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf] = uint8_tmp;
6110 18030 : move16();
6111 : }
6112 : }
6113 5424 : IF( hQMetaData->coherence_flag )
6114 : {
6115 5424 : fx_tmp = hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0];
6116 5424 : move32();
6117 5424 : hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0] = hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[0]; // Q30
6118 5424 : move32();
6119 5424 : hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[0] = fx_tmp;
6120 5424 : move32();
6121 : }
6122 : }
6123 : }
6124 : }
6125 :
6126 4580 : return;
6127 : }
6128 :
6129 : /*-------------------------------------------------------------------*
6130 : * write_2dir_info()
6131 : *
6132 : *
6133 : *-------------------------------------------------------------------*/
6134 21696 : static Word16 write_2dir_info(
6135 : BSTR_ENC_HANDLE hMetaData,
6136 : UWord8 *twoDirBands,
6137 : const Word16 n,
6138 : const Word16 k )
6139 : {
6140 : Word16 nbits;
6141 : Word16 p[MASA_MAXIMUM_CODING_SUBBANDS];
6142 : UWord16 dif_p[MASA_MAXIMUM_CODING_SUBBANDS];
6143 : Word16 i, j;
6144 :
6145 21696 : j = 0;
6146 21696 : p[0] = 0;
6147 21696 : move16();
6148 21696 : move16();
6149 276852 : FOR( i = 0; i < n; i++ )
6150 : {
6151 255156 : IF( EQ_16( twoDirBands[i], 1 ) )
6152 : {
6153 216414 : p[j] = i;
6154 216414 : j = add( j, 1 );
6155 216414 : move16();
6156 : }
6157 : }
6158 :
6159 21696 : dif_p[0] = p[0];
6160 21696 : move16();
6161 216414 : FOR( i = 1; i < j; i++ )
6162 : {
6163 194718 : dif_p[i] = sub( sub( p[i], p[i - 1] ), 1 );
6164 194718 : move16();
6165 : }
6166 :
6167 21696 : j = hMetaData->nb_bits_tot;
6168 21696 : move16();
6169 238110 : FOR( i = 0; i < k; i++ )
6170 : {
6171 216414 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, dif_p[i], 24, 0 );
6172 : }
6173 21696 : nbits = sub( hMetaData->nb_bits_tot, j );
6174 :
6175 21696 : return nbits;
6176 : }
6177 :
6178 : /*-------------------------------------------------------------------*
6179 : * transform_azimuth_dir2()
6180 : *
6181 : *
6182 : *-------------------------------------------------------------------*/
6183 20820 : static void transform_azimuth_dir2_fx(
6184 : IVAS_QMETADATA_HANDLE hQMetaData,
6185 : Word16 *dir2_bands )
6186 : {
6187 : Word16 i, b;
6188 :
6189 228900 : FOR( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ )
6190 : {
6191 208080 : IF( LT_16( hQMetaData->q_direction[0].band_data[dir2_bands[i]].energy_ratio_index[0], 7 ) )
6192 : {
6193 : /* transform azimuth */
6194 803759 : FOR( b = 0; b < hQMetaData->q_direction[1].cfg.nblocks; b++ )
6195 : {
6196 : Word64 azimuth;
6197 641281 : azimuth = W_add( W_deposit32_l( L_sub( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], hQMetaData->q_direction[0].band_data[dir2_bands[i]].azimuth_fx[b] ) ), DEGREE_180_Q_22 ); // Q22
6198 :
6199 641281 : IF( GE_64( azimuth, DEGREE_180_Q_22 ) )
6200 : {
6201 93868 : azimuth = W_sub( azimuth, DEGREE_360_Q_22 );
6202 : }
6203 641281 : IF( LT_64( azimuth, -DEGREE_180_Q_22 ) )
6204 : {
6205 0 : azimuth = W_add( azimuth, DEGREE_360_Q_22 );
6206 : }
6207 641281 : IF( GE_64( azimuth, DEGREE_180_Q_22 ) )
6208 : {
6209 0 : azimuth = W_sub( azimuth, DEGREE_360_Q_22 );
6210 : }
6211 641281 : IF( LT_64( azimuth, -DEGREE_180_Q_22 ) )
6212 : {
6213 0 : azimuth = W_add( azimuth, DEGREE_360_Q_22 );
6214 : }
6215 :
6216 641281 : hQMetaData->q_direction[1].band_data[i].azimuth_fx[b] = W_extract_l( azimuth );
6217 641281 : move32();
6218 : }
6219 : }
6220 : }
6221 :
6222 20820 : return;
6223 : }
6224 4836 : static Word16 divide_GR_orders_fx(
6225 : const Word16 *q_idx,
6226 : const Word16 GR1,
6227 : const Word16 GR2,
6228 : const Word16 len,
6229 : const Word16 len_max_GR1,
6230 : Word16 *i_min )
6231 : {
6232 : Word16 nb_GR_min;
6233 : Word16 i, j, nb_GR;
6234 4836 : nb_GR_min = 1000;
6235 4836 : *i_min = -1;
6236 4836 : move16();
6237 4836 : move16();
6238 72840 : FOR( i = 0; i < s_min( len_max_GR1, len ); i++ )
6239 : {
6240 68004 : nb_GR = 0;
6241 68004 : move16();
6242 :
6243 587088 : FOR( j = 0; j <= i; j++ )
6244 : {
6245 519084 : nb_GR = add( nb_GR, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR1 ) );
6246 : }
6247 741204 : FOR( j = i + 1; j < len; j++ )
6248 : {
6249 673200 : nb_GR = add( nb_GR, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR2 ) );
6250 : }
6251 :
6252 68004 : IF( LT_16( nb_GR, nb_GR_min ) )
6253 : {
6254 16421 : nb_GR_min = nb_GR;
6255 16421 : *i_min = add( i, 1 );
6256 16421 : move16();
6257 16421 : move16();
6258 : }
6259 : }
6260 :
6261 4836 : return nb_GR_min;
6262 : }
6263 :
6264 :
6265 250 : static Word16 find_optimal_GR_order_fx(
6266 : const Word16 *q_idx,
6267 : const Word16 len,
6268 : Word16 *GR )
6269 : {
6270 : Word16 nb_GR_0, nb_GR_1;
6271 : Word16 i;
6272 : /* find optimum length of the part encoded with GR2 */
6273 250 : nb_GR_0 = 0;
6274 250 : nb_GR_1 = 0;
6275 250 : move16();
6276 250 : move16();
6277 1226 : FOR( i = 0; i < len; i++ )
6278 : {
6279 976 : nb_GR_0 = add( nb_GR_0, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[i], 100, 0 ) );
6280 976 : nb_GR_1 = add( nb_GR_1, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[i], 100, 1 ) );
6281 : }
6282 :
6283 250 : IF( LT_16( nb_GR_0, nb_GR_1 ) )
6284 : {
6285 113 : *GR = 0;
6286 113 : move16();
6287 113 : return nb_GR_0;
6288 : }
6289 : ELSE
6290 : {
6291 137 : *GR = 1;
6292 137 : move16();
6293 :
6294 137 : return nb_GR_1;
6295 : }
6296 : }
6297 :
6298 :
6299 1612 : static Word16 find_optimal_GR_orders_fx(
6300 : const Word16 *q_idx,
6301 : const Word16 len,
6302 : const Word16 len_max_GR1,
6303 : Word16 *GR1,
6304 : Word16 *GR2,
6305 : Word16 *i_min )
6306 : {
6307 : Word16 nb_GR_20, nb_GR_21, nb_GR_10, nb_GR_min;
6308 : Word16 i_min_20, i_min_21, i_min_10;
6309 : /* find optimum length of the part encoded with GR2 */
6310 1612 : nb_GR_20 = divide_GR_orders_fx( q_idx, 2, 0, len, len_max_GR1, &i_min_20 );
6311 1612 : nb_GR_21 = divide_GR_orders_fx( q_idx, 2, 1, len, len_max_GR1, &i_min_21 );
6312 1612 : nb_GR_10 = divide_GR_orders_fx( q_idx, 1, 0, len, len_max_GR1, &i_min_10 );
6313 :
6314 1612 : test();
6315 1612 : IF( LT_16( nb_GR_20, nb_GR_21 ) && LT_16( nb_GR_20, nb_GR_10 ) )
6316 : {
6317 1046 : *GR1 = 2;
6318 1046 : *GR2 = 0;
6319 1046 : nb_GR_min = nb_GR_20;
6320 1046 : *i_min = i_min_20;
6321 1046 : move16();
6322 1046 : move16();
6323 1046 : move16();
6324 1046 : move16();
6325 : }
6326 : ELSE
6327 : {
6328 566 : test();
6329 566 : IF( LT_16( nb_GR_21, nb_GR_20 ) && LT_16( nb_GR_21, nb_GR_10 ) )
6330 : {
6331 187 : *GR1 = 2;
6332 187 : *GR2 = 1;
6333 187 : nb_GR_min = nb_GR_21;
6334 187 : *i_min = i_min_21;
6335 187 : move16();
6336 187 : move16();
6337 187 : move16();
6338 187 : move16();
6339 : }
6340 : ELSE
6341 : {
6342 379 : *GR1 = 1;
6343 379 : *GR2 = 0;
6344 379 : nb_GR_min = nb_GR_10;
6345 379 : *i_min = i_min_10;
6346 379 : move16();
6347 379 : move16();
6348 379 : move16();
6349 379 : move16();
6350 : }
6351 : }
6352 :
6353 1612 : return nb_GR_min;
6354 : }
6355 :
6356 :
6357 1862 : static Word16 write_stream_dct_coeffs_omasa_fx(
6358 : Word16 *q_idx, /* i : array of indexes to be written */
6359 : const Word16 len_stream, /* i : array length */
6360 : BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream */
6361 : const Word16 first_line, /* i : is first line of the matrix? 1/0 */
6362 : const Word16 low_bitrate_mode /* i : is low bitrate mode? if yes, limit the number of bits written */
6363 : )
6364 : {
6365 1862 : Word16 nb_bits = 0, bits_pos;
6366 : UWord16 nb_GR_min;
6367 : Word16 i, j;
6368 : Word16 changed, update_needed;
6369 1862 : move16();
6370 : Word16 GR1, GR2, i_min;
6371 : Word16 max_bits;
6372 :
6373 1862 : bits_pos = hMetaData->nb_bits_tot;
6374 1862 : move16();
6375 1862 : IF( EQ_16( low_bitrate_mode, 1 ) )
6376 : {
6377 250 : max_bits = 50;
6378 250 : move16();
6379 : }
6380 : ELSE
6381 : {
6382 1612 : max_bits = 1000;
6383 1612 : move16();
6384 : }
6385 :
6386 : /* write DCT 0 component */
6387 : /* write sign only if not the very first DCT coeff */
6388 1862 : IF( first_line == 0 )
6389 : {
6390 0 : IF( q_idx[0] > 0 )
6391 : {
6392 0 : push_next_indice( hMetaData, 1, 1 );
6393 0 : push_next_indice( hMetaData, q_idx[0], BITS_MASA2TOTTAL_DCT0 );
6394 : }
6395 : ELSE
6396 : {
6397 0 : push_next_indice( hMetaData, 0, 1 );
6398 0 : push_next_indice( hMetaData, negate( q_idx[0] ), BITS_MASA2TOTTAL_DCT0 );
6399 : }
6400 0 : nb_bits = add( nb_bits, BITS_MASA2TOTTAL_DCT0 + 1 );
6401 : }
6402 : ELSE
6403 : {
6404 1862 : push_next_indice( hMetaData, q_idx[0], BITS_MASA2TOTTAL_DCT0 );
6405 1862 : nb_bits = add( nb_bits, BITS_MASA2TOTTAL_DCT0 );
6406 : }
6407 :
6408 1862 : IF( q_idx[0] != 0 )
6409 : {
6410 1862 : i_min = 1;
6411 1862 : GR2 = 0;
6412 1862 : move16();
6413 1862 : move16();
6414 1862 : IF( GE_16( len_stream, 8 ) )
6415 : {
6416 1612 : nb_GR_min = find_optimal_GR_orders_fx( &q_idx[1], sub( len_stream, 1 ), 15, &GR1, &GR2, &i_min );
6417 : }
6418 : ELSE
6419 : {
6420 250 : nb_GR_min = find_optimal_GR_order_fx( &q_idx[1], sub( len_stream, 1 ), &GR1 );
6421 : }
6422 :
6423 1862 : assert( nb_GR_min < 1000 );
6424 1862 : changed = 1;
6425 1862 : update_needed = 0;
6426 1862 : move16();
6427 1862 : move16();
6428 1862 : WHILE( ( len_stream >= 8 ) && ( nb_GR_min > max_bits ) && ( changed >= 1 ) )
6429 : {
6430 0 : test();
6431 0 : test();
6432 0 : update_needed = 1;
6433 0 : changed = 0;
6434 0 : move16();
6435 0 : move16();
6436 0 : FOR( j = len_stream - 1; j > 6; j-- )
6437 : {
6438 0 : IF( GE_16( q_idx[j], 2 ) )
6439 : {
6440 :
6441 0 : IF( GT_16( j, i_min ) )
6442 : {
6443 0 : changed = 1;
6444 0 : move16();
6445 0 : nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR2 ) );
6446 0 : q_idx[j] = sub( q_idx[j], 2 );
6447 0 : move16();
6448 0 : nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR2 ) );
6449 : }
6450 : ELSE
6451 : {
6452 0 : changed = 1;
6453 0 : move16();
6454 0 : nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR1 ) );
6455 0 : q_idx[j] = sub( q_idx[j], 2 );
6456 0 : move16();
6457 0 : nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, 0 ) );
6458 : }
6459 : }
6460 0 : ELSE IF( EQ_16( q_idx[j], 1 ) )
6461 : {
6462 0 : IF( GT_16( j, i_min ) )
6463 : {
6464 0 : changed = 1;
6465 0 : move16();
6466 0 : nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR2 ) );
6467 0 : q_idx[j] = sub( q_idx[j], 1 );
6468 0 : move16();
6469 :
6470 0 : nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR2 ) );
6471 : }
6472 : ELSE
6473 : {
6474 0 : changed = 1;
6475 0 : move16();
6476 0 : nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR1 ) );
6477 0 : q_idx[j] = sub( q_idx[j], 1 );
6478 0 : move16();
6479 0 : nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, 0 ) );
6480 : }
6481 : }
6482 0 : IF( LT_16( nb_GR_min, max_bits ) )
6483 : {
6484 0 : BREAK;
6485 : }
6486 : }
6487 : }
6488 :
6489 1862 : IF( EQ_16( update_needed, 1 ) )
6490 : {
6491 : /* re-calculate */
6492 : /* find optimum length of the part encoded with GR2 */
6493 0 : nb_GR_min = find_optimal_GR_orders_fx( &q_idx[1], sub( len_stream, 1 ), 15, &GR1, &GR2, &i_min );
6494 : }
6495 :
6496 1862 : IF( GE_16( len_stream, 8 ) )
6497 : {
6498 : /* write number of indexes encoded with GR2 on 4 bits */
6499 1612 : push_next_indice( hMetaData, i_min, 4 );
6500 1612 : nb_bits = add( nb_bits, 4 );
6501 : /* write GR orders */
6502 1612 : push_next_indice( hMetaData, sub( GR1, 1 ), 1 );
6503 1612 : nb_bits = add( nb_bits, 1 );
6504 1612 : IF( EQ_16( GR1, 2 ) )
6505 : {
6506 1233 : push_next_indice( hMetaData, GR2, 1 );
6507 1233 : nb_bits = add( nb_bits, 1 );
6508 : }
6509 :
6510 : /* write GR data */
6511 9246 : FOR( i = 1; i <= i_min; i++ )
6512 : {
6513 7634 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_idx[i], 100, GR1 );
6514 : }
6515 :
6516 21582 : FOR( i = i_min + 1; i < len_stream; i++ )
6517 : {
6518 19970 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_idx[i], 100, GR2 );
6519 : }
6520 : }
6521 : ELSE
6522 : {
6523 : /* len_stream <= 8 */
6524 : /* write GR order */
6525 250 : push_next_indice( hMetaData, GR1, 1 );
6526 250 : nb_bits = add( nb_bits, 1 );
6527 1226 : FOR( i = 1; i < len_stream; i++ )
6528 : {
6529 976 : ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_idx[i], 100, GR1 );
6530 : }
6531 : }
6532 :
6533 1862 : nb_bits = add( nb_bits, nb_GR_min );
6534 :
6535 1862 : assert( nb_bits == ( hMetaData->nb_bits_tot - bits_pos ) );
6536 : }
6537 :
6538 1862 : return nb_bits;
6539 : }
6540 :
6541 :
6542 : /*-------------------------------------------------------------------------
6543 : * ivas_omasa_encode_masa_to_total()
6544 : *
6545 : *------------------------------------------------------------------------*/
6546 1862 : void ivas_omasa_encode_masa_to_total_fx(
6547 : Word32 masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Q30 */
6548 : BSTR_ENC_HANDLE hMetaData,
6549 : const Word16 low_bitrate_mode,
6550 : const Word16 nbands,
6551 : const Word16 nblocks )
6552 : {
6553 : Word16 i, j, k;
6554 : Word32 data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; // Q30
6555 : Word32 q_dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
6556 1862 : Word32 step = STEP_M2T_FX;
6557 : Word16 q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
6558 : Word32 dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
6559 : Word32 dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
6560 : Word16 bits_pos, nb_bits;
6561 : Word16 n_streams, len_stream, tmp_e;
6562 : Word32 L_tmp;
6563 1862 : move32();
6564 1862 : move16();
6565 :
6566 1862 : set32_fx( q_dct_data, 0, MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS );
6567 1862 : bits_pos = hMetaData->nb_bits_tot;
6568 1862 : k = 0;
6569 1862 : move16();
6570 1862 : move16();
6571 13722 : FOR( i = 0; i < nbands; i++ )
6572 : {
6573 42302 : FOR( j = 0; j < nblocks; j++ )
6574 : {
6575 30442 : data[k] = L_shr( masa_to_total_energy_ratio[j][i], Q5 );
6576 30442 : move32();
6577 30442 : k = add( k, 1 );
6578 : }
6579 : }
6580 :
6581 : /* DCT2 transform */
6582 1862 : n_streams = 1;
6583 1862 : move16();
6584 1862 : len_stream = imult1616( nbands, nblocks );
6585 1862 : SWITCH( len_stream )
6586 : {
6587 24 : case 4:
6588 24 : matrix_product_fx( dct4_fx, nblocks, nblocks, 0, data, 1, nblocks, 1, dct_data );
6589 24 : n_streams = 1;
6590 24 : len_stream = 4;
6591 24 : move16();
6592 24 : BREAK;
6593 226 : case 5:
6594 226 : matrix_product_fx( dct5_fx, nbands, nbands, 0, data, 1, nbands, 1, dct_data );
6595 226 : n_streams = 1;
6596 226 : len_stream = nbands;
6597 226 : move16();
6598 226 : move16();
6599 226 : BREAK;
6600 0 : case 8:
6601 0 : matrix_product_fx( dct8_fx, nbands, nbands, 0, data, 1, nbands, 1, dct_data );
6602 0 : n_streams = 1;
6603 0 : len_stream = nbands;
6604 0 : move16();
6605 0 : BREAK;
6606 378 : case 12:
6607 378 : matrix_product_fx( dct12_fx, nbands, nbands, 0, data, 1, nbands, 1, dct_data );
6608 378 : n_streams = 1;
6609 378 : len_stream = nbands;
6610 378 : move16();
6611 378 : move16();
6612 378 : BREAK;
6613 1234 : case 20:
6614 1234 : matrix_product_fx( dct5_fx, nbands, nbands, 0, data, nblocks, nbands, 1, dct_data_tmp );
6615 1234 : matrix_product_fx( dct_data_tmp, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 1, dct_data );
6616 1234 : n_streams = 1;
6617 1234 : len_stream = imult1616( nbands, nblocks );
6618 1234 : move16();
6619 1234 : move16();
6620 1234 : BREAK;
6621 0 : case 32:
6622 0 : matrix_product_fx( dct8_fx, nbands, nbands, 0, data, nblocks, nbands, 1, dct_data_tmp );
6623 0 : matrix_product_fx( dct_data_tmp, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 1, dct_data );
6624 0 : n_streams = nblocks;
6625 0 : len_stream = nbands;
6626 0 : move16();
6627 0 : move16();
6628 0 : BREAK;
6629 0 : default:
6630 0 : printf( "Incorrect number of coefficients for OMASA.\n" );
6631 0 : BREAK;
6632 : }
6633 :
6634 3724 : FOR( k = 0; k < n_streams; k++ )
6635 : {
6636 1862 : j = imult1616( k, len_stream );
6637 : /* quantize with fixed common step */
6638 1862 : L_tmp = BASOP_Util_Divide3232_Scale_newton( dct_data[j], step, &tmp_e );
6639 1862 : tmp_e = add( tmp_e, Q6 );
6640 1862 : q_idx[j] = rint_new_fx( L_shr( L_tmp, sub( 15, tmp_e ) ) /* Q16 */ ); // Q0
6641 1862 : move16();
6642 :
6643 1862 : IF( GT_16( q_idx[j], ( ( 1 << BITS_MASA2TOTTAL_DCT0 ) - 1 ) ) ) /* limit DCT0 to BITS_MASA2TOTTAL_DCT0 bit representation */
6644 : {
6645 0 : q_idx[j] = ( ( 1 << BITS_MASA2TOTTAL_DCT0 ) - 1 );
6646 0 : move16();
6647 : }
6648 :
6649 1862 : q_dct_data[j] = Mpy_32_16_1( step, shl( q_idx[j], 9 ) /* Q9 */ ); // Q25
6650 1862 : move16();
6651 :
6652 1862 : IF( q_idx[j] == 0 )
6653 : {
6654 0 : set16_fx( &q_idx[j], 0, len_stream );
6655 0 : set32_fx( &q_dct_data[j], 0, len_stream );
6656 : }
6657 : ELSE
6658 : {
6659 30442 : FOR( i = 1; i < len_stream; i++ )
6660 : {
6661 28580 : L_tmp = BASOP_Util_Divide3232_Scale_newton( dct_data[j + i], step, &tmp_e );
6662 28580 : tmp_e = add( tmp_e, Q6 );
6663 28580 : q_idx[j + i] = rint_new_fx( L_shr( L_tmp, sub( 15, tmp_e ) ) );
6664 28580 : move16();
6665 28580 : q_dct_data[j + i] = Mpy_32_16_1( step, shl( q_idx[j + i], 9 ) /* Q9 */ ); // Q25
6666 28580 : move32();
6667 28580 : IF( q_idx[j + i] <= 0 )
6668 : {
6669 19960 : q_idx[j + i] = imult1616( -2, q_idx[j + i] );
6670 19960 : move16();
6671 : }
6672 : ELSE
6673 : {
6674 8620 : q_idx[j + i] = sub( imult1616( 2, q_idx[j + i] ), 1 );
6675 8620 : move16();
6676 : }
6677 : }
6678 : }
6679 : }
6680 :
6681 : /* write data */
6682 1862 : nb_bits = 0;
6683 1862 : move16();
6684 3724 : FOR( i = 0; i < n_streams; i++ )
6685 : {
6686 1862 : nb_bits = add( nb_bits, write_stream_dct_coeffs_omasa_fx( &q_idx[i * len_stream], len_stream, hMetaData, ( i == 0 ), low_bitrate_mode ) );
6687 : }
6688 :
6689 : /* reconstruct masa2total */
6690 1862 : q_dct_data[0] = Mpy_32_16_1( step, shl( q_idx[0], 9 ) /* Q9 */ ); // Q25
6691 1862 : move32();
6692 30442 : FOR( i = 1; i < len_stream; i++ )
6693 : {
6694 28580 : IF( ( q_idx[i] % 2 ) == 0 )
6695 : {
6696 19960 : q_dct_data[i] = L_negate( Mpy_32_16_1( step, shl( q_idx[i], 8 ) /* Q9 */ ) ); // Q25
6697 19960 : move32();
6698 : }
6699 : ELSE
6700 : {
6701 8620 : q_dct_data[i] = Mpy_32_16_1( step, shl( add( q_idx[i], 1 ), 8 ) /* Q9 */ ); // Q25
6702 8620 : move32();
6703 : }
6704 : }
6705 :
6706 : /* inverse DCT2 transform */
6707 1862 : SWITCH( len_stream )
6708 : {
6709 24 : case 4:
6710 24 : matrix_product_q30_fx( dct4_fx, nblocks, nblocks, 1, q_dct_data, nblocks, 1, 0, dct_data_tmp );
6711 24 : Copy32( dct_data_tmp, q_dct_data, nblocks );
6712 24 : BREAK;
6713 226 : case 5:
6714 226 : matrix_product_q30_fx( dct5_fx, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp );
6715 226 : Copy32( dct_data_tmp, q_dct_data, nbands );
6716 226 : BREAK;
6717 0 : case 8:
6718 0 : matrix_product_q30_fx( dct8_fx, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp );
6719 0 : Copy32( dct_data_tmp, q_dct_data, nbands );
6720 0 : BREAK;
6721 378 : case 12:
6722 378 : matrix_product_q30_fx( dct12_fx, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp );
6723 378 : Copy32( dct_data_tmp, q_dct_data, nbands );
6724 378 : BREAK;
6725 1234 : case 20:
6726 1234 : matrix_product_fx( dct5_fx, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp );
6727 1234 : matrix_product_q30_fx( dct_data_tmp, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data ); /* reuse of variable*/
6728 1234 : BREAK;
6729 0 : case 32:
6730 0 : matrix_product_fx( dct8_fx, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp );
6731 0 : matrix_product_q30_fx( dct_data_tmp, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data );
6732 0 : BREAK;
6733 0 : default:
6734 0 : printf( "Incorrect number of coefficients for OMASA.\n" );
6735 0 : BREAK;
6736 : }
6737 :
6738 1862 : k = 0;
6739 1862 : move16();
6740 7498 : FOR( i = 0; i < nblocks; i++ )
6741 : {
6742 36078 : FOR( j = 0; j < nbands; j++ )
6743 : {
6744 30442 : masa_to_total_energy_ratio[i][j] = L_max( 0, q_dct_data[k] );
6745 30442 : masa_to_total_energy_ratio[i][j] = L_min( ONE_IN_Q30, masa_to_total_energy_ratio[i][j] ); // Q30
6746 30442 : move32();
6747 30442 : move32();
6748 30442 : k = add( k, 1 );
6749 : }
6750 : }
6751 1862 : assert( nb_bits == ( hMetaData->nb_bits_tot - bits_pos ) );
6752 :
6753 :
6754 1862 : return;
6755 : }
|