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 5 : 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 5 : set16_fx( mem_hp400_enc, 0, 6 );
30 5 : set16_fx( mem_hf1_enc, 0, L_FIR - 1 );
31 5 : set16_fx( mem_syn_hf_enc, 0, M );
32 5 : set16_fx( mem_hf2_enc, 0, L_FIR - 1 );
33 :
34 5 : *gain_alpha_fx = 16384;
35 5 : move16();
36 :
37 5 : 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 :
91 : /* Original speech signal as reference for high band gain quantisation */
92 0 : Copy( speech16k_fx, HF_SP_fx, L_SUBFR16k );
93 :
94 : /*-----------------------------------------------------------------*
95 : * generate white noise vector
96 : *-----------------------------------------------------------------*/
97 :
98 0 : Random_Fill( seed2_enc_fx, L_SUBFR16k, HF_fx, 3 ); /*Q(-3) */
99 :
100 : /*-----------------------------------------------------------------*
101 : * calculate energy scaling factor so that white noise would have the
102 : * same energy as exc12k8
103 : *-----------------------------------------------------------------*/
104 :
105 0 : ener_exc_fx = dot_prod_satcontr( exc_fx, exc_fx, Q_exc, Q_exc, &q1, L_SUBFR );
106 0 : ener_hf_fx = dot_prod_satcontr( HF_fx, HF_fx, -3, -3, &q2, L_SUBFR16k );
107 :
108 0 : scale_fx = div_s( shl( 1, 14 ), ener_exc_fx ); /*Q(29-q1) */
109 0 : L_tmp = L_mult( ener_hf_fx, scale_fx ); /*30-q1+q2 */
110 0 : q2 = sub( q1, q2 ); /*30-q2 */
111 0 : scale_fx = round_fx( Isqrt( L_shl_sat( L_tmp, sub( q2, 26 ) ) ) ); /*Q13 */
112 :
113 0 : pt1 = HF_fx;
114 0 : FOR( i = 0; i < L_SUBFR16k; i++ )
115 : {
116 0 : *pt1 = round_fx( L_shl( L_mult( ( *pt1 ), scale_fx ), 5 ) ); /*Q0 */
117 0 : pt1++;
118 : }
119 :
120 : /*-----------------------------------------------------------------*
121 : * calculate energy scaling factor to respect tilt of synth12k8
122 : * (tilt: 1=voiced, -1=unvoiced)
123 : *-----------------------------------------------------------------*/
124 :
125 0 : hp400_12k8_fx( synth_fx, L_SUBFR, mem_hp400_enc_fx ); /*synth_fx: Q(Q_syn-4) */
126 :
127 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 ) );
128 0 : tmp_fx = dot_prod_satcontr( &synth_fx[1], synth_fx, sub( Q_syn, 4 ), sub( Q_syn, 4 ), &q2, sub( L_SUBFR, 1 ) );
129 :
130 0 : IF( GE_16( abs_s( tmp_fx ), ener_fx ) )
131 : {
132 0 : tmp_fx = shr( tmp_fx, 1 );
133 0 : q2 = sub( q2, 1 );
134 : }
135 :
136 0 : sign = 0;
137 0 : move16();
138 0 : IF( tmp_fx < 0 )
139 : {
140 0 : tmp_fx = abs_s( tmp_fx );
141 0 : sign = 1;
142 0 : move16();
143 : }
144 :
145 0 : fac_fx = div_s( tmp_fx, ener_fx ); /*Q(15+q2-q1) */
146 0 : shift = sub( q1, add( q2, 5 ) );
147 0 : fac_fx = shl( fac_fx, shift ); /*Q10 */
148 0 : IF( sign )
149 : {
150 0 : fac_fx = s_xor( fac_fx, -1 );
151 : }
152 :
153 0 : HF_est_gain_fx = sub( 1024, fac_fx ); /*Q12 */
154 :
155 0 : test();
156 0 : IF( EQ_32( core_brate_fx, SID_1k75 ) || core_brate_fx == FRAME_NO_DATA )
157 : {
158 0 : HF_est_gain_fx = round_fx( L_shl( L_mult( HF_est_gain_fx, 20480 ), 1 ) ); /*Q10 */
159 : }
160 :
161 0 : HF_est_gain_fx = s_max( HF_est_gain_fx, 102 );
162 0 : HF_est_gain_fx = s_min( HF_est_gain_fx, 1024 );
163 :
164 : /*-----------------------------------------------------------------*
165 : * synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz
166 : *-----------------------------------------------------------------*/
167 :
168 0 : weight_a_lc_fx( Aq_fx, Ap_fx, Gamma_19661_Tbl_fx, M );
169 0 : Syn_filt_s( 0, Ap_fx, M, HF_fx, HF_syn_fx, L_SUBFR16k, mem_syn_hf_enc_fx, 1 ); /*Q0 */
170 :
171 : /*-----------------------------------------------------------------*
172 : * high pass filtering (0.9375ms of delay = 15 samples@16k)
173 : *-----------------------------------------------------------------*/
174 :
175 0 : fir_fx( HF_syn_fx, fir_6k_8k_fx, HF_syn_fx, mem_hf1_enc_fx, L_SUBFR16k, L_FIR - 1, 1, 0 );
176 0 : fir_fx( HF_SP_fx, fir_6k_8k_fx, HF_SP_fx, mem_hf2_enc_fx, L_SUBFR16k, L_FIR - 1, 1, 0 );
177 :
178 : /* check the gain difference */
179 :
180 0 : ener_hf_fx = dot_prod_satcontr( HF_syn_fx, HF_syn_fx, 0, 0, &q2, L_SUBFR16k );
181 0 : ener_input_fx = dot_prod_satcontr( HF_SP_fx, HF_SP_fx, 0, 0, &q1, L_SUBFR16k );
182 :
183 0 : HF_calc_gain_fx = div_s( shl( 1, 14 ), ener_input_fx ); /*Q(29-q1) */
184 0 : L_tmp = L_mult( ener_hf_fx, HF_calc_gain_fx ); /*30-q1+q2 */
185 0 : q2 = sub( q1, q2 ); /*30-q2 */
186 0 : HF_calc_gain_fx = round_fx_sat( Isqrt( L_shl_sat( L_tmp, sub( q2, 20 ) ) ) ); /*Q10 */
187 :
188 : /* set energy of HF synthesis to energy of original HF:
189 : cross-fade between HF levels in active and inactive frame in hangover period */
190 :
191 0 : IF( GT_16( 4, dtxHangoverCount_fx ) )
192 : {
193 0 : *gain_alpha_fx = 16384;
194 0 : move16();
195 : }
196 : ELSE
197 : {
198 0 : L_tmp = L_shl( L_mult( sub( 10, dtxHangoverCount_fx ), 4681 ), 15 ); /*Q31 */
199 0 : L_tmp = Mult_32_16( L_tmp, *gain_alpha_fx ); /*Q30 */
200 0 : *gain_alpha_fx = round_fx( L_tmp ); /*Q14 */
201 : }
202 0 : L_tmp = L_mult( sub( 16384, *gain_alpha_fx ), HF_est_gain_fx ); /*Q25 */
203 0 : L_tmp = L_mac( L_tmp, *gain_alpha_fx, HF_calc_gain_fx ); /*Q25 */
204 0 : IF( GE_32( L_tmp, 67108863 ) )
205 : {
206 0 : L_tmp = 67108863;
207 0 : move32();
208 : }
209 0 : L_tmp = L_shl( L_tmp, 5 );
210 0 : HF_corr_gain_fx = extract_h( L_tmp ); /*Q14; HF_corr_gain_fx/2 in Q15 */
211 :
212 : /* Quantize the correction gain */
213 0 : dist_min_fx = 2147483647;
214 0 : move32();
215 0 : HF_gain_ind_fx = 0;
216 0 : move16();
217 0 : pt2 = HP_gain_fx;
218 0 : FOR( i = 0; i < 16; i++ )
219 : {
220 0 : dist_fx = L_mult( sub( HF_corr_gain_fx, *pt2 ), sub( HF_corr_gain_fx, *pt2 ) );
221 0 : pt2++;
222 0 : IF( GT_32( dist_min_fx, dist_fx ) )
223 : {
224 0 : dist_min_fx = L_add( dist_fx, 0 );
225 0 : HF_gain_ind_fx = i;
226 0 : move16();
227 : }
228 : }
229 0 : *hf_gain_fx = HF_gain_ind_fx;
230 0 : move16();
231 :
232 0 : return;
233 : }
|