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 <assert.h>
36 : #include "options.h"
37 : #include "ivas_prot.h"
38 : #include "prot.h"
39 : #include "cnst.h"
40 : #include "ivas_cnst.h"
41 : #include "ivas_rom_com.h"
42 : #include "wmc_auto.h"
43 :
44 : /*-------------------------------------------------------------------------
45 : * Local function definitions
46 : *------------------------------------------------------------------------*/
47 :
48 :
49 20720 : static void ivas_param_ism_compute_obj_parameters(
50 : const int16_t nchan_ism, /* i : number of ISM channels */
51 : float reference_power_obj[MAX_NUM_OBJECTS][PARAM_ISM_MDFT_NO_SLOTS][DIRAC_NO_FB_BANDS_MAX], /* i : Reference power */
52 : PARAM_ISM_CONFIG_HANDLE hParamIsm /* i/o: Param ISM Enc Handle */
53 : )
54 : {
55 : int16_t i, b, m, br, mr;
56 : int16_t brange_start, brange_end, mrange_start, mrange_end, time_merge_fac;
57 : float power_ratios_m[MAX_PARAM_ISM_NBANDS][MAX_PARAM_ISM_NBLOCKS];
58 : float ref_power_local_frame[MAX_NUM_OBJECTS];
59 : float tmp_ratio;
60 :
61 20720 : set_f( ref_power_local_frame, 0, MAX_NUM_OBJECTS );
62 :
63 20720 : assert( nchan_ism == 3 || nchan_ism == 4 );
64 :
65 248640 : for ( b = 0; b < hParamIsm->nbands; b++ )
66 : {
67 : /* current frequency band borders */
68 227920 : brange_start = hParamIsm->band_grouping[b];
69 227920 : brange_end = hParamIsm->band_grouping[b + 1];
70 :
71 : /* time slots to aggregate for current block */
72 227920 : time_merge_fac = PARAM_ISM_MDFT_NO_SLOTS / hParamIsm->nblocks[b];
73 :
74 455840 : for ( m = 0; m < hParamIsm->nblocks[b]; m++ )
75 : {
76 : int16_t index_1, index_2;
77 : float ref_power_local[MAX_NUM_OBJECTS];
78 :
79 : /* initialize to 0 so unused entries are not considered later */
80 227920 : set_f( ref_power_local, 0, MAX_NUM_OBJECTS );
81 :
82 : /* current block borders */
83 227920 : mrange_start = m * time_merge_fac;
84 227920 : mrange_end = ( m + 1 ) * time_merge_fac;
85 :
86 : /* for each object, sum up reference power within current T/F tile */
87 :
88 1065350 : for ( i = 0; i < nchan_ism; i++ )
89 : {
90 4187150 : for ( mr = mrange_start; mr < mrange_end; mr++ )
91 : {
92 76434520 : for ( br = brange_start; br < brange_end; br++ )
93 : {
94 73084800 : ref_power_local[i] += reference_power_obj[i][mr][br];
95 : }
96 : }
97 : /* Sum up T/F tiles per object */
98 837430 : ref_power_local_frame[i] += ref_power_local[i];
99 : }
100 :
101 : /* find two dominant objects and derive object indices for current T/F tile */
102 227920 : if ( ref_power_local[0] >= ref_power_local[1] )
103 : {
104 108004 : index_1 = 0;
105 108004 : index_2 = 1;
106 : }
107 : else
108 : {
109 119916 : index_1 = 1;
110 119916 : index_2 = 0;
111 : }
112 :
113 609510 : for ( i = MAX_PARAM_ISM_WAVE; i < nchan_ism; i++ )
114 : {
115 381590 : if ( ref_power_local[i] > ref_power_local[index_1] )
116 : {
117 71852 : index_2 = index_1;
118 71852 : index_1 = i;
119 : }
120 309738 : else if ( ref_power_local[i] > ref_power_local[index_2] )
121 : {
122 107957 : index_2 = i;
123 : }
124 : }
125 :
126 : /* Copy the quantized indices */
127 227920 : hParamIsm->obj_indices[b][m][0] = index_1;
128 227920 : hParamIsm->obj_indices[b][m][1] = index_2;
129 :
130 : /* Compute power ratios */
131 227920 : if ( ( ref_power_local[index_1] + ref_power_local[index_2] ) == 0.f )
132 : {
133 0 : power_ratios_m[b][m] = 0.5;
134 : }
135 : else
136 : {
137 227920 : power_ratios_m[b][m] = ref_power_local[index_1] / ( ref_power_local[index_1] + ref_power_local[index_2] );
138 : }
139 227920 : assert( ( power_ratios_m[b][m] >= 0.5 ) && ( power_ratios_m[b][m] <= 1 ) );
140 :
141 : /* Quantize power ratios */
142 : /* Power ratio range [0.5,1] is mapped to [0,1] first, rounding via truncation float->integer */
143 227920 : hParamIsm->power_ratios_idx[b][m] = (int16_t) ( ( ( power_ratios_m[b][m] - 0.5f ) * 2 ) * ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) + 0.5f );
144 227920 : assert( ( hParamIsm->power_ratios_idx[b][m] >= 0 ) && ( hParamIsm->power_ratios_idx[b][m] <= ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) ) );
145 : #ifdef DEBUG_MODE_PARAM_ISM
146 : dbgwrite( ref_power_local, sizeof( float ), 3, 1, "res/ParamISM_refPowerLocal.dat" );
147 : dbgwrite( hParamIsm->obj_indices[b][m], sizeof( int16_t ), 2, 1, "res/ParamISM_objIndices.dat" );
148 : dbgwrite( &hParamIsm->power_ratios_idx[b][m], sizeof( int16_t ), 1, 1, "res/ParamISM_powerRatioIdx.dat" );
149 : dbgwrite( &power_ratios_m[b][m], sizeof( float ), 1, 1, "res/ParamISM_powerRatio.dat" );
150 : #endif
151 : }
152 : }
153 :
154 : /* Check if objects have roughly equal power by comparing reference power of first object against all others*/
155 20720 : hParamIsm->flag_equal_energy = 1;
156 20896 : for ( i = 1; i < nchan_ism; i++ )
157 : {
158 20896 : if ( ref_power_local_frame[i] != 0.0f )
159 : {
160 20896 : tmp_ratio = ref_power_local_frame[0] / ref_power_local_frame[i];
161 :
162 20896 : if ( ( tmp_ratio > 0.975f ) && ( tmp_ratio < 1.025f ) )
163 : {
164 176 : hParamIsm->flag_equal_energy &= 1;
165 : }
166 : else
167 : {
168 20720 : hParamIsm->flag_equal_energy &= 0;
169 20720 : break;
170 : }
171 : }
172 : }
173 :
174 20720 : return;
175 : }
176 :
177 :
178 20720 : static void ivas_param_ism_enc_quantize_DOA(
179 : const int16_t nchan_ism, /* i : number of ISM channels */
180 : ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS], /* i : ISM metadata */
181 : PARAM_ISM_CONFIG_HANDLE hParamIsm /* i/o: Param ISM encoder handle */
182 : )
183 : {
184 : int16_t i, azi_idx, ele_idx;
185 : float valQ;
186 :
187 :
188 : /* Loop over objects */
189 96850 : for ( i = 0; i < nchan_ism; i++ )
190 : {
191 : /* Quantize the elevation and obtain quantized elevation value and index */
192 76130 : ele_idx = ism_quant_meta( hIsmMetaData[i]->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS );
193 :
194 : /* Obtain the index of quantized azimuth values */
195 76130 : azi_idx = ism_quant_meta( hIsmMetaData[i]->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
196 :
197 : /*Replace azimuth with quantized values */
198 76130 : hIsmMetaData[i]->azimuth = valQ;
199 :
200 : /* Copy the quantized indices */
201 76130 : hParamIsm->azi_index[i] = azi_idx;
202 76130 : hParamIsm->ele_index[i] = ele_idx;
203 : }
204 :
205 20720 : return;
206 : }
207 :
208 :
209 : /*-------------------------------------------------------------------------*
210 : * ivas_param_ism_stereo_dmx()
211 : *
212 : * Downmix input channels to stereo
213 : *-------------------------------------------------------------------------*/
214 :
215 20720 : void ivas_param_ism_stereo_dmx(
216 : Encoder_Struct *st_ivas, /* i : IVAS encoder structure */
217 : float *data[MAX_NUM_OBJECTS], /* i/o: input signal/stereo dmx */
218 : const int16_t input_frame /* i : Length of input frame */
219 : )
220 : {
221 : int16_t i, j;
222 : float alpha, azi_shift, tmp, tmp_1;
223 : float cardioid_left[MAX_NUM_OBJECTS], cardioid_right[MAX_NUM_OBJECTS];
224 : float stereo_dmx[2][L_FRAME48k];
225 : float dmx_gain, ene_dmx, ene_data, grad;
226 : float last_dmx_gain;
227 : float last_cardioid_left;
228 : ISM_METADATA_HANDLE hIsmMetaData;
229 :
230 20720 : push_wmops( "ivas_param_ism_st_dmx" );
231 :
232 : /*Initialization*/
233 20720 : alpha = 0.5;
234 20720 : azi_shift = 0;
235 20720 : dmx_gain = 0;
236 20720 : ene_dmx = 0;
237 20720 : ene_data = 0;
238 20720 : last_dmx_gain = st_ivas->hParamIsm->last_dmx_gain;
239 :
240 : /* Set the stereo dmx to zero */
241 20720 : set_zero( stereo_dmx[0], L_FRAME48k );
242 20720 : set_zero( stereo_dmx[1], L_FRAME48k );
243 :
244 : /* Loop over all objects */
245 96850 : for ( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ )
246 : {
247 76130 : hIsmMetaData = st_ivas->hIsmMetaData[i];
248 76130 : last_cardioid_left = st_ivas->hParamIsm->last_cardioid_left[i];
249 : /*Compute the Cardioids for the corresponding object direction */
250 76130 : tmp = hIsmMetaData->azimuth * ( EVS_PI / 180 );
251 76130 : tmp_1 = ( EVS_PI / 2 ) + azi_shift;
252 76130 : cardioid_left[i] = alpha + ( 1 - alpha ) * cosf( tmp - tmp_1 );
253 76130 : if ( st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame > 0 )
254 : {
255 : float last_cardioid_right;
256 76066 : last_cardioid_right = 1.0f - last_cardioid_left;
257 : /* Smoothing */
258 76066 : cardioid_left[i] = 0.75f * cardioid_left[i] + 0.25f * last_cardioid_left;
259 76066 : grad = ( cardioid_left[i] - last_cardioid_left ) * 2.0f / (float) input_frame; /* for the right cardioid, multiply with -1 */
260 : /* Cardioids sum up to 1 */
261 76066 : cardioid_right[i] = 1.0f - cardioid_left[i]; /* corresponds to: alpha + ( 1 - alpha ) * cosf( tmp + tmp_1 ); */
262 : /* Loop over all samples */
263 36587746 : for ( j = 0; j < input_frame / 2; j++ )
264 : {
265 36511680 : tmp = data[i][j];
266 36511680 : stereo_dmx[0][j] += ( ( last_cardioid_left + j * grad ) * tmp ); /* DMX Left */
267 36511680 : stereo_dmx[1][j] += ( ( last_cardioid_right + j * grad * ( -1.0f ) ) * tmp ); /* DMX Right */
268 36511680 : ene_data += ( tmp * tmp ); /* energy of all objects combined */
269 : }
270 36587746 : for ( ; j < input_frame; j++ )
271 : {
272 36511680 : tmp = data[i][j];
273 36511680 : stereo_dmx[0][j] += cardioid_left[i] * tmp; /* DMX Left */
274 36511680 : stereo_dmx[1][j] += cardioid_right[i] * tmp; /* DMX Right */
275 36511680 : ene_data += ( tmp * tmp ); /* energy of all objects combined */
276 : }
277 : }
278 : else
279 : {
280 : /* Cardioids sum up to 1 */
281 64 : cardioid_right[i] = 1.0f - cardioid_left[i]; /* corresponds to: alpha + ( 1 - alpha ) * cosf( tmp + tmp_1 ); */
282 : /* Loop over all samples */
283 61504 : for ( j = 0; j < input_frame; j++ )
284 : {
285 61440 : tmp = data[i][j];
286 61440 : stereo_dmx[0][j] += cardioid_left[i] * tmp; /* DMX Left */
287 61440 : stereo_dmx[1][j] += cardioid_right[i] * tmp; /* DMX Right */
288 61440 : ene_data += ( tmp * tmp ); /* energy of all objects combined */
289 : }
290 : }
291 76130 : st_ivas->hParamIsm->last_cardioid_left[i] = cardioid_left[i];
292 : }
293 :
294 : /* Energy compensation */
295 19911920 : for ( j = 0; j < input_frame; j++ )
296 : {
297 19891200 : ene_dmx += stereo_dmx[0][j] * stereo_dmx[0][j] + stereo_dmx[1][j] * stereo_dmx[1][j];
298 : }
299 20720 : dmx_gain = sqrtf( ene_data / ( ene_dmx + EPSILON ) );
300 : /* Smoothing */
301 20720 : if ( st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame > 0 )
302 : {
303 20703 : dmx_gain = 0.75f * dmx_gain + 0.25f * last_dmx_gain;
304 : /* 10ms ramp */
305 20703 : grad = ( dmx_gain - last_dmx_gain ) * 2.0f / (float) input_frame; /* slope between two consecutive gains, 480 samples length */
306 9958143 : for ( i = 0; i < ( input_frame / 2 ); i++ )
307 : {
308 9937440 : stereo_dmx[0][i] *= ( last_dmx_gain + i * grad );
309 9937440 : stereo_dmx[1][i] *= ( last_dmx_gain + i * grad );
310 : }
311 9958143 : for ( ; i < input_frame; i++ )
312 : {
313 9937440 : stereo_dmx[0][i] *= dmx_gain;
314 9937440 : stereo_dmx[1][i] *= dmx_gain;
315 : }
316 : }
317 : else
318 : {
319 16337 : for ( j = 0; j < input_frame; j++ )
320 : {
321 16320 : stereo_dmx[0][j] *= dmx_gain;
322 16320 : stereo_dmx[1][j] *= dmx_gain;
323 : }
324 : }
325 20720 : st_ivas->hParamIsm->last_dmx_gain = dmx_gain;
326 :
327 : /* Copy the stereo dmx to data variable */
328 20720 : mvr2r( stereo_dmx[0], data[0], input_frame );
329 20720 : mvr2r( stereo_dmx[1], data[1], input_frame );
330 :
331 20720 : pop_wmops();
332 :
333 20720 : return;
334 : }
335 :
336 :
337 : /*-------------------------------------------------------------------------*
338 : * ivas_param_ism_enc_open()
339 : *
340 : * Open Param ISM handle
341 : *-------------------------------------------------------------------------*/
342 :
343 320 : ivas_error ivas_param_ism_enc_open(
344 : Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
345 : )
346 : {
347 : int16_t i;
348 : IVAS_FB_CFG *fb_cfg;
349 : PARAM_ISM_CONFIG_HANDLE hParamIsm;
350 : int16_t max_bins;
351 : int32_t input_Fs;
352 : ivas_error error;
353 :
354 320 : error = IVAS_ERR_OK;
355 :
356 :
357 : /* Assign memory to Param Object handle */
358 320 : if ( ( hParamIsm = (PARAM_ISM_CONFIG_HANDLE) malloc( sizeof( PARAM_ISM_CONFIG_DATA ) ) ) == NULL )
359 : {
360 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM\n" ) );
361 : }
362 :
363 320 : input_Fs = st_ivas->hEncoderConfig->input_Fs;
364 :
365 :
366 : /* set FB config. */
367 320 : if ( ( error = ivas_fb_set_cfg( &fb_cfg, ISM_FORMAT, st_ivas->hEncoderConfig->nchan_inp, 0, 0, input_Fs, 0 ) ) != IVAS_ERR_OK )
368 : {
369 0 : return error;
370 : }
371 :
372 : /* Allocate and initialize FB mixer handle */
373 320 : if ( ( error = ivas_FB_mixer_open( &( hParamIsm->hFbMixer ), input_Fs, fb_cfg, 0 ) ) != IVAS_ERR_OK )
374 : {
375 0 : return error;
376 : }
377 :
378 320 : ivas_param_ism_config( hParamIsm, st_ivas->hEncoderConfig->nchan_inp );
379 :
380 : /* Assign memories for Band and Block grouping */
381 320 : hParamIsm->nbands = MAX_PARAM_ISM_NBANDS;
382 :
383 320 : max_bins = (int16_t) ( ( MDFT_FB_BANDS_240 * input_Fs ) / 48000 );
384 4160 : for ( i = 0; i < ( hParamIsm->nbands + 1 ); i++ )
385 : {
386 3840 : hParamIsm->band_grouping[i] = CLDFB_TO_MDFT_FAC * Param_ISM_band_grouping[i];
387 3840 : if ( ( Param_ISM_band_grouping[i] * CLDFB_TO_MDFT_FAC ) > max_bins )
388 : {
389 0 : hParamIsm->band_grouping[i] = max_bins;
390 : }
391 : }
392 :
393 320 : set_s( hParamIsm->noisy_speech_buffer, 0, PARAM_ISM_HYS_BUF_SIZE );
394 :
395 320 : st_ivas->hParamIsm = hParamIsm;
396 :
397 320 : return error;
398 : }
399 :
400 :
401 : /*-------------------------------------------------------------------------*
402 : * ivas_param_ism_enc_close()
403 : *
404 : * Close Param ISM encoder handle
405 : *-------------------------------------------------------------------------*/
406 :
407 933 : void ivas_param_ism_enc_close(
408 : PARAM_ISM_CONFIG_HANDLE *hParamIsm, /* i/o: ParamISM handle */
409 : const int32_t input_Fs /* i : input sampling_rate */
410 : )
411 : {
412 933 : if ( hParamIsm == NULL || *hParamIsm == NULL )
413 : {
414 613 : return;
415 : }
416 :
417 320 : ivas_FB_mixer_close( &( *hParamIsm )->hFbMixer, input_Fs, 0 );
418 :
419 320 : free( ( *hParamIsm ) );
420 320 : ( *hParamIsm ) = NULL;
421 :
422 320 : return;
423 : }
424 :
425 :
426 : /*-------------------------------------------------------------------------*
427 : * ivas_param_ism_enc()
428 : *
429 : * Parametric ISM encoder
430 : *-------------------------------------------------------------------------*/
431 :
432 20720 : void ivas_param_ism_enc(
433 : Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */
434 : float *data[MAX_NUM_OBJECTS], /* i : input signal */
435 : const int16_t input_frame /* i : input frame length per channel */
436 : )
437 : {
438 : int16_t i, j, ts, l_ts;
439 : int16_t nchan_ism;
440 : int16_t num_time_slots;
441 : float *pcm_in[MAX_NUM_OBJECTS];
442 : float fb_RealBuffer[MAX_NUM_OBJECTS][DIRAC_NO_FB_BANDS_MAX];
443 : float fb_ImagBuffer[MAX_NUM_OBJECTS][DIRAC_NO_FB_BANDS_MAX];
444 : float *p_fb_RealBuffer[MAX_NUM_OBJECTS];
445 : float *p_fb_ImagBuffer[MAX_NUM_OBJECTS];
446 : float reference_power_obj[MAX_NUM_OBJECTS][PARAM_ISM_MDFT_NO_SLOTS][DIRAC_NO_FB_BANDS_MAX];
447 : PARAM_ISM_CONFIG_HANDLE hParamIsm;
448 :
449 20720 : nchan_ism = st_ivas->hEncoderConfig->nchan_ism;
450 20720 : hParamIsm = st_ivas->hParamIsm;
451 :
452 20720 : push_wmops( "ivas_param_ism_enc" );
453 :
454 20720 : l_ts = input_frame / PARAM_ISM_MDFT_NO_SLOTS;
455 20720 : num_time_slots = PARAM_ISM_MDFT_NO_SLOTS;
456 :
457 96850 : for ( i = 0; i < nchan_ism; i++ )
458 : {
459 76130 : pcm_in[i] = data[i];
460 :
461 76130 : set_zero( fb_RealBuffer[i], DIRAC_NO_FB_BANDS_MAX );
462 76130 : set_zero( fb_ImagBuffer[i], DIRAC_NO_FB_BANDS_MAX );
463 76130 : p_fb_RealBuffer[i] = &fb_RealBuffer[i][0];
464 76130 : p_fb_ImagBuffer[i] = &fb_ImagBuffer[i][0];
465 : }
466 :
467 103600 : for ( ts = 0; ts < num_time_slots; ts++ )
468 : {
469 82880 : ivas_fb_mixer_get_windowed_fr( hParamIsm->hFbMixer, pcm_in, p_fb_RealBuffer, p_fb_ImagBuffer, l_ts, l_ts, hParamIsm->hFbMixer->fb_cfg->num_in_chans );
470 :
471 82880 : ivas_fb_mixer_update_prior_input( hParamIsm->hFbMixer, pcm_in, l_ts, hParamIsm->hFbMixer->fb_cfg->num_in_chans );
472 :
473 387400 : for ( i = 0; i < nchan_ism; i++ )
474 : {
475 304520 : pcm_in[i] += l_ts;
476 73389320 : for ( j = 0; j < DIRAC_NO_FB_BANDS_MAX; j++ )
477 : {
478 73084800 : reference_power_obj[i][ts][j] = fb_RealBuffer[i][j] * fb_RealBuffer[i][j] + fb_ImagBuffer[i][j] * fb_ImagBuffer[i][j];
479 : }
480 : }
481 : }
482 :
483 : /* Quantize DOAs */
484 20720 : ivas_param_ism_enc_quantize_DOA( nchan_ism, st_ivas->hIsmMetaData, hParamIsm );
485 :
486 : /* Compute object indices and power ratios */
487 20720 : ivas_param_ism_compute_obj_parameters( nchan_ism, reference_power_obj, hParamIsm );
488 :
489 20720 : pop_wmops();
490 20720 : return;
491 : }
492 :
493 :
494 : /*-------------------------------------------------------------------*
495 : * ivas_param_ism_compute_noisy_speech_flag()
496 : *
497 : *
498 : *-------------------------------------------------------------------*/
499 :
500 20720 : void ivas_param_ism_compute_noisy_speech_flag(
501 : Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
502 : )
503 : {
504 : int16_t i;
505 :
506 : /* Move the Noisy speech buffer */
507 207200 : for ( i = 0; i < ( PARAM_ISM_HYS_BUF_SIZE - 1 ); i++ )
508 : {
509 186480 : st_ivas->hParamIsm->noisy_speech_buffer[i] = st_ivas->hParamIsm->noisy_speech_buffer[i + 1];
510 : }
511 :
512 : /* Set flag_noisy_speech to 0 for cases where object energies are not roughly equal */
513 20720 : if ( !st_ivas->hParamIsm->flag_equal_energy )
514 : {
515 20720 : st_ivas->hParamIsm->noisy_speech_buffer[i] = 0;
516 20720 : st_ivas->hParamIsm->flag_noisy_speech = 0;
517 : }
518 : else
519 : {
520 : /* For the current frame, make a decision based on some core-coder flags */
521 0 : if ( st_ivas->hSCE[0]->hCoreCoder[0]->flag_noisy_speech_snr && st_ivas->hSCE[1]->hCoreCoder[0]->flag_noisy_speech_snr )
522 : {
523 0 : if ( st_ivas->hSCE[0]->hCoreCoder[0]->vad_flag || st_ivas->hSCE[1]->hCoreCoder[0]->vad_flag )
524 : {
525 0 : st_ivas->hParamIsm->noisy_speech_buffer[i] = 0;
526 : }
527 : else
528 : {
529 0 : st_ivas->hParamIsm->noisy_speech_buffer[i] = 1;
530 : }
531 : }
532 : else
533 : {
534 0 : st_ivas->hParamIsm->noisy_speech_buffer[i] = 0;
535 : }
536 :
537 : /* Do a decision based on hysteresis */
538 0 : st_ivas->hParamIsm->flag_noisy_speech = 1;
539 0 : for ( i = 0; i < PARAM_ISM_HYS_BUF_SIZE; i++ )
540 : {
541 0 : st_ivas->hParamIsm->flag_noisy_speech = st_ivas->hParamIsm->flag_noisy_speech && st_ivas->hParamIsm->noisy_speech_buffer[i];
542 : }
543 : }
544 :
545 20720 : return;
546 : }
|