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 <stdint.h>
34 : #include <math.h>
35 : #include "options.h"
36 : #include "ivas_cnst.h"
37 : #include "prot_fx.h"
38 : #include "wmc_auto.h"
39 : #include "ivas_prot_fx.h"
40 : #include "prot_fx_enc.h"
41 :
42 :
43 : /*-----------------------------------------------------------------------*
44 : * Local constants
45 : *-----------------------------------------------------------------------*/
46 : #define MD_MAX_DIFF_AZIMUTH_FX 41943040
47 : #define MD_MAX_DIFF_ELEVATION_FX 41943040
48 :
49 : #define MD_MAX_DIFF_AZIMUTH 10
50 : #define MD_MAX_DIFF_ELEVATION 10
51 :
52 :
53 : /*-------------------------------------------------------------------*
54 : * ivas_ism_dtx_open()
55 : *
56 : * Open ISM DTX handle
57 : *-------------------------------------------------------------------*/
58 :
59 14 : ivas_error ivas_ism_dtx_open(
60 : Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
61 : )
62 : {
63 : ivas_error error;
64 : ISM_DTX_HANDLE hISMDTX;
65 : Word16 i;
66 :
67 14 : error = IVAS_ERR_OK;
68 14 : move32();
69 :
70 : /* Assign memory to DirAC handle */
71 14 : IF( ( hISMDTX = (ISM_DTX_HANDLE) malloc( sizeof( ISM_DTX_DATA ) ) ) == NULL )
72 : {
73 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM DTX Handle \n" ) );
74 : }
75 :
76 14 : hISMDTX->dtx_flag = 0;
77 14 : move16();
78 14 : hISMDTX->sce_id_dtx = 0;
79 14 : move16();
80 14 : hISMDTX->cnt_SID_ISM = -1;
81 14 : move16();
82 :
83 70 : FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
84 : {
85 56 : set32_fx( hISMDTX->long_term_energy_stereo_dmx_enc_fx[i], 0, PARAM_ISM_HYS_BUF_SIZE );
86 : }
87 14 : hISMDTX->long_term_energy_stereo_dmx_enc_e = 0;
88 14 : move16();
89 :
90 14 : set16_fx( hISMDTX->coh_fx, 0, MAX_NUM_OBJECTS );
91 :
92 14 : st_ivas->hISMDTX = hISMDTX;
93 :
94 14 : return error;
95 : }
96 :
97 :
98 : /*-------------------------------------------------------------------*
99 : * ivas_ism_get_dtx_enc()
100 : *
101 : * Analysis and decision about DTX in ISM format
102 : *-------------------------------------------------------------------*/
103 :
104 : /*! r: indication of DTX frame */
105 14826 : Word16 ivas_ism_dtx_enc_fx(
106 : ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */
107 : SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */
108 : const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/
109 : const Word16 nchan_ism, /* i : number of objects Q0*/
110 : const Word16 nchan_transport, /* i : number of transport channels Q0*/
111 : Word16 vad_flag[MAX_NUM_OBJECTS], /* i : VAD flag Q0*/
112 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
113 : Word16 md_diff_flag[], /* o : metadata differential flag Q0*/
114 : Word16 *sid_flag /* o : indication of SID frame Q0*/
115 : )
116 : {
117 : Word16 ch, dtx_flag;
118 : Word16 nBits, nBits_MD_max;
119 : Word16 nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id;
120 : Word16 lp_noise_fx[MAX_NUM_OBJECTS], lp_noise_variation_fx, lp_noise_mean_fx;
121 : Word16 lp_noise_max_fx;
122 : Word32 tmp1_fx, tmp2_fx;
123 : /* initialization */
124 52942 : FOR( ch = 0; ch < nchan_transport; ch++ )
125 : {
126 38116 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
127 38116 : move16();
128 : }
129 :
130 : /*------------------------------------------------------------------*
131 : * compute global ISM DTX flag
132 : *-----------------------------------------------------------------*/
133 :
134 : /* compute global ISM based on localVAD */
135 14826 : dtx_flag = 1;
136 14826 : move16();
137 52942 : FOR( ch = 0; ch < nchan_transport; ch++ )
138 : {
139 38116 : dtx_flag = s_and( dtx_flag, !vad_flag[ch] ); /* Q0 */
140 : }
141 :
142 : /* compute global ISM based on long-term background noise */
143 : /* one of the channels is active -> no DTX */
144 52942 : FOR( ch = 0; ch < nchan_transport; ch++ )
145 : {
146 38116 : lp_noise_fx[ch] = hSCE[ch]->hCoreCoder[0]->lp_noise_fx; /*Q8*/
147 38116 : move16();
148 : }
149 :
150 14826 : lp_noise_variation_fx = var_fx( lp_noise_fx, Q8, nchan_transport ); /*Q8*/
151 14826 : lp_noise_mean_fx = mean_fx( lp_noise_fx, nchan_transport ); /*Q8*/
152 :
153 14826 : test();
154 14826 : test();
155 14826 : if ( GT_16( lp_noise_mean_fx, ( 50 << 8 ) ) || ( GT_16( lp_noise_mean_fx, ( 25 << 8 ) ) && GT_16( lp_noise_variation_fx, ( 32 << 8 ) ) ) )
156 : {
157 134 : dtx_flag = 0;
158 134 : move16();
159 : }
160 :
161 :
162 : /* default DTX is applied at lower bitrates; otherwise DTX is applied only in silence */
163 14826 : maximum_fx( lp_noise_fx, nchan_transport, &lp_noise_max_fx ); /*Q8*/
164 :
165 14826 : test();
166 14826 : test();
167 14826 : test();
168 14826 : test();
169 14826 : test();
170 14826 : test();
171 14826 : test();
172 14826 : test();
173 33218 : if ( !( ( EQ_16( nchan_ism, 1 ) && LE_32( ivas_total_brate, IVAS_24k4 ) ) ||
174 28052 : ( EQ_16( nchan_ism, 2 ) && LE_32( ivas_total_brate, IVAS_48k ) ) ||
175 22552 : ( EQ_16( nchan_ism, 3 ) && LE_32( ivas_total_brate, IVAS_80k ) ) ||
176 16776 : ( EQ_16( nchan_ism, 4 ) && LE_32( ivas_total_brate, IVAS_96k ) ) ||
177 4916 : LT_16( lp_noise_max_fx, ( DTX_THR << 8 ) ) ) )
178 : {
179 3960 : dtx_flag = 0;
180 3960 : move16();
181 : }
182 :
183 : /*------------------------------------------------------------------*
184 : * Reset the bitstream
185 : *-----------------------------------------------------------------*/
186 :
187 14826 : IF( dtx_flag )
188 : {
189 : /* reset the bitstream (IVAS format signaling was already written) */
190 2437 : reset_indices_enc_fx( hSCE[0]->hCoreCoder[0]->hBstr, hSCE[0]->hCoreCoder[0]->hBstr->nb_ind_tot );
191 : }
192 :
193 : /*------------------------------------------------------------------*
194 : * decide about SID metadata to be sent or not (per object)
195 : * estimate the MD bit-budget consumption
196 : *-----------------------------------------------------------------*/
197 :
198 14826 : IF( dtx_flag )
199 : {
200 2437 : ivas_get_ism_sid_quan_bitbudget_fx( nchan_ism, &nBits_azimuth, &nBits_elevation, &tmp1_fx, &tmp2_fx, &nBits_coh, &nBits_sce_id );
201 :
202 2437 : nBits = 0;
203 2437 : move16();
204 9543 : FOR( ch = 0; ch < nchan_ism; ch++ )
205 : {
206 : /* check difference between current and last metadata */
207 7106 : md_diff_flag[ch] = 0;
208 7106 : move16();
209 7106 : if ( GT_32( L_abs( L_sub( hIsmMeta[ch]->azimuth_fx, hIsmMeta[ch]->last_azimuth_fx ) ), MD_MAX_DIFF_AZIMUTH_FX ) )
210 : {
211 3484 : md_diff_flag[ch] = 1;
212 3484 : move16();
213 : }
214 :
215 7106 : if ( GT_32( L_abs( L_sub( hIsmMeta[ch]->elevation_fx, hIsmMeta[ch]->last_elevation_fx ) ), MD_MAX_DIFF_ELEVATION_FX ) )
216 : {
217 1608 : md_diff_flag[ch] = 1;
218 1608 : move16();
219 : }
220 :
221 : /* estimate SID metadata bit-budget */
222 7106 : nBits = add( nBits, 1 ); /* number of objects Q0*/
223 7106 : nBits = add( nBits, 1 ); /* SID metadata flag Q0*/
224 7106 : IF( EQ_16( md_diff_flag[ch], 1 ) )
225 : {
226 3860 : nBits = add( nBits, nBits_azimuth ); /* Q0 */
227 3860 : nBits = add( nBits, nBits_elevation ); /* Q0 */
228 : }
229 : }
230 :
231 : /* calculate maximum available MD bit-budget */
232 2437 : nBits_MD_max = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC;
233 2437 : move16();
234 2437 : nBits_MD_max = sub( nBits_MD_max, SID_FORMAT_NBITS ); /* Q0 */
235 :
236 2437 : if ( GT_16( nchan_transport, 1 ) )
237 : {
238 2069 : nBits_MD_max = sub( nBits_MD_max, nBits_sce_id ); /* Q0 */
239 : }
240 :
241 6362 : FOR( ch = 0; ch < nchan_transport - 1; ch++ )
242 : {
243 3925 : nBits_MD_max = sub( nBits_MD_max, nBits_coh ); /* coherence Q0*/
244 : }
245 :
246 2437 : if ( GT_16( nchan_ism, 3 ) )
247 : {
248 1300 : nBits_MD_max = sub( nBits_MD_max, 1 ); /* ism_mode flag Q0*/
249 : }
250 :
251 : /* too many metadata bits -> switch to active coding */
252 2437 : if ( GT_16( nBits, nBits_MD_max ) )
253 : {
254 322 : dtx_flag = 0;
255 322 : move16();
256 : }
257 : }
258 :
259 : /*------------------------------------------------------------------*
260 : * set core_brate for all channels
261 : * get 'sid_flag' value
262 : *-----------------------------------------------------------------*/
263 :
264 14826 : *sid_flag = 0;
265 14826 : move16();
266 :
267 14826 : IF( !dtx_flag )
268 : {
269 : /* at least one of the channels is active -> no DTX */
270 45621 : FOR( ch = 0; ch < nchan_transport; ch++ )
271 : {
272 32910 : hSCE[ch]->hCoreCoder[0]->core_brate = -1;
273 32910 : move32();
274 32910 : set_bw_fx( IVAS_SCE, hSCE[ch]->element_brate, hSCE[ch]->hCoreCoder[0], MODE1 );
275 : }
276 :
277 12711 : hISMDTX->cnt_SID_ISM = -1;
278 12711 : move16();
279 :
280 : /* IVAS format signaling was erased in dtx() */
281 12711 : IF( EQ_16( hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot, 0 ) )
282 : {
283 : /* replicate ivas_write_format() */
284 1844 : Word16 ind = 2;
285 1844 : nBits = IVAS_FORMAT_SIGNALING_NBITS;
286 1844 : move16();
287 1844 : move16();
288 1844 : IF( GE_32( ivas_total_brate, IVAS_24k4 ) )
289 : {
290 1844 : ind = 4;
291 1844 : nBits = IVAS_FORMAT_SIGNALING_NBITS_EXTENDED;
292 1844 : move16();
293 1844 : move16();
294 : }
295 :
296 1844 : push_indice( hSCE[0]->hCoreCoder[0]->hBstr, IND_IVAS_FORMAT, ind, nBits );
297 : }
298 : }
299 : ELSE /* ism_dtx_flag == 1 */
300 : {
301 7321 : FOR( ch = 0; ch < nchan_transport; ch++ )
302 : {
303 5206 : hSCE[ch]->hCoreCoder[0]->cng_type = FD_CNG;
304 5206 : move16();
305 : }
306 :
307 : /* * update the global SID counter */
308 2115 : hISMDTX->cnt_SID_ISM = add( hISMDTX->cnt_SID_ISM, 1 ); /* Q0 */
309 2115 : move16();
310 2115 : IF( GE_16( hISMDTX->cnt_SID_ISM, hSCE[0]->hCoreCoder[0]->hDtxEnc->max_SID ) )
311 : {
312 : /* adaptive SID update interval */
313 145 : hSCE[0]->hCoreCoder[0]->hDtxEnc->max_SID = hSCE[0]->hCoreCoder[0]->hDtxEnc->interval_SID; /* Q0 */
314 145 : hISMDTX->cnt_SID_ISM = 0;
315 145 : move16();
316 145 : move16();
317 : }
318 :
319 : /* encode SID in one channel only */
320 7321 : FOR( ch = 0; ch < nchan_transport; ch++ )
321 : {
322 5206 : hSCE[ch]->hCoreCoder[0]->core_brate = FRAME_NO_DATA;
323 5206 : move32();
324 : }
325 :
326 2115 : IF( hISMDTX->cnt_SID_ISM == 0 )
327 : {
328 535 : hSCE[hISMDTX->sce_id_dtx]->hCoreCoder[0]->core_brate = SID_2k40;
329 535 : *sid_flag = 1;
330 535 : move32();
331 535 : move16();
332 : }
333 : }
334 :
335 14826 : test();
336 14826 : IF( EQ_16( dtx_flag, 1 ) && *sid_flag == 0 )
337 : {
338 1580 : set16_fx( md_diff_flag, 0, nchan_transport );
339 : }
340 :
341 14826 : return dtx_flag;
342 : }
343 :
344 : /*-------------------------------------------------------------------*
345 : * ivas_ism_get_sce_id_dtx()
346 : *
347 : *
348 : *-------------------------------------------------------------------*/
349 14826 : void ivas_ism_get_sce_id_dtx_fx(
350 : ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */
351 : SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */
352 : const Word16 nchan_transport, /* i : number of transport channels Q0*/
353 : const Word16 input_frame /* i : input frame length per channel Q0*/
354 : )
355 : {
356 : Word32 tmp_energy[MAX_NUM_OBJECTS];
357 : Word16 tmp_energy_e[MAX_NUM_OBJECTS];
358 : Word16 i, j;
359 : Word16 long_term_energy_stereo_dmx_enc_e[MAX_NUM_OBJECTS];
360 : Word16 max_exp;
361 :
362 14826 : set16_fx( long_term_energy_stereo_dmx_enc_e, hISMDTX->long_term_energy_stereo_dmx_enc_e, nchan_transport );
363 14826 : IF( EQ_16( nchan_transport, 1 ) )
364 : {
365 3026 : hISMDTX->sce_id_dtx = 0;
366 3026 : move16();
367 :
368 3026 : return;
369 : }
370 :
371 : /* Initialize*/
372 11800 : set32_fx( tmp_energy, 0, MAX_NUM_OBJECTS );
373 11800 : set16_fx( tmp_energy_e, 0, MAX_NUM_OBJECTS );
374 :
375 : /* compute long term energy parameter */
376 46890 : FOR( j = 0; j < nchan_transport; j++ )
377 : {
378 350900 : FOR( i = 0; i < ( PARAM_ISM_HYS_BUF_SIZE - 1 ); i++ )
379 : {
380 315810 : hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i] = hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i + 1]; /* exp(hISMDTX->long_term_energy_stereo_dmx_enc_e) */
381 315810 : move32();
382 : }
383 35090 : long_term_energy_stereo_dmx_enc_e[j] = 20;
384 35090 : move16();
385 35090 : hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1] = sum2_32_fx( hSCE[j]->hCoreCoder[0]->input32_fx, input_frame, &long_term_energy_stereo_dmx_enc_e[j] ); /*Resultant Q_lte=2*Q(input_fx)+1=2*-5+1=>-9*/
386 35090 : move32();
387 35090 : tmp_energy[j] = L_deposit_l( 0 );
388 35090 : move32();
389 350900 : FOR( i = 0; i < PARAM_ISM_HYS_BUF_SIZE - 1; i++ )
390 : {
391 315810 : tmp_energy[j] = BASOP_Util_Add_Mant32Exp( tmp_energy[j], tmp_energy_e[j], hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i], hISMDTX->long_term_energy_stereo_dmx_enc_e, &tmp_energy_e[j] ); /*Resultant Q(tmp_energy)=Q_lte*/
392 315810 : move32();
393 : }
394 35090 : tmp_energy[j] = BASOP_Util_Add_Mant32Exp( tmp_energy[j], tmp_energy_e[j], hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1], long_term_energy_stereo_dmx_enc_e[j], &tmp_energy_e[j] ); /*Resultant Q(tmp_energy)=Q_lte*/
395 35090 : move32();
396 : }
397 :
398 11800 : maximum_fx( long_term_energy_stereo_dmx_enc_e, nchan_transport, &max_exp );
399 11800 : max_exp = s_max( max_exp, hISMDTX->long_term_energy_stereo_dmx_enc_e );
400 46890 : FOR( j = 0; j < nchan_transport; j++ )
401 : {
402 350900 : FOR( i = 0; i < PARAM_ISM_HYS_BUF_SIZE - 1; i++ )
403 : {
404 315810 : hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i] = L_shr( hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i], max_exp - hISMDTX->long_term_energy_stereo_dmx_enc_e ); /* exp(max_exp) */
405 315810 : move32();
406 : }
407 35090 : hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1] = L_shr( hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1], max_exp - long_term_energy_stereo_dmx_enc_e[j] ); /* exp(max_exp) */
408 35090 : move32();
409 : }
410 11800 : hISMDTX->long_term_energy_stereo_dmx_enc_e = max_exp;
411 11800 : move16();
412 : /* determine the sce_id */
413 11800 : hISMDTX->sce_id_dtx = 0;
414 11800 : move16();
415 35090 : FOR( j = 1; j < nchan_transport; j++ )
416 : {
417 23290 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tmp_energy[j], tmp_energy_e[j], tmp_energy[hISMDTX->sce_id_dtx], tmp_energy_e[hISMDTX->sce_id_dtx] ), 1 ) )
418 : {
419 12161 : hISMDTX->sce_id_dtx = j;
420 12161 : move16();
421 : }
422 : }
423 :
424 11800 : return;
425 : }
426 :
427 : /*-------------------------------------------------------------------*
428 : * ivas_ism_coh_estim_dtx_enc()
429 : *
430 : *
431 : *-------------------------------------------------------------------*/
432 535 : void ivas_ism_coh_estim_dtx_enc_fx(
433 : ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */
434 : SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */
435 : const Word16 nchan_transport, /* i : number of transport channels Q0*/
436 : const Word16 input_frame /* i : input frame length Q0*/
437 : )
438 : {
439 : Encoder_State *st, *st_id0;
440 : Word16 sce_id, i;
441 : Word32 acorr_ene_fx[MAX_NUM_OBJECTS], xcorr_ene_fx;
442 : Word16 acorr_ene_e[MAX_NUM_OBJECTS], xcorr_ene_e;
443 : Word16 norm_inp, norm_inp0;
444 : Word16 tot_exp, tot_exp2;
445 : Word32 scaled_inp, scaled_inp0;
446 535 : set16_fx( acorr_ene_e, 0, MAX_NUM_OBJECTS );
447 :
448 535 : IF( EQ_16( nchan_transport, 1 ) )
449 : {
450 55 : hISMDTX->coh_fx[0] = 0;
451 55 : move16();
452 55 : return;
453 : }
454 :
455 : /* Compute Coherence */
456 480 : acorr_ene_fx[hISMDTX->sce_id_dtx] = 0;
457 480 : move32();
458 480 : st_id0 = hSCE[hISMDTX->sce_id_dtx]->hCoreCoder[0];
459 :
460 461280 : FOR( i = 0; i < input_frame; i++ )
461 : {
462 460800 : norm_inp = norm_l( st_id0->input32_fx[i] );
463 460800 : scaled_inp = L_shl( st_id0->input32_fx[i], norm_inp );
464 460800 : tot_exp = shl( sub( 20, norm_inp ), 1 );
465 460800 : acorr_ene_fx[hISMDTX->sce_id_dtx] = BASOP_Util_Add_Mant32Exp( acorr_ene_fx[hISMDTX->sce_id_dtx], acorr_ene_e[hISMDTX->sce_id_dtx], Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &acorr_ene_e[hISMDTX->sce_id_dtx] ); /* exp(acorr_ene_e) */
466 460800 : move32();
467 : }
468 :
469 2004 : FOR( sce_id = 0; sce_id < nchan_transport; sce_id++ )
470 : {
471 1524 : IF( EQ_16( sce_id, hISMDTX->sce_id_dtx ) )
472 : {
473 480 : hISMDTX->coh_fx[sce_id] = 32767; /* 1 in Q15 */
474 480 : move16();
475 480 : CONTINUE;
476 : }
477 :
478 1044 : st = hSCE[sce_id]->hCoreCoder[0];
479 :
480 1044 : acorr_ene_fx[sce_id] = 0;
481 1044 : xcorr_ene_fx = 0;
482 1044 : xcorr_ene_e = 0;
483 1044 : move32();
484 1044 : move32();
485 1044 : move16();
486 :
487 1003284 : FOR( i = 0; i < input_frame; i++ )
488 : {
489 1002240 : norm_inp = norm_l( st->input32_fx[i] );
490 1002240 : scaled_inp = L_shl( st->input32_fx[i], norm_inp );
491 1002240 : tot_exp = shl( sub( sub( 31, st->q_inp32 ), norm_inp ), 1 );
492 1002240 : acorr_ene_fx[sce_id] = BASOP_Util_Add_Mant32Exp( acorr_ene_fx[sce_id], acorr_ene_e[sce_id], Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &acorr_ene_e[sce_id] ); /* exp(acorr_ene_e) */
493 1002240 : move32();
494 1002240 : norm_inp0 = norm_l( st_id0->input32_fx[i] );
495 1002240 : scaled_inp0 = L_shl( st_id0->input32_fx[i], norm_inp0 );
496 1002240 : tot_exp2 = add( sub( sub( 31, st_id0->q_inp32 ), norm_inp0 ), sub( sub( 31, st->q_inp32 ), norm_inp ) );
497 1002240 : xcorr_ene_fx = BASOP_Util_Add_Mant32Exp( xcorr_ene_fx, xcorr_ene_e, Mult_32_32( scaled_inp, scaled_inp0 ), tot_exp2, &xcorr_ene_e ); /* exp(xcorr_ene_e) */
498 : }
499 : Word16 coh_e;
500 1044 : Word16 temp_e = acorr_ene_e[hISMDTX->sce_id_dtx] + acorr_ene_e[sce_id];
501 1044 : Word32 temp = Sqrt32( L_add( Mult_32_32( acorr_ene_fx[hISMDTX->sce_id_dtx], acorr_ene_fx[sce_id] ), EPSILON_FX ), &temp_e ); /*fabsf( xcorr_ene ) / ( sqrtf( ( acorr_ene[hISMDTX->sce_id_dtx] * acorr_ene[sce_id] ) + EPSILON ) );*/
502 1044 : hISMDTX->coh_fx[sce_id] = BASOP_Util_Divide3232_Scale( L_abs( xcorr_ene_fx ), temp, &coh_e ); /* coh_e + (xcorr_ene_e - temp_e) */
503 1044 : move16();
504 1044 : coh_e = add( coh_e, sub( xcorr_ene_e, temp_e ) );
505 1044 : IF( coh_e < 0 )
506 : {
507 673 : hISMDTX->coh_fx[sce_id] = shl( hISMDTX->coh_fx[sce_id], coh_e );
508 673 : move16();
509 673 : coh_e = 0;
510 : }
511 : /* ensure value of coherence is between [0,1] */
512 1044 : hISMDTX->coh_fx[sce_id] = check_bounds_s_fx( hISMDTX->coh_fx[sce_id], 0, shl_sat( 1, 15 - coh_e ) ); /* Q0 */
513 1044 : hISMDTX->coh_fx[sce_id] = shl_sat( hISMDTX->coh_fx[sce_id], coh_e );
514 1044 : move16();
515 1044 : move16();
516 : }
517 :
518 480 : return;
519 : }
|