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 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include "options.h"
39 : #include <math.h>
40 : #include "cnst.h"
41 : #include "rom_com.h"
42 : #include "prot_fx.h"
43 : #include "wmc_auto.h"
44 :
45 22696 : static void GSC_gain_DQ_fx(
46 : const Word16 element_mode, /* i : element mode */
47 : const Word16 enc_dec, /* i : encoder/decoder flag */
48 : const Word16 coder_type, /* i : Coder type */
49 : const Word16 Mbands_gn, /* i : Number of band */
50 : const Word32 core_brate, /* i : Core bitrate */
51 : const Word16 mean_g, /* i : Average gain Q12 */
52 : const Word16 *Gain_in, /* i : Unquantized gain vector Q12 */
53 : Word16 *Gain_out /* o : Level adjusted unquantized gain vector Q12 */
54 : )
55 : {
56 : Word16 Gain_off;
57 : Word16 i;
58 :
59 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
60 22696 : Gain_off = 0;
61 22696 : move16();
62 :
63 22696 : test();
64 22696 : IF( coder_type == INACTIVE || EQ_16( coder_type, UNVOICED ) )
65 : {
66 11711 : test();
67 11711 : IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
68 : {
69 0 : Gain_off = 1843; // 9/20 in Q12
70 0 : move16();
71 : }
72 11711 : ELSE IF( LE_32( core_brate, ACELP_7k20 ) )
73 : {
74 7494 : Gain_off = 1638; // 8/20 in Q12; /* 0 dB */
75 7494 : move16();
76 : }
77 4217 : ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
78 : {
79 9 : Gain_off = 1351; // 6.6f/20 in Q12 /* ~-3.3 dB */
80 9 : move16();
81 : }
82 4208 : ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
83 : {
84 361 : Gain_off = 983; // 4.8f/20 in Q12 /* ~-2.4 dB */
85 361 : move16();
86 : }
87 3847 : ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
88 : {
89 167 : Gain_off = 717; // 3.5f/20 in Q12 /* ~-2.4 dB */
90 167 : move16();
91 : }
92 3680 : ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
93 : {
94 392 : Gain_off = 614; // 3.0f/20 in Q12 /* ~-2.4 dB */
95 392 : move16();
96 : }
97 : }
98 :
99 22696 : test();
100 22696 : IF( coder_type != INACTIVE && NE_16( coder_type, UNVOICED ) )
101 : {
102 186745 : FOR( i = 0; i < Mbands_gn; i++ )
103 : {
104 175760 : Gain_out[i] = add( Gain_in[i], mean_g ); // Q12
105 175760 : move16();
106 : }
107 : }
108 : ELSE
109 : {
110 : /*mimic ACELP decay of energy for low rates*/
111 11711 : test();
112 11711 : IF( element_mode == EVS_MONO && EQ_16( enc_dec, DEC ) )
113 : {
114 : /* This is to keep EVS mono bit-exact with the standard (there might be a small desynchronization between encoder and decoder but there is no real quality or interop. issue) */
115 0 : FOR( i = 0; i < Mbands_gn; i++ )
116 : {
117 0 : Gain_out[i] = add( Gain_out[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
118 0 : move16();
119 : // Gain_out[i] += mean_g - i * ( Gain_off / 20.f ) / ( (float) Mbands_gn );
120 : }
121 : }
122 : ELSE
123 : {
124 204387 : FOR( i = 0; i < Mbands_gn; i++ )
125 : {
126 192676 : Gain_out[i] = add( Gain_in[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
127 192676 : move16();
128 : // Gain_out[i] = Gain_in[i] + mean_g - ( i * ( Gain_off / 20.f ) / ( (float) Mbands_gn ) );
129 : }
130 : }
131 : }
132 :
133 22696 : return;
134 : }
135 :
136 22696 : Word16 gsc_gainQ_ivas_fx(
137 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
138 : const Word16 element_mode, /* i : element mode */
139 : const Word16 idchan, /* i : channel ID */
140 : const Word16 y_gain4[],
141 : /* i : Energy per band */ // Q12
142 : Word16 y_gainQ[],
143 : /* o : quantized energy per band */ // Q12
144 : const Word32 core_brate, /* i : Core rate */
145 : const Word16 coder_type, /* i : coding type */
146 : const Word16 bwidth, /* i : input signal bandwidth */
147 : const Word16 L_frame, /* i : frame length */
148 : const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */
149 : const Word32 core_brate_inp /* i : true core bitrate */
150 : )
151 : {
152 : Word16 y_gain_tmp[MBANDS_GN16k];
153 : Word16 y_gain_tmp2[MBANDS_GN16k];
154 22696 : Word16 i, idx_g = 0;
155 22696 : move16();
156 : Word16 mean_4g_fx[1], ftmp1_fx;
157 22696 : Word16 Mbands_gn = MBANDS_GN;
158 22696 : move16();
159 : Word16 y_gain_tmp3[MBANDS_GN];
160 : Word32 L_tmp;
161 :
162 22696 : if ( EQ_16( L_frame, L_FRAME16k ) )
163 : {
164 2650 : Mbands_gn = MBANDS_GN16k;
165 2650 : move16();
166 : }
167 :
168 22696 : mean_4g_fx[0] = 0;
169 22696 : move32();
170 :
171 22696 : test();
172 22696 : test();
173 22696 : IF( ( EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && bwidth == NB )
174 : {
175 0 : L_tmp = 0;
176 0 : move32();
177 0 : FOR( i = 0; i < 10; i++ )
178 : {
179 0 : L_tmp = L_add( L_tmp, y_gain4[i] );
180 : }
181 0 : L_tmp = L_sub( Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ), 2457 /* 0.6f in Q12 */ ); // Q12
182 0 : ftmp1_fx = extract_l( L_tmp );
183 0 : FOR( i = 0; i < Mbands_gn; i++ )
184 : {
185 0 : IF( LT_16( y_gain4[i], ftmp1_fx ) )
186 : {
187 0 : y_gain_tmp2[i] = ftmp1_fx; /*Q12*/
188 : }
189 : ELSE
190 : {
191 0 : y_gain_tmp2[i] = y_gain4[i]; /*Q12*/
192 : }
193 0 : move16();
194 : }
195 :
196 : /* Quantized mean gain without clipping */
197 0 : L_tmp = 0;
198 0 : move32();
199 0 : FOR( i = 0; i < 10; i++ )
200 : {
201 0 : L_tmp = L_add( L_tmp, y_gain4[i] );
202 : }
203 0 : L_tmp = Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ); // Q12
204 0 : mean_4g_fx[0] = extract_l( L_tmp ); // Q12
205 0 : move16();
206 0 : idx_g = vquant_fx( mean_4g_fx, Gain_meanNB_fx, mean_4g_fx, Gain_mean_dicNB_fx, 1, 64 );
207 0 : push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
208 :
209 0 : FOR( i = 0; i < Mbands_gn; i++ )
210 : {
211 0 : y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
212 0 : move16();
213 : }
214 :
215 0 : if ( LT_16( y_gain_tmp[9], -1229 /* -0.3f in Q12 */ ) )
216 : {
217 0 : y_gain_tmp[9] = -1229; /* -0.3f in Q12 */
218 0 : move16();
219 : }
220 :
221 0 : set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
222 0 : idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 );
223 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
224 :
225 0 : IF( LT_32( core_brate, ACELP_9k60 ) )
226 : {
227 0 : idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 );
228 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
229 :
230 0 : idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 );
231 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
232 : }
233 : ELSE
234 : {
235 0 : idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 );
236 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
237 :
238 0 : idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 );
239 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
240 : }
241 :
242 0 : test();
243 0 : IF( LE_32( core_brate, ACELP_9k60 ) && coder_type == INACTIVE )
244 : {
245 : /* Some energy is needed in high band for stat_noise_uv_enc() to be functional in inactive speech */
246 0 : y_gain_tmp[10] = mean_fx( y_gain_tmp + 6, 3 ); /*Q12*/
247 0 : move16();
248 0 : y_gain_tmp[11] = mean_fx( y_gain_tmp + 7, 3 ); /*Q12*/
249 0 : move16();
250 0 : y_gain_tmp[12] = mean_fx( y_gain_tmp + 8, 3 ); /*Q12*/
251 0 : move16();
252 0 : y_gain_tmp[13] = mean_fx( y_gain_tmp + 9, 3 ); /*Q12*/
253 0 : move16();
254 0 : y_gain_tmp[14] = mean_fx( y_gain_tmp + 10, 3 ); /*Q12*/
255 0 : move16();
256 0 : y_gain_tmp[15] = mean_fx( y_gain_tmp + 11, 3 ); /*Q12*/
257 0 : move16();
258 : }
259 : ELSE
260 : {
261 0 : set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
262 : }
263 : }
264 : ELSE
265 : {
266 22696 : L_tmp = 0;
267 22696 : move32();
268 385832 : FOR( i = 0; i < 16; i++ )
269 : {
270 363136 : L_tmp = L_add( L_tmp, y_gain4[i] );
271 : }
272 22696 : L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
273 22696 : ftmp1_fx = extract_l( L_tmp );
274 391132 : FOR( i = 0; i < Mbands_gn; i++ )
275 : {
276 368436 : IF( LT_16( y_gain4[i], sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
277 : {
278 1967 : y_gain_tmp2[i] = sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
279 : }
280 366469 : ELSE IF( GT_16( y_gain4[i], add( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
281 : {
282 543 : y_gain_tmp2[i] = add( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
283 : }
284 : ELSE
285 : {
286 365926 : y_gain_tmp2[i] = y_gain4[i];
287 : }
288 368436 : move16();
289 : }
290 :
291 22696 : L_tmp = 0;
292 22696 : move32();
293 385832 : FOR( i = 0; i < 16; i++ )
294 : {
295 363136 : L_tmp = L_add( L_tmp, y_gain_tmp2[i] );
296 : }
297 22696 : L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
298 22696 : mean_4g_fx[0] = extract_l( L_tmp ); // Q12
299 22696 : move16();
300 22696 : idx_g = vquant_fx( mean_4g_fx, mean_m_fx, mean_4g_fx, mean_gain_dic_fx, 1, 64 );
301 22696 : push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
302 :
303 : /* Subtraction of the average gain */
304 391132 : FOR( i = 0; i < Mbands_gn; i++ )
305 : {
306 368436 : y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
307 368436 : move16();
308 : }
309 :
310 22696 : IF( LT_32( core_brate, ACELP_9k60 ) )
311 : {
312 : /* prediction and quantization of the average gain */
313 :
314 : /*--------------------------------------------------------------------------------------*
315 : * Quantization of the first 8 bands
316 : * Keep only 4 bands out of the last 8 bands
317 : *--------------------------------------------------------------------------------------*/
318 :
319 14544 : Copy( y_gain_tmp, y_gain_tmp2, 8 );
320 :
321 14544 : y_gain_tmp2[8] = y_gain_tmp[8];
322 14544 : move16();
323 14544 : y_gain_tmp2[9] = y_gain_tmp[10];
324 14544 : move16();
325 14544 : y_gain_tmp2[10] = y_gain_tmp[12];
326 14544 : move16();
327 14544 : y_gain_tmp2[11] = y_gain_tmp[14];
328 14544 : move16();
329 :
330 14544 : idx_g = 0;
331 14544 : move16();
332 14544 : idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
333 14544 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
334 :
335 14544 : test();
336 14544 : test();
337 14544 : test();
338 14544 : IF( !( coder_type == INACTIVE && tdm_LRTD_flag == 0 && EQ_16( idchan, 1 ) ) || GT_32( core_brate_inp, GSC_LRES_GAINQ_LIMIT ) )
339 : {
340 14544 : idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 );
341 14544 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
342 :
343 : /*----------------------------------------------------------------------*
344 : * Vector quantization of the first 8 bands + quantization of the 4 bands out of the last 8
345 : * Interpolation of the last 4 bands Q to create bands 8-16
346 : *----------------------------------------------------------------------*/
347 :
348 14544 : idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 );
349 14544 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
350 :
351 14544 : set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 );
352 :
353 : /* Update to quantized vector */
354 14544 : Copy( y_gain_tmp2, y_gain_tmp, 8 );
355 :
356 14544 : Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 );
357 14544 : set16_fx( y_gain_tmp + 8, 0, 8 );
358 14544 : fft_rel_fx( y_gain_tmp2 + 8, 4, 2 );
359 :
360 14544 : Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 );
361 14544 : y_gain_tmp[15] = y_gain_tmp2[11];
362 14544 : move16();
363 14544 : ifft_rel_fx( y_gain_tmp + 8, 8, 3 );
364 :
365 130896 : FOR( i = 8; i < 16; i++ )
366 : {
367 116352 : y_gain_tmp[i] = shl( mult( y_gain_tmp[i], 23101 /* 1.41 in Q14 */ ), 1 ); /*Q12*/
368 116352 : move16();
369 : }
370 :
371 14544 : y_gain_tmp[8] = y_gain_tmp3[0];
372 14544 : move16();
373 14544 : y_gain_tmp[10] = y_gain_tmp3[1];
374 14544 : move16();
375 14544 : y_gain_tmp[12] = y_gain_tmp3[2];
376 14544 : move16();
377 14544 : y_gain_tmp[14] = y_gain_tmp3[3];
378 14544 : move16();
379 : }
380 : ELSE
381 : {
382 0 : Copy( y_gain_tmp2, y_gain_tmp, 3 );
383 0 : set16_fx( y_gain_tmp + 3, 0, MBANDS_GN16k - 3 );
384 : }
385 : }
386 : ELSE
387 : {
388 8152 : IF( EQ_16( L_frame, L_FRAME ) )
389 : {
390 5502 : idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
391 5502 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
392 :
393 5502 : idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
394 5502 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
395 :
396 5502 : idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
397 5502 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
398 :
399 5502 : idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
400 5502 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
401 : }
402 : ELSE
403 : {
404 2650 : idx_g = vquant_fx( y_gain_tmp, YG_mean16HR_fx, y_gain_tmp, YG_dicHR_1_fx, 4, 128 );
405 2650 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
406 :
407 2650 : idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16HR_fx + 4, y_gain_tmp + 4, YG_dicHR_2_fx, 4, 64 );
408 2650 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
409 :
410 2650 : idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16HR_fx + 8, y_gain_tmp + 8, YG_dicHR_3_fx, 4, 64 );
411 2650 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
412 :
413 2650 : idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16HR_16kHz_fx, y_gain_tmp + 12, YG_dicHR_4_16kHz_fx, 4, 64 );
414 2650 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
415 :
416 2650 : idx_g = vquant_fx( y_gain_tmp + 16, YG_meanL2G_16kHz_fx, y_gain_tmp + 16, YG_dicL2G_16kHz_fx, 2, 8 );
417 2650 : push_indice( hBstr, IND_Y_GAIN_HF, idx_g, 3 );
418 : }
419 : }
420 : }
421 :
422 22696 : GSC_gain_DQ_fx( element_mode, ENC, coder_type, Mbands_gn, core_brate, mean_4g_fx[0], y_gain_tmp, y_gainQ );
423 :
424 22696 : return mean_4g_fx[0];
425 : }
|