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 :
34 : #include <stdint.h>
35 : #include "options.h"
36 : #ifdef DEBUGGING
37 : #include "debug.h"
38 : #endif
39 : #include "ivas_prot.h"
40 : #include "prot.h"
41 : #include <math.h>
42 : #include <assert.h>
43 : #include "wmc_auto.h"
44 :
45 :
46 : /*------------------------------------------------------------------------------------------*
47 : * Local constants
48 : *------------------------------------------------------------------------------------------*/
49 :
50 : #define AGC_MIN_DELTA ( 4.656612873077393e-10f ) /*2^-31*/
51 :
52 : #ifdef DEBUG_AGC
53 : /*------------------------------------------------------------------------------------------*
54 : * Local functions declarations
55 : *------------------------------------------------------------------------------------------*/
56 :
57 : extern FILE *agcOut;
58 :
59 : static int16_t ivas_agc_writeBits( FILE *stream, const int16_t n_channels, ivas_agc_enc_state_t *pState );
60 :
61 : #endif
62 :
63 : /*-----------------------------------------------------------------------------------------*
64 : * Function ivas_agc_enc_get_flag()
65 : *
66 : * This function determines if AGC is enabled or disabled.
67 : *-----------------------------------------------------------------------------------------*/
68 :
69 : /*! r: AGC enable flag */
70 3590 : int16_t ivas_agc_enc_get_flag(
71 : #ifdef DEBUG_AGC_ENCODER_CMD_OPTION
72 : const int16_t agc_configuration, /* i : AGC configuration from command-line */
73 : #endif
74 : const int16_t nchan_transport /* i : number of transport channels */
75 : )
76 : {
77 : int16_t agc_flag;
78 :
79 : /* AGC is enabled only if there is one transport channel. */
80 3590 : agc_flag = (int16_t) ( nchan_transport == 1 );
81 :
82 : #ifdef DEBUG_AGC_ENCODER_CMD_OPTION
83 : /* If agc_configuration is not undefined, then this value decides on the state of * enablement,
84 : otherwise AGC is enabled only if there is one transport channel. */
85 : agc_flag = ( agc_configuration != SBA_AGC_DEFAULT ) ? agc_configuration : agc_flag;
86 : #endif
87 :
88 3590 : return agc_flag;
89 : }
90 :
91 :
92 : /*-----------------------------------------------------------------------------------------*
93 : * Function ivas_agc_enc_init()
94 : *
95 : * AGC encoder initialization
96 : *-----------------------------------------------------------------------------------------*/
97 :
98 567 : static void ivas_agc_enc_init(
99 : ivas_agc_enc_state_t *hAgcEnc,
100 : const int16_t input_frame,
101 : const int16_t nchan_inp,
102 : const uint16_t delay )
103 : {
104 : int16_t i;
105 567 : ivas_agc_enc_chan_state_t *ptrG = hAgcEnc->gain_state;
106 567 : ivas_agc_chan_data_t *ptr = hAgcEnc->gain_data;
107 :
108 567 : hAgcEnc->agc_com.in_delay = delay;
109 567 : hAgcEnc->agc_com.num_coeff = FOA_CHANNELS;
110 :
111 567 : ivas_agc_calcGainParams( &hAgcEnc->agc_com.absEmin, &hAgcEnc->agc_com.betaE, &hAgcEnc->agc_com.maxAttExp, hAgcEnc->agc_com.num_coeff );
112 :
113 567 : ivas_agc_initWindowFunc( hAgcEnc->agc_com.winFunc, input_frame - hAgcEnc->agc_com.in_delay );
114 :
115 567 : hAgcEnc->minDelta = AGC_MIN_DELTA;
116 567 : hAgcEnc->smFact = 0.1f;
117 :
118 2835 : for ( i = 0; i < nchan_inp; i++ )
119 : {
120 : /* gain_state */
121 2268 : ptrG->lastExp = 0;
122 2268 : ptrG->prevExp = 0;
123 2268 : ptrG->lastGain = 1.f;
124 2268 : ptrG->lastMaxAbs = 0.f;
125 2268 : ptrG->gainExpVal = 0;
126 2268 : ptrG->MaxAbsVal_del = 0.f;
127 2268 : ptrG->MaxAbsValIdx_del = 0;
128 2268 : ptrG++;
129 :
130 : /* gain_data */
131 2268 : ptr->absGainExp = hAgcEnc->agc_com.absEmin;
132 2268 : ptr->absGainExpCurr = hAgcEnc->agc_com.absEmin;
133 2268 : ptr++;
134 : }
135 :
136 567 : return;
137 : }
138 :
139 :
140 : /*-------------------------------------------------------------------------
141 : * ivas_spar_agc_enc_open()
142 : *
143 : * Allocate and initialize SPAR AGC encoder handle
144 : *------------------------------------------------------------------------*/
145 :
146 567 : ivas_error ivas_spar_agc_enc_open(
147 : ivas_agc_enc_state_t **hAgcEnc, /* i/o: SPAR AGC encoder handle */
148 : const int32_t input_Fs, /* i : input sampling rate */
149 : const int16_t nchan_inp /* i : number of input channels */
150 : )
151 : {
152 : ivas_agc_enc_state_t *hAgc;
153 : int16_t input_frame, delay;
154 :
155 567 : if ( ( hAgc = (ivas_agc_enc_state_t *) malloc( sizeof( ivas_agc_enc_state_t ) ) ) == NULL )
156 : {
157 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" );
158 : }
159 :
160 567 : input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
161 567 : delay = NS2SA( input_Fs, ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) );
162 :
163 567 : if ( ( hAgc->agc_com.winFunc = (float *) malloc( sizeof( float ) * ( input_frame - delay ) ) ) == NULL )
164 : {
165 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" );
166 : }
167 :
168 567 : if ( ( hAgc->gain_state = (ivas_agc_enc_chan_state_t *) malloc( sizeof( ivas_agc_enc_chan_state_t ) * nchan_inp ) ) == NULL )
169 : {
170 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" );
171 : }
172 :
173 567 : if ( ( hAgc->gain_data = (ivas_agc_chan_data_t *) malloc( sizeof( ivas_agc_chan_data_t ) * nchan_inp ) ) == NULL )
174 : {
175 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" );
176 : }
177 :
178 567 : ivas_agc_enc_init( hAgc, input_frame, nchan_inp, delay );
179 :
180 567 : *hAgcEnc = hAgc;
181 :
182 567 : return IVAS_ERR_OK;
183 : }
184 :
185 :
186 : /*-------------------------------------------------------------------------
187 : * ivas_spar_agc_enc_close()
188 : *
189 : * Deallocate SPAR AGC encoder handle
190 : *------------------------------------------------------------------------*/
191 :
192 1636 : void ivas_spar_agc_enc_close(
193 : ivas_agc_enc_state_t **hAgcEnc /* i/o: SPAR AGC encoder handle */
194 : )
195 : {
196 : ivas_agc_enc_state_t *hAgc;
197 :
198 1636 : if ( hAgcEnc == NULL || *hAgcEnc == NULL )
199 : {
200 1069 : return;
201 : }
202 :
203 567 : hAgc = *hAgcEnc;
204 :
205 567 : free( hAgc->agc_com.winFunc );
206 567 : hAgc->agc_com.winFunc = NULL;
207 :
208 567 : free( hAgc->gain_state );
209 567 : hAgc->gain_state = NULL;
210 :
211 567 : free( hAgc->gain_data );
212 567 : hAgc->gain_data = NULL;
213 :
214 567 : free( *hAgcEnc );
215 567 : *hAgcEnc = NULL;
216 :
217 567 : return;
218 : }
219 :
220 :
221 : /*-----------------------------------------------------------------------------------------*
222 : * Function ivas_agc_enc_process()
223 : *
224 : * AGC encoder
225 : *-----------------------------------------------------------------------------------------*/
226 :
227 42108 : void ivas_agc_enc_process(
228 : ivas_agc_enc_state_t *hAgcEnc, /* i/o: AGC encoder handle */
229 : BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */
230 : float **ppPcm_in, /* i : input audio channels */
231 : float **ppPcm_out, /* o : output audio channels */
232 : const int16_t n_channels, /* i : number of channels */
233 : const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */
234 : )
235 : {
236 : int16_t i, j, idx, input_frame, offset;
237 : int16_t per_ch_bit[FOA_CHANNELS], AGC_flag;
238 42108 : int16_t extendedExpVal = FALSE;
239 : int16_t isGainAdjusted;
240 : float gain;
241 42108 : ivas_agc_enc_state_t *pState = hAgcEnc;
242 :
243 42108 : input_frame = (int16_t) ( hEncoderConfig->input_Fs / FRAMES_PER_SEC );
244 42108 : offset = input_frame - pState->agc_com.in_delay;
245 :
246 42108 : AGC_flag = 0;
247 :
248 84216 : for ( i = 0; i < n_channels; i++ )
249 : {
250 : float sampleAbsVal;
251 42108 : int16_t isClipped = FALSE;
252 42108 : int16_t clippedIdx = 0;
253 42108 : int16_t MaxAbsValIdx = 0;
254 42108 : float MaxAbsVal = pState->gain_state[i].MaxAbsVal_del;
255 42108 : float predMaxAbsVal = fabsf( ppPcm_in[i][offset] );
256 :
257 30466428 : for ( j = 0; j < input_frame; j++ )
258 : {
259 30424320 : sampleAbsVal = fabsf( ppPcm_in[i][j] );
260 :
261 30424320 : if ( sampleAbsVal > MaxAbsVal )
262 : {
263 251865 : MaxAbsVal = sampleAbsVal;
264 251865 : MaxAbsValIdx = j;
265 : }
266 :
267 30424320 : if ( j > offset )
268 : {
269 18212484 : if ( sampleAbsVal > predMaxAbsVal )
270 : {
271 812227 : predMaxAbsVal = sampleAbsVal;
272 : }
273 : }
274 :
275 30424320 : ppPcm_out[i][j] = ppPcm_in[i][j] * pState->gain_state[i].lastGain;
276 :
277 30424320 : if ( !isClipped )
278 : {
279 30347885 : if ( ( ppPcm_out[i][j] > ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) || ( ppPcm_out[i][j] < MIN16B_FLT ) )
280 : {
281 307 : clippedIdx = j;
282 307 : isClipped = TRUE;
283 : }
284 : }
285 : }
286 :
287 42108 : pState->gain_state[i].MaxAbsVal_del = predMaxAbsVal;
288 :
289 42108 : isGainAdjusted = FALSE;
290 42108 : if ( !isClipped )
291 : {
292 :
293 41801 : if ( pState->gain_state[i].lastExp == AGC_EMAX || MaxAbsVal < FLT_MIN )
294 : {
295 36720 : pState->gain_state[i].gainExpVal = 0;
296 36720 : pState->gain_state[i].prevExp = pState->gain_state[i].lastExp;
297 36720 : isGainAdjusted = TRUE;
298 : }
299 : else
300 : {
301 : float smoothedMaxAbsVal, maxGain;
302 5081 : smoothedMaxAbsVal = pState->smFact * MaxAbsVal + ( 1.f - pState->smFact ) * pState->gain_state[i].lastMaxAbs;
303 5081 : pState->gain_state[i].lastMaxAbs = smoothedMaxAbsVal;
304 :
305 5081 : maxGain = max( smoothedMaxAbsVal, MaxAbsVal ) * pState->gain_state[i].lastGain * 2.f;
306 :
307 5081 : if ( maxGain < ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC )
308 : {
309 282 : pState->gain_state[i].gainExpVal = -1;
310 : }
311 : else
312 : {
313 4799 : pState->gain_state[i].gainExpVal = 0;
314 : }
315 : }
316 : }
317 : else
318 : {
319 307 : pState->gain_state[i].lastMaxAbs = MaxAbsVal;
320 : }
321 :
322 42108 : if ( !isGainAdjusted )
323 : {
324 5388 : float actualMaxAbsVal = 0.f;
325 : int16_t currMaxAttExp;
326 :
327 5388 : currMaxAttExp = min( ( pState->gain_state[i].lastExp + pState->agc_com.absEmin ), pState->agc_com.maxAttExp );
328 5388 : extendedExpVal = FALSE;
329 :
330 5388 : if ( isClipped )
331 : {
332 307 : int16_t isCompensated = FALSE;
333 307 : actualMaxAbsVal = pState->gain_state[i].lastMaxAbs * pState->gain_state[i].lastGain;
334 307 : idx = min( offset - 1, MaxAbsValIdx );
335 307 : pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal * MDFT_NORM_SCALING ) / logf( pState->agc_com.winFunc[idx] ) );
336 :
337 614 : while ( !isCompensated )
338 : {
339 : float tmpSignal;
340 307 : isCompensated = TRUE;
341 :
342 5114 : for ( idx = clippedIdx; idx <= MaxAbsValIdx; idx++ )
343 : {
344 4807 : if ( idx >= offset )
345 : {
346 282 : idx = MaxAbsValIdx;
347 282 : tmpSignal = ppPcm_out[i][idx] * powf( pState->agc_com.winFunc[offset - 1], (float) pState->gain_state[i].gainExpVal );
348 : }
349 : else
350 : {
351 4525 : tmpSignal = ppPcm_out[i][idx] * powf( pState->agc_com.winFunc[idx], (float) pState->gain_state[i].gainExpVal );
352 : }
353 :
354 4807 : if ( ( tmpSignal > ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) || ( tmpSignal < MIN16B_FLT ) )
355 : {
356 0 : isCompensated = FALSE;
357 0 : break;
358 : }
359 : }
360 :
361 307 : if ( !isCompensated )
362 : {
363 0 : pState->gain_state[i].gainExpVal++;
364 : }
365 :
366 307 : if ( pState->gain_state[i].gainExpVal > currMaxAttExp )
367 : {
368 0 : pState->gain_state[i].gainExpVal = min( pState->gain_state[i].gainExpVal, currMaxAttExp );
369 0 : break;
370 : }
371 : }
372 : }
373 :
374 3462028 : for ( idx = 0; idx < input_frame; idx++ )
375 : {
376 3456640 : if ( idx < offset )
377 : {
378 1382656 : gain = powf( pState->agc_com.winFunc[idx], pState->gain_state[i].gainExpVal );
379 : }
380 : else
381 : {
382 :
383 2073984 : gain = powf( pState->agc_com.winFunc[offset - 1], pState->gain_state[i].gainExpVal );
384 : }
385 3456640 : ppPcm_out[i][idx] *= gain;
386 : }
387 :
388 5388 : pState->gain_state[i].lastGain *= powf( pState->agc_com.winFunc[offset - 1], pState->gain_state[i].gainExpVal );
389 : /*safety check starts*/
390 5388 : if ( pState->gain_state[i].gainExpVal == pState->agc_com.maxAttExp + 1 )
391 : {
392 0 : extendedExpVal = TRUE;
393 : }
394 : /*safety check ends*/
395 :
396 5388 : pState->gain_state[i].prevExp = pState->gain_state[i].lastExp;
397 :
398 5388 : pState->gain_state[i].lastExp -= pState->gain_state[i].gainExpVal;
399 5388 : if ( extendedExpVal )
400 : {
401 :
402 0 : pState->gain_state[i].gainExpVal = -1;
403 : }
404 : }
405 :
406 42108 : pState->gain_data[i].absGainExp = pState->gain_state[i].prevExp + pState->agc_com.absEmin;
407 :
408 42108 : if ( extendedExpVal && pState->gain_state[i].gainExpVal <= 0 )
409 : {
410 0 : pState->gain_state[i].gainExpVal = pState->agc_com.maxAttExp + 1;
411 : }
412 :
413 42108 : pState->gain_data[i].absGainExpCurr = pState->gain_data[i].absGainExp - pState->gain_state[i].gainExpVal;
414 :
415 42108 : if ( ( pState->gain_data[i].absGainExpCurr > pState->agc_com.absEmin ) || ( pState->gain_data[i].absGainExpCurr < 0 ) )
416 : {
417 0 : assert( 0 );
418 : }
419 :
420 42108 : if ( pState->gain_data[i].absGainExpCurr == pState->agc_com.absEmin )
421 : {
422 36827 : per_ch_bit[i] = 0;
423 : }
424 : else
425 : {
426 5281 : per_ch_bit[i] = 1;
427 5281 : AGC_flag = 1;
428 : }
429 : }
430 :
431 42108 : push_next_indice( hMetaData, AGC_flag, 1 );
432 :
433 : /* encode AGC parameters */
434 42108 : if ( AGC_flag == 1 )
435 : {
436 5281 : if ( n_channels > 1 )
437 : {
438 0 : for ( i = 0; i < n_channels; i++ )
439 : {
440 0 : push_next_indice( hMetaData, per_ch_bit[i], 1 );
441 : }
442 : }
443 5281 : assert( AGC_BITS_PER_CH == ( pState->agc_com.betaE + 1 ) );
444 :
445 10562 : for ( i = 0; i < n_channels; i++ )
446 : {
447 5281 : if ( per_ch_bit[i] == 1 )
448 : {
449 5281 : push_next_indice( hMetaData, (uint16_t) pState->gain_data[i].absGainExpCurr, (int16_t) pState->agc_com.betaE );
450 : }
451 : }
452 : }
453 :
454 : #ifdef DEBUG_AGC
455 : /* writing to a temporary bitstream file */
456 : if ( ivas_agc_writeBits( agcOut, n_channels, pState ) )
457 : {
458 : IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR ENC AGC Failed to open agcOut\n " );
459 : }
460 : #endif
461 :
462 42108 : return;
463 : }
464 :
465 : #ifdef DEBUG_AGC
466 : static int16_t ivas_agc_writeBits( FILE *stream, const int16_t n_channels, ivas_agc_enc_state_t *pState )
467 : {
468 : if ( stream == NULL )
469 : {
470 : return TRUE;
471 : }
472 :
473 : int16_t num_bits = 0, num_dmx_bits[4] = { 0 };
474 : for ( int16_t i = 0; i < n_channels; i++ )
475 : {
476 : if ( pState->gain_data[i].absGainExpCurr < 0 ||
477 : pState->gain_data[i].absGainExpCurr >= (int16_t) pow( 2, pState->agc_com.betaE ) )
478 : {
479 : IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error Gain values to write!!\n\n" );
480 : }
481 :
482 : fwrite( &( pState->gain_data[i].absGainExpCurr ), sizeof( int32_t ), 1, stream ); /* n bits */
483 : num_bits += pState->agc_com.betaE;
484 : num_dmx_bits[i]++;
485 :
486 : /*fprintf(stdout, "absGainExpCurr[%d]:= %d[%d bits]; ", i, pState->gain_data[i].absGainExpCurr, pState->betaE); */
487 : }
488 : /*fprintf(stdout, "AGC bits:= %d ", num_bits);*/
489 :
490 : return FALSE;
491 : }
492 : #endif
|