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