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