Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h" /* Compilation switches */
7 : #include "cnst.h" /* Common constants */
8 : //#include "prot_fx.h" /* Function prototypes */
9 : #include "rom_com.h" /* Common constants */
10 : #include "prot_fx.h" /* Function prototypes */
11 : #include "prot_fx_enc.h" /* Function prototypes */
12 : #include "basop_util.h"
13 :
14 : /*==============================================================================*/
15 : /* FUNCTION : encod_nelp_fx() */
16 : /*------------------------------------------------------------------------------*/
17 : /* PURPOSE : Encode Unvoiced frames in SC-VBR */
18 : /*------------------------------------------------------------------------------*/
19 : /* INPUT ARGUMENTS : */
20 : /* _ (Encoder_State) st_fx: state structure */
21 : /* _ (Word16[]) speech_fx : input speech Q_new-1 */
22 : /* _ (Word16[]) Aq_fx : 12k8 Lp coefficient Q12 */
23 : /* _ (Word16[]) A_fx : unquantized A(z) filter */
24 : /* with bandwidth expansion Q12 */
25 : /* _ (Word16) coder_type : coding type */
26 : /* _ (Word16[]) res_fx : residual signal Q_new */
27 : /* _ (Word16*) Q_new : res qformat */
28 : /* _ (Word16) shift */
29 : /*------------------------------------------------------------------------------*/
30 : /* OUTPUT ARGUMENTS : */
31 : /* _ (Word16[]) synth_fx : core synthesis */
32 : /* _ (Word16[]) tmp_noise_fx: long-term noise energy Q0 */
33 : /* _ (Word16[]) exc_fx : current non-enhanced excitation Q_new */
34 : /* _ (Word16[]) exc2_fx : current enhanced excitation Q_new */
35 : /* _ (Word16[]) pitch_buf_fx: floating pitch values for each subframe Q6 */
36 : /* _ (Word16*) voice_factors : voicing factors */
37 : /* _ (Word16*) bwe_exc : excitation for SWB TBE */
38 : /*------------------------------------------------------------------------------*/
39 :
40 : /*------------------------------------------------------------------------------*/
41 : /* RETURN ARGUMENTS : */
42 : /* _ None */
43 : /*==============================================================================*/
44 0 : void encod_nelp_fx(
45 : Encoder_State *st_fx, /* i/o: state structure */
46 : const Word16 *speech_fx, /* i : input speech Q_new-1*/
47 : const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/
48 : const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/
49 : Word16 *res_fx, /* o : residual signal Q_new*/
50 : Word16 *synth_fx, /* o : core synthesis Q_new*/
51 : Word16 *tmp_noise_fx, /* o : long-term noise energy Q0*/
52 : Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/
53 : Word16 *exc2_fx, /* i/o: current enhanced excitation Q_new*/
54 : Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/
55 : Word16 *voice_factors_fx, /* o : voicing factors Q15*/
56 : Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q_new*/
57 : Word16 Q_new,
58 : Word16 shift
59 :
60 : )
61 : {
62 : Word16 xn_fx[L_SUBFR]; /* Target vector for pitch search */
63 : Word16 h1_fx[L_SUBFR]; /* Impulse response vector */
64 : Word16 exc_nelp_fx[L_FRAME];
65 :
66 : Word16 i_subfr, j;
67 :
68 : const Word16 *p_Aw_fx, *p_Aq_fx; /* pointer to LP filter coeff. vector */
69 0 : Word16 saved_Q_new = Q_new;
70 :
71 0 : Word16 reduce_gains = 0;
72 0 : move16();
73 0 : LPD_state_HANDLE hLPDmem = st_fx->hLPDmem;
74 0 : SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR;
75 :
76 0 : IF( EQ_16( st_fx->bwidth, NB ) && GE_32( st_fx->input_Fs, 16000 ) )
77 : {
78 0 : IF( hSC_VBR->last_nelp_mode == 0 )
79 : {
80 0 : set16_fx( hSC_VBR->nelp_lp_fit_mem, 0, NELP_LP_ORDER * 2 );
81 : }
82 0 : Scale_sig( hSC_VBR->nelp_lp_fit_mem, NELP_LP_ORDER * 2, sub( Q_new, st_fx->prev_Q_new ) );
83 :
84 0 : pz_filter_sp_fx( num_nelp_lp_fx, den_nelp_lp_fx, res_fx, res_fx, hSC_VBR->nelp_lp_fit_mem, NELP_LP_ORDER, NELP_LP_ORDER, L_FRAME, 3 ); /*16-Q of filter coeff*/
85 : }
86 :
87 0 : p_Aw_fx = Aw_fx;
88 0 : p_Aq_fx = Aq_fx;
89 :
90 :
91 0 : FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
92 : {
93 : /*----------------------------------------------------------------*
94 : * - Bandwidth expansion of A(z) filter coefficients
95 : * - Find the excitation search target "xn" and innovation
96 : * target in residual domain "cn"
97 : * - Compute impulse response, h1[], of weighted synthesis filter
98 : *----------------------------------------------------------------*/
99 0 : Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */
100 :
101 0 : find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx,
102 : res_fx, L_SUBFR, p_Aw_fx, TILT_FAC_FX, xn_fx, NULL, h1_fx );
103 :
104 : /* scale xn[] and h1[] to avoid overflow in dot_product12() */
105 0 : Scale_sig( xn_fx, L_SUBFR, shift ); /* scaling of xn[] to limit dynamic at 12 bits Q_new -1 + shift */
106 :
107 0 : IF( i_subfr == 0 )
108 : {
109 0 : test();
110 0 : IF( EQ_16( hSC_VBR->Local_VAD, 1 ) && EQ_16( st_fx->bwidth, NB ) )
111 : {
112 0 : reduce_gains = 1;
113 0 : move16();
114 : }
115 :
116 0 : nelp_encoder_fx( st_fx, res_fx, exc_nelp_fx, &Q_new, reduce_gains );
117 :
118 0 : Scale_sig( exc_nelp_fx, L_FRAME, ( saved_Q_new - Q_new ) ); /* saved_Q_new*/
119 : }
120 :
121 :
122 0 : *tmp_noise_fx = 0;
123 0 : move16();
124 :
125 : /*-----------------------------------------------------------------*
126 : * Synthesize speech to update mem_syn[].
127 : * Update A(z) filters
128 : *-----------------------------------------------------------------*/
129 0 : Syn_filt_s( 1, p_Aq_fx, M, &exc_nelp_fx[i_subfr], &synth_fx[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1 );
130 :
131 0 : p_Aw_fx += ( M + 1 );
132 0 : move16();
133 0 : p_Aq_fx += ( M + 1 );
134 0 : move16();
135 0 : *pitch_buf_fx = L_SUBFR_Q6;
136 0 : move16();
137 :
138 0 : pitch_buf_fx++;
139 0 : move16();
140 : }
141 :
142 0 : Copy( exc_nelp_fx, exc_fx, L_FRAME ); /* Q_new */
143 :
144 : /*-----------------------------------------------------------------*
145 : * Updates: last value of new target is stored in mem_w0
146 : *-----------------------------------------------------------------*/
147 :
148 0 : hLPDmem->mem_w0 = sub_sat( shr_sat( xn_fx[L_SUBFR - 1], shift ), shr( exc_fx[L_FRAME - 1], 1 ) );
149 0 : move16(); /*Q_new-1 */
150 0 : hLPDmem->tilt_code = 0;
151 0 : move16(); /* purely unvoiced */
152 0 : hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */
153 0 : move16();
154 :
155 0 : Copy( exc_fx, exc2_fx, L_FRAME ); /* Q_new */
156 :
157 0 : hSC_VBR->prev_ppp_gain_pit_fx = 0;
158 0 : move16();
159 :
160 0 : hLPDmem->dm_fx.prev_state = 0;
161 0 : move16();
162 0 : hLPDmem->dm_fx.prev_gain_pit[0] = hSC_VBR->prev_ppp_gain_pit_fx; /* Q14 */
163 0 : move16();
164 :
165 0 : FOR( j = 1; j < 5; j++ )
166 : {
167 0 : hLPDmem->dm_fx.prev_gain_pit[j] = hLPDmem->dm_fx.prev_gain_pit[j - 1]; /* Q14 */
168 0 : move16();
169 : }
170 0 : interp_code_5over2_fx( exc2_fx, bwe_exc_fx, L_FRAME );
171 0 : set16_fx( voice_factors_fx, 0, NB_SUBFR16k );
172 :
173 0 : return;
174 : }
175 :
176 0 : void encod_nelp_ivas_fx(
177 : Encoder_State *st_fx, /* i/o: state structure */
178 : const Word16 *speech_fx,
179 : /* i : input speech */ /* Q_new-1 */
180 : const Word16 Aw_fx[],
181 : /* i : weighted A(z) unquantized for subframes */ /*exp(norm_s(Aw_fx[0])+1)*/
182 : const Word16 Aq_fx[],
183 : /* i : 12k8 Lp coefficient */ /*exp(norm_s(Aw_fx[0])+1)*/
184 : Word16 *res_fx,
185 : /* o : residual signal */ /* Q_new */
186 : Word16 *synth_fx,
187 : /* o : core synthesis */ /* Q_new */
188 : Word16 *tmp_noise_fx,
189 : /* o : long-term noise energy */ /* Q8 */
190 : Word16 *exc_fx,
191 : /* i/o: current non-enhanced excitation */ /* Q_new */
192 : Word16 *exc2_fx,
193 : /* i/o: current enhanced excitation */ /* Q_new */
194 : Word16 *pitch_buf_fx,
195 : /* o : floating pitch values for each subframe */ /* Q6 */
196 : Word16 *voice_factors_fx,
197 : /* o : voicing factors */ /* Q15 */
198 : Word16 *bwe_exc_fx,
199 : /* o : excitation for SWB TBE */ /* Q_new */
200 : Word16 Q_new,
201 : Word16 shift )
202 : {
203 : Word16 xn_fx[L_SUBFR]; /* Target vector for pitch search */
204 : Word16 h1_fx[L_SUBFR]; /* Impulse response vector */
205 : Word16 exc_nelp_fx[L_FRAME];
206 :
207 : Word16 i_subfr, j;
208 :
209 : const Word16 *p_Aw_fx, *p_Aq_fx; /* pointer to LP filter coeff. vector */
210 0 : Word16 saved_Q_new = Q_new;
211 0 : move16();
212 :
213 0 : Word16 reduce_gains = 0;
214 0 : move16();
215 0 : LPD_state_HANDLE hLPDmem = st_fx->hLPDmem;
216 0 : SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR;
217 :
218 0 : test();
219 0 : IF( EQ_16( st_fx->bwidth, NB ) && GE_32( st_fx->input_Fs, 16000 ) )
220 : {
221 0 : IF( hSC_VBR->last_nelp_mode == 0 )
222 : {
223 0 : set16_fx( hSC_VBR->nelp_lp_fit_mem, 0, NELP_LP_ORDER * 2 );
224 : }
225 0 : Scale_sig( hSC_VBR->nelp_lp_fit_mem, NELP_LP_ORDER * 2, sub( Q_new, st_fx->prev_Q_new ) ); /* Q_new */
226 :
227 0 : pz_filter_sp_fx( num_nelp_lp_fx, den_nelp_lp_fx, res_fx, res_fx, hSC_VBR->nelp_lp_fit_mem, NELP_LP_ORDER, NELP_LP_ORDER, L_FRAME, 3 ); /*16-Q of filter coeff*/
228 : }
229 :
230 0 : p_Aw_fx = Aw_fx;
231 0 : p_Aq_fx = Aq_fx;
232 :
233 :
234 0 : FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
235 : {
236 : /*----------------------------------------------------------------*
237 : * - Bandwidth expansion of A(z) filter coefficients
238 : * - Find the excitation search target "xn" and innovation
239 : * target in residual domain "cn"
240 : * - Compute impulse response, h1[], of weighted synthesis filter
241 : *----------------------------------------------------------------*/
242 0 : Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */
243 :
244 0 : find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx,
245 : res_fx, L_SUBFR, p_Aw_fx, TILT_FAC_FX, xn_fx, NULL, h1_fx );
246 :
247 : /* scale xn[] and h1[] to avoid overflow in dot_product12() */
248 0 : Scale_sig( xn_fx, L_SUBFR, shift ); /* scaling of xn[] to limit dynamic at 12 bits Q_new-1+shift */
249 :
250 0 : IF( i_subfr == 0 )
251 : {
252 0 : test();
253 0 : IF( EQ_16( hSC_VBR->Local_VAD, 1 ) && EQ_16( st_fx->bwidth, NB ) )
254 : {
255 0 : reduce_gains = 1;
256 0 : move16();
257 : }
258 :
259 0 : nelp_encoder_ivas_fx( st_fx, res_fx, exc_nelp_fx, &Q_new, reduce_gains );
260 :
261 0 : Scale_sig( exc_nelp_fx, L_FRAME, ( saved_Q_new - Q_new ) ); /* saved_Q_new */
262 : }
263 :
264 :
265 0 : *tmp_noise_fx = 0;
266 0 : move16();
267 :
268 : /*-----------------------------------------------------------------*
269 : * Synthesize speech to update mem_syn[].
270 : * Update A(z) filters
271 : *-----------------------------------------------------------------*/
272 0 : Syn_filt_s( 1, p_Aq_fx, M, &exc_nelp_fx[i_subfr], &synth_fx[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1 );
273 :
274 0 : p_Aw_fx += ( M + 1 );
275 0 : p_Aq_fx += ( M + 1 );
276 0 : *pitch_buf_fx = L_SUBFR_Q6; /* Q6 */
277 0 : move16();
278 :
279 0 : pitch_buf_fx++;
280 : }
281 :
282 0 : Copy( exc_nelp_fx, exc_fx, L_FRAME ); /* Q_new */
283 :
284 : /*-----------------------------------------------------------------*
285 : * Updates: last value of new target is stored in mem_w0
286 : *-----------------------------------------------------------------*/
287 :
288 0 : hLPDmem->mem_w0 = sub_sat( shr_sat( xn_fx[L_SUBFR - 1], shift ), shr( exc_fx[L_FRAME - 1], 1 ) );
289 0 : move16(); /*Q_new-1 */
290 0 : hLPDmem->tilt_code = 0;
291 0 : move16(); /* purely unvoiced */
292 0 : hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code;
293 0 : move16();
294 :
295 0 : Copy( exc_fx, exc2_fx, L_FRAME ); /* Q_new */
296 :
297 0 : hSC_VBR->prev_ppp_gain_pit_fx = 0;
298 0 : move16();
299 :
300 0 : hLPDmem->dm_fx.prev_state = 0;
301 0 : move16();
302 0 : hLPDmem->dm_fx.prev_gain_pit[0] = hSC_VBR->prev_ppp_gain_pit_fx; /* Q14 */
303 0 : move16();
304 :
305 0 : FOR( j = 1; j < 5; j++ )
306 : {
307 0 : hLPDmem->dm_fx.prev_gain_pit[j] = hLPDmem->dm_fx.prev_gain_pit[j - 1]; /* Q14 */
308 0 : move16();
309 : }
310 0 : interp_code_5over2_fx( exc2_fx, bwe_exc_fx, L_FRAME );
311 0 : set16_fx( voice_factors_fx, 0, NB_SUBFR16k );
312 :
313 0 : return;
314 : }
|