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 <assert.h>
38 : #include "prot.h"
39 : #include <stdint.h>
40 : #include "options.h"
41 : #ifdef DEBUGGING
42 : #include "debug.h"
43 : #endif
44 : #include "rom_com.h"
45 : #include "wmc_auto.h"
46 :
47 : /*-------------------------------------------------------------------*
48 : * coder_acelp()
49 : *
50 : * Encode ACELP frame
51 : *-------------------------------------------------------------------*/
52 :
53 604 : void coder_acelp(
54 : Encoder_State *st, /* i/o: coder memory state */
55 : const float A[], /* i : coefficients 4xAz[M+1] */
56 : const float Aq[], /* i : coefficients 4xAz_q[M+1] */
57 : const float speech[], /* i : speech[-M..lg] */
58 : LPD_state *LPDmem, /* i/o: ACELP memories */
59 : int16_t *prm, /* o : acelp parameters */
60 : const float stab_fac,
61 : const int16_t target_bits,
62 : float *gain_pitch_buf, /* o : gain pitch values */
63 : float *gain_code_buf, /* o : gain code values */
64 : float *pitch_buf, /* o : pitch values for each subfr.*/
65 : float *voice_factors, /* o : voicing factors */
66 : float *bwe_exc /* o : excitation for SWB TBE */
67 : )
68 : {
69 : int16_t i, i_subfr;
70 : int16_t T0, T0_min, T0_min_frac, T0_max, T0_max_frac, T0_res, T0_frac;
71 : float tmp, Es_pred;
72 : float gain_pit, gain_code, voice_fac;
73 : ACELP_CbkCorr g_corr;
74 : float g_corr2[6];
75 : const float *p_A, *p_Aq;
76 : float h1[L_SUBFR]; /* weighted impulse response of LP */
77 : float code[L_SUBFR];
78 : float cn[L_SUBFR];
79 : float xn[L_SUBFR];
80 : float xn2[L_SUBFR];
81 : float y1[L_SUBFR]; /* Filtered adaptive excitation */
82 : float y2[L_SUBFR]; /* Filtered adaptive excitation */
83 : float res_save;
84 : float exc_buf[L_EXC_MEM + L_FRAME16k + 1], *exc;
85 : float exc2[L_SUBFR];
86 : float *syn, syn_buf[M + L_FRAME16k + L_FRAME16k / 2]; /*128 for the memory, L_FRAME for the current synth and 128 for the ZIR for next TCX*/
87 : float syn2[L_FRAME16k];
88 : float norm_gain_code, gain_inov;
89 : int16_t clip_gain;
90 : float gain_code2;
91 : float code2[L_SUBFR];
92 : float y22[L_SUBFR]; /* Filtered adaptive excitation */
93 : int16_t lp_select;
94 : float *pt_pitch, *pt_gain_pitch, *pt_gain_code;
95 : float error;
96 : float gain_preQ; /* Gain of prequantizer excitation */
97 : float code_preQ[L_SUBFR]; /* Prequantizer excitation */
98 : ACELP_config *acelp_cfg;
99 :
100 604 : acelp_cfg = &( st->acelp_cfg );
101 :
102 : /* Configure ACELP */
103 604 : BITS_ALLOC_config_acelp( target_bits, st->coder_type, acelp_cfg, st->narrowBand, st->nb_subfr );
104 :
105 : /*------------------------------------------------------------------------*
106 : * Initialize buffers *
107 : *------------------------------------------------------------------------*/
108 :
109 604 : set_f( code_preQ, 0.f, L_SUBFR );
110 604 : gain_preQ = 0.0f;
111 :
112 : /* Reset phase dispersion */
113 604 : if ( st->last_core > ACELP_CORE )
114 : {
115 30 : set_zero( st->hLPDmem->dispMem, 8 );
116 : }
117 :
118 : /* set excitation memory*/
119 604 : exc = exc_buf + L_EXC_MEM;
120 604 : mvr2r( LPDmem->old_exc, exc_buf, L_EXC_MEM );
121 604 : *( exc + st->L_frame ) = 0.f; /*to solve a warning*/
122 :
123 : /* Init syn buffer */
124 604 : syn = syn_buf + M;
125 604 : mvr2r( LPDmem->mem_syn, syn_buf, M );
126 :
127 604 : pt_pitch = pitch_buf;
128 604 : pt_gain_pitch = gain_pitch_buf;
129 604 : pt_gain_code = gain_code_buf;
130 :
131 604 : T0 = 0;
132 604 : T0_res = 0;
133 604 : T0_frac = 0;
134 :
135 604 : error = 0.0f;
136 :
137 : /*---------------------------------------------------------------*
138 : * Calculation of LP residual (filtering through A[z] filter)
139 : *---------------------------------------------------------------*/
140 :
141 604 : calc_residu( speech, exc, Aq, st->L_frame );
142 :
143 : /*------------------------------------------------------------------------*
144 : * Find and quantize mean_ener_code for gain quantizer *
145 : *------------------------------------------------------------------------*/
146 :
147 604 : if ( acelp_cfg->nrg_mode > 0 )
148 : {
149 604 : Es_pred_enc( &Es_pred, prm, st->L_frame, L_SUBFR, exc, st->voicing, acelp_cfg->nrg_bits, acelp_cfg->nrg_mode > 1 );
150 604 : prm++;
151 : }
152 : else
153 : {
154 0 : Es_pred = 0.f;
155 : }
156 :
157 604 : if ( st->L_frame == L_FRAME )
158 : {
159 0 : mvr2r( Aq + 2 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq, ( M + 1 ) );
160 : }
161 : else
162 : {
163 604 : mvr2r( Aq + 3 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq, ( M + 1 ) );
164 : }
165 :
166 : /*------------------------------------------------------------------------*
167 : * Loop for every subframe in the analysis frame *
168 : *------------------------------------------------------------------------*
169 : * To find the pitch and innovation parameters. The subframe size is *
170 : * L_SUBFR and the loop is repeated L_FRAME_PLUS/L_SUBFR times. *
171 : * - compute impulse response of weighted synthesis filter (h1[]) *
172 : * - compute the target signal for pitch search *
173 : * - find the closed-loop pitch parameters *
174 : * - encode the pitch delay *
175 : * - update the impulse response h1[] by including fixed-gain pitch *
176 : * - find target vector for codebook search *
177 : * - correlation between target vector and impulse response *
178 : * - codebook search *
179 : * - encode codebook address *
180 : * - VQ of pitch and codebook gains *
181 : * - find synthesis speech *
182 : * - update states of weighting filter *
183 : *------------------------------------------------------------------------*/
184 :
185 604 : p_A = A;
186 604 : p_Aq = Aq;
187 :
188 604 : res_save = exc[0];
189 :
190 3624 : for ( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
191 : {
192 : /* Restore exc[i_subfr] and save next exc[L_SUBFR+i_subfr] */
193 3020 : exc[i_subfr] = res_save;
194 3020 : res_save = exc[L_SUBFR + i_subfr];
195 :
196 : /*--------------------------------------------------------------------------*
197 : * Find target for pitch search (xn[]), target for innovation search (cn[]) *
198 : * and impulse response of the weighted synthesis filter (h1[]). *
199 : *--------------------------------------------------------------------------*/
200 :
201 3020 : find_targets( speech, &syn[i_subfr - M], i_subfr, &LPDmem->mem_w0, p_Aq, exc, L_SUBFR, p_A, st->preemph_fac, xn, cn, h1 );
202 :
203 : /*-----------------------------------------------------------------*
204 : * Gain clipping test to avoid unstable synthesis on frame erasure
205 : * or in case of floating point encoder & fixed p. decoder
206 : *-----------------------------------------------------------------*/
207 :
208 3020 : clip_gain = gp_clip( st->element_mode, st->core_brate, st->voicing, i_subfr, st->coder_type, xn, st->clip_var );
209 :
210 : /*-----------------------------------------------------------------*
211 : * - find unity gain pitch excitation (adaptive codebook entry) *
212 : * with fractional interpolation. *
213 : * - find filtered pitch exc. y1[]=exc[] convolved with h1[]) *
214 : * - compute pitch gain1 *
215 : *-----------------------------------------------------------------*/
216 :
217 3020 : if ( acelp_cfg->ltp_bits != 0 )
218 : {
219 : /* pitch lag coding */
220 3020 : Mode2_pit_encode( acelp_cfg->ltp_mode, i_subfr, &prm, &exc[i_subfr], st->pitch, &T0_min, &T0_min_frac, &T0_max, &T0_max_frac, &T0, &T0_frac, &T0_res, h1, xn, st->pit_min, st->pit_fr1, st->pit_fr1b, st->pit_fr2, st->pit_max, st->pit_res_max );
221 :
222 : /* find pitch excitation */
223 3020 : if ( st->pit_res_max == 6 )
224 : {
225 3020 : if ( T0_res == ( st->pit_res_max >> 1 ) )
226 : {
227 2912 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 );
228 : }
229 : else
230 : {
231 108 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 );
232 : }
233 : }
234 : else
235 : {
236 0 : if ( T0_res == ( st->pit_res_max >> 1 ) )
237 : {
238 0 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP );
239 : }
240 : else
241 : {
242 0 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP );
243 : }
244 : }
245 :
246 : /* filter adaptive codebook */
247 3020 : lp_select = lp_filt_exc_enc( MODE2, st->coder_type, i_subfr, exc, h1, xn, y1, xn2, L_SUBFR, st->L_frame, g_corr2, clip_gain, &( gain_pit ), &( acelp_cfg->ltf_mode ) );
248 :
249 3020 : if ( acelp_cfg->ltf_mode == NORMAL_OPERATION )
250 : {
251 1340 : *prm = lp_select;
252 1340 : prm++;
253 : }
254 :
255 3020 : g_corr.y1y1 = g_corr2[0];
256 3020 : g_corr.xy1 = -0.5f * ( g_corr2[1] - 0.01f ) + 0.01f;
257 : }
258 : else
259 : {
260 : /* No adaptive codebook (UC) */
261 0 : gain_pit = 0.f;
262 0 : g_corr.xy1 = 0.f;
263 0 : g_corr.y1y1 = 0.f;
264 0 : set_zero( y1, L_SUBFR );
265 0 : set_zero( exc + i_subfr, L_SUBFR );
266 0 : T0 = L_SUBFR;
267 0 : T0_frac = 0;
268 0 : T0_res = 1;
269 : }
270 :
271 3020 : if ( st->igf )
272 : {
273 3020 : tbe_celp_exc( st->element_mode, st->idchan, bwe_exc, st->L_frame, L_SUBFR, i_subfr, T0, T0_frac, &error, 0 );
274 : }
275 :
276 3020 : pitch_buf[i_subfr / L_SUBFR] = (float) T0 + (float) T0_frac / (float) T0_res;
277 :
278 : /*----------------------------------------------------------------------*
279 : * Encode the algebraic innovation *
280 : *----------------------------------------------------------------------*/
281 :
282 3020 : E_ACELP_innovative_codebook( exc, T0, T0_frac, T0_res, gain_pit, LPDmem->tilt_code, acelp_cfg, i_subfr, p_Aq, h1, xn, cn, y1, y2, st->acelp_autocorr, &prm, code, st->L_frame, st->last_L_frame, st->total_brate );
283 :
284 3020 : E_corr_xy2( xn, y1, y2, g_corr2, L_SUBFR );
285 3020 : g_corr.y2y2 = 0.01F + g_corr2[2];
286 3020 : g_corr.xy2 = 0.01F + -0.5f * g_corr2[3];
287 3020 : g_corr.y1y2 = 0.01F + 0.5f * g_corr2[4];
288 :
289 3020 : g_corr.xx = 0.01F + dotp( xn, xn, L_SUBFR );
290 :
291 : /*----------------------------------------------------------------------*
292 : * Add Gaussian excitation *
293 : *----------------------------------------------------------------------*/
294 :
295 3020 : if ( acelp_cfg->gains_mode[i_subfr / L_SUBFR] == 7 )
296 : {
297 0 : assert( gain_pit == 0.f );
298 :
299 0 : gauss_L2( h1, code2, y2, y22, &gain_code2, g_corr2, LPDmem->tilt_code, p_Aq, acelp_cfg->formant_enh_num, &( st->seed_acelp ) );
300 :
301 0 : g_corr.y1y1 = g_corr2[0];
302 0 : g_corr.y1y2 = g_corr2[4];
303 : }
304 : else
305 : {
306 3020 : gain_code2 = 0.f;
307 3020 : set_zero( code2, L_SUBFR );
308 3020 : set_zero( y22, L_SUBFR );
309 : }
310 :
311 : /*----------------------------------------------------------*
312 : * - Compute the fixed codebook gain *
313 : * - quantize fixed codebook gain *
314 : *----------------------------------------------------------*/
315 :
316 3020 : encode_acelp_gains( code, acelp_cfg->gains_mode[i_subfr / L_SUBFR], Es_pred, clip_gain, &g_corr, &gain_pit, &gain_code, &prm, &norm_gain_code, &gain_inov, L_SUBFR, code2, &gain_code2, st->flag_noisy_speech_snr );
317 :
318 3020 : gp_clip_test_gain_pit( st->element_mode, st->core_brate, gain_pit, st->clip_var );
319 :
320 : /*----------------------------------------------------------*
321 : * - voice factor (for codebook tilt sharpening) *
322 : *----------------------------------------------------------*/
323 :
324 3020 : LPDmem->tilt_code = est_tilt( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, L_SUBFR, acelp_cfg->voice_tilt );
325 :
326 3020 : if ( st->Opt_RF_ON )
327 : {
328 0 : st->hRF->rf_tilt_buf[i_subfr / L_SUBFR] = LPDmem->tilt_code;
329 : }
330 :
331 :
332 : /*-----------------------------------------------------------------*
333 : * Update memory of the weighting filter
334 : *-----------------------------------------------------------------*/
335 :
336 3020 : LPDmem->mem_w0 = xn[L_SUBFR - 1] - gain_pit * y1[L_SUBFR - 1] - gain_code * y2[L_SUBFR - 1] - gain_code2 * y22[L_SUBFR - 1];
337 :
338 : /*-------------------------------------------------------*
339 : * - Find the total excitation. *
340 : *-------------------------------------------------------*/
341 :
342 196300 : for ( i = 0; i < L_SUBFR; i++ )
343 : {
344 193280 : exc2[i] = gain_pit * exc[i + i_subfr];
345 193280 : exc2[i] += gain_code2 * code2[i];
346 193280 : exc[i + i_subfr] = exc2[i] + gain_code * code[i];
347 : }
348 :
349 : /*-----------------------------------------------------------------*
350 : * Prepare TBE excitation
351 : *-----------------------------------------------------------------*/
352 :
353 3020 : prep_tbe_exc( st->L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, gain_preQ, code_preQ, T0, st->coder_type, st->core_brate, st->element_mode, st->idchan, 0, 0 );
354 :
355 : /*---------------------------------------------------------*
356 : * Enhance the excitation *
357 : *---------------------------------------------------------*/
358 :
359 3020 : enhancer( MODE2, -1, acelp_cfg->fixed_cdk_index[i_subfr / L_SUBFR], 0, st->coder_type, st->L_frame, voice_fac, stab_fac, norm_gain_code, gain_inov, &( LPDmem->gc_threshold ), code, exc2, gain_pit, LPDmem->dispMem );
360 :
361 : /*----------------------------------------------------------*
362 : * - compute the synthesis speech *
363 : *----------------------------------------------------------*/
364 :
365 3020 : syn_filt( p_Aq, M, exc2, &syn2[i_subfr], L_SUBFR, LPDmem->mem_syn2, 1 );
366 :
367 3020 : syn_filt( p_Aq, M, &exc[i_subfr], &syn[i_subfr], L_SUBFR, &syn[i_subfr - M], 0 );
368 :
369 : /*----------------------------------------------------------*
370 : * Save buffers for BPF *
371 : *----------------------------------------------------------*/
372 :
373 3020 : *pt_pitch = ( (float) T0 + (float) T0_frac / (float) T0_res + 0.5f );
374 3020 : *pt_gain_pitch = gain_pit;
375 3020 : *pt_gain_code = gain_code;
376 :
377 : /*----------------------------------------------------------*
378 : * Update *
379 : *----------------------------------------------------------*/
380 :
381 3020 : p_A += ( M + 1 );
382 3020 : p_Aq += ( M + 1 );
383 3020 : pt_pitch++;
384 3020 : pt_gain_pitch++;
385 3020 : pt_gain_code++;
386 :
387 3020 : if ( st->hPlcExt != NULL )
388 : {
389 3020 : st->hPlcExt->T0_4th = T0;
390 : }
391 :
392 : } /* end of subframe loop */
393 :
394 604 : p_A -= ( M + 1 );
395 604 : p_Aq -= ( M + 1 );
396 :
397 : #ifdef DEBUGGING
398 : /* SNR measuremenet of CELP output */
399 : if ( st->idchan == 0 )
400 : {
401 : snr_celp( st->L_frame, L_SUBFR, st->gamma, st->preemph_fac, st->vad_flag, st->coder_type, speech, syn, A, 0, "CELP_output" );
402 : }
403 : else
404 : {
405 : snr_celp( st->L_frame, L_SUBFR, st->gamma, st->preemph_fac, st->vad_flag, st->coder_type, speech, syn, A, 1, "CELP_output_chan2" );
406 : }
407 : #endif
408 :
409 : /*----------------------------------------------------------*
410 : * Update LPD memory *
411 : *----------------------------------------------------------*/
412 :
413 604 : mvr2r( exc + st->L_frame - L_EXC_MEM, LPDmem->old_exc, L_EXC_MEM );
414 604 : mvr2r( syn + st->L_frame - M, LPDmem->mem_syn, M );
415 604 : mvr2r( syn + st->L_frame - L_SYN_MEM, LPDmem->mem_syn_r, L_SYN_MEM );
416 :
417 604 : if ( st->hPlcExt != NULL )
418 : {
419 604 : mvr2r( exc + st->L_frame - L_EXC_MEM - 8, st->hPlcExt->old_exc, 8 );
420 : }
421 :
422 : /*----------------------------------------------------------*
423 : * ZIR at the end of the ACELP frame (for TCX) *
424 : *----------------------------------------------------------*/
425 :
426 604 : mvr2r( syn2, syn, st->L_frame );
427 604 : tmp = LPDmem->syn[M];
428 604 : deemph( syn, st->preemph_fac, st->L_frame, &tmp );
429 604 : if ( st->hTcxEnc != NULL )
430 : {
431 604 : mvr2r( syn + st->L_frame / 2, st->hTcxEnc->Txnq, st->L_frame / 2 );
432 : }
433 604 : mvr2r( syn + st->L_frame - ( M + 1 ), LPDmem->syn, M + 1 );
434 604 : mvr2r( syn, st->synth, st->L_frame );
435 :
436 : /*Update MODE1*/
437 604 : mvr2r( p_Aq, st->old_Aq_12_8, M + 1 );
438 604 : st->old_Es_pred = Es_pred;
439 :
440 604 : return;
441 : }
|