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 "cnst.h"
43 : #include "rom_com.h"
44 : #include "prot.h"
45 : #include "wmc_auto.h"
46 :
47 : /*-------------------------------------------------------------------*
48 : * enc_pit_exc()
49 : *
50 : * Encode pitch only contribution
51 : *-------------------------------------------------------------------*/
52 :
53 115164 : void enc_pit_exc(
54 : Encoder_State *st, /* i/o: State structure */
55 : const float *speech, /* i : Input speech */
56 : const float Aw[], /* i : weighted A(z) unquantized for subframes */
57 : const float *Aq, /* i : 12k8 Lp coefficient */
58 : const float Es_pred, /* i : predicted scaled innov. energy */
59 : const float *res, /* i : residual signal */
60 : float *synth, /* i/o: core synthesis */
61 : float *exc, /* i/o: current non-enhanced excitation */
62 : int16_t *T0, /* i/o: close loop integer pitch */
63 : int16_t *T0_frac, /* i/o: close-loop pitch period - fractional part */
64 : float *pitch_buf, /* i/o: Fractionnal per subframe pitch */
65 : const int16_t nb_subfr, /* i : Number of subframe considered */
66 : float *gpit, /* o : pitch mean gpit */
67 : const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */
68 : const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */
69 : )
70 : {
71 : float xn[PIT_EXC_L_SUBFR]; /* Target vector for pitch search */
72 : float xn2[PIT_EXC_L_SUBFR]; /* Target vector for codebook search */
73 : float cn[PIT_EXC_L_SUBFR]; /* Target vector in residual domain */
74 : float h1[PIT_EXC_L_SUBFR + ( M + 1 )]; /* Impulse response vector */
75 : float y1[PIT_EXC_L_SUBFR]; /* Filtered adaptive excitation */
76 : float code[2 * L_SUBFR]; /* Fixed codebook excitation */
77 : float y2[2 * L_SUBFR]; /* Filtered algebraic excitation */
78 : float voice_fac; /* Voicing factor */
79 : float gain_code; /* Gain of code */
80 : float gain_inov; /* inovation gain */
81 : float gain_pit; /* Pitch gain */
82 : int16_t pit_idx, i_subfr; /* tmp variables */
83 : int16_t T0_min, T0_max; /* pitch variables */
84 : float g_corr[10]; /* ACELP correlation values + gain pitch */
85 : int16_t clip_gain, i; /* LSF clip gain and LP flag */
86 : const float *p_Aw, *p_Aq; /* pointer to LP filter coefficient vector */
87 : float *pt_pitch; /* pointer to floating pitch */
88 : int16_t L_subfr;
89 : float cum_gpit, gpit_tmp;
90 : int32_t Local_BR, Pitch_BR;
91 : int16_t Pitch_CT, unbits_PI;
92 : float norm_gain_code;
93 : int16_t pitch_limit_flag;
94 : int16_t lp_select, lp_flag;
95 115164 : BSTR_ENC_HANDLE hBstr = st->hBstr;
96 : int16_t use_fcb;
97 : float gains_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */
98 :
99 115164 : LPD_state_HANDLE hLPDmem = st->hLPDmem;
100 :
101 : /*------------------------------------------------------------------*
102 : * Initialization
103 : *------------------------------------------------------------------*/
104 :
105 115164 : pitch_limit_flag = 1; /* always extended pitch Q range */
106 115164 : use_fcb = 0;
107 115164 : unbits_PI = 0;
108 :
109 115164 : if ( st->GSC_IVAS_mode > 0 && ( st->GSC_noisy_speech || st->core_brate > GSC_H_RATE_STG ) )
110 : {
111 4832 : Local_BR = ACELP_8k00;
112 4832 : Pitch_CT = GENERIC;
113 4832 : Pitch_BR = ACELP_8k00;
114 4832 : if ( st->L_frame == L_FRAME16k )
115 : {
116 0 : Local_BR = ACELP_14k80;
117 0 : if ( st->GSC_IVAS_mode > 0 )
118 : {
119 0 : Local_BR = ACELP_9k60;
120 : }
121 0 : Pitch_BR = st->core_brate;
122 : }
123 : }
124 110332 : else if ( st->GSC_noisy_speech )
125 : {
126 2066 : Local_BR = ACELP_7k20;
127 2066 : Pitch_CT = GENERIC;
128 2066 : Pitch_BR = ACELP_7k20;
129 2066 : if ( st->L_frame == L_FRAME16k )
130 : {
131 0 : Pitch_BR = st->core_brate;
132 : }
133 : }
134 : else
135 : {
136 108266 : Local_BR = ACELP_7k20;
137 108266 : Pitch_CT = AUDIO;
138 108266 : Pitch_BR = st->core_brate;
139 :
140 108266 : if ( st->L_frame == L_FRAME16k )
141 : {
142 19792 : Local_BR = ACELP_13k20;
143 19792 : Pitch_CT = GENERIC;
144 : }
145 : }
146 :
147 115164 : gain_code = 0;
148 :
149 115164 : if ( st->L_frame == L_FRAME16k )
150 : {
151 19792 : T0_max = PIT16k_MAX;
152 19792 : T0_min = PIT16k_MIN;
153 : }
154 : else
155 : {
156 95372 : T0_max = PIT_MAX;
157 95372 : T0_min = PIT_MIN;
158 : }
159 :
160 115164 : cum_gpit = 0.0f;
161 :
162 115164 : L_subfr = st->L_frame / nb_subfr;
163 :
164 115164 : lp_flag = st->acelp_cfg.ltf_mode;
165 :
166 115164 : if ( ( ( st->core_brate >= MIN_RATE_FCB || ( st->GSC_noisy_speech == 1 && ( ( st->L_frame == L_FRAME && st->core_brate >= ACELP_13k20 ) || ( st->L_frame == L_FRAME16k && st->core_brate >= GSC_H_RATE_STG ) || st->GSC_IVAS_mode == 0 ) ) ) && L_subfr == L_SUBFR ) )
167 : {
168 2670 : use_fcb = 1;
169 : }
170 112494 : else if ( st->GSC_IVAS_mode > 0 && L_subfr == 2 * L_SUBFR && st->GSC_IVAS_mode < 3 )
171 : {
172 16116 : use_fcb = 2;
173 16116 : st->acelp_cfg.fcb_mode = 1;
174 16116 : set_s( st->acelp_cfg.gains_mode, 6, NB_SUBFR );
175 16116 : set_s( st->acelp_cfg.pitch_bits, 9, NB_SUBFR );
176 16116 : set_s( st->acelp_cfg.fixed_cdk_index, 14, NB_SUBFR16k );
177 : }
178 :
179 : /*------------------------------------------------------------------*
180 : * ACELP subframe loop
181 : *------------------------------------------------------------------*/
182 :
183 115164 : p_Aw = Aw;
184 115164 : p_Aq = Aq;
185 115164 : pt_pitch = pitch_buf; /* pointer to the pitch buffer */
186 :
187 381663 : for ( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_subfr )
188 : {
189 : /*----------------------------------------------------------------*
190 : * Find the the excitation search target "xn" and innovation
191 : * target in residual domain "cn"
192 : * Compute impulse response, h1[], of weighted synthesis filter
193 : *----------------------------------------------------------------*/
194 :
195 266499 : mvr2r( &res[i_subfr], &exc[i_subfr], L_subfr );
196 :
197 266499 : find_targets( speech, st->hGSCEnc->mem_syn_tmp, i_subfr, &st->hGSCEnc->mem_w0_tmp, p_Aq, res, L_subfr, p_Aw, st->preemph_fac, xn, cn, h1 );
198 :
199 : /*----------------------------------------------------------------*
200 : * Close-loop pitch search and quantization
201 : * Adaptive exc. construction
202 : *----------------------------------------------------------------*/
203 :
204 266499 : *pt_pitch = pit_encode( hBstr, st->acelp_cfg.pitch_bits, Pitch_BR, 0, st->L_frame, Pitch_CT, &pitch_limit_flag, i_subfr, exc, L_subfr, st->pitch, &T0_min, &T0_max, T0, T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf );
205 :
206 : /*-----------------------------------------------------------------*
207 : * Find adaptive exitation
208 : *-----------------------------------------------------------------*/
209 :
210 266499 : pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_subfr + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP );
211 :
212 : /*-----------------------------------------------------------------*
213 : * Gain clipping test to avoid unstable synthesis on frame erasure
214 : * or in case of floating point encoder & fixed p. decoder
215 : *-----------------------------------------------------------------*/
216 :
217 266499 : clip_gain = gp_clip( st->element_mode, st->core_brate, st->voicing, i_subfr, AUDIO, xn, st->clip_var );
218 :
219 : /*-----------------------------------------------------------------*
220 : * Codebook target computation
221 : * (No LP filtering of the adaptive excitation)
222 : *-----------------------------------------------------------------*/
223 :
224 266499 : lp_select = lp_filt_exc_enc( MODE1, AUDIO, i_subfr, exc, h1, xn, y1, xn2, L_subfr, st->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag );
225 :
226 266499 : if ( lp_flag == NORMAL_OPERATION )
227 : {
228 0 : push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 );
229 : }
230 :
231 : /* update long-term pitc hgain for speech/music classifier */
232 266499 : st->hSpMusClas->lowrate_pitchGain = 0.9f * st->hSpMusClas->lowrate_pitchGain + 0.1f * gain_pit;
233 :
234 266499 : gpit_tmp = gain_pit;
235 :
236 266499 : if ( use_fcb == 0 )
237 : {
238 223587 : if ( st->core_brate >= MIN_RATE_FCB )
239 : {
240 4675 : pit_idx = (int16_t) vquant( &gain_pit, mean_gp, &gain_pit, dic_gp, 1, 32 );
241 4675 : push_indice( hBstr, IND_PIT_IDX, pit_idx, 5 );
242 : }
243 : else
244 : {
245 218912 : pit_idx = (int16_t) vquant( &gain_pit, mean_gp, &gain_pit, dic_gp, 1, 16 );
246 218912 : push_indice( hBstr, IND_PIT_IDX, pit_idx, 4 );
247 : }
248 : }
249 42912 : else if ( use_fcb == 2 )
250 : {
251 : /*-----------------------------------------------------------------*
252 : * Innovation encoding
253 : *-----------------------------------------------------------------*/
254 :
255 32232 : inov_encode( st, st->core_brate, 0, st->L_frame, st->last_L_frame, GENERIC, st->bwidth, 0, i_subfr, -1, p_Aq, gain_pit, cn, exc, h1, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &i, 2 * L_SUBFR );
256 :
257 : /*-----------------------------------------------------------------*
258 : * Gain encoding
259 : *-----------------------------------------------------------------*/
260 :
261 32232 : gain_enc_lbr( st->hBstr, st->acelp_cfg.gains_mode, GENERIC, i_subfr, xn, y1, y2, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, gains_mem, clip_gain, 2 * L_SUBFR );
262 : }
263 : else
264 : {
265 : /*-----------------------------------------------------------------*
266 : * Innovation & gain encoding
267 : *-----------------------------------------------------------------*/
268 :
269 10680 : inov_encode( st, Local_BR, 0, st->L_frame, st->last_L_frame, LOCAL_CT, WB, 1, i_subfr, -1, p_Aq, gain_pit, cn, exc, h1, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, L_SUBFR );
270 :
271 10680 : gain_enc_mless( hBstr, st->acelp_cfg.gains_mode, st->element_mode, st->L_frame, i_subfr, -1, xn, y1, y2, code, Es_pred, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain );
272 : }
273 :
274 266499 : gp_clip_test_gain_pit( st->element_mode, st->core_brate, gain_pit, st->clip_var );
275 :
276 266499 : if ( use_fcb != 0 )
277 : {
278 42912 : hLPDmem->tilt_code = est_tilt( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, L_subfr, 0 );
279 : }
280 : else
281 : {
282 223587 : hLPDmem->tilt_code = 0.0f;
283 : }
284 :
285 : /*-----------------------------------------------------------------*
286 : * Update memory of the weighting filter
287 : *-----------------------------------------------------------------*/
288 :
289 266499 : if ( use_fcb != 0 )
290 : {
291 42912 : st->hGSCEnc->mem_w0_tmp = xn[L_subfr - 1] - ( gain_pit * y1[L_subfr - 1] ) - ( gain_code * y2[L_subfr - 1] );
292 : }
293 : else
294 : {
295 223587 : st->hGSCEnc->mem_w0_tmp = xn[L_subfr - 1] - ( gain_pit * y1[L_subfr - 1] );
296 : }
297 :
298 : /*-----------------------------------------------------------------*
299 : * Construct adaptive part of the excitation
300 : * Save the non-enhanced excitation for FEC_exc
301 : *-----------------------------------------------------------------*/
302 :
303 266499 : if ( use_fcb != 0 )
304 : {
305 4852128 : for ( i = 0; i < L_subfr; i++ )
306 : {
307 4809216 : exc[i + i_subfr] = gain_pit * exc[i + i_subfr] + gain_code * code[i];
308 : }
309 : }
310 : else
311 : {
312 26163043 : for ( i = 0; i < L_subfr; i++ )
313 : {
314 25939456 : exc[i + i_subfr] = gain_pit * exc[i + i_subfr];
315 : }
316 : }
317 :
318 : /*-----------------------------------------------------------------*
319 : * Synthesize speech to update mem_syn[].
320 : * Update A(z) filters
321 : *-----------------------------------------------------------------*/
322 :
323 266499 : syn_filt( p_Aq, M, &exc[i_subfr], &synth[i_subfr], L_subfr, st->hGSCEnc->mem_syn_tmp, 1 );
324 :
325 266499 : if ( L_subfr == 5 * L_SUBFR )
326 : {
327 19792 : cum_gpit = gpit_tmp;
328 :
329 19792 : pt_pitch++;
330 19792 : *pt_pitch = *( pt_pitch - 1 );
331 19792 : pt_pitch++;
332 19792 : *pt_pitch = *( pt_pitch - 1 );
333 19792 : pt_pitch++;
334 19792 : *pt_pitch = *( pt_pitch - 1 );
335 19792 : pt_pitch++;
336 19792 : *pt_pitch = *( pt_pitch - 1 );
337 19792 : pt_pitch++;
338 :
339 19792 : p_Aw += 5 * ( M + 1 );
340 19792 : p_Aq += 5 * ( M + 1 );
341 : }
342 246707 : else if ( L_subfr == 5 * L_SUBFR / 2 )
343 : {
344 0 : if ( i_subfr == 0 )
345 : {
346 0 : cum_gpit = gpit_tmp * .4f;
347 0 : pt_pitch++;
348 0 : *pt_pitch = *( pt_pitch - 1 );
349 0 : pt_pitch++;
350 0 : p_Aw += 2 * ( M + 1 );
351 0 : p_Aq += 2 * ( M + 1 );
352 : }
353 : else
354 : {
355 0 : cum_gpit += gpit_tmp * .6f;
356 0 : pt_pitch++;
357 0 : *pt_pitch = *( pt_pitch - 1 );
358 0 : pt_pitch++;
359 0 : *pt_pitch = *( pt_pitch - 1 );
360 0 : pt_pitch++;
361 0 : p_Aw += 3 * ( M + 1 );
362 0 : p_Aq += 3 * ( M + 1 );
363 : }
364 : }
365 246707 : else if ( L_subfr == 2 * L_SUBFR )
366 : {
367 64494 : if ( i_subfr == 0 )
368 : {
369 32247 : cum_gpit = gpit_tmp * .5f;
370 : }
371 : else
372 : {
373 32247 : cum_gpit += gpit_tmp * .5f;
374 : }
375 :
376 64494 : p_Aw += 2 * ( M + 1 );
377 64494 : p_Aq += 2 * ( M + 1 );
378 64494 : pt_pitch++;
379 64494 : *pt_pitch = *( pt_pitch - 1 );
380 64494 : pt_pitch++;
381 : }
382 182213 : else if ( L_subfr == 4 * L_SUBFR )
383 : {
384 23429 : cum_gpit = gpit_tmp;
385 :
386 23429 : pt_pitch++;
387 23429 : *pt_pitch = *( pt_pitch - 1 );
388 23429 : pt_pitch++;
389 23429 : *pt_pitch = *( pt_pitch - 1 );
390 23429 : pt_pitch++;
391 23429 : *pt_pitch = *( pt_pitch - 1 );
392 23429 : pt_pitch++;
393 :
394 23429 : p_Aw += 4 * ( M + 1 );
395 23429 : p_Aq += 4 * ( M + 1 );
396 : }
397 : else
398 : {
399 158784 : if ( i_subfr == 0 )
400 : {
401 39696 : cum_gpit = gpit_tmp * .25f;
402 : }
403 : else
404 : {
405 119088 : cum_gpit += gpit_tmp * .25f;
406 : }
407 :
408 158784 : pt_pitch++;
409 158784 : p_Aw += ( M + 1 );
410 158784 : p_Aq += ( M + 1 );
411 : }
412 : }
413 :
414 115164 : *gpit = 0.1f * *gpit + 0.9f * cum_gpit;
415 :
416 115164 : return;
417 : }
|