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 "cnst.h"
44 : #include "rom_com.h"
45 : #include "prot.h"
46 : #include "wmc_auto.h"
47 :
48 : /*-------------------------------------------------------------------*
49 : * Local constants
50 : *-------------------------------------------------------------------*/
51 :
52 : #define NMAX 8 /* Control of the routine's complexity */
53 : #define FAC_DELTA 16.0f
54 :
55 : /*---------------------------------------------------------------------*
56 : * Prototypes
57 : *---------------------------------------------------------------------*/
58 :
59 : static int16_t cod_2pos( const int16_t ind1, const int16_t ind2, const float sign1, const float sign2, const int16_t n );
60 :
61 : static void gauss2v( BSTR_ENC_HANDLE hBstr, const float h[], const float xn[], const float dn[], float code[], float y1[], float *gain, const int16_t lg, const int16_t nb_bits );
62 :
63 : /*-------------------------------------------------------------------*
64 : * Gaus_encode
65 : *
66 : * Encoder UnVoiced excitation coding using Gaussian codebooks
67 : * - ACELP quantized Gaussian excitation
68 : * - gain quantization
69 : * - Total excitation for UnVoiced coders
70 : * - Updates
71 : *-------------------------------------------------------------------*/
72 :
73 0 : float gaus_encode(
74 : Encoder_State *st, /* i/o: encoder state structure */
75 : const int16_t i_subfr, /* i : subframe index */
76 : const float *h1, /* i : weighted filter input response */
77 : const float *xn, /* i : target vector */
78 : float *exc, /* o : pointer to excitation signal frame */
79 : float *mem_w0, /* o : weighting filter denominator memory */
80 : float *gp_clip_mem, /* o : memory of gain of pitch clipping algorithm */
81 : float *tilt_code, /* o : synthesis excitation spectrum tilt */
82 : float *code, /* o : algebraic excitation */
83 : float *gain_code, /* o : Code gain. */
84 : float *y2, /* o : zero-memory filtered adaptive excitation */
85 : float *gain_inov, /* o : innovation gain */
86 : float *voice_fac, /* o : voicing factor */
87 : float *gain_pit, /* o : adaptive excitation gain */
88 : float *norm_gain_code /* o : normalized innovative cb. gain */
89 : )
90 : {
91 0 : int16_t i = 0, nb_bits, idx;
92 : float dn[L_SUBFR]; /* Correlation between xn and h1 */
93 0 : BSTR_ENC_HANDLE hBstr = st->hBstr;
94 :
95 : /*----------------------------------------------------------------*
96 : * Encode gaussian excitation
97 : *----------------------------------------------------------------*/
98 :
99 0 : corr_xh( xn, dn, h1, L_SUBFR ); /* Correlation between target xn[] and impulse response h1[] */
100 :
101 0 : nb_bits = st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR];
102 :
103 0 : gauss2v( hBstr, h1, xn, dn, code, y2, gain_code, L_SUBFR, nb_bits >> 1 );
104 :
105 : /*----------------------------------------------------------------*
106 : * Encode gaussian gain
107 : *----------------------------------------------------------------*/
108 :
109 : /* codeword energy computation */
110 0 : *gain_inov = 1.0f / (float) sqrt( ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR );
111 :
112 0 : nb_bits = st->acelp_cfg.gains_mode[i_subfr / L_SUBFR];
113 :
114 0 : idx = gain_enc_gaus( gain_code, nb_bits, -30.0f, 190.0f );
115 0 : push_indice( hBstr, IND_GAIN, idx, nb_bits );
116 :
117 : /*-----------------------------------------------------------------*
118 : * Total excitation for Unvoiced coders
119 : *-----------------------------------------------------------------*/
120 :
121 0 : for ( i = 0; i < L_SUBFR; i++ )
122 : {
123 0 : exc[i + i_subfr] = *gain_code * code[i];
124 : }
125 :
126 : /*-----------------------------------------------------------------*
127 : * Updates: last value of new target is stored in mem_w0
128 : *-----------------------------------------------------------------*/
129 :
130 0 : *mem_w0 = xn[L_SUBFR - 1] - *gain_code * y2[L_SUBFR - 1];
131 :
132 0 : init_gp_clip( gp_clip_mem ); /* reset pitch clipping parameters */
133 0 : *gain_pit = 0.0f;
134 0 : *tilt_code = 0.0f; /* purely unvoiced */
135 0 : *voice_fac = -1.0f; /* purely unvoiced */
136 :
137 0 : *norm_gain_code = *gain_code / *gain_inov;
138 :
139 0 : return L_SUBFR;
140 : }
141 :
142 : /*-------------------------------------------------------------------*
143 : * gauss2v()
144 : *
145 : * encoder of Gaussian Codebook for unvoiced
146 : * consisting of addition of 2 Gaussian vectors
147 : *
148 : * One Gaussian vector of 192 values vectors delayed by 2
149 : *-------------------------------------------------------------------*/
150 :
151 0 : static void gauss2v(
152 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
153 : const float h[], /* i : weighted LP filter impulse response */
154 : const float xn[], /* i : target signal */
155 : const float dn[], /* i : backward filtered target */
156 : float code[], /* o : gaussian excitation */
157 : float y11[], /* o : zero-memory filtered gauss. excitation */
158 : float *gain, /* o : excitation gain */
159 : const int16_t lg, /* i : subframe size */
160 : const int16_t nb_bits /* i : nb ob bits per track (max 6) */
161 : )
162 : {
163 : int16_t i, j, ind1, ind2, idx;
164 : int16_t nvec, step;
165 : float cor, cora, cor2, cor2w, eneri, enerw;
166 : float *pt1, *pt2;
167 : float max_val[NMAX + 1], *pos[NMAX + 1], sign[NMAX + 1];
168 : float ener[NMAX + 1], corr[NMAX + 1], ener1;
169 : float dico2[L_SUBFR * NMAX];
170 : float c1, c0;
171 : float gxx, gcc;
172 : float gaus_dico2[190];
173 : float hg[190];
174 : float delta;
175 : int16_t index_delta;
176 :
177 : /*-----------------------------------------------------------------*
178 : * Encode the tilt of gaussian excitation
179 : *-----------------------------------------------------------------*/
180 :
181 0 : c0 = 0.0f; /* Compute spectral tilt of target */
182 0 : c1 = 0.0f;
183 0 : for ( i = 1; i < L_SUBFR; i++ )
184 : {
185 0 : c0 += xn[i] * xn[i];
186 0 : c1 += xn[i] * xn[i - 1];
187 : }
188 0 : if ( c0 < FLT_MIN )
189 : {
190 0 : gxx = 0.f;
191 : }
192 : else
193 : {
194 0 : gxx = c1 / c0;
195 : }
196 :
197 0 : set_f( hg, 0, 190 ); /* Compute spectral tilt of filtered codebook */
198 0 : mvr2r( h, hg, L_SUBFR );
199 0 : conv( gaus_dico, hg, gaus_dico2, 190 );
200 :
201 0 : c0 = 0.0f;
202 0 : c1 = 0.0f;
203 0 : for ( i = 1; i < 190; i++ )
204 : {
205 0 : c0 += gaus_dico2[i] * gaus_dico2[i];
206 0 : c1 += gaus_dico2[i] * gaus_dico2[i - 1];
207 : }
208 0 : gcc = c1 / c0;
209 0 : delta = ( 1 - gcc * gxx ) / ( 2 * gcc + gxx ); /* Compute and quantize spectral tilt modification factor (3b) */
210 :
211 0 : index_delta = (int16_t) ( FAC_DELTA * delta );
212 0 : if ( index_delta < 0 )
213 : {
214 0 : index_delta = 0;
215 : }
216 0 : if ( index_delta > 7 )
217 : {
218 0 : index_delta = 7;
219 : }
220 :
221 0 : delta = STEP_DELTA * (float) index_delta;
222 0 : if ( delta > 0.0f ) /* Adapt spectral tilt of initial codebook */
223 : {
224 0 : gaus_dico2[0] = gaus_dico[0];
225 0 : for ( i = 1; i < 190; i++ )
226 : {
227 0 : gaus_dico2[i] = ( gaus_dico[i] - delta * gaus_dico[i - 1] ) / ( 1 + delta * delta );
228 : }
229 : }
230 : else
231 : {
232 0 : for ( i = 0; i < 190; i++ )
233 : {
234 0 : gaus_dico2[i] = gaus_dico[i];
235 : }
236 : }
237 :
238 : /*-----------------------------------------------------------------*
239 : * Codebook search initializations
240 : *-----------------------------------------------------------------*/
241 :
242 0 : ind1 = 0;
243 0 : ind2 = 0;
244 :
245 0 : nvec = 1 << nb_bits;
246 0 : step = 0x80 >> nb_bits;
247 :
248 : /*-----------------------------------------------------------------*
249 : * dot product between dn and gaussian codevectors,
250 : * keep NMAX best vectors
251 : *-----------------------------------------------------------------*/
252 :
253 0 : set_f( max_val, 0, NMAX + 1 );
254 0 : set_f( sign, 0, NMAX + 1 );
255 :
256 0 : for ( i = 0; i < NMAX + 1; i++ )
257 : {
258 0 : pos[i] = (float *) gaus_dico2;
259 : }
260 :
261 0 : pt1 = (float *) gaus_dico2;
262 :
263 0 : for ( i = 0; i < nvec; i++, pt1 += step )
264 : {
265 0 : cor = dotp( pt1, dn, lg );
266 0 : cora = (float) fabs( cor );
267 0 : j = NMAX - 1;
268 : do
269 : {
270 0 : if ( cora >= max_val[j] )
271 : {
272 0 : max_val[j + 1] = max_val[j];
273 0 : pos[j + 1] = pos[j];
274 0 : sign[j + 1] = sign[j];
275 0 : max_val[j] = cora;
276 0 : pos[j] = pt1;
277 0 : sign[j] = cor;
278 : }
279 :
280 0 : j--;
281 0 : } while ( j >= 0 );
282 : }
283 :
284 : /*-----------------------------------------------------------------*
285 : * filter selected vectors
286 : * put sign
287 : * compute energy
288 : *-----------------------------------------------------------------*/
289 :
290 0 : pt1 = dico2;
291 0 : for ( i = 0; i < NMAX; i++, pt1 += L_SUBFR )
292 : {
293 0 : conv( pos[i], h, pt1, lg );
294 :
295 : /* put sign and compute energy */
296 0 : if ( sign[i] < 0.0f )
297 : {
298 0 : for ( j = 0; j < lg; j++ )
299 : {
300 0 : pt1[j] = -pt1[j]; /*Store into dico2*/
301 : }
302 : }
303 0 : ener[i] = dotp( pt1, pt1, lg );
304 0 : corr[i] = dotp( pt1, xn, lg ); /* must be equal to sign[i] */
305 : }
306 :
307 : /*-----------------------------------------------------------------*
308 : * try all combinations of NMAX best vectors
309 : *-----------------------------------------------------------------*/
310 :
311 0 : pt1 = dico2;
312 :
313 : /* Initial values for search algorithm */
314 0 : enerw = 1.0f;
315 0 : cor2w = -1.0f;
316 :
317 0 : for ( i = 0; i < NMAX; i++, pt1 += L_SUBFR )
318 : {
319 0 : pt2 = pt1;
320 0 : for ( j = i; j < NMAX; j++, pt2 += L_SUBFR )
321 : {
322 0 : cor = corr[i] + corr[j];
323 0 : eneri = ener[i] + ener[j] + 2.0f * dotp( pt1, pt2, lg );
324 0 : cor2 = cor * cor;
325 0 : if ( cor2 * enerw > cor2w * eneri )
326 : {
327 0 : cor2w = cor2;
328 0 : enerw = eneri;
329 0 : ind1 = i;
330 0 : ind2 = j;
331 : }
332 : }
333 : }
334 :
335 : /*-----------------------------------------------------------------*
336 : * Compute zero-memory filtered gauss. excitation y
337 : *-----------------------------------------------------------------*/
338 :
339 0 : pt1 = dico2 + ind1 * L_SUBFR;
340 0 : pt2 = dico2 + ind2 * L_SUBFR;
341 0 : for ( i = 0; i < lg; i++ )
342 : {
343 0 : y11[i] = pt1[i] + pt2[i];
344 : }
345 :
346 : /*-----------------------------------------------------------------*
347 : * Signs of vectors
348 : *-----------------------------------------------------------------*/
349 :
350 0 : if ( sign[ind1] >= 0.0f )
351 : {
352 0 : sign[ind1] = 1.0f;
353 : }
354 : else
355 : {
356 0 : sign[ind1] = -1.0f;
357 : }
358 :
359 0 : if ( sign[ind2] >= 0.0f )
360 : {
361 0 : sign[ind2] = 1.0f;
362 : }
363 : else
364 : {
365 0 : sign[ind2] = -1.0f;
366 : }
367 :
368 : /*-----------------------------------------------------------------*
369 : * Compute code
370 : *-----------------------------------------------------------------*/
371 :
372 0 : pt1 = pos[ind1];
373 0 : pt2 = pos[ind2];
374 0 : for ( i = 0; i < lg; i++ )
375 : {
376 0 : code[i] = pt1[i] * sign[ind1] + pt2[i] * sign[ind2];
377 : }
378 0 : cor = corr[ind1] + corr[ind2];
379 :
380 : /*-----------------------------------------------------------------*
381 : * Compute index
382 : *-----------------------------------------------------------------*/
383 :
384 0 : i = (int16_t) ( ( pos[ind1] - gaus_dico2 ) / step ); /* Division by step can be replaced by shift */
385 0 : j = (int16_t) ( ( pos[ind2] - gaus_dico2 ) / step ); /* Division by step can be replaced by shift */
386 :
387 0 : idx = cod_2pos( i, j, sign[ind1], sign[ind2], nvec );
388 :
389 0 : push_indice( hBstr, IND_GAUS_CDBK_INDEX, idx, 2 * nb_bits + 1 );
390 0 : push_indice( hBstr, IND_TILT_FACTOR, index_delta, 3 );
391 :
392 : /*-----------------------------------------------------------------*
393 : * Find quantized gain
394 : *-----------------------------------------------------------------*/
395 :
396 0 : *gain = cor / enerw;
397 0 : ener1 = dotp( xn, xn, lg );
398 0 : ener1 = (float) sqrt( ener1 / enerw ); /* Minimize ebergy error */
399 0 : *gain = *gain * 0.6f + ener1 * 0.4f;
400 :
401 0 : return;
402 : }
403 :
404 : /*---------------------------------------------------------------------*
405 : * Put selected codevector positions and signs into quantization index
406 : *---------------------------------------------------------------------*/
407 :
408 : /*! r: codebook quantization index */
409 0 : static int16_t cod_2pos(
410 : const int16_t ind1, /* i : index of 1st gaussian vector */
411 : const int16_t ind2, /* i : index of 2nd gaussian vector */
412 : const float sign1, /* i : sign of 1st gaussian vector */
413 : const float sign2, /* i : sign of 2nd gaussian vector */
414 : const int16_t n /* i : nb. of codebook vectors */
415 : )
416 : {
417 : int16_t i1, i2, index, s1, s2;
418 :
419 :
420 0 : s1 = 1;
421 0 : if ( sign1 > 0.0f )
422 : {
423 0 : s1 = 0;
424 : }
425 :
426 0 : s2 = 1;
427 0 : if ( sign2 > 0.0f )
428 : {
429 0 : s2 = 0;
430 : }
431 :
432 0 : if ( s1 == s2 )
433 : {
434 0 : if ( ind1 <= ind2 )
435 : {
436 0 : i1 = ind1;
437 0 : i2 = ind2;
438 : }
439 : else
440 : {
441 0 : i1 = ind2;
442 0 : i2 = ind1;
443 : }
444 : }
445 : else
446 : {
447 0 : if ( ind1 > ind2 )
448 : {
449 0 : i1 = ind1;
450 0 : i2 = ind2;
451 : }
452 : else
453 : {
454 0 : i1 = ind2;
455 0 : i2 = ind1;
456 0 : s1 = s2;
457 : }
458 : }
459 0 : index = i1 * n + i2;
460 0 : index = ( index << 1 ) + s1;
461 :
462 0 : return index;
463 : }
|