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 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include <math.h>
43 : #include "prot.h"
44 : #include "cnst.h"
45 : #include "rom_com.h"
46 : #include "wmc_auto.h"
47 :
48 : /*-------------------------------------------------------------------------*
49 : * Local function prototypes
50 : *-------------------------------------------------------------------------*/
51 :
52 : static int16_t gain_enc_uv( const float *code, const int16_t lcode, float *gain_pit, float *gain_code, ACELP_CbkCorr *coeff, float *past_gcode, float *gain_inov );
53 :
54 :
55 : /*-------------------------------------------------------------------------*
56 : * procedure q_gain2_plus *
57 : * ~~~~~~~~~~~~~~~~~~~~~~ *
58 : * Quantization of pitch and codebook gains. *
59 : * The following routines is Q_gains updated for AMR_WB_PLUS. *
60 : * MA prediction is removed and MEAN_ENER is now quantized with 2 bits and *
61 : * transmitted once every ACELP frame to the gains decoder. *
62 : * The pitch gain and the code gain are vector quantized and the *
63 : * mean-squared weighted error criterion is used in the quantizer search. *
64 : *-------------------------------------------------------------------------*/
65 :
66 3020 : void encode_acelp_gains(
67 : const float *code,
68 : const int16_t gains_mode,
69 : const float mean_ener_code,
70 : const int16_t clip_gain,
71 : ACELP_CbkCorr *g_corr,
72 : float *gain_pit,
73 : float *gain_code,
74 : int16_t **pt_indice,
75 : float *past_gcode,
76 : float *gain_inov,
77 : const int16_t L_subfr,
78 : float *code2,
79 : float *gain_code2,
80 : const int16_t noisy_speech_flag )
81 : {
82 3020 : int16_t index = 0;
83 :
84 3020 : if ( ( ( gains_mode > 0 ) && ( gains_mode < 4 ) ) )
85 : {
86 : /* Memory-less gain coding */
87 3020 : index = Mode2_gain_enc_mless( code, L_subfr, gain_pit, gain_code, g_corr, mean_ener_code, clip_gain, past_gcode, gain_inov, gains_mode - 1 );
88 : }
89 0 : else if ( gains_mode == 6 )
90 : {
91 : /* UV gains quantizer (6bits/subfr) */
92 0 : index = gain_enc_uv( code, L_subfr, gain_pit, gain_code, g_corr, past_gcode, gain_inov );
93 : }
94 0 : else if ( gains_mode == 7 )
95 : {
96 : /* GACELP_UV gains quantizer (7=5-2bits/subfr) */
97 0 : index = gain_enc_gacelp_uv( code, code2, L_subfr, mean_ener_code, gain_pit, gain_code, gain_code2, g_corr, past_gcode, gain_inov, noisy_speech_flag );
98 : }
99 : else
100 : {
101 0 : IVAS_ERROR( IVAS_ERR_INTERNAL, "invalid gains coding for acelp!" );
102 : }
103 :
104 3020 : **pt_indice = index;
105 3020 : ( *pt_indice )++;
106 :
107 3020 : return;
108 : }
109 :
110 : /*---------------------------------------------------------------------*
111 : * procedure Mode2_gain_enc_mless
112 : * Quantization of pitch and codebook gains.
113 : * - an initial predicted gain, gcode0, is first determined based on
114 : * the predicted scaled innovation energy
115 : * - the correction factor gamma = g_code / gcode0 is then vector quantized
116 : * along with gain_pit
117 : * - the mean-squared weighted error criterion is used for the quantizer search
118 : *---------------------------------------------------------------------*/
119 :
120 3020 : int16_t Mode2_gain_enc_mless(
121 : const float *code, /* i : algebraic excitation */
122 : const int16_t lcode, /* i : Subframe size */
123 : float *gain_pit, /* o : quantized pitch gain */
124 : float *gain_code, /* o : quantized codebook gain */
125 : ACELP_CbkCorr *pcoeff, /* i/o: correlations <y1,y1>, -2<xn,y 1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>*/
126 : const float mean_ener, /* i : mean_ener defined in open-loop (3 bits) */
127 : const int16_t clip_gain, /* i : gain pitch clipping flag (1 = clipping) */
128 : float *past_gcode, /* i/o: past gain of code */
129 : float *gain_inov, /* o : unscaled innovation gain */
130 : const int16_t coder_type /* i : coder type */
131 : )
132 : {
133 : int16_t index, i, size, size_clip;
134 : const Word16 *p, *t_qua_gain;
135 : float dist, dist_min, g_pitch, g_code, gcode0, ener_code;
136 : ACELP_CbkCorr coeff;
137 :
138 : /*-----------------------------------------------------------------*
139 : * - calculate the unscaled innovation energy
140 : * - calculate the predicted gain code
141 : *-----------------------------------------------------------------*/
142 :
143 3020 : if ( coder_type == 0 )
144 : {
145 0 : *gain_inov = 1.0f / (float) sqrt( ( dotp( code, code, lcode ) + 0.01f ) / lcode );
146 0 : ener_code = 10 * (float) log10( ( dotp( code, code, lcode ) + 0.01f ) / lcode );
147 0 : gcode0 = (float) pow( 10, 0.05 * ( mean_ener - ener_code ) );
148 : }
149 : else
150 : {
151 3020 : ener_code = 0.01F;
152 196300 : for ( i = 0; i < lcode; i++ )
153 : {
154 193280 : ener_code += code[i] * code[i];
155 : }
156 :
157 3020 : *gain_inov = (float) sqrt( (float) lcode / ener_code );
158 :
159 3020 : ener_code = (float) ( -10.0 * log10( (float) lcode / ener_code ) );
160 3020 : gcode0 = mean_ener - ener_code;
161 3020 : gcode0 = (float) pow( 10.0, gcode0 / 20.0 ); /* predicted gain */
162 : }
163 :
164 : /*-----------------------------------------------------------------*
165 : * gain quantization initializations
166 : * - find the initial quantization pitch index
167 : * - set the gains searching range
168 : *-----------------------------------------------------------------*/
169 :
170 3020 : if ( coder_type == 0 )
171 : {
172 0 : t_qua_gain = E_ROM_qua_gain5b_const;
173 0 : size_clip = 9;
174 0 : size = NB_QUA_GAIN5B;
175 : }
176 3020 : else if ( coder_type == 1 )
177 : {
178 130 : t_qua_gain = E_ROM_qua_gain6b_const;
179 130 : size_clip = 6;
180 130 : size = NB_QUA_GAIN6B; /* searching range of the gain quantizer */
181 : }
182 : else
183 : {
184 2890 : t_qua_gain = E_ROM_qua_gain7b_const;
185 2890 : size_clip = 21;
186 2890 : size = NB_QUA_GAIN7B;
187 : }
188 :
189 3020 : if ( clip_gain == 1 )
190 : {
191 0 : size -= size_clip; /* limit pitch gain to 1.0 */
192 : }
193 :
194 3020 : coeff = *pcoeff;
195 3020 : coeff.xy1 *= -2.0f;
196 3020 : coeff.xy2 *= -2.0f;
197 3020 : coeff.y1y2 *= 2.0f;
198 :
199 : /*-----------------------------------------------------------------*
200 : * search for the best quantizer
201 : *-----------------------------------------------------------------*/
202 :
203 3020 : p = t_qua_gain;
204 3020 : dist_min = FLT_MAX;
205 3020 : index = 0;
206 :
207 381260 : for ( i = 0; i < size; i++ )
208 : {
209 378240 : g_pitch = (float) ( *p++ ) / ( 1 << 14 ); /* pitch gain */
210 378240 : g_code = gcode0 * (float) ( *p++ ) / ( 1 << 11 ); /* codebook gain */
211 :
212 378240 : dist = g_pitch * g_pitch * coeff.y1y1 + g_pitch * coeff.xy1 + g_code * g_code * coeff.y2y2 + g_code * coeff.xy2 + g_pitch * g_code * coeff.y1y2;
213 :
214 378240 : if ( dist < dist_min )
215 : {
216 61769 : dist_min = dist;
217 61769 : index = i;
218 : }
219 : }
220 :
221 3020 : *gain_pit = (float) ( t_qua_gain[index * 2] ) / ( 1 << 14 );
222 3020 : *gain_code = (float) ( t_qua_gain[index * 2 + 1] ) / ( 1 << 11 ) * gcode0;
223 :
224 3020 : *past_gcode = *gain_code / *gain_inov;
225 :
226 3020 : return index;
227 : }
228 :
229 : /*---------------------------------------------------------------------*
230 : * procedure gain_enc_uv
231 : * Quantization of pitch and codebook gains.
232 : * - an initial predicted gain, gcode0, is first determined based on
233 : * the predicted scaled innovation energy
234 : * - the correction factor gamma = g_code / gcode0 is then vector quantized
235 : * along with gain_pit
236 : * - the mean-squared weighted error criterion is used for the quantizer search
237 : *---------------------------------------------------------------------*/
238 :
239 0 : static int16_t gain_enc_uv(
240 : const float *code, /* i : algebraic excitation */
241 : const int16_t lcode, /* i ) : Subframe size */
242 : float *gain_pit, /* o : quantized pitch gain */
243 : float *gain_code, /* o : quantized codebook gain */
244 : ACELP_CbkCorr *coeff, /* i/o : correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> */
245 : float *past_gcode, /* i/o : past gain of code */
246 : float *gain_inov /* o : unscaled innovation gain */
247 : )
248 : {
249 : int16_t index;
250 : float g_code, g_code_corr;
251 :
252 : /*-----------------------------------------------------------------*
253 : * - calculate the unscaled innovation energy
254 : *-----------------------------------------------------------------*/
255 :
256 0 : *gain_inov = 1.0f / (float) sqrt( ( dotp( code, code, lcode ) + 0.01f ) / lcode );
257 :
258 0 : g_code_corr = coeff->xy2 / ( coeff->y2y2 * ( *gain_inov ) ); /*Correlation based*/
259 :
260 0 : g_code = g_code_corr;
261 :
262 : /*90dB max of gain for 2^15 amplitude code, */
263 0 : if ( g_code > 0.000001f )
264 : {
265 0 : index = (int16_t) ( ( ( 20.f * log10( g_code ) + 30.f ) / 1.9f ) + 0.5f );
266 :
267 0 : if ( index > 63 )
268 : {
269 0 : index = 63;
270 : }
271 0 : else if ( index < 0 )
272 : {
273 0 : index = 0;
274 : }
275 : }
276 : else
277 : {
278 0 : index = 0;
279 : }
280 :
281 0 : *gain_code = (float) pow( 10.f, ( ( ( index * 1.9f ) - 30.f ) / 20.f ) );
282 0 : *past_gcode = *gain_code; /*unscaled gain*/
283 0 : *gain_code *= *gain_inov; /*scaled gain*/
284 0 : *gain_pit = 0.f;
285 :
286 0 : return index;
287 : }
288 :
289 : /*---------------------------------------------------------------------*
290 : * procedure gain_enc_gacelp_uv
291 : * Quantization of pitch and codebook gains.
292 : * - an initial predicted gain, gcode0, is first determined based on
293 : * the predicted scaled innovation energy
294 : * - the correction factor gamma = g_code / gcode0 is then vector quantized
295 : * along with gain_pit
296 : * - the mean-squared weighted error criterion is used for the quantizer search
297 : *---------------------------------------------------------------------*/
298 :
299 8148 : int16_t gain_enc_gacelp_uv(
300 : const float *code, /* i : algebraic excitation */
301 : const float *code2, /* i : gaussian excitation */
302 : const int16_t lcode, /* i : Subframe size */
303 : const float mean_ener, /* i : quantized mean energy of the frame */
304 : float *gain_pit, /* o : quantized pitch gain */
305 : float *gain_code, /* o : quantized codebook gain */
306 : float *gain_code2, /* o : quantized codebook gain */
307 : ACELP_CbkCorr *coeff, /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> */
308 : float *past_gcode, /* i/o: past gain of code */
309 : float *gain_inov, /* o : unscaled innovation gain */
310 : const int16_t noisy_speech_flag /* i : noisy speech flag */
311 : )
312 : {
313 : int16_t index;
314 : float gcode, gcode2, pred_nrg_frame;
315 : float norm_code2;
316 : int16_t i;
317 : float c, c_index2, c_first;
318 : int16_t index2;
319 :
320 : /*-----------------------------------------------------------------*
321 : * - calculate the unscaled innovation energy
322 : *-----------------------------------------------------------------*/
323 :
324 8148 : *gain_inov = 1.0f / (float) sqrt( ( dotp( code, code, lcode ) + 0.01f ) / lcode );
325 8148 : pred_nrg_frame = (float) pow( 10.0, mean_ener / 20.0 );
326 8148 : gcode = pred_nrg_frame * ( *gain_inov );
327 8148 : norm_code2 = 1.0f / (float) sqrt( ( dotp( code2, code2, lcode ) + 0.01f ) / lcode );
328 8148 : gcode2 = pred_nrg_frame * ( norm_code2 );
329 :
330 : /*-----------------------------------------------------------------*
331 : * search for the best quantizer
332 : *-----------------------------------------------------------------*/
333 :
334 8148 : *gain_code = coeff->xy2 / ( coeff->y2y2 * gcode );
335 :
336 8148 : if ( *gain_code > 0.000001f )
337 : {
338 8148 : index = (int16_t) ( ( ( 20.f * log10( *gain_code ) + 20.f ) / 1.25f ) + 0.5f );
339 :
340 8148 : if ( index > 31 )
341 : {
342 8 : index = 31;
343 : }
344 8140 : else if ( index < 0 )
345 : {
346 4 : index = 0;
347 : }
348 : }
349 : else
350 : {
351 0 : index = 0;
352 : }
353 :
354 8148 : *gain_code = (float) pow( 10.f, ( ( ( index * 1.25f ) - 20.f ) / 20.f ) );
355 8148 : *gain_code *= gcode;
356 :
357 8148 : if ( noisy_speech_flag )
358 : {
359 528 : c_first = 0.8f * coeff->xx - ( *gain_code ) * ( *gain_code ) * coeff->y2y2;
360 : }
361 : else
362 : {
363 7620 : c_first = coeff->xx - ( *gain_code ) * ( *gain_code ) * coeff->y2y2;
364 : }
365 8148 : index2 = 0;
366 8148 : *gain_code2 = (float) ( index2 * 0.25f + 0.25f ) * ( *gain_code * ( gcode2 / gcode ) );
367 :
368 8148 : c_index2 = c_first - ( *gain_code2 ) * ( *gain_code2 ) * coeff->y1y1 - 2 * ( *gain_code ) * ( *gain_code2 ) * coeff->y1y2;
369 :
370 32592 : for ( i = 1; i < 4; i++ )
371 : {
372 24444 : *gain_code2 = (float) ( i * 0.25f + 0.25f ) * ( *gain_code * ( gcode2 / gcode ) );
373 :
374 24444 : c = c_first - ( *gain_code2 ) * ( *gain_code2 ) * coeff->y1y1 - 2 * ( *gain_code ) * ( *gain_code2 ) * coeff->y1y2;
375 :
376 24444 : if ( fabs( c ) < fabs( c_index2 ) )
377 : {
378 16638 : index2 = i;
379 16638 : c_index2 = c;
380 : }
381 : }
382 :
383 8148 : *gain_code2 = (float) ( index2 * 0.25f + 0.25f ) * ( *gain_code * ( gcode2 / gcode ) );
384 8148 : index += index2 * 32;
385 :
386 8148 : *gain_pit = 0.f;
387 8148 : *past_gcode = *gain_code / *gain_inov; /*unscaled gain*/
388 :
389 8148 : return index;
390 : }
|