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 7537 : 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 7537 : LPD_state_HANDLE hLPDmem = st->hLPDmem;
73 :
74 : /*---------------------------------------------------------------*
75 : * Initialization
76 : *---------------------------------------------------------------*/
77 :
78 7537 : nb_subfr = 2;
79 7537 : move16();
80 :
81 7537 : st->GSC_IVAS_mode = 0;
82 7537 : move16();
83 7537 : st->GSC_noisy_speech = 1;
84 7537 : move16();
85 7537 : st->hGSCEnc->noise_lev = 14;
86 7537 : move16();
87 :
88 7537 : hLPDmem->tilt_code = 0;
89 7537 : move16();
90 7537 : set16_fx( dct_epit_fx, 0, L_FRAME );
91 7537 : set16_fx( pitch_buf, L_SUBFR_Q6, NB_SUBFR ); /* Q6 */
92 7537 : last_pit_bin = L_FRAME / 2;
93 7537 : move16();
94 :
95 : /*---------------------------------------------------------------*
96 : * DCT transform of the residual and create a subsample residual
97 : *---------------------------------------------------------------*/
98 :
99 7537 : 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 7537 : tmp_nb_bits_tot = st->hBstr->nb_bits_tot; /* Q0 */
107 7537 : move16();
108 :
109 7537 : if ( st->extl_brate > 0 )
110 : {
111 : /* subtract 1 bit for TBE/BWE BWE flag (bit counted in extl_brate) */
112 68 : tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 );
113 : }
114 :
115 7537 : Word16 Q_exc = Q_new;
116 7537 : move16();
117 7537 : 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 7537 : edct_16fx( dct_epit_fx, exc_fx, L_FRAME, 7, st->element_mode );
124 :
125 7537 : 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 7537 : 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 7537 : IF( st->hBWE_TD != NULL )
138 : {
139 7529 : set16_fx( voice_factors, 0, NB_SUBFR );
140 :
141 7529 : IF( st->tdm_LRTD_flag )
142 : {
143 11 : interp_code_5over2_fx( exc_fx, bwe_exc_fx, L_FRAME );
144 : }
145 : ELSE
146 : {
147 7518 : set16_fx( bwe_exc_fx, 0, L_FRAME32k );
148 : }
149 : }
150 :
151 : /*--------------------------------------------------------------------------------------*
152 : * Synthesis
153 : *--------------------------------------------------------------------------------------*/
154 :
155 7537 : p_Aq = Aq; /* Q12 */
156 37685 : FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
157 : {
158 30148 : 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 30148 : p_Aq += ( M + 1 );
160 30148 : 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 7537 : Copy( exc_wo_nf_fx, exc_fx, L_FRAME ); /* Q_new */
167 :
168 7537 : return;
169 : }
170 :
171 :
172 : /*-------------------------------------------------------------------*
173 : * encod_gen_2sbfr()
174 : *
175 : * Encode GC, 2 subframes mode
176 : *-------------------------------------------------------------------*/
177 :
178 5 : void encod_gen_2sbfr(
179 : Encoder_State *st, /* i/o: state structure */
180 : const Word16 speech[], /* i : input speech Q_new-1 */
181 : const Word16 Aw[], /* i : weighted A(z) unquantized for subframes e(norm_s(Aw[0]+1)*/
182 : const Word16 Aq[], /* i : LP coefficients e(norm_s(Aw[0]+1)*/
183 : const Word16 *res, /* i : residual signal Q_new */
184 : Word16 *syn, /* i/o: core synthesis Q_new */
185 : Word16 *exc, /* i/o: current non-enhanced excitation Q_new-1 */
186 : Word16 *exc2, /* i/o: current enhanced excitation Q_new-1 */
187 : Word16 *pitch_buf, /* i/o: floating pitch values for each subframe Q6 */
188 : Word16 *voice_factors, /* o : voicing factors Q15 */
189 : Word16 *bwe_exc, /* o : excitation for SWB TBE Q_new */
190 : const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */
191 : const Word16 tdm_Pri_pitch_buf[], /* i : pitch values for primary channel Q4 */
192 : Word16 Q_new,
193 : Word16 shift )
194 : {
195 : Word16 xn[2 * L_SUBFR]; /* Target vector for pitch search */
196 : Word16 xn2[2 * L_SUBFR]; /* Target vector for codebook search */
197 : Word16 cn[2 * L_SUBFR]; /* Target vector in residual domain */
198 : Word16 h1[2 * L_SUBFR + ( M + 1 )]; /* Impulse response vector */
199 : Word16 h2[2 * L_SUBFR + ( M + 1 )]; /* Impulse response vector */
200 : Word16 code[2 * L_SUBFR]; /* Fixed codebook excitation */
201 : Word16 y1[2 * L_SUBFR]; /* Filtered adaptive excitation */
202 : Word16 y2[2 * L_SUBFR]; /* Filtered algebraic excitation */
203 : Word16 gain_pit; /* Pitch gain */
204 : Word16 voice_fac; /* Voicing factor */
205 : Word32 gain_code; /* Gain of code */
206 : Word16 gain_inov; /* inovation gain */
207 : Word16 L_frame, coder_type; /* L_frame; coder type */
208 : Word16 i, i_subfr; /* tmp variables */
209 : Word16 T0, T0_frac; /* close loop integer pitch and fractional part */
210 : Word16 T0_min, T0_max; /* pitch variables */
211 : Word16 *pt_pitch; /* pointer to floating pitch buffer */
212 : Word16 g_corr[6]; /* ACELP correl, values + gain pitch */
213 : // Word16 gains_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */
214 : Word32 gc_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */
215 : Word16 gp_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */
216 : Word16 clip_gain; /* LSF clip gain */
217 : const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coeff. vector*/
218 : Word32 norm_gain_code;
219 : Word16 pitch_limit_flag;
220 : Word16 error;
221 : Word16 q_h1;
222 :
223 5 : LPD_state_HANDLE hLPDmem = st->hLPDmem;
224 :
225 : Word16 gcode16;
226 : Word32 Lgcode, Ltmp;
227 5 : set16_fx( cn, 0, 2 * L_SUBFR ); /* Target vector in residual domain */
228 :
229 : /*------------------------------------------------------------------*
230 : * Initializations
231 : *------------------------------------------------------------------*/
232 :
233 5 : gain_pit = 0;
234 5 : move16();
235 5 : gain_code = 0;
236 5 : move16();
237 5 : error = 0;
238 5 : move16();
239 :
240 5 : T0_max = PIT_MAX;
241 5 : move16();
242 5 : T0_min = PIT_MIN;
243 5 : move16();
244 :
245 5 : L_frame = L_FRAME;
246 5 : move16();
247 5 : coder_type = GENERIC;
248 5 : move16();
249 :
250 5 : p_Aw = Aw; /* e(norm_s(Aw[0]+1) */
251 5 : p_Aq = Aq; /* e(norm_s(Aw[0]+1) */
252 5 : pt_pitch = pitch_buf; /*Q6*/
253 :
254 : /*------------------------------------------------------------------*
255 : * ACELP subframe loop
256 : *------------------------------------------------------------------*/
257 :
258 15 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += 2 * L_SUBFR )
259 : {
260 : /*----------------------------------------------------------------*
261 : * Find the the excitation search target "xn" and innovation
262 : * target in residual domain "cn"
263 : * Compute impulse response, h1[], of weighted synthesis filter
264 : *----------------------------------------------------------------*/
265 :
266 10 : Copy( &res[i_subfr], &exc[i_subfr], 2 * L_SUBFR ); // Q_new
267 :
268 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 );
269 :
270 10 : q_h1 = sub( 14, norm_s( h1[0] ) );
271 10 : Copy_Scale_sig( h1, h2, 2 * L_SUBFR, sub( 11, q_h1 ) );
272 :
273 : /*------------------------------------------------------------------------*
274 : * Close-loop pitch search on the 1st and 3rd subfr only and quantization
275 : * Adaptive exc. construction
276 : *------------------------------------------------------------------------*/
277 10 : *pt_pitch = pit_encode_ivas_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, Q_new );
278 10 : move16();
279 :
280 10 : Scale_sig( h1, 2 * L_SUBFR, sub( 13, q_h1 ) ); // Q13
281 :
282 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 );
283 :
284 : /*-----------------------------------------------------------------*
285 : * Find adaptive exitation
286 : *-----------------------------------------------------------------*/
287 :
288 10 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, 2 * L_SUBFR + 1, inter4_2_fx_Q15, L_INTERPOL2, PIT_UP_SAMP );
289 :
290 : /*-----------------------------------------------------------------*
291 : * Gain clipping test to avoid unstable synthesis on frame erasure
292 : *-----------------------------------------------------------------*/
293 :
294 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
295 : /*-----------------------------------------------------------------*
296 : * LP filtering of the adaptive excitation, codebook target computation
297 : *-----------------------------------------------------------------*/
298 10 : Scale_sig( h1, 2 * L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */
299 :
300 10 : lp_filt_exc_enc_ivas_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 );
301 : /* update long-term pitch gain for speech/music classifier */
302 10 : st->hSpMusClas->lowrate_pitchGain = add( mult( 29491, st->hSpMusClas->lowrate_pitchGain ), mult( 3277 /*Q15*/, gain_pit ) ); // Q14
303 10 : move16();
304 :
305 : /*-----------------------------------------------------------------*
306 : * Innovation encoding
307 : *-----------------------------------------------------------------*/
308 :
309 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 );
310 :
311 : /*-----------------------------------------------------------------*
312 : * Gain encoding
313 : *-----------------------------------------------------------------*/
314 :
315 10 : gain_enc_lbr_ivas_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 );
316 :
317 10 : IF( st->Opt_SC_VBR )
318 : {
319 0 : if ( EQ_16( st->hSC_VBR->last_ppp_mode, 1 ) )
320 : {
321 : /* SC-VBR - all other st->clip_var values will be updated even in a PPP frame */
322 0 : st->clip_var_fx[1] = gain_pit;
323 0 : move16();
324 : }
325 : }
326 :
327 : /*-----------------------------------------------------------------*
328 : * update LP-filtered gains for the case of frame erasures
329 : *-----------------------------------------------------------------*/
330 :
331 10 : gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx );
332 :
333 10 : Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/
334 10 : gcode16 = round_fx_sat( Lgcode ); /*Q0*/
335 10 : hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); /* Q15 */
336 10 : move16();
337 :
338 : /*-----------------------------------------------------------------*
339 : * Update memory of the weighting filter
340 : *-----------------------------------------------------------------*/
341 :
342 10 : Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/
343 10 : Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/
344 10 : Ltmp = L_negate( Ltmp );
345 10 : Ltmp = L_mac( Ltmp, xn[2 * L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */
346 10 : Ltmp = L_msu( Ltmp, y1[2 * L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */
347 10 : Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* 15 + Q_new */
348 10 : hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */
349 10 : move16();
350 :
351 : /*-----------------------------------------------------------------*
352 : * Construct adaptive part of the excitation
353 : * Save the non-enhanced excitation for FEC_exc
354 : *-----------------------------------------------------------------*/
355 :
356 1290 : FOR( i = 0; i < 2 * L_SUBFR; i++ )
357 : {
358 : /* code in Q9, gain_pit in Q14 */
359 1280 : exc2[i + i_subfr] = shl_sat( mult( gain_pit, exc[i + i_subfr] ), 1 ); /* Q_new-1 */
360 1280 : Ltmp = L_mult( gcode16, code[i] ); /* Q10 */
361 1280 : Ltmp = L_shl_sat( Ltmp, 5 ); /* Q15 */
362 1280 : Ltmp = L_mac_sat( Ltmp, exc[i + i_subfr], gain_pit ); /* Q15 */
363 1280 : Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16*/
364 1280 : exc[i + i_subfr] = round_fx_sat( Ltmp );
365 1280 : move16();
366 1280 : move16();
367 : }
368 : /*-----------------------------------------------------------------*
369 : * Prepare TBE excitation
370 : *-----------------------------------------------------------------*/
371 :
372 10 : prep_tbe_exc_ivas_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 );
373 :
374 10 : voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR]; /* Q15 */
375 10 : move16();
376 :
377 : /*-----------------------------------------------------------------*
378 : * Synthesize speech to update mem_syn_flt[].
379 : * Update A(z) filters
380 : *-----------------------------------------------------------------*/
381 10 : Syn_filt_s( 1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1 );
382 10 : p_Aw += 2 * ( M + 1 );
383 10 : p_Aq += 2 * ( M + 1 );
384 :
385 10 : pt_pitch++;
386 10 : *pt_pitch = *( pt_pitch - 1 );
387 10 : move16();
388 10 : pt_pitch++;
389 : }
390 :
391 : /* SC-VBR */
392 5 : IF( st->Opt_SC_VBR )
393 : {
394 0 : st->hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; /* Q14 */
395 0 : st->hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */
396 0 : move16();
397 0 : move16();
398 : }
399 :
400 5 : return;
401 : }
|