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 "cnst.h"
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 : /*---------------------------------------------------------------------*
16 : * hf_cod_init()
17 : *
18 : *
19 : *---------------------------------------------------------------------*/
20 :
21 3 : void hf_cod_init_fx(
22 : Word16 *mem_hp400_enc, /* o: memory of hp 400 Hz filter */
23 : Word16 *mem_hf1_enc, /* o: HF band-pass filter memory */
24 : Word16 *mem_syn_hf_enc, /* o: HF synthesis memory */
25 : Word16 *mem_hf2_enc, /* o: HF band-pass filter memory */
26 : Word16 *gain_alpha_fx /* o: smoothing gain for transitions between active and inactive frames */
27 : )
28 : {
29 3 : set16_fx( mem_hp400_enc, 0, 6 );
30 3 : set16_fx( mem_hf1_enc, 0, L_FIR - 1 );
31 3 : set16_fx( mem_syn_hf_enc, 0, M );
32 3 : set16_fx( mem_hf2_enc, 0, L_FIR - 1 );
33 :
34 3 : *gain_alpha_fx = 16384;
35 3 : move16();
36 :
37 3 : return;
38 : }
39 :
40 : /*---------------------------------------------------------------------*
41 : * hf_cod()
42 : *
43 : *
44 : *---------------------------------------------------------------------*/
45 :
46 0 : void hf_cod_fx(
47 : const Word32 core_brate_fx, /* i : core bitrate */
48 : const Word16 *speech16k_fx, /* i : original speech at 16 kHz */
49 : const Word16 Aq_fx[], /* i : quantized Aq */
50 : const Word16 exc_fx[], /* i : excitation at 12.8 kHz */
51 : Word16 synth_fx[], /* i : 12.8kHz synthesis signal */
52 : Word16 *seed2_enc_fx, /* i/o: random seed for HF noise gen */
53 : Word16 *mem_hp400_enc_fx, /* i/o: memory of hp 400 Hz filter */
54 : Word16 *mem_syn_hf_enc_fx, /* i/o: HF synthesis memory */
55 : Word16 *mem_hf1_enc_fx, /* i/o: HF band-pass filter memory */
56 : Word16 *mem_hf2_enc_fx, /* i/o: HF band-pass filter memory */
57 : const Word16 dtxHangoverCount_fx,
58 : Word16 *gain_alpha_fx, /* i/o: smoothing gain for transitions between active and inactive frames */
59 : Word16 *hf_gain_fx, /* o : HF gain to be transmitted to decoder */
60 : Word16 Q_exc,
61 : Word16 Q_syn )
62 : {
63 : /*------------------------Scaling-------------------------------------------------
64 : speech16k - Q0
65 : Aq - Q12
66 : exc - Q_exc
67 : synth - Q_syn
68 : mem_hp400_enc - Q_syn
69 : mem_syn_hf_enc - Q0
70 : mem_hf1_enc - Q0
71 : mem_hf2_enc - Q0
72 : gain_alpha_fx - Q14
73 : ener - all dynamic
74 : fac, scale - Q12
75 : Ap - Q12
76 : HF_SP - Q0
77 : ---------------------------------------------------------------------------------*/
78 :
79 : Word16 i, q1, q2, sign;
80 : Word16 shift;
81 : Word16 ener_hf_fx, ener_exc_fx, ener_input_fx, fac_fx, tmp_fx, ener_fx, scale_fx;
82 : Word16 Ap_fx[M + 1];
83 : Word16 HF_SP_fx[L_SUBFR16k];
84 : Word16 HF_est_gain_fx, HF_calc_gain_fx, HF_corr_gain_fx, HF_gain_ind_fx;
85 : Word32 dist_min_fx, dist_fx;
86 : Word16 HF_fx[L_SUBFR16k], HF_syn_fx[L_SUBFR16k]; /* o : HF excitation */
87 : Word32 L_tmp;
88 : Word16 *pt1;
89 : const Word16 *pt2;
90 : #ifndef ISSUE_1867_replace_overflow_libenc
91 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
92 : Flag Overflow = 0;
93 : #endif
94 : #endif
95 :
96 : /* Original speech signal as reference for high band gain quantisation */
97 0 : Copy( speech16k_fx, HF_SP_fx, L_SUBFR16k );
98 :
99 : /*-----------------------------------------------------------------*
100 : * generate white noise vector
101 : *-----------------------------------------------------------------*/
102 :
103 0 : Random_Fill( seed2_enc_fx, L_SUBFR16k, HF_fx, 3 ); /*Q(-3) */
104 :
105 : /*-----------------------------------------------------------------*
106 : * calculate energy scaling factor so that white noise would have the
107 : * same energy as exc12k8
108 : *-----------------------------------------------------------------*/
109 :
110 0 : ener_exc_fx = dot_prod_satcontr( exc_fx, exc_fx, Q_exc, Q_exc, &q1, L_SUBFR );
111 0 : ener_hf_fx = dot_prod_satcontr( HF_fx, HF_fx, -3, -3, &q2, L_SUBFR16k );
112 :
113 0 : scale_fx = div_s( shl( 1, 14 ), ener_exc_fx ); /*Q(29-q1) */
114 0 : L_tmp = L_mult( ener_hf_fx, scale_fx ); /*30-q1+q2 */
115 0 : q2 = sub( q1, q2 ); /*30-q2 */
116 : #ifdef ISSUE_1867_replace_overflow_libenc
117 0 : scale_fx = round_fx( Isqrt( L_shl_sat( L_tmp, sub( q2, 26 ) ) ) ); /*Q13 */
118 : #else
119 : scale_fx = round_fx( Isqrt( L_shl_o( L_tmp, sub( q2, 26 ), &Overflow ) ) ); /*Q13 */
120 : #endif
121 :
122 :
123 0 : pt1 = HF_fx;
124 0 : FOR( i = 0; i < L_SUBFR16k; i++ )
125 : {
126 0 : *pt1 = round_fx( L_shl( L_mult( ( *pt1 ), scale_fx ), 5 ) ); /*Q0 */
127 0 : pt1++;
128 : }
129 :
130 : /*-----------------------------------------------------------------*
131 : * calculate energy scaling factor to respect tilt of synth12k8
132 : * (tilt: 1=voiced, -1=unvoiced)
133 : *-----------------------------------------------------------------*/
134 :
135 0 : hp400_12k8_fx( synth_fx, L_SUBFR, mem_hp400_enc_fx ); /*synth_fx: Q(Q_syn-4) */
136 :
137 0 : ener_fx = dot_prod_satcontr( &synth_fx[1], &synth_fx[1], sub( Q_syn, 4 ), sub( Q_syn, 4 ), &q1, sub( L_SUBFR, 1 ) );
138 0 : tmp_fx = dot_prod_satcontr( &synth_fx[1], synth_fx, sub( Q_syn, 4 ), sub( Q_syn, 4 ), &q2, sub( L_SUBFR, 1 ) );
139 :
140 0 : IF( GE_16( abs_s( tmp_fx ), ener_fx ) )
141 : {
142 0 : tmp_fx = shr( tmp_fx, 1 );
143 0 : q2 = sub( q2, 1 );
144 : }
145 :
146 0 : sign = 0;
147 0 : move16();
148 0 : IF( tmp_fx < 0 )
149 : {
150 0 : tmp_fx = abs_s( tmp_fx );
151 0 : sign = 1;
152 0 : move16();
153 : }
154 :
155 0 : fac_fx = div_s( tmp_fx, ener_fx ); /*Q(15+q2-q1) */
156 0 : shift = sub( q1, add( q2, 5 ) );
157 0 : fac_fx = shl( fac_fx, shift ); /*Q10 */
158 0 : IF( sign )
159 : {
160 0 : fac_fx = s_xor( fac_fx, -1 );
161 : }
162 :
163 0 : HF_est_gain_fx = sub( 1024, fac_fx ); /*Q12 */
164 :
165 0 : test();
166 0 : IF( EQ_32( core_brate_fx, SID_1k75 ) || core_brate_fx == FRAME_NO_DATA )
167 : {
168 0 : HF_est_gain_fx = round_fx( L_shl( L_mult( HF_est_gain_fx, 20480 ), 1 ) ); /*Q10 */
169 : }
170 :
171 0 : HF_est_gain_fx = s_max( HF_est_gain_fx, 102 );
172 0 : HF_est_gain_fx = s_min( HF_est_gain_fx, 1024 );
173 :
174 : /*-----------------------------------------------------------------*
175 : * synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz
176 : *-----------------------------------------------------------------*/
177 :
178 0 : weight_a_lc_fx( Aq_fx, Ap_fx, Gamma_19661_Tbl_fx, M );
179 0 : Syn_filt_s( 0, Ap_fx, M, HF_fx, HF_syn_fx, L_SUBFR16k, mem_syn_hf_enc_fx, 1 ); /*Q0 */
180 :
181 : /*-----------------------------------------------------------------*
182 : * high pass filtering (0.9375ms of delay = 15 samples@16k)
183 : *-----------------------------------------------------------------*/
184 :
185 0 : fir_fx( HF_syn_fx, fir_6k_8k_fx, HF_syn_fx, mem_hf1_enc_fx, L_SUBFR16k, L_FIR - 1, 1, 0 );
186 0 : fir_fx( HF_SP_fx, fir_6k_8k_fx, HF_SP_fx, mem_hf2_enc_fx, L_SUBFR16k, L_FIR - 1, 1, 0 );
187 :
188 : /* check the gain difference */
189 :
190 0 : ener_hf_fx = dot_prod_satcontr( HF_syn_fx, HF_syn_fx, 0, 0, &q2, L_SUBFR16k );
191 0 : ener_input_fx = dot_prod_satcontr( HF_SP_fx, HF_SP_fx, 0, 0, &q1, L_SUBFR16k );
192 :
193 0 : HF_calc_gain_fx = div_s( shl( 1, 14 ), ener_input_fx ); /*Q(29-q1) */
194 0 : L_tmp = L_mult( ener_hf_fx, HF_calc_gain_fx ); /*30-q1+q2 */
195 0 : q2 = sub( q1, q2 ); /*30-q2 */
196 : #ifdef ISSUE_1867_replace_overflow_libenc
197 0 : HF_calc_gain_fx = round_fx_sat( Isqrt( L_shl_sat( L_tmp, sub( q2, 20 ) ) ) ); /*Q10 */
198 : #else
199 : HF_calc_gain_fx = round_fx_o( Isqrt( L_shl_sat( L_tmp, sub( q2, 20 ) ) ), &Overflow ); /*Q10 */
200 : #endif
201 :
202 :
203 : /* set energy of HF synthesis to energy of original HF:
204 : cross-fade between HF levels in active and inactive frame in hangover period */
205 :
206 0 : IF( GT_16( 4, dtxHangoverCount_fx ) )
207 : {
208 0 : *gain_alpha_fx = 16384;
209 0 : move16();
210 : }
211 : ELSE
212 : {
213 0 : L_tmp = L_shl( L_mult( sub( 10, dtxHangoverCount_fx ), 4681 ), 15 ); /*Q31 */
214 0 : L_tmp = Mult_32_16( L_tmp, *gain_alpha_fx ); /*Q30 */
215 0 : *gain_alpha_fx = round_fx( L_tmp ); /*Q14 */
216 : }
217 0 : L_tmp = L_mult( sub( 16384, *gain_alpha_fx ), HF_est_gain_fx ); /*Q25 */
218 0 : L_tmp = L_mac( L_tmp, *gain_alpha_fx, HF_calc_gain_fx ); /*Q25 */
219 0 : IF( GE_32( L_tmp, 67108863 ) )
220 : {
221 0 : L_tmp = 67108863;
222 0 : move32();
223 : }
224 0 : L_tmp = L_shl( L_tmp, 5 );
225 0 : HF_corr_gain_fx = extract_h( L_tmp ); /*Q14; HF_corr_gain_fx/2 in Q15 */
226 :
227 : /* Quantize the correction gain */
228 0 : dist_min_fx = 2147483647;
229 0 : move32();
230 0 : HF_gain_ind_fx = 0;
231 0 : move16();
232 0 : pt2 = HP_gain_fx;
233 0 : FOR( i = 0; i < 16; i++ )
234 : {
235 0 : dist_fx = L_mult( sub( HF_corr_gain_fx, *pt2 ), sub( HF_corr_gain_fx, *pt2 ) );
236 0 : pt2++;
237 0 : IF( GT_32( dist_min_fx, dist_fx ) )
238 : {
239 0 : dist_min_fx = L_add( dist_fx, 0 );
240 0 : HF_gain_ind_fx = i;
241 0 : move16();
242 : }
243 : }
244 0 : *hf_gain_fx = HF_gain_ind_fx;
245 0 : move16();
246 :
247 0 : return;
248 : }
|