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 "prot_fx.h"
38 : #include "ivas_prot_fx.h"
39 : #include "rom_com.h"
40 : #include "wmc_auto.h"
41 :
42 :
43 : /*-----------------------------------------------------------------------------------------*
44 : * Function ivas_agc_dec_init_fx()
45 : *
46 : * AGC decoder initialization call
47 : *
48 : *-----------------------------------------------------------------------------------------*/
49 :
50 1476 : static void ivas_agc_dec_init_fx(
51 : ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle */
52 : const Word16 output_frame,
53 : const Word16 delay )
54 : {
55 : Word16 i;
56 1476 : ivas_agc_dec_chan_state_t *ptrG = hAgcDec->gain_state;
57 1476 : ivas_agc_chan_data_t *ptr = hAgcDec->gain_data;
58 :
59 1476 : hAgcDec->agc_com.in_delay = delay;
60 1476 : move16();
61 1476 : hAgcDec->agc_com.num_coeff = IVAS_SPAR_MAX_DMX_CHS;
62 1476 : move16();
63 1476 : ivas_agc_calcGainParams_fx( &hAgcDec->agc_com.absEmin, &hAgcDec->agc_com.betaE, &hAgcDec->agc_com.maxAttExp, hAgcDec->agc_com.num_coeff );
64 :
65 1476 : ivas_agc_initWindowFunc_fx( hAgcDec->agc_com.winFunc_fx, output_frame - hAgcDec->agc_com.in_delay );
66 :
67 7380 : FOR( i = 0; i < IVAS_SPAR_MAX_DMX_CHS; i++ )
68 : {
69 : /* gain_state */
70 5904 : ptrG->lastGain_fx = MAX_16;
71 5904 : move16();
72 5904 : ptrG->gainExpVal = 0;
73 5904 : move16();
74 5904 : ptrG++;
75 :
76 : /* gain_data */
77 5904 : ptr->absGainExp = hAgcDec->agc_com.absEmin;
78 5904 : move16();
79 5904 : ptr->absGainExpCurr = hAgcDec->agc_com.absEmin;
80 5904 : move16();
81 5904 : ptr++;
82 : }
83 :
84 1476 : return;
85 : }
86 :
87 :
88 : /*-------------------------------------------------------------------------
89 : * ivas_spar_agc_dec_open_fx()
90 : *
91 : * Allocate and initialize SPAR AGC decoder handle
92 : *------------------------------------------------------------------------*/
93 :
94 1476 : ivas_error ivas_spar_agc_dec_open_fx(
95 : ivas_agc_dec_state_t **hAgcDec, /* i/o: SPAR AGC decoder handle */
96 : const Word32 output_Fs /* i : output sampling rate */
97 : )
98 : {
99 : ivas_agc_dec_state_t *hAgc;
100 : Word16 output_frame, delay;
101 :
102 1476 : IF( ( hAgc = (ivas_agc_dec_state_t *) malloc( sizeof( ivas_agc_dec_state_t ) ) ) == NULL )
103 : {
104 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
105 : }
106 :
107 1476 : output_frame = extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) );
108 1476 : delay = NS2SA_FX2( output_Fs, ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) );
109 1476 : move16();
110 :
111 1476 : IF( ( hAgc->agc_com.winFunc_fx = (Word16 *) malloc( sizeof( Word16 ) * ( output_frame - delay ) ) ) == NULL )
112 : {
113 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
114 : }
115 :
116 1476 : IF( ( hAgc->gain_state = (ivas_agc_dec_chan_state_t *) malloc( sizeof( ivas_agc_dec_chan_state_t ) * FOA_CHANNELS ) ) == NULL )
117 : {
118 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
119 : }
120 :
121 1476 : IF( ( hAgc->gain_data = (ivas_agc_chan_data_t *) malloc( sizeof( ivas_agc_chan_data_t ) * FOA_CHANNELS ) ) == NULL )
122 : {
123 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
124 : }
125 :
126 1476 : ivas_agc_dec_init_fx( hAgc, output_frame, delay );
127 :
128 1476 : *hAgcDec = hAgc;
129 :
130 1476 : return IVAS_ERR_OK;
131 : }
132 :
133 :
134 : /*-------------------------------------------------------------------------
135 : * ivas_spar_agc_dec_close_fx()
136 : *
137 : * Deallocate SPAR AGC decoder handle
138 : *------------------------------------------------------------------------*/
139 :
140 1476 : void ivas_spar_agc_dec_close_fx(
141 : ivas_agc_dec_state_t **hAgcDec /* i/o: SPAR AGC decoder handle */
142 : )
143 : {
144 : ivas_agc_dec_state_t *hAgc;
145 :
146 1476 : test();
147 1476 : IF( hAgcDec == NULL || *hAgcDec == NULL )
148 : {
149 0 : return;
150 : }
151 :
152 1476 : hAgc = *hAgcDec;
153 :
154 1476 : free( hAgc->agc_com.winFunc_fx );
155 1476 : hAgc->agc_com.winFunc_fx = NULL;
156 :
157 1476 : free( hAgc->gain_state );
158 1476 : hAgc->gain_state = NULL;
159 :
160 1476 : free( hAgc->gain_data );
161 1476 : hAgc->gain_data = NULL;
162 :
163 1476 : free( *hAgcDec );
164 1476 : *hAgcDec = NULL;
165 :
166 1476 : return;
167 : }
168 :
169 :
170 : /*-----------------------------------------------------------------------------------------*
171 : * Function ivas_agc_dec_process_fx()
172 : *
173 : * AGC decoder
174 : *-----------------------------------------------------------------------------------------*/
175 :
176 146387 : void ivas_agc_dec_process_fx(
177 : ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle */
178 : Word32 *pcm_in[], /* i : input audio channels Qx*/
179 : Word32 *pcm_out[], /* o : output audio channels Q_pcm_in - 3*/
180 : const Word16 n_channels, /* i : number of channels */
181 : const Word16 output_frame /* i : output frame length */
182 : )
183 : {
184 : Word16 i, j, idx;
185 : Word16 tmp, tmp_2;
186 : UWord16 offset;
187 : Word16 gainLast, gain;
188 146387 : ivas_agc_dec_state_t *pState = hAgcDec;
189 :
190 146387 : offset = sub( output_frame, pState->agc_com.in_delay );
191 :
192 502645 : FOR( i = 0; i < n_channels; i++ )
193 : {
194 356258 : pState->gain_state[i].gainExpVal = sub( pState->gain_data[i].absGainExp, pState->gain_data[i].absGainExpCurr );
195 356258 : move16();
196 :
197 356258 : test();
198 :
199 356258 : IF( GT_16( pState->gain_state[i].gainExpVal, add( pState->agc_com.maxAttExp, 1 ) ) || LT_16( pState->gain_state[i].gainExpVal, -1 ) )
200 : {
201 : /* Such conditions indicate packet loss, better reset and do nothing*/
202 0 : pState->gain_data[i].absGainExp = pState->agc_com.absEmin;
203 0 : move16();
204 0 : pState->gain_state[i].gainExpVal = 0;
205 0 : move16();
206 : }
207 :
208 : // pState->gain_state[i].lastGain = powf( pState->agc_com.winFunc[offset - 1], ( -1.f * (float) ( pState->gain_data[i].absGainExp - pState->agc_com.absEmin ) ) );
209 : // gainLast = 1.f / pState->gain_state[i].lastGain;
210 :
211 356258 : tmp = negate( sub( pState->gain_data[i].absGainExp, pState->agc_com.absEmin ) );
212 :
213 356258 : IF( tmp < 0 )
214 : {
215 0 : tmp_2 = MAX_16;
216 0 : move16();
217 0 : FOR( idx = 0; idx < -tmp; idx++ )
218 : {
219 0 : tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 );
220 : }
221 0 : tmp_2 = div_l( ONE_IN_Q30, tmp_2 );
222 : }
223 : ELSE
224 : {
225 356258 : tmp_2 = MAX_16;
226 356258 : move16();
227 363379 : FOR( idx = 0; idx < ( tmp ); idx++ )
228 : {
229 7121 : tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 ); // Q15(15+15-15)
230 : }
231 : }
232 356258 : pState->gain_state[i].lastGain_fx = tmp_2; // Q15
233 356258 : move16();
234 356258 : gainLast = div_l( ONE_IN_Q29, pState->gain_state[i].lastGain_fx ); // Q13
235 :
236 356258 : IF( pState->gain_state[i].gainExpVal != 0 )
237 : {
238 366005 : FOR( idx = 0; idx < output_frame; idx++ )
239 : {
240 365440 : IF( GE_16( idx, pState->agc_com.in_delay ) )
241 : {
242 : // gain = powf( pState->agc_com.winFunc[idx - pState->agc_com.in_delay], (float) ( -1 * pState->gain_state[i].gainExpVal ) ) * gainLast;
243 :
244 146176 : tmp = negate( pState->gain_state[i].gainExpVal );
245 146176 : IF( tmp < 0 )
246 : {
247 76288 : tmp_2 = MAX_16;
248 76288 : move16();
249 152576 : FOR( j = 0; j < -tmp; j++ )
250 : {
251 76288 : tmp_2 = mult( pState->agc_com.winFunc_fx[idx - pState->agc_com.in_delay], tmp_2 ); // Q14(15+14-15)
252 : }
253 76288 : IF( tmp_2 < 0 )
254 : {
255 0 : tmp_2 = div_l( ONE_IN_Q30, negate( tmp_2 ) ); // Q14
256 0 : tmp_2 = negate( tmp_2 );
257 : }
258 : ELSE
259 : {
260 76288 : tmp_2 = div_l( ONE_IN_Q30, tmp_2 ); // Q14
261 : }
262 : }
263 : ELSE
264 : {
265 69888 : tmp_2 = MAX_16;
266 69888 : move16();
267 139776 : FOR( j = 0; j < ( tmp ); j++ )
268 : {
269 69888 : tmp_2 = mult( pState->agc_com.winFunc_fx[idx - pState->agc_com.in_delay], tmp_2 ); // Q15 (15+15-15)
270 : }
271 69888 : tmp_2 = shr( tmp_2, 1 ); // Q14
272 : }
273 146176 : gain = mult( tmp_2, gainLast ); // Q12
274 : }
275 : ELSE
276 : {
277 219264 : gain = shr( gainLast, 1 ); // Q12
278 : }
279 :
280 365440 : pcm_out[i][idx] = Mpy_32_16_1( pcm_in[i][idx], gain ); // Q_pcm_out = Q_pcm_in - 3
281 365440 : move32();
282 : }
283 :
284 : // pState->gain_state[i].lastGain *= powf( pState->agc_com.winFunc[offset - 1], (float) pState->gain_state[i].gainExpVal );
285 565 : tmp = pState->gain_state[i].gainExpVal;
286 565 : move16();
287 565 : IF( tmp < 0 )
288 : {
289 270 : tmp_2 = MAX_16;
290 270 : move16();
291 540 : FOR( idx = 0; idx < -tmp; idx++ )
292 : {
293 270 : tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 ); // Q14 (14+15-15)
294 : }
295 270 : tmp_2 = div_l( ONE_IN_Q30, tmp_2 ); // Q14
296 : }
297 : ELSE
298 : {
299 295 : tmp_2 = MAX_16;
300 295 : move16();
301 590 : FOR( idx = 0; idx < ( tmp ); idx++ )
302 : {
303 295 : tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 ); // Q15
304 : }
305 295 : tmp_2 = shr( tmp_2, 1 ); // Q14
306 : }
307 565 : pState->gain_state[i].lastGain_fx = mult( pState->gain_state[i].lastGain_fx, tmp_2 ); // Q14
308 565 : move16();
309 : }
310 : ELSE
311 : {
312 355693 : gain = shr( gainLast, 1 ); // Q12
313 278969453 : FOR( idx = 0; idx < output_frame; idx++ )
314 : {
315 278613760 : pcm_out[i][idx] = Mpy_32_16_1( pcm_in[i][idx], gain ); // Q_pcm_out = Q_pcm_in - 3
316 278613760 : move32();
317 : }
318 : }
319 356258 : pState->gain_data[i].absGainExp = pState->gain_data[i].absGainExpCurr;
320 356258 : move16();
321 : }
322 :
323 146387 : return;
324 : }
325 :
326 :
327 : /*-----------------------------------------------------------------------------------------*
328 : * ivas_agc_read_bits_fx()
329 : *
330 : * decode AGC parameters
331 : *-----------------------------------------------------------------------------------------*/
332 :
333 140347 : void ivas_agc_read_bits_fx(
334 : ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle */
335 : Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling */
336 : const Word16 n_channels, /* i : number of channels */
337 : const Word16 AGC_flag /* i : AGC on/off flag */
338 : )
339 : {
340 : Word16 i;
341 : Word16 per_ch_bit[FOA_CHANNELS];
342 140347 : ivas_agc_dec_state_t *pState = hAgcDec;
343 :
344 140347 : set16_fx( per_ch_bit, 0, FOA_CHANNELS );
345 :
346 : /* read AGC parameters */
347 140347 : IF( EQ_16( AGC_flag, 1 ) )
348 : {
349 4075 : per_ch_bit[0] = 1;
350 4075 : move16();
351 :
352 4075 : assert( EQ_16( AGC_BITS_PER_CH, ( pState->agc_com.betaE + 1 ) ) );
353 8150 : FOR( i = 0; i < n_channels; i++ )
354 : {
355 4075 : IF( EQ_16( per_ch_bit[i], 1 ) )
356 : {
357 4075 : pState->gain_data[i].absGainExpCurr = get_next_indice_fx( st0, (Word16) pState->agc_com.betaE );
358 4075 : move16();
359 : }
360 : ELSE
361 : {
362 0 : pState->gain_data[i].absGainExpCurr = (Word16) pState->agc_com.absEmin;
363 0 : move16();
364 : }
365 : }
366 : }
367 : ELSE
368 : {
369 478932 : FOR( i = 0; i < n_channels; i++ )
370 : {
371 342660 : pState->gain_data[i].absGainExpCurr = (Word16) pState->agc_com.absEmin;
372 342660 : move16();
373 : }
374 : }
375 :
376 140347 : return;
377 : }
|