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