Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : //#include "prot_fx.h" /* Function prototypes */
8 : #include "rom_com_fx.h" /* Static table 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" /* Function prototypes */
13 :
14 : /*-------------------------------------------------------------------*
15 : * encod_amr_wb()
16 : *
17 : * Encode excitation signal in AMR-WB IO mode
18 : *-------------------------------------------------------------------*/
19 0 : void encod_amr_wb_fx(
20 : Encoder_State *st, /* i/o: state structure */
21 : const Word16 speech[], /* i : input speech Q_new-1*/
22 : const Word16 Aw[], /* i : weighted A(z) unquantized for subframes Q12*/
23 : const Word16 Aq[], /* i : 12k8 Lp coefficient Q12*/
24 : const Word16 *res, /* i : residual signal Q_new*/
25 : Word16 *syn, /* i/o: core synthesis st->Q_syn*/
26 : Word16 *exc, /* i/o: current non-enhanced excitation Q_new*/
27 : Word16 *exc2, /* i/o: current enhanced excitation Q_new*/
28 : Word16 *pitch_buf, /* i/o: floating pitch values for each subframe Q6*/
29 : Word16 hf_gain_fx[NB_SUBFR], /* o : decoded HF gain Q0*/
30 : const Word16 *speech16k_fx, /* i : input speech @16kHz Qx*/
31 : Word16 shift,
32 : Word16 Q_new )
33 : {
34 : Word16 xn[L_SUBFR]; /* Target vector for pitch search */
35 : Word16 xn2[L_SUBFR]; /* Target vector for codebook search */
36 : Word16 cn[L_SUBFR]; /* Target vector in residual domain */
37 : Word16 h1[L_SUBFR + ( M + 1 )]; /* Impulse response vector */
38 : Word16 h2[L_SUBFR + ( M + 1 )]; /* Impulse response vector */
39 : Word16 code[L_SUBFR]; /* Fixed codebook excitation */
40 : Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */
41 : Word16 y2[L_SUBFR]; /* Filtered algebraic excitation */
42 : Word16 gain_pit; /* Pitch gain */
43 : Word16 voice_fac; /* Voicing factor */
44 : Word32 gain_code; /* Gain of code */
45 : Word16 gain_inov; /* inovation gain */
46 : Word16 i, i_subfr; /* tmp variables */
47 : Word16 T0, T0_frac; /* close loop integer pitch and fractional part */
48 : Word16 T0_min, T0_max; /* pitch variables */
49 : Word16 *pt_pitch; /* pointer to floating pitch buffer */
50 : Word16 g_corr[10]; /* ACELP correl, values + gain pitch */
51 : Word16 clip_gain; /* LSF clip gain */
52 : const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coeff. vector*/
53 : Word16 unbits;
54 : Word32 norm_gain_code;
55 : Word16 pitch_limit_flag;
56 : Word16 shift_wsp;
57 : Word32 L_tmp;
58 : Word16 gcode16;
59 : Word32 Ltmp;
60 : Word32 Lgcode;
61 : Word16 T_op[3]; /* pitch period for quantization */
62 : Word16 lp_select, lp_flag;
63 0 : VAD_HANDLE hVAD = st->hVAD;
64 0 : AMRWB_IO_ENC_HANDLE hAmrwb_IO = st->hAmrwb_IO;
65 0 : BSTR_ENC_HANDLE hBstr = st->hBstr;
66 0 : LPD_state_HANDLE hLPDmem = st->hLPDmem;
67 : #ifndef ISSUE_1867_replace_overflow_libenc
68 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
69 : Flag Overflow = 0;
70 : move32();
71 : #endif
72 : #endif
73 :
74 : /*------------------------------------------------------------------*
75 : * Initializations
76 : *------------------------------------------------------------------*/
77 :
78 0 : set16_fx( y2, 0, L_SUBFR );
79 0 : set16_fx( code, 0, L_SUBFR );
80 :
81 0 : pitch_limit_flag = 0;
82 0 : move16(); /* always restrained pitch Q range in IO mode */
83 0 : T0_max = PIT_MAX;
84 0 : move16();
85 0 : T0_min = PIT_MIN;
86 0 : move16();
87 0 : unbits = 0;
88 0 : move16();
89 :
90 0 : p_Aw = Aw; /*Q12*/
91 0 : p_Aq = Aq; /*Q12*/
92 0 : pt_pitch = pitch_buf; /*Q6*/
93 0 : shift_wsp = add( Q_new, shift );
94 :
95 0 : Copy( st->pitch, T_op, 2 ); /*Q0*/
96 0 : if ( LE_16( T_op[0], PIT_MIN ) )
97 : {
98 0 : T_op[0] = shl( T_op[0], 1 ); /*Q0*/
99 0 : move16();
100 : }
101 :
102 0 : if ( LE_16( T_op[1], PIT_MIN ) )
103 : {
104 : /*T_op[1] *= 2;*/
105 0 : T_op[1] = shl( T_op[1], 1 ); /*Q0*/
106 0 : move16();
107 : }
108 0 : st->acelp_cfg.fcb_mode = 0; /* flag used in inov_encode() */
109 0 : move16();
110 :
111 : /*-----------------------------------------------------------------*
112 : * Select LP filtering flag
113 : *-----------------------------------------------------------------*/
114 :
115 0 : lp_flag = NORMAL_OPERATION;
116 0 : move16();
117 0 : if ( LT_32( st->core_brate, ACELP_11k60 ) )
118 : {
119 0 : lp_flag = LOW_PASS;
120 0 : move16();
121 : }
122 :
123 : /*------------------------------------------------------------------*
124 : * ACELP subframe loop
125 : *------------------------------------------------------------------*/
126 0 : FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
127 : {
128 : /*----------------------------------------------------------------*
129 : * Bandwidth expansion of A(z) filter coefficients
130 : * Find the the excitation search target "xn" and innovation
131 : * target in residual domain "cn"
132 : * Compute impulse response, h1[], of weighted synthesis filter
133 : *----------------------------------------------------------------*/
134 :
135 0 : Copy( &res[i_subfr], &exc[i_subfr], L_SUBFR ); /*Q_new*/
136 :
137 0 : find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq,
138 : res, L_SUBFR, p_Aw, TILT_FAC_FX, xn, cn, h1 );
139 :
140 0 : Copy_Scale_sig( h1, h2, L_SUBFR, -2 );
141 0 : Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */
142 :
143 : /* scaling of xn[] to limit dynamic at 12 bits */
144 0 : Scale_sig( xn, L_SUBFR, shift );
145 :
146 : /*----------------------------------------------------------------*
147 : * Close-loop pitch search and quantization
148 : * Adaptive exc. construction
149 : *----------------------------------------------------------------*/
150 :
151 0 : *pt_pitch = pit_encode_fx( hBstr, st->acelp_cfg.pitch_bits, st->core_brate, 1, L_FRAME, -1, &pitch_limit_flag, i_subfr, exc,
152 : L_SUBFR, T_op, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, 0 /*hStereoTD->tdm_Pitch_reuse_flag*/, NULL /*hStereoTD->tdm_Pri_pitch_buf*/, 0, Q_new );
153 :
154 : /*-----------------------------------------------------------------*
155 : * Find adaptive exitation
156 : *-----------------------------------------------------------------*/
157 :
158 0 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP );
159 :
160 : /*-----------------------------------------------------------------*
161 : * Gain clipping test to avoid unstable synthesis on frame erasure
162 : * or in case of floating point encoder & fixed p. decoder
163 : *-----------------------------------------------------------------*/
164 :
165 0 : clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, 0, xn, st->clip_var_fx, sub( shift_wsp, 1 ) );
166 :
167 : /*-----------------------------------------------------------------*
168 : * LP filtering of the adaptive excitation, codebook target computation
169 : *-----------------------------------------------------------------*/
170 :
171 0 : lp_select = lp_filt_exc_enc_fx( MODE1, -1, i_subfr, exc, h1, xn, y1, xn2, L_SUBFR, L_FRAME, g_corr, clip_gain, &gain_pit, &lp_flag );
172 :
173 0 : IF( EQ_16( lp_flag, NORMAL_OPERATION ) )
174 : {
175 0 : push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 );
176 : }
177 :
178 : /*-----------------------------------------------------------------*
179 : * Innovation encoding
180 : *-----------------------------------------------------------------*/
181 :
182 0 : inov_encode_fx( st, st->core_brate, 1, L_FRAME, st->last_L_frame, -1, -1, 0, i_subfr, -1, p_Aq, gain_pit, cn,
183 0 : exc, h2, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits, L_SUBFR, shift );
184 :
185 : /*-----------------------------------------------------------------*
186 : * Gain encoding
187 : * Pitch gain clipping test
188 : * Estimate spectrum tilt and voicing
189 : *-----------------------------------------------------------------*/
190 :
191 0 : gain_enc_amr_wb_fx( hBstr, xn, shift_wsp, y1, y2, code, st->core_brate, &gain_pit, &gain_code,
192 0 : &gain_inov, &norm_gain_code, g_corr, clip_gain, hAmrwb_IO->past_qua_en_fx );
193 :
194 0 : gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx );
195 : #ifdef ISSUE_1867_replace_overflow_libenc
196 0 : Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/
197 0 : gcode16 = round_fx_sat( Lgcode ); /*Q0*/
198 : #else
199 : Lgcode = L_shl_o( gain_code, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/
200 : gcode16 = round_fx_o( Lgcode, &Overflow ); /*Q0*/
201 : #endif
202 :
203 0 : hLPDmem->tilt_code = Est_tilt2( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, shift ); /*Q15*/
204 :
205 0 : FOR( i = 0; i < L_SUBFR; i++ )
206 : {
207 : #ifdef ISSUE_1867_replace_overflow_libenc
208 0 : exc2[i + i_subfr] = round_fx_sat( L_shl_sat( L_mult( gain_pit, exc[i + i_subfr] ), 1 ) ); /*Q_new*/
209 : #else
210 : exc2[i + i_subfr] = round_fx_o( L_shl_o( L_mult( gain_pit, exc[i + i_subfr] ), 1, &Overflow ), &Overflow ); /*Q_new*/
211 : #endif
212 0 : move16();
213 : }
214 :
215 : /*-----------------------------------------------------------------*
216 : * Update memory of the weighting filter
217 : *-----------------------------------------------------------------*/
218 :
219 : /*st->mem_w0 = xn[L_SUBFR-1] - gain_pit * y1[L_SUBFR-1] - gain_code * y2[L_SUBFR-1];*/
220 0 : Ltmp = L_mult( gcode16, y2[L_SUBFR - 1] ); /*Q10*/
221 0 : Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15 - shift*/
222 0 : Ltmp = L_negate( Ltmp );
223 0 : Ltmp = L_mac( Ltmp, xn[L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */
224 0 : Ltmp = L_msu( Ltmp, y1[L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */
225 0 : Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new+15 */
226 0 : hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */
227 0 : move16();
228 :
229 : /*-----------------------------------------------------------------*
230 : * Find the total excitation
231 : *-----------------------------------------------------------------*/
232 :
233 0 : FOR( i = 0; i < L_SUBFR; i++ )
234 : {
235 0 : L_tmp = L_mult( gcode16, code[i] ); /*Q10*/
236 0 : L_tmp = L_shl_sat( L_tmp, 5 ); /*Q15*/
237 0 : L_tmp = L_mac_sat( L_tmp, exc[i + i_subfr], gain_pit ); /* Q_new+15 */
238 : #ifdef ISSUE_1867_replace_overflow_libenc
239 0 : L_tmp = L_shl_sat( L_tmp, 1 ); /* saturation can occur here Q_new+15*/
240 0 : exc[i + i_subfr] = round_fx_sat( L_tmp ); /*Q_new*/
241 : #else
242 : L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /* saturation can occur here Q_new+15*/
243 : exc[i + i_subfr] = round_fx_o( L_tmp, &Overflow ); /*Q_new*/
244 : #endif
245 0 : move16();
246 : }
247 :
248 : /*-----------------------------------------------------------------*
249 : * Synthesize speech to update mem_syn[]
250 : * Update A(z) filters
251 : *-----------------------------------------------------------------*/
252 :
253 0 : Syn_filt_s( 1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1 );
254 :
255 : /*-----------------------------------------------------------------*
256 : * HF gain modification factors at 23.85 kbps
257 : *-----------------------------------------------------------------*/
258 :
259 0 : IF( EQ_32( st->core_brate, ACELP_23k85 ) )
260 : {
261 0 : IF( GE_32( st->input_Fs, 16000 ) )
262 : {
263 0 : hf_cod_fx( st->core_brate, &speech16k_fx[i_subfr * L_SUBFR16k / L_SUBFR], Aq, &exc[i_subfr], &syn[i_subfr],
264 0 : &hAmrwb_IO->seed2_enc, hAmrwb_IO->mem_hp400_enc_fx, hAmrwb_IO->mem_syn_hf_enc_fx, hAmrwb_IO->mem_hf_enc_fx, hAmrwb_IO->mem_hf2_enc_fx,
265 0 : hVAD->hangover_cnt, &hAmrwb_IO->gain_alpha_fx, &hf_gain_fx[i_subfr / L_SUBFR], add( Q_new, 1 ), st->Q_syn );
266 : }
267 :
268 0 : push_indice( hBstr, IND_HF_GAIN_MODIFICATION, hf_gain_fx[i_subfr / L_SUBFR], 4 );
269 : }
270 :
271 0 : p_Aw += ( M + 1 );
272 0 : p_Aq += ( M + 1 );
273 0 : pt_pitch++;
274 : }
275 :
276 0 : return;
277 : }
|