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 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
68 0 : Flag Overflow = 0;
69 0 : move32();
70 : #endif
71 :
72 : /*------------------------------------------------------------------*
73 : * Initializations
74 : *------------------------------------------------------------------*/
75 :
76 0 : set16_fx( y2, 0, L_SUBFR );
77 0 : set16_fx( code, 0, L_SUBFR );
78 :
79 0 : pitch_limit_flag = 0;
80 0 : move16(); /* always restrained pitch Q range in IO mode */
81 0 : T0_max = PIT_MAX;
82 0 : move16();
83 0 : T0_min = PIT_MIN;
84 0 : move16();
85 0 : unbits = 0;
86 0 : move16();
87 :
88 0 : p_Aw = Aw; /*Q12*/
89 0 : p_Aq = Aq; /*Q12*/
90 0 : pt_pitch = pitch_buf; /*Q6*/
91 0 : shift_wsp = add( Q_new, shift );
92 :
93 0 : Copy( st->pitch, T_op, 2 ); /*Q0*/
94 0 : if ( LE_16( T_op[0], PIT_MIN ) )
95 : {
96 0 : T_op[0] = shl( T_op[0], 1 ); /*Q0*/
97 0 : move16();
98 : }
99 :
100 0 : if ( LE_16( T_op[1], PIT_MIN ) )
101 : {
102 : /*T_op[1] *= 2;*/
103 0 : T_op[1] = shl( T_op[1], 1 ); /*Q0*/
104 0 : move16();
105 : }
106 0 : st->acelp_cfg.fcb_mode = 0; /* flag used in inov_encode() */
107 0 : move16();
108 :
109 : /*-----------------------------------------------------------------*
110 : * Select LP filtering flag
111 : *-----------------------------------------------------------------*/
112 :
113 0 : lp_flag = NORMAL_OPERATION;
114 0 : move16();
115 0 : if ( LT_32( st->core_brate, ACELP_11k60 ) )
116 : {
117 0 : lp_flag = LOW_PASS;
118 0 : move16();
119 : }
120 :
121 : /*------------------------------------------------------------------*
122 : * ACELP subframe loop
123 : *------------------------------------------------------------------*/
124 0 : FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
125 : {
126 : /*----------------------------------------------------------------*
127 : * Bandwidth expansion of A(z) filter coefficients
128 : * Find the the excitation search target "xn" and innovation
129 : * target in residual domain "cn"
130 : * Compute impulse response, h1[], of weighted synthesis filter
131 : *----------------------------------------------------------------*/
132 0 : Copy( &res[i_subfr], &exc[i_subfr], L_SUBFR ); /*Q_new*/
133 :
134 0 : find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq,
135 : res, L_SUBFR, p_Aw, TILT_FAC_FX, xn, cn, h1 );
136 :
137 0 : Copy_Scale_sig( h1, h2, L_SUBFR, -2 );
138 0 : Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */
139 :
140 : /* scaling of xn[] to limit dynamic at 12 bits */
141 0 : Scale_sig( xn, L_SUBFR, shift );
142 :
143 : /*----------------------------------------------------------------*
144 : * Close-loop pitch search and quantization
145 : * Adaptive exc. construction
146 : *----------------------------------------------------------------*/
147 :
148 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,
149 : 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*/ );
150 :
151 : /*-----------------------------------------------------------------*
152 : * Find adaptive exitation
153 : *-----------------------------------------------------------------*/
154 :
155 0 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP );
156 :
157 : /*-----------------------------------------------------------------*
158 : * Gain clipping test to avoid unstable synthesis on frame erasure
159 : * or in case of floating point encoder & fixed p. decoder
160 : *-----------------------------------------------------------------*/
161 :
162 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 ) );
163 :
164 : /*-----------------------------------------------------------------*
165 : * LP filtering of the adaptive excitation, codebook target computation
166 : *-----------------------------------------------------------------*/
167 :
168 0 : lp_select = lp_filt_exc_enc_fx( MODE1, -1, i_subfr, exc, h1,
169 : xn, y1, xn2, L_SUBFR, L_FRAME, g_corr, clip_gain, &gain_pit, &lp_flag );
170 :
171 0 : IF( EQ_16( lp_flag, NORMAL_OPERATION ) )
172 : {
173 0 : push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 );
174 : }
175 :
176 : /*-----------------------------------------------------------------*
177 : * Innovation encoding
178 : *-----------------------------------------------------------------*/
179 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,
180 0 : exc, h2, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits, L_SUBFR, shift );
181 : /*-----------------------------------------------------------------*
182 : * Gain encoding
183 : * Pitch gain clipping test
184 : * Estimate spectrum tilt and voicing
185 : *-----------------------------------------------------------------*/
186 0 : gain_enc_amr_wb_fx( hBstr, xn, shift_wsp, y1, y2, code, st->core_brate, &gain_pit, &gain_code,
187 0 : &gain_inov, &norm_gain_code, g_corr, clip_gain, hAmrwb_IO->past_qua_en_fx );
188 :
189 0 : gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx );
190 0 : Lgcode = L_shl_o( gain_code, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/
191 0 : gcode16 = round_fx_o( Lgcode, &Overflow ); /*Q0*/
192 :
193 0 : hLPDmem->tilt_code = Est_tilt2( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, shift ); /*Q15*/
194 :
195 0 : FOR( i = 0; i < L_SUBFR; i++ )
196 : {
197 0 : exc2[i + i_subfr] = round_fx_o( L_shl_o( L_mult( gain_pit, exc[i + i_subfr] ), 1, &Overflow ), &Overflow ); /*Q_new*/
198 0 : move16();
199 : }
200 :
201 : /*-----------------------------------------------------------------*
202 : * Update memory of the weighting filter
203 : *-----------------------------------------------------------------*/
204 :
205 : /*st->mem_w0 = xn[L_SUBFR-1] - gain_pit * y1[L_SUBFR-1] - gain_code * y2[L_SUBFR-1];*/
206 0 : Ltmp = L_mult( gcode16, y2[L_SUBFR - 1] ); /*Q10*/
207 0 : Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15 - shift*/
208 0 : Ltmp = L_negate( Ltmp );
209 0 : Ltmp = L_mac( Ltmp, xn[L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */
210 0 : Ltmp = L_msu( Ltmp, y1[L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */
211 0 : Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new+15 */
212 0 : hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */
213 0 : move16();
214 : /*-----------------------------------------------------------------*
215 : * Find the total excitation
216 : *-----------------------------------------------------------------*/
217 0 : FOR( i = 0; i < L_SUBFR; i++ )
218 : {
219 0 : L_tmp = L_mult( gcode16, code[i] ); /*Q10*/
220 0 : L_tmp = L_shl_sat( L_tmp, 5 ); /*Q15*/
221 0 : L_tmp = L_mac_sat( L_tmp, exc[i + i_subfr], gain_pit ); /* Q_new+15 */
222 0 : L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /* saturation can occur here Q_new+15*/
223 0 : exc[i + i_subfr] = round_fx_o( L_tmp, &Overflow ); /*Q_new*/
224 0 : move16();
225 : }
226 :
227 : /*-----------------------------------------------------------------*
228 : * Synthesize speech to update mem_syn[]
229 : * Update A(z) filters
230 : *-----------------------------------------------------------------*/
231 0 : Syn_filt_s( 1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1 );
232 :
233 : /*-----------------------------------------------------------------*
234 : * HF gain modification factors at 23.85 kbps
235 : *-----------------------------------------------------------------*/
236 :
237 0 : IF( EQ_32( st->core_brate, ACELP_23k85 ) )
238 : {
239 0 : IF( GE_32( st->input_Fs, 16000 ) )
240 : {
241 0 : hf_cod_fx( st->core_brate, &speech16k_fx[i_subfr * L_SUBFR16k / L_SUBFR], Aq, &exc[i_subfr], &syn[i_subfr],
242 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,
243 0 : hVAD->hangover_cnt, &hAmrwb_IO->gain_alpha_fx, &hf_gain_fx[i_subfr / L_SUBFR], add( Q_new, 1 ), st->Q_syn );
244 : }
245 :
246 0 : push_indice( hBstr, IND_HF_GAIN_MODIFICATION, hf_gain_fx[i_subfr / L_SUBFR], 4 );
247 : }
248 :
249 0 : p_Aw += ( M + 1 );
250 0 : p_Aq += ( M + 1 );
251 0 : pt_pitch++;
252 : }
253 :
254 0 : return;
255 : }
|