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 : #include <stdint.h>
34 : #include "options.h"
35 : #include "cnst.h"
36 : #include "stat_enc.h"
37 : #include "rom_com.h"
38 : #include "ivas_rom_com.h"
39 : #include "ivas_cnst.h"
40 : #include "prot_fx.h"
41 : #include "prot_fx_enc.h"
42 : #include "ivas_prot_fx.h"
43 : #include "wmc_auto.h"
44 :
45 :
46 : /*-------------------------------------------------------------------*
47 : * tdm_low_rate_enc()
48 : *
49 : * Encode secondary channel of TD Stereo with a low-bitrate encoder
50 : *-------------------------------------------------------------------*/
51 :
52 7563 : void tdm_low_rate_enc(
53 : Encoder_State *st, /* i/o: State structure */
54 : const Word16 Aq[], /* i : 12k8 Lp coefficient Q12*/
55 : const Word16 *res, /* i : residual signal Q_new*/
56 : Word16 *synth, /* i/o: core synthesis Q_new*/
57 : Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/
58 : Word16 *pitch_buf,
59 : /* i/o: floating pitch values for each subframe */ // Q6
60 : Word16 *voice_factors, /* o : voicing factors Q15*/
61 : Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q_new*/
62 : const Word16 attack_flag, /* i : GSC attack flag Q0*/
63 : const Word16 *lsf_new, /* i : current frame ISF vector Qx2.56*/
64 : Word16 *tmp_noise, /* o : long-term noise energy Q11*/
65 : Word16 Q_new )
66 : {
67 : const Word16 *p_Aq;
68 : Word16 i_subfr, nb_subfr, last_pit_bin;
69 : Word16 tmp_nb_bits_tot;
70 : Word16 dct_res_fx[L_FRAME], dct_epit_fx[L_FRAME];
71 : Word16 exc_wo_nf_fx[L_FRAME];
72 7563 : LPD_state_HANDLE hLPDmem = st->hLPDmem;
73 :
74 : /*---------------------------------------------------------------*
75 : * Initialization
76 : *---------------------------------------------------------------*/
77 :
78 7563 : nb_subfr = 2;
79 7563 : move16();
80 :
81 7563 : st->GSC_IVAS_mode = 0;
82 7563 : move16();
83 7563 : st->GSC_noisy_speech = 1;
84 7563 : move16();
85 7563 : st->hGSCEnc->noise_lev = 14;
86 7563 : move16();
87 :
88 7563 : hLPDmem->tilt_code = 0;
89 7563 : move16();
90 7563 : set16_fx( dct_epit_fx, 0, L_FRAME );
91 7563 : set16_fx( pitch_buf, L_SUBFR_Q6, NB_SUBFR ); /* Q6 */
92 7563 : last_pit_bin = L_FRAME / 2;
93 7563 : move16();
94 :
95 : /*---------------------------------------------------------------*
96 : * DCT transform of the residual and create a subsample residual
97 : *---------------------------------------------------------------*/
98 :
99 7563 : edct_16fx( res, dct_res_fx, L_FRAME, 7, st->element_mode );
100 :
101 : /*--------------------------------------------------------------------------------------*
102 : * GSC encoder
103 : *--------------------------------------------------------------------------------------*/
104 :
105 : /* Find the current total number of bits used */
106 7563 : tmp_nb_bits_tot = st->hBstr->nb_bits_tot; /* Q0 */
107 7563 : move16();
108 :
109 7563 : if ( st->extl_brate > 0 )
110 : {
111 : /* subtract 1 bit for TBE/BWE BWE flag (bit counted in extl_brate) */
112 70 : tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 );
113 : }
114 :
115 7563 : Word16 Q_exc = Q_new;
116 7563 : move16();
117 7563 : gsc_enc_ivas_fx( st, dct_res_fx, dct_epit_fx, last_pit_bin, tmp_nb_bits_tot, nb_subfr, lsf_new, exc_wo_nf_fx, tmp_noise, &Q_exc );
118 :
119 : /*--------------------------------------------------------------------------------------*
120 : * iDCT transform
121 : *--------------------------------------------------------------------------------------*/
122 :
123 7563 : edct_16fx( dct_epit_fx, exc_fx, L_FRAME, 7, st->element_mode );
124 :
125 7563 : edct_16fx( exc_wo_nf_fx, exc_wo_nf_fx, L_FRAME, 7, st->element_mode );
126 :
127 : /*--------------------------------------------------------------------------------------*
128 : * Remove potential pre-echo in case an onset has been detected
129 : *--------------------------------------------------------------------------------------*/
130 :
131 7563 : pre_echo_att_ivas_fx( &st->hGSCEnc->Last_frame_ener_fx, exc_fx, attack_flag, Q_exc, st->last_coder_type, st->L_frame );
132 :
133 : /*--------------------------------------------------------------------------------------*
134 : * Update BWE excitation
135 : *--------------------------------------------------------------------------------------*/
136 :
137 7563 : IF( st->hBWE_TD != NULL )
138 : {
139 7548 : set16_fx( voice_factors, 0, NB_SUBFR );
140 :
141 7548 : IF( st->tdm_LRTD_flag )
142 : {
143 11 : interp_code_5over2_fx( exc_fx, bwe_exc_fx, L_FRAME );
144 : }
145 : ELSE
146 : {
147 7537 : set16_fx( bwe_exc_fx, 0, L_FRAME32k );
148 : }
149 : }
150 :
151 : /*--------------------------------------------------------------------------------------*
152 : * Synthesis
153 : *--------------------------------------------------------------------------------------*/
154 :
155 7563 : p_Aq = Aq; /* Q12 */
156 37815 : FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
157 : {
158 30252 : E_UTIL_synthesis( 0, p_Aq, &exc_wo_nf_fx[i_subfr], &synth[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1, M ); /* Q_new */
159 30252 : p_Aq += ( M + 1 );
160 30252 : scale_sig( hLPDmem->mem_syn, M, sub( hLPDmem->q_mem_syn, Q_new ) ); // Q_new -> hLPDmem->q_mem_syn
161 : }
162 :
163 : /*--------------------------------------------------------------------------------------*
164 : * Updates
165 : *--------------------------------------------------------------------------------------*/
166 :
167 7563 : Copy( exc_wo_nf_fx, exc_fx, L_FRAME ); /* Q_new */
168 :
169 7563 : return;
170 : }
171 :
172 :
173 : /*-------------------------------------------------------------------*
174 : * encod_gen_2sbfr()
175 : *
176 : * Encode GC, 2 subframes mode
177 : *-------------------------------------------------------------------*/
178 :
179 5 : void encod_gen_2sbfr(
180 : Encoder_State *st, /* i/o: state structure */
181 : const Word16 speech[], /* i : input speech Q_new-1 */
182 : const Word16 Aw[], /* i : weighted A(z) unquantized for subframes e(norm_s(Aw[0]+1)*/
183 : const Word16 Aq[], /* i : LP coefficients e(norm_s(Aw[0]+1)*/
184 : const Word16 *res, /* i : residual signal Q_new */
185 : Word16 *syn, /* i/o: core synthesis Q_new */
186 : Word16 *exc, /* i/o: current non-enhanced excitation Q_new-1 */
187 : Word16 *exc2, /* i/o: current enhanced excitation Q_new-1 */
188 : Word16 *pitch_buf, /* i/o: floating pitch values for each subframe Q6 */
189 : Word16 *voice_factors, /* o : voicing factors Q15 */
190 : Word16 *bwe_exc, /* o : excitation for SWB TBE Q_new */
191 : const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */
192 : const Word16 tdm_Pri_pitch_buf[], /* i : pitch values for primary channel Q4 */
193 : Word16 Q_new,
194 : Word16 shift )
195 : {
196 : Word16 xn[2 * L_SUBFR]; /* Target vector for pitch search */
197 : Word16 xn2[2 * L_SUBFR]; /* Target vector for codebook search */
198 : Word16 cn[2 * L_SUBFR]; /* Target vector in residual domain */
199 : Word16 h1[2 * L_SUBFR + ( M + 1 )]; /* Impulse response vector */
200 : Word16 h2[2 * L_SUBFR + ( M + 1 )]; /* Impulse response vector */
201 : Word16 code[2 * L_SUBFR]; /* Fixed codebook excitation */
202 : Word16 y1[2 * L_SUBFR]; /* Filtered adaptive excitation */
203 : Word16 y2[2 * L_SUBFR]; /* Filtered algebraic excitation */
204 : Word16 gain_pit; /* Pitch gain */
205 : Word16 voice_fac; /* Voicing factor */
206 : Word32 gain_code; /* Gain of code */
207 : Word16 gain_inov; /* inovation gain */
208 : Word16 L_frame, coder_type; /* L_frame; coder type */
209 : Word16 i, i_subfr; /* tmp variables */
210 : Word16 T0, T0_frac; /* close loop integer pitch and fractional part */
211 : Word16 T0_min, T0_max; /* pitch variables */
212 : Word16 *pt_pitch; /* pointer to floating pitch buffer */
213 : Word16 g_corr[6]; /* ACELP correl, values + gain pitch */
214 : // Word16 gains_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */
215 : Word32 gc_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */
216 : Word16 gp_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */
217 : Word16 clip_gain; /* LSF clip gain */
218 : const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coeff. vector*/
219 : Word32 norm_gain_code;
220 : Word16 pitch_limit_flag;
221 : Word16 error;
222 : Word16 q_h1;
223 :
224 5 : LPD_state_HANDLE hLPDmem = st->hLPDmem;
225 :
226 : Word16 gcode16;
227 : Word32 Lgcode, Ltmp;
228 5 : set16_fx( cn, 0, 2 * L_SUBFR ); /* Target vector in residual domain */
229 :
230 : /*------------------------------------------------------------------*
231 : * Initializations
232 : *------------------------------------------------------------------*/
233 :
234 5 : gain_pit = 0;
235 5 : move16();
236 5 : gain_code = 0;
237 5 : move16();
238 5 : error = 0;
239 5 : move16();
240 :
241 5 : T0_max = PIT_MAX;
242 5 : move16();
243 5 : T0_min = PIT_MIN;
244 5 : move16();
245 :
246 5 : L_frame = L_FRAME;
247 5 : move16();
248 5 : coder_type = GENERIC;
249 5 : move16();
250 :
251 5 : p_Aw = Aw; /* e(norm_s(Aw[0]+1) */
252 5 : p_Aq = Aq; /* e(norm_s(Aw[0]+1) */
253 5 : pt_pitch = pitch_buf; /*Q6*/
254 :
255 : /*------------------------------------------------------------------*
256 : * ACELP subframe loop
257 : *------------------------------------------------------------------*/
258 :
259 15 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += 2 * L_SUBFR )
260 : {
261 : /*----------------------------------------------------------------*
262 : * Find the the excitation search target "xn" and innovation
263 : * target in residual domain "cn"
264 : * Compute impulse response, h1[], of weighted synthesis filter
265 : *----------------------------------------------------------------*/
266 :
267 10 : Copy( &res[i_subfr], &exc[i_subfr], 2 * L_SUBFR ); // Q_new
268 :
269 10 : find_targets_ivas_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 );
270 :
271 10 : q_h1 = sub( 14, norm_s( h1[0] ) );
272 10 : Copy_Scale_sig( h1, h2, 2 * L_SUBFR, sub( 11, q_h1 ) );
273 :
274 : /*------------------------------------------------------------------------*
275 : * Close-loop pitch search on the 1st and 3rd subfr only and quantization
276 : * Adaptive exc. construction
277 : *------------------------------------------------------------------------*/
278 :
279 10 : *pt_pitch = pit_encode_fx( st->hBstr, st->acelp_cfg.pitch_bits, st->core_brate, 0, L_frame, coder_type, &pitch_limit_flag, i_subfr, exc, 2 * L_SUBFR, st->pitch, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf, st->element_mode, Q_new );
280 10 : move16();
281 :
282 10 : Scale_sig( h1, 2 * L_SUBFR, sub( 13, q_h1 ) ); // Q13
283 :
284 10 : tbe_celp_exc_ivas( st->element_mode, st->idchan, L_frame, 2 * L_SUBFR, i_subfr, T0, T0_frac, &error, bwe_exc, st->tdm_LRTD_flag );
285 :
286 : /*-----------------------------------------------------------------*
287 : * Find adaptive exitation
288 : *-----------------------------------------------------------------*/
289 :
290 10 : pred_lt4_ivas_fx( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, 2 * L_SUBFR + 1, L_pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP );
291 :
292 : /*-----------------------------------------------------------------*
293 : * Gain clipping test to avoid unstable synthesis on frame erasure
294 : *-----------------------------------------------------------------*/
295 :
296 10 : clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, sub( Q_new, 1 ) ); // Q0
297 :
298 : /*-----------------------------------------------------------------*
299 : * LP filtering of the adaptive excitation, codebook target computation
300 : *-----------------------------------------------------------------*/
301 :
302 10 : Scale_sig( h1, 2 * L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */
303 :
304 10 : lp_filt_exc_enc_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode );
305 :
306 : /* update long-term pitch gain for speech/music classifier */
307 10 : st->hSpMusClas->lowrate_pitchGain = add( mult( 29491, st->hSpMusClas->lowrate_pitchGain ), mult( 3277 /*Q15*/, gain_pit ) ); // Q14
308 10 : move16();
309 :
310 : /*-----------------------------------------------------------------*
311 : * Innovation encoding
312 : *-----------------------------------------------------------------*/
313 :
314 10 : inov_encode_ivas_fx( st, st->core_brate, 0, L_frame, st->last_L_frame, coder_type, st->bwidth, st->sharpFlag, i_subfr, -1, p_Aq, gain_pit, cn, exc, h2, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &i, 2 * L_SUBFR, shift, Q_new );
315 :
316 : /*-----------------------------------------------------------------*
317 : * Gain encoding
318 : *-----------------------------------------------------------------*/
319 :
320 10 : gain_enc_lbr_fx( st->hBstr, st->acelp_cfg.gains_mode, coder_type, i_subfr, xn, y1, add( sub( Q_new, 1 ), shift ), y2, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, gc_mem, gp_mem, clip_gain, 2 * L_SUBFR,
321 10 : st->element_mode );
322 :
323 10 : IF( st->Opt_SC_VBR )
324 : {
325 0 : if ( EQ_16( st->hSC_VBR->last_ppp_mode, 1 ) )
326 : {
327 : /* SC-VBR - all other st->clip_var values will be updated even in a PPP frame */
328 0 : st->clip_var_fx[1] = gain_pit;
329 0 : move16();
330 : }
331 : }
332 :
333 : /*-----------------------------------------------------------------*
334 : * update LP-filtered gains for the case of frame erasures
335 : *-----------------------------------------------------------------*/
336 :
337 10 : gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx );
338 :
339 10 : Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/
340 10 : gcode16 = round_fx_sat( Lgcode ); /*Q0*/
341 10 : hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); /* Q15 */
342 10 : move16();
343 :
344 : /*-----------------------------------------------------------------*
345 : * Update memory of the weighting filter
346 : *-----------------------------------------------------------------*/
347 :
348 10 : Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/
349 10 : Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/
350 10 : Ltmp = L_negate( Ltmp );
351 10 : Ltmp = L_mac( Ltmp, xn[2 * L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */
352 10 : Ltmp = L_msu( Ltmp, y1[2 * L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */
353 10 : Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* 15 + Q_new */
354 10 : hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */
355 10 : move16();
356 :
357 : /*-----------------------------------------------------------------*
358 : * Construct adaptive part of the excitation
359 : * Save the non-enhanced excitation for FEC_exc
360 : *-----------------------------------------------------------------*/
361 :
362 1290 : FOR( i = 0; i < 2 * L_SUBFR; i++ )
363 : {
364 : /* code in Q9, gain_pit in Q14 */
365 1280 : exc2[i + i_subfr] = shl_sat( mult( gain_pit, exc[i + i_subfr] ), 1 ); /* Q_new-1 */
366 1280 : Ltmp = L_mult( gcode16, code[i] ); /* Q10 */
367 1280 : Ltmp = L_shl_sat( Ltmp, 5 ); /* Q15 */
368 1280 : Ltmp = L_mac_sat( Ltmp, exc[i + i_subfr], gain_pit ); /* Q15 */
369 1280 : Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16*/
370 1280 : exc[i + i_subfr] = round_fx_sat( Ltmp );
371 1280 : move16();
372 1280 : move16();
373 : }
374 :
375 : /*-----------------------------------------------------------------*
376 : * Prepare TBE excitation
377 : *-----------------------------------------------------------------*/
378 :
379 10 : prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, Q_new, T0, T0_frac, coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag );
380 :
381 10 : voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR]; /* Q15 */
382 10 : move16();
383 :
384 : /*-----------------------------------------------------------------*
385 : * Synthesize speech to update mem_syn_flt[].
386 : * Update A(z) filters
387 : *-----------------------------------------------------------------*/
388 :
389 10 : Syn_filt_s( 1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1 );
390 10 : p_Aw += 2 * ( M + 1 );
391 10 : p_Aq += 2 * ( M + 1 );
392 :
393 10 : pt_pitch++;
394 10 : *pt_pitch = *( pt_pitch - 1 );
395 10 : move16();
396 10 : pt_pitch++;
397 : }
398 :
399 : /* SC-VBR */
400 5 : IF( st->Opt_SC_VBR )
401 : {
402 0 : st->hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; /* Q14 */
403 0 : st->hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */
404 0 : move16();
405 0 : move16();
406 : }
407 :
408 5 : return;
409 : }
|