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.h" /* Static table prototypes */
9 : #include "basop32.h"
10 :
11 : /*---------------------------------------------------------------------*
12 : * Local constants
13 : *---------------------------------------------------------------------*/
14 :
15 : #define L_SUBFR48k 240
16 : #define L_SUBFR32k 160
17 :
18 : /*---------------------------------------------------------------------*
19 : * Local function prototypes
20 : *---------------------------------------------------------------------*/
21 :
22 : static void filt_6k_7k_scale_fx( Word16 signal[], Word16 lg, Word16 mem[], Word16 fact, Word16 exp );
23 : static void hf_synthesis_fx( ZERO_BWE_DEC_HANDLE hBWE_zero, const Word32 core_brate, const Word16 output_subfr, const Word16 Aq[], const Word16 exc[], const Word16 Q_exc, Word16 synth[], Word16 synth16k[], const Word16 Q_syn );
24 : static void hf_synthesis_ivas_fx( ZERO_BWE_DEC_HANDLE hBWE_zero, const Word32 core_brate, const Word16 output_subfr, const Word16 Aq[], const Word16 exc[], const Word16 Q_exc, Word16 synth[], Word16 synth16k[], const Word16 Q_syn );
25 : static void hf_synthesis_amr_wb_fx( const Word32 core_brate, const Word16 output_subfr, const Word16 Ap[], Word16 exc16k[], Word16 synth_out[], Word16 *mem_syn_hf, Word16 *delay_syn_hf, Word16 *mem_hp_interp, Word16 p_r, Word16 HF_corr_gain, Word16 til, Word16 voice_factors, const Word16 exc[], const Word16 Q_exc, const Word16 Q_out, Word16 qhf );
26 : static void envelope_fx( AMRWB_IO_DEC_HANDLE hAmrwb_IO, const Word32 core_brate, const Word16 Aq[], Word16 Ap[], Word16 *r, Word16 tilt0, Word16 tilt, Word16 voice_factor );
27 : static void AdaptiveStartBand_fx( Word16 *start_band, const Word32 rate, const Word16 *lsf, const Word16 voicing_fac, const Word16 clas, Word16 *voicing_flag, Word16 *start_band_old, Word32 *OptCrit_old );
28 :
29 :
30 : /*-------------------------------------------------------------------*
31 : * hf_synth_init()
32 : *
33 : * hf synthesis filters initialization
34 : * - initialization of 400 Hz high pass filter
35 : * - initialization of band pass 6kHz to 7kHz FIR filter
36 : *-------------------------------------------------------------------*/
37 :
38 3444 : void hf_synth_init_fx(
39 : ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */
40 : )
41 : {
42 3444 : hBWE_zero->seed2 = RANDOM_INITSEED;
43 3444 : move16();
44 3444 : set16_fx( hBWE_zero->mem_hf_fx, 0, ( L_FIR - 1 ) );
45 3444 : set16_fx( hBWE_zero->mem_syn_hf_fx, 0, M );
46 3444 : set16_fx( hBWE_zero->mem_hp400_fx, 0, 4 );
47 3444 : set16_fx( hBWE_zero->delay_syn_hf_fx, 0, NS2SA( 16000, DELAY_CLDFB_NS ) );
48 3444 : set16_fx( hBWE_zero->mem_hp_interp_fx, 0, INTERP_3_1_MEM_LEN );
49 3444 : hBWE_zero->memExp1 = 0;
50 3444 : move16();
51 3444 : return;
52 : }
53 357487 : void hf_synth_reset_fx(
54 : ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */
55 : )
56 : {
57 : Word16 i;
58 :
59 114753327 : FOR( i = 0; i < L_FRAME16k; i++ )
60 : {
61 114395840 : Random( &hBWE_zero->seed2 );
62 : }
63 :
64 357487 : set16_fx( hBWE_zero->mem_hf_fx, 0, ( L_FIR - 1 ) );
65 357487 : set16_fx( hBWE_zero->mem_syn_hf_fx, 0, M );
66 357487 : set16_fx( hBWE_zero->mem_hp400_fx, 0, 4 );
67 :
68 357487 : set16_fx( hBWE_zero->delay_syn_hf_fx, 0, NS2SA( 16000, DELAY_CLDFB_NS ) );
69 357487 : set16_fx( hBWE_zero->mem_hp_interp_fx, 0, INTERP_3_1_MEM_LEN );
70 357487 : hBWE_zero->memExp1 = 0;
71 357487 : move16();
72 357487 : return;
73 : }
74 :
75 : /*---------------------------------------------------------------------*
76 : * hf_synth()
77 : *
78 : * High frequency regeneration
79 : *---------------------------------------------------------------------*/
80 :
81 0 : void hf_synth_fx(
82 : ZERO_BWE_DEC_HANDLE hBWE_zero, /* i/o: handle to 0 bit BWE parameters */
83 : const Word32 core_brate, /* i : core bitrate Q0*/
84 : const Word16 output_frame, /* i : output frame length Q0*/
85 : const Word16 *Aq, /* i : quantized Az Q12*/
86 : const Word16 *exc, /* i : excitation at 12.8 kHz Q_exc*/
87 : Word16 *synth, /* i : 12.8kHz synthesis signal Q_syn2*/
88 : Word16 *synth16k, /* o : 16kHz synthesis signal Q_syn2*/
89 : const Word16 Q_exc, /* i : excitation scaling */
90 : const Word16 Q_syn2 /* i : synthesis scaling */
91 : )
92 : {
93 : const Word16 *p_Aq;
94 : Word16 i_subfr, output_subfr;
95 :
96 0 : output_subfr = output_frame / NB_SUBFR;
97 0 : move16();
98 :
99 0 : p_Aq = Aq; /* Q12 */
100 0 : FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
101 : {
102 0 : hf_synthesis_fx( hBWE_zero, core_brate, output_subfr, p_Aq, &exc[i_subfr], Q_exc, &synth[i_subfr], &synth16k[imult3216( (Word32) i_subfr, output_subfr ) / L_SUBFR], Q_syn2 );
103 :
104 0 : p_Aq += ( M + 1 ); /* Q12 */
105 : }
106 :
107 0 : return;
108 : }
109 :
110 : /*-----------------------------------------------------------------------------------*
111 : * hf_synthesis()
112 : *
113 : * HF noise synthesis
114 : * - Generate HF noise between 6 and 7 kHz.
115 : * - Set energy of noise according to synthesis tilt.
116 : * tilt > 0.8 ==> - 14 dB (voiced)
117 : * tilt 0.5 ==> - 6 dB (voiced or noise)
118 : * tilt < 0.0 ==> 0 dB (noise)
119 : *-----------------------------------------------------------------------------------*/
120 :
121 0 : static void hf_synthesis_fx(
122 : ZERO_BWE_DEC_HANDLE hBWE_zero,
123 : const Word32 core_brate, /* i : core bitrate Q0*/
124 : const Word16 output_subfr, /* i : output sub-frame length Q0*/
125 : const Word16 Aq[], /* i : quantized Az Q12*/
126 : const Word16 exc[], /* i : excitation at 12.8 kHz Q_exc*/
127 : const Word16 Q_exc, /* i : excitation scaling */
128 : Word16 synth[], /* i : 12.8kHz synthesis signal Q_syn*/
129 : Word16 synth16k[], /* i/o: 16kHz synthesis signal Q_syn*/
130 : const Word16 Q_syn /* i : synthesis scaling */
131 : )
132 : {
133 : Word16 i, s;
134 : Word16 HF_syn[L_SUBFR16k], upsampled_HF_syn[L_FRAME48k / NB_SUBFR];
135 : Word16 HF_exc[L_SUBFR16k];
136 : Word16 tmp, ener, exp1, exp2, scale;
137 : Word32 L_tmp;
138 : Word16 Ap[M16k + 1];
139 : #ifndef ISSUE_1866_replace_overflow_libdec
140 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
141 : Flag Overflow = 0;
142 : move32();
143 : #endif
144 : #endif
145 :
146 : /*-----------------------------------------------------------------*
147 : * generate white noise vector
148 : *-----------------------------------------------------------------*/
149 :
150 0 : Random_Fill( &hBWE_zero->seed2, L_SUBFR16k, HF_exc, 3 ); /* 3 = Shift Right by 3 */
151 :
152 : /* o: HF_exc in Q-3 */
153 :
154 : /*-----------------------------------------------------------------*
155 : * calculate energy scaling factor so that white noise would have the
156 : * same energy as exc12k8
157 : *-----------------------------------------------------------------*/
158 :
159 : /*ener = sum2_f( exc, L_SUBFR ) + 0.01f*/
160 0 : ener = extract_h( Dot_product12( exc, exc, L_SUBFR, &exp2 ) ); /* Q15 */
161 0 : exp2 = sub( exp2, add( Q_exc, Q_exc ) );
162 :
163 : /*tmp = round_fx(Dot_product12(HF_exc, HF_exc, output_subfr, &exp1)); */
164 0 : L_tmp = Dot_product12( HF_exc, HF_exc, L_SUBFR16k, &exp1 );
165 0 : tmp = round_fx( L_tmp ); /* Q15 */
166 : /* tmp = (float)(sqrt(ener/tmp)) */
167 : /* scale is -1 if tmp > ener */
168 0 : scale = shr( sub( ener, tmp ), 15 ); /* Q0 */
169 0 : tmp = shl( tmp, scale ); /* Q15 + scale*/
170 0 : exp1 = sub( exp1, scale );
171 :
172 0 : tmp = div_s( tmp, ener ); /* Q15 */
173 0 : exp1 = sub( exp1, exp2 );
174 :
175 0 : L_tmp = L_deposit_h( tmp ); /* Q31 */
176 :
177 0 : L_tmp = Isqrt_lc( L_tmp, &exp1 );
178 0 : scale = round_fx( L_tmp ); /* Q18 when Q_exc=-1, HF_exc in Q-3 */
179 :
180 0 : exp2 = sub( hBWE_zero->memExp1, exp1 );
181 0 : hBWE_zero->memExp1 = exp1;
182 0 : move16();
183 :
184 : /*-----------------------------------------------------------------*
185 : * calculate energy scaling factor to respect tilt of synth12k8
186 : * (tilt: 1=voiced, -1=unvoiced)
187 : *-----------------------------------------------------------------*/
188 0 : hp400_12k8_fx( synth, L_SUBFR, hBWE_zero->mem_hp400_fx );
189 : /* i: mem_hp400 in Q_syn */
190 : /* i: synth in Q_syn */
191 : /* o: synth in Q_syn-3 */
192 :
193 0 : L_tmp = L_mac( 1L, synth[0], synth[0] ); /* 2*(Q_syn-3)+1 */
194 0 : FOR( i = 1; i < L_SUBFR; i++ )
195 : {
196 0 : L_tmp = L_mac_sat( L_tmp, synth[i], synth[i] ); /* 2*(Q_syn-3)+1 */
197 : }
198 0 : tmp = norm_l( L_tmp );
199 0 : ener = extract_h( L_shl( L_tmp, tmp ) ); /* ener = r[0] */
200 : /*ener in Q = 2*(Q_syn-3)+1 = Q-5 when Q_syn=0*/
201 :
202 0 : L_tmp = L_mac( 1L, synth[1], synth[0] ); /* 2*(Q_syn-3)+1 */
203 0 : FOR( i = 2; i < L_SUBFR; i++ )
204 : {
205 0 : L_tmp = L_mac_sat( L_tmp, synth[i], synth[i - 1] ); /* 2*(Q_syn-3)+1 */
206 : }
207 0 : tmp = extract_h( L_shl( L_tmp, tmp ) ); /* tmp = r[1] */
208 : /*tmp in Q = 2*(Q_syn-3)+1 = Q-5 when Q_syn=0 */
209 : /*we use the same normalization factor for both ener and tmp, */
210 : /*if the headroom in "tmp" is less than "ener", tmp can saturate */
211 : /*but this is ok since below we apply some thresholds to tmp */
212 :
213 0 : tmp = s_max( 0, tmp );
214 0 : if ( tmp > 0 )
215 : {
216 0 : tmp = div_s( tmp, ener ); /* Q15 */
217 : }
218 :
219 : /*-----------------------------------------------------------------*
220 : * modify energy of white noise according to synthesis tilt
221 : *-----------------------------------------------------------------*/
222 : /* tmp = 1.0 - fac */
223 : #ifdef ISSUE_1866_replace_overflow_libdec
224 0 : tmp = add_sat( 1, sub( 32767 /* 1 in Q15 */, tmp ) );
225 : #else
226 : tmp = add_o( 1, sub( 32767 /* 1 in Q15 */, tmp ), &Overflow );
227 : #endif
228 0 : test();
229 0 : if ( core_brate == FRAME_NO_DATA || EQ_32( core_brate, SID_2k40 ) )
230 : {
231 : /* emphasize HF noise in CNG */
232 : /*fac *= 2.0f;*/
233 : #ifdef ISSUE_1866_replace_overflow_libdec
234 0 : tmp = add_sat( tmp, tmp ); /* Q15 */
235 : #else
236 : tmp = add_o( tmp, tmp, &Overflow ); /* Q15 */
237 : #endif
238 : }
239 0 : tmp = s_max( tmp, 3277 ); /* 0.1 in Q15 */
240 :
241 : /*scale *= fac;*/
242 0 : tmp = mult_r( scale, tmp );
243 : /*-----------------------------------------------------------------*
244 : * modify HF excitation according to both calculated scaling factors
245 : * high pass filtering (0.94ms of delay)
246 : *-----------------------------------------------------------------*/
247 :
248 0 : filt_6k_7k_scale_fx( HF_exc, L_SUBFR16k, hBWE_zero->mem_hf_fx, tmp, exp2 );
249 : /* i: input HF_exc is scaled in float, here scaling is done inside this filter */
250 : /* i: mem_hf in Q-2 */
251 : /* o: HF_exc in Q0 */
252 :
253 : /*-----------------------------------------------------------------*
254 : * synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz
255 : *-----------------------------------------------------------------*/
256 :
257 : /*weight_a( Aq, Ap, 0.6f, M );*/
258 0 : weight_a_lc_fx( Aq, Ap, Gamma_19661_Tbl_fx, M );
259 : /* o: Ap in Q14 */
260 :
261 0 : Syn_filt_s( 0, Ap, M, HF_exc, HF_syn, L_SUBFR16k, hBWE_zero->mem_syn_hf_fx, 1 );
262 : /* i: Ap in Q14 */
263 : /* i: HF_exc in Q0 */
264 : /* o: HF_syn in Q0 */
265 : /* i/o: mem_syn_hf in Q0 */
266 :
267 0 : Scale_sig( HF_syn, L_SUBFR16k, ( add( Q_syn, exp1 ) ) ); /* bring HF_syn to (Q_syn+exp1) */
268 :
269 : /*-----------------------------------------------------------------*
270 : * add filtered HF noise to speech synthesis
271 : *-----------------------------------------------------------------*/
272 :
273 : /* delay by 5 samples @16kHz to compensate CLDFB resampling delay (20samples) and HP filtering delay (roughly 15 samples) */
274 0 : delay_signal_fx( HF_syn, L_SUBFR16k, hBWE_zero->delay_syn_hf_fx, NS2SA_FX2( 16000, DELAY_CLDFB_NS ) - 15 );
275 :
276 : /* interpolate the HF synthesis */
277 0 : IF( EQ_16( output_subfr, L_SUBFR48k ) ) /* 48kHz sampled output */
278 : {
279 0 : s = s_max( s_min( sub( s_min( Find_Max_Norm16( HF_syn, L_SUBFR16k ), Find_Max_Norm16( hBWE_zero->mem_hp_interp_fx, INTERP_3_1_MEM_LEN - 3 ) ), 3 ),
280 0 : sub( Find_Max_Norm16( hBWE_zero->mem_hp_interp_fx + INTERP_3_1_MEM_LEN - 3, 3 ), 1 ) ),
281 : 0 );
282 0 : Scale_sig( HF_syn, L_SUBFR16k, s ); /* Q_syn+exp1+s */
283 0 : Scale_sig( hBWE_zero->mem_hp_interp_fx, INTERP_3_1_MEM_LEN, s ); /* Qx + s */
284 0 : interpolate_3_over_1_allpass_fx( HF_syn, L_SUBFR16k, upsampled_HF_syn, hBWE_zero->mem_hp_interp_fx );
285 0 : Scale_sig( upsampled_HF_syn, 3 * L_SUBFR16k, -s ); /* Q_syn + exp1 + s */
286 0 : Scale_sig( hBWE_zero->mem_hp_interp_fx, INTERP_3_1_MEM_LEN, -s ); /* Qx */
287 0 : Scale_sig( HF_syn, L_SUBFR16k, -s ); /* Q_syn+exp1 */
288 0 : Scale_sig( upsampled_HF_syn, L_SUBFR48k, -1 );
289 : }
290 0 : ELSE IF( EQ_16( output_subfr, L_SUBFR32k ) ) /* 32kHz sampled output */
291 : {
292 0 : s = s_max( sub( s_min( Find_Max_Norm16( HF_syn, L_SUBFR16k ), Find_Max_Norm16( hBWE_zero->mem_hp_interp_fx, 2 * ALLPASSSECTIONS_STEEP ) ), 2 ), 0 );
293 0 : Scale_sig( HF_syn, L_SUBFR16k, s ); /* Q_syn+exp1+s */
294 0 : Scale_sig( hBWE_zero->mem_hp_interp_fx, 2 * ALLPASSSECTIONS_STEEP, s ); /* Qx + s */
295 0 : Interpolate_allpass_steep_fx( HF_syn, hBWE_zero->mem_hp_interp_fx, L_SUBFR16k, upsampled_HF_syn );
296 0 : Scale_sig( upsampled_HF_syn, 2 * L_SUBFR16k, -s ); /* Q_syn + exp1 */
297 0 : Scale_sig( hBWE_zero->mem_hp_interp_fx, 2 * ALLPASSSECTIONS_STEEP, -s ); /* Qx */
298 0 : Scale_sig( HF_syn, L_SUBFR16k, -s ); /* Q_syn+exp1 */
299 : }
300 : ELSE /* 16kHz sampled output */
301 : {
302 0 : Copy( HF_syn, upsampled_HF_syn, L_SUBFR16k ); /* Q_syn */
303 : }
304 0 : Vr_add( synth16k, upsampled_HF_syn, synth16k, output_subfr );
305 :
306 0 : return;
307 : }
308 :
309 14889 : void hf_synth_ivas_fx(
310 : ZERO_BWE_DEC_HANDLE hBWE_zero, /* i/o: handle to 0 bit BWE parameters */
311 : const Word32 core_brate, /* i : core bitrate Q0*/
312 : const Word16 output_frame, /* i : output frame length Q0*/
313 : const Word16 *Aq, /* i : quantized Az Q12*/
314 : const Word16 *exc, /* i : excitation at 12.8 kHz Q_exc*/
315 : Word16 *synth, /* i : 12.8kHz synthesis signal Q_syn2*/
316 : Word16 *synth16k, /* o : 16kHz synthesis signal Q_syn2*/
317 : const Word16 Q_exc, /* i : excitation scaling */
318 : const Word16 Q_syn2 /* i : synthesis scaling */
319 : )
320 : {
321 : const Word16 *p_Aq;
322 : Word16 i_subfr, output_subfr;
323 :
324 14889 : output_subfr = shr( output_frame, 2 );
325 :
326 14889 : p_Aq = Aq; /* Q12 */
327 74445 : FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
328 : {
329 59556 : hf_synthesis_ivas_fx( hBWE_zero, core_brate, output_subfr, p_Aq, &exc[i_subfr], Q_exc, &synth[i_subfr], &synth16k[i_subfr * output_subfr / L_SUBFR], Q_syn2 );
330 :
331 59556 : p_Aq += ( M + 1 ); /* Q12 */
332 : }
333 :
334 14889 : return;
335 : }
336 :
337 59556 : static void hf_synthesis_ivas_fx(
338 : ZERO_BWE_DEC_HANDLE hBWE_zero,
339 : const Word32 core_brate, /* i : core bitrate Q0*/
340 : const Word16 output_subfr, /* i : output sub-frame length Q0*/
341 : const Word16 Aq[], /* i : quantized Az Q12*/
342 : const Word16 exc[], /* i : excitation at 12.8 kHz Q_exc*/
343 : const Word16 Q_exc, /* i : excitation scaling */
344 : Word16 synth[], /* i : 12.8kHz synthesis signal Q_syn*/
345 : Word16 synth16k[], /* i/o: 16kHz synthesis signal Q_syn*/
346 : const Word16 Q_syn /* i : synthesis scaling */
347 : )
348 : {
349 : Word16 i, s;
350 : Word16 HF_syn[L_SUBFR16k], upsampled_HF_syn[L_FRAME48k / NB_SUBFR];
351 : Word16 HF_exc[L_SUBFR16k];
352 : Word16 exp1, exp2, scale, tmp, ener, Q_tmp, Q_ener, sft;
353 : Word32 L_tmp, ONE, P_ONE;
354 : Word16 Ap[M16k + 1];
355 : Word64 prod;
356 :
357 : /*-----------------------------------------------------------------*
358 : * generate white noise vector
359 : *-----------------------------------------------------------------*/
360 :
361 59556 : Random_Fill( &hBWE_zero->seed2, L_SUBFR16k, HF_exc, 3 ); /* 3 = Shift Right by 3 */
362 :
363 : /* o: HF_exc in Q(-3) */
364 :
365 : /*-----------------------------------------------------------------*
366 : * calculate energy scaling factor so that white noise would have the
367 : * same energy as exc12k8
368 : *-----------------------------------------------------------------*/
369 :
370 : /*ener = sum2_f( exc, L_SUBFR ) + 0.01f*/
371 59556 : ener = extract_h( Dot_product12( exc, exc, L_SUBFR, &exp2 ) );
372 59556 : exp2 = sub( exp2, add( Q_exc, Q_exc ) ); // ener exponent
373 :
374 : /*tmp = round_fx(Dot_product12(HF_exc, HF_exc, output_subfr, &exp1)); */
375 59556 : L_tmp = Dot_product12( HF_exc, HF_exc, L_SUBFR16k, &exp1 );
376 59556 : tmp = round_fx( L_tmp );
377 59556 : exp1 = add( exp1, 6 ); /* tmp exponent */
378 :
379 59556 : ener = shr( ener, 1 ); /* to avoid the assertion in div_s() further*/
380 59556 : exp2 = add( exp2, 1 );
381 :
382 59556 : tmp = div_s( ener, tmp );
383 59556 : exp1 = sub( exp2, exp1 );
384 :
385 59556 : scale = Sqrt16( tmp, &exp1 ); /* scale exponent = exp1 */
386 :
387 : /*-----------------------------------------------------------------*
388 : * calculate energy scaling factor to respect tilt of synth12k8
389 : * (tilt: 1=voiced, -1=unvoiced)
390 : *-----------------------------------------------------------------*/
391 :
392 59556 : hp400_12k8_ivas_fx( synth, L_SUBFR, hBWE_zero->mem_hp400_fx );
393 :
394 : /* i: mem_hp400 in Q_syn */
395 : /* i: synth in Q_syn */
396 : /* o: synth in Q_syn-3 */
397 59556 : prod = W_mac0_16_16( 1L, synth[0], synth[0] ); /* 2*(Q_syn-3) */
398 3811584 : FOR( i = 1; i < L_SUBFR; i++ )
399 : {
400 3752028 : prod = W_mac0_16_16( prod, synth[i], synth[i] ); /* 2*(Q_syn-3) */
401 : }
402 59556 : sft = W_norm( prod );
403 59556 : ener = extract_h( W_extract_h( W_shl( prod, sft ) ) );
404 59556 : Q_ener = sub( add( shl( sub( Q_syn, 3 ), 1 ), sft ), 48 );
405 :
406 59556 : prod = W_mac0_16_16( 1L, synth[1], synth[0] ); /* 2*(Q_syn-3) */
407 3752028 : FOR( i = 2; i < L_SUBFR; i++ )
408 : {
409 3692472 : prod = W_mac0_16_16( prod, synth[i], synth[i - 1] ); /* 2*(Q_syn-3) */
410 : }
411 59556 : sft = sub( W_norm( prod ), 1 );
412 59556 : tmp = extract_h( W_extract_h( W_shl( prod, sft ) ) );
413 59556 : Q_tmp = sub( add( shl( sub( Q_syn, 3 ), 1 ), sft ), 48 );
414 :
415 59556 : tmp = s_max( 0, tmp );
416 59556 : IF( tmp > 0 )
417 : {
418 59514 : tmp = div_s( tmp, ener );
419 59514 : Q_tmp = add( 15, sub( Q_tmp, Q_ener ) );
420 : }
421 :
422 : /*-----------------------------------------------------------------*
423 : * modify energy of white noise according to synthesis tilt
424 : *-----------------------------------------------------------------*/
425 : /* tmp = 1.0 - fac */
426 59556 : ONE = L_shl( 1, Q_tmp );
427 59556 : P_ONE = L_shl( 3277 /* 0.1 in Q15 */, sub( Q_tmp, 15 ) );
428 59556 : L_tmp = L_msu0( ONE, tmp, 1 );
429 59556 : test();
430 59556 : if ( core_brate == FRAME_NO_DATA || EQ_32( core_brate, SID_2k40 ) )
431 : {
432 : /* emphasize HF noise in CNG */
433 : /*fac *= 2.0f;*/
434 29360 : L_tmp = L_add( L_tmp, L_tmp );
435 : }
436 59556 : L_tmp = L_max( L_tmp, P_ONE );
437 59556 : L_tmp = L_min( L_tmp, ONE );
438 :
439 59556 : sft = norm_l( L_tmp );
440 59556 : L_tmp = L_shl( L_tmp, sft );
441 :
442 59556 : tmp = round_fx( L_tmp );
443 59556 : Q_tmp = sub( add( Q_tmp, sft ), 16 );
444 :
445 : /*scale *= fac;*/
446 59556 : tmp = mult_r( scale, tmp ); /* Q = (15 - exp1) + Q_tmp - 15 */
447 59556 : Q_tmp = sub( Q_tmp, exp1 );
448 : /*-----------------------------------------------------------------*
449 : * modify HF excitation according to both calculated scaling factors
450 : * high pass filtering (0.94ms of delay)
451 : *-----------------------------------------------------------------*/
452 :
453 59556 : exp2 = sub( hBWE_zero->memExp1, exp1 );
454 59556 : hBWE_zero->memExp1 = exp1;
455 59556 : move16();
456 :
457 59556 : filt_6k_7k_scale_fx( HF_exc, L_SUBFR16k, hBWE_zero->mem_hf_fx, tmp, exp2 );
458 : /* i: HF_exc in Q(-3) */
459 : /* o: HF_exc in ((-3) + Q_tmp - 17) */
460 : /* o: hBWE_zero->mem_hf_fx in Q(HF_exc)-2 */
461 :
462 : /*-----------------------------------------------------------------*
463 : * synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz
464 : *-----------------------------------------------------------------*/
465 :
466 : /*weight_a( Aq, Ap, 0.6f, M );*/
467 59556 : weight_a_lc_fx( Aq, Ap, Gamma_19661_Tbl_fx, M );
468 : /* o: Ap in Q14 */
469 :
470 59556 : Syn_filt_s( 0, Ap, M, HF_exc, HF_syn, L_SUBFR16k, hBWE_zero->mem_syn_hf_fx, 1 );
471 : /* o: HF_syn in same Q as HF_exc */
472 : /* o: mem_syn_hf_fx same Q as HF_syn */
473 :
474 59556 : Scale_sig( HF_syn, L_SUBFR16k, ( add( Q_syn, exp1 ) ) ); /* bring HF_syn to (Q_syn+exp1) */
475 :
476 : /*-----------------------------------------------------------------*
477 : * add filtered HF noise to speech synthesis
478 : *-----------------------------------------------------------------*/
479 :
480 : /* delay by 5 samples @16kHz to compensate CLDFB resampling delay (20samples) and HP filtering delay (roughly 15 samples) */
481 59556 : delay_signal_fx( HF_syn, L_SUBFR16k, hBWE_zero->delay_syn_hf_fx, NS2SA_FX2( 16000, DELAY_CLDFB_NS ) - 15 );
482 :
483 : /* interpolate the HF synthesis */
484 59556 : IF( EQ_16( output_subfr, L_SUBFR48k ) ) /* 48kHz sampled output */
485 : {
486 50004 : s = s_max( s_min( sub( s_min( Find_Max_Norm16( HF_syn, L_SUBFR16k ), Find_Max_Norm16( hBWE_zero->mem_hp_interp_fx, INTERP_3_1_MEM_LEN - 3 ) ), 3 ),
487 50004 : sub( Find_Max_Norm16( hBWE_zero->mem_hp_interp_fx + INTERP_3_1_MEM_LEN - 3, 3 ), 1 ) ),
488 : 0 );
489 50004 : Scale_sig( HF_syn, L_SUBFR16k, s ); /* Q_syn+exp1+s */
490 50004 : Scale_sig( hBWE_zero->mem_hp_interp_fx, INTERP_3_1_MEM_LEN, s ); /* Qx + s */
491 50004 : interpolate_3_over_1_allpass_fx( HF_syn, L_SUBFR16k, upsampled_HF_syn, hBWE_zero->mem_hp_interp_fx );
492 50004 : Scale_sig( upsampled_HF_syn, 3 * L_SUBFR16k, -s ); /* Q_syn + exp1 + s */
493 50004 : Scale_sig( hBWE_zero->mem_hp_interp_fx, INTERP_3_1_MEM_LEN, -s ); /* Qx */
494 50004 : Scale_sig( HF_syn, L_SUBFR16k, -s ); /* Q_syn+exp1 */
495 50004 : Scale_sig( upsampled_HF_syn, L_SUBFR48k, -1 );
496 : }
497 9552 : ELSE IF( EQ_16( output_subfr, L_SUBFR32k ) ) /* 32kHz sampled output */
498 : {
499 6188 : s = s_max( sub( s_min( Find_Max_Norm16( HF_syn, L_SUBFR16k ), Find_Max_Norm16( hBWE_zero->mem_hp_interp_fx, 2 * ALLPASSSECTIONS_STEEP ) ), 2 ), 0 );
500 6188 : Scale_sig( HF_syn, L_SUBFR16k, s ); /* Q_syn+exp1+s */
501 6188 : Scale_sig( hBWE_zero->mem_hp_interp_fx, 2 * ALLPASSSECTIONS_STEEP, s ); /* Qx + s */
502 6188 : Interpolate_allpass_steep_fx( HF_syn, hBWE_zero->mem_hp_interp_fx, L_SUBFR16k, upsampled_HF_syn );
503 6188 : Scale_sig( upsampled_HF_syn, 2 * L_SUBFR16k, -s ); /* Q_syn + exp1 */
504 6188 : Scale_sig( hBWE_zero->mem_hp_interp_fx, 2 * ALLPASSSECTIONS_STEEP, -s ); /* Qx */
505 6188 : Scale_sig( HF_syn, L_SUBFR16k, -s ); /* Q_syn+exp1 */
506 : }
507 : ELSE /* 16kHz sampled output */
508 : {
509 3364 : Copy( HF_syn, upsampled_HF_syn, L_SUBFR16k ); /* Q_syn */
510 : }
511 59556 : Vr_add( synth16k, upsampled_HF_syn, synth16k, output_subfr );
512 :
513 59556 : return;
514 : }
515 :
516 : /*-------------------------------------------------------------------*
517 : * filt_6k_7k:
518 : *
519 : * 15th order band pass 6kHz to 7kHz FIR filter.
520 : *
521 : * frequency: 4kHz 5kHz 5.5kHz 6kHz 6.5kHz 7kHz 7.5kHz 8kHz
522 : * dB loss: -60dB -45dB -13dB -3dB 0dB -3dB -13dB -45dB
523 : * (gain=4.0)
524 : *-------------------------------------------------------------------*/
525 59556 : static void filt_6k_7k_scale_fx(
526 : Word16 signal[], /* i/o: signal Qx*/
527 : Word16 lg, /* i : length of input Q0*/
528 : Word16 mem[], /* i/o: memory (size=30) exp*/
529 : Word16 fact, /* i : multiply factor Q0*/
530 : Word16 exp /* i : Mem Exponent */
531 : )
532 : {
533 : Word16 i, x[L_FRAME48k / NB_SUBFR + ( L_FIR - 1 )];
534 : Word32 L_tmp;
535 : #ifndef ISSUE_1866_replace_overflow_libdec
536 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
537 : Flag Overflow = 0;
538 : move32();
539 : #endif
540 : #endif
541 59556 : Copy_Scale_sig( mem, x, L_FIR - 1, exp );
542 :
543 4824036 : FOR( i = 0; i < lg; i++ )
544 : {
545 4764480 : x[i + L_FIR - 1] = shr( mult( signal[i], fact ), 2 ); /* Qx - 2 */
546 4764480 : move16(); /* gain of filter = 4 */
547 : }
548 4824036 : FOR( i = 0; i < lg; i++ )
549 : {
550 :
551 : Word16 j;
552 4764480 : L_tmp = 0;
553 4764480 : move32();
554 152463360 : FOR( j = 0; j < 31; j++ )
555 : {
556 : #ifdef ISSUE_1866_replace_overflow_libdec
557 147698880 : L_tmp = L_mac_sat( L_tmp, x[i + j], fir_6k_7k_fx[j] ); /* Q16 */
558 : #else
559 : L_tmp = L_mac_o( L_tmp, x[i + j], fir_6k_7k_fx[j], &Overflow ); /* Q16 */
560 : #endif
561 : }
562 :
563 : #ifdef ISSUE_1866_replace_overflow_libdec
564 4764480 : signal[i] = round_fx_sat( L_tmp ); /* Q0 */
565 : #else
566 : signal[i] = round_fx_o( L_tmp, &Overflow ); /* Q0 */
567 : #endif
568 4764480 : move16();
569 : }
570 59556 : Copy( x + lg, mem, L_FIR - 1 ); /* Qx - 2 */
571 59556 : }
572 :
573 : /*-------------------------------------------------------------------*
574 : * hf_synth_amr_wb_init()
575 : *
576 : * hf synthesis filters initialization
577 : * - initialization of 1600 Hz low pass filter
578 : * - initialization of band pass 6kHz to 8kHz FIR filter for noise and line resampled signals
579 : *-------------------------------------------------------------------*/
580 :
581 6 : void hf_synth_amr_wb_init_fx(
582 : AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */
583 : )
584 : {
585 6 : hAmrwb_IO->prev_r_fx = 0;
586 6 : move16();
587 6 : hAmrwb_IO->fmerit_w_sm_fx = 0;
588 6 : move16();
589 6 : hAmrwb_IO->frame_count_fx = 0;
590 6 : move16();
591 6 : hAmrwb_IO->ne_min_fx = -7680;
592 6 : move16(); /*-30.0f in Q8*/
593 6 : hAmrwb_IO->fmerit_m_sm_fx = 0;
594 6 : move16();
595 6 : hAmrwb_IO->voice_fac_amr_wb_hf = 0;
596 6 : move16();
597 6 : hAmrwb_IO->unvoicing_fx = 0;
598 6 : move16();
599 6 : hAmrwb_IO->unvoicing_sm_fx = 32767;
600 6 : move16(); /*1.0f in Q15*/
601 6 : hAmrwb_IO->unvoicing_flag_fx = 0;
602 6 : move16();
603 6 : hAmrwb_IO->voicing_flag_fx = 0;
604 6 : move16();
605 6 : hAmrwb_IO->start_band_old_fx = 160;
606 6 : move16();
607 6 : hAmrwb_IO->OptCrit_old_fx = 32768;
608 6 : move32(); /*1.0f in Q15*/
609 : ;
610 6 : return;
611 : }
612 :
613 :
614 : /*-------------------------------------------------------------------*
615 : * hf_synth_amr_wb_reset()
616 : *
617 : * reset of HF synthesis filters
618 : * - needed in switching scenarios
619 : *-------------------------------------------------------------------*/
620 0 : void hf_synth_amr_wb_reset_fx(
621 : ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */
622 : AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */
623 : )
624 : {
625 : Word16 i;
626 :
627 :
628 0 : FOR( i = 0; i < L_FRAME16k; i++ )
629 : {
630 0 : Random( &hBWE_zero->seed2 );
631 : }
632 :
633 0 : set16_fx( hBWE_zero->mem_syn_hf_fx, 0, M );
634 0 : set16_fx( hBWE_zero->delay_syn_hf_fx, 0, NS2SA( 16000, DELAY_CLDFB_NS ) );
635 0 : set16_fx( hBWE_zero->mem_hp_interp_fx, 0, INTERP_3_1_MEM_LEN );
636 :
637 0 : hAmrwb_IO->prev_r_fx = 0;
638 0 : move16();
639 0 : hAmrwb_IO->fmerit_w_sm_fx = 0;
640 0 : move16();
641 0 : hAmrwb_IO->frame_count_fx = 0;
642 0 : move16();
643 0 : hAmrwb_IO->ne_min_fx = -7680;
644 0 : move16(); /*-30.0f in Q8*/
645 0 : hAmrwb_IO->fmerit_m_sm_fx = 0;
646 0 : move16();
647 0 : hAmrwb_IO->voice_fac_amr_wb_hf = 0;
648 0 : move16();
649 0 : hAmrwb_IO->unvoicing_fx = 0;
650 0 : move16();
651 0 : hAmrwb_IO->unvoicing_sm_fx = 32767;
652 0 : move16(); /*1.0f in Q15*/
653 0 : hAmrwb_IO->unvoicing_flag_fx = 0;
654 0 : move16();
655 0 : hAmrwb_IO->voicing_flag_fx = 0;
656 0 : move16();
657 0 : hAmrwb_IO->start_band_old_fx = 160;
658 0 : move16();
659 0 : hAmrwb_IO->OptCrit_old_fx = 32768;
660 0 : move32(); /*1.0f in Q15*/
661 :
662 0 : return;
663 : }
664 :
665 : /*-------------------------------------------------------------------*
666 : * hf_synth_amr_wb()
667 : *
668 : * HF synthesis in AMR-WB IO
669 : *-------------------------------------------------------------------*/
670 :
671 0 : void hf_synth_amr_wb_fx(
672 : AMRWB_IO_DEC_HANDLE hAmrwb_IO, /* i/o: AMR-WB IO data handle */
673 : ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */
674 : const Word32 core_brate, /* i : core bitrate Q0*/
675 : const Word16 output_frame, /* i : output frame length Q0*/
676 : const Word16 *Aq, /* i : quantized Az : Q12*/
677 : const Word16 *exc, /* i : excitation at 12.8 kHz : Q_exc*/
678 : Word16 *synth, /* i/o: synthesis signal at 12.8k : Q_syn*/
679 : Word16 *amr_io_class, /* i : signal class (determined by FEC algorithm) Q0*/
680 : Word16 *synth_out, /* i/o: output signal at output Fs : Q_out*/
681 : Word16 fmerit, /* i : classify parameter from FEC : Q14*/
682 : const Word16 *hf_gain, /* i : decoded HF gain Q0*/
683 : const Word16 *voice_factors, /* i : voicing factors : Q15*/
684 : const Word16 pitch_buf[], /* i : pitch buffer : Q5*/
685 : const Word16 ng_ener_ST, /* i : Noise gate - short-term energy : Q8*/
686 : const Word16 *lsf_new, /* i : ISF vector : Q2*/
687 : const Word16 Q_exc, /* i : exc scaling */
688 : const Word16 Q_out /* i : Q_syn2-1 */
689 : )
690 : {
691 0 : Word16 core_type = 1;
692 : Word16 start_band;
693 : Word16 HF_corr_gain[NB_SUBFR];
694 : Word16 filt_weight_coeff;
695 : Word16 i, j, output_subfr;
696 : Word16 *pt3, *pt4, *pt5;
697 : const Word16 *pt6, *pt7;
698 : Word16 *pt1, *pt2;
699 : Word32 enr1, enr2;
700 : Word16 til[NB_SUBFR], til0[NB_SUBFR];
701 : Word16 tmp1, tmp2;
702 : Word32 L_tmp;
703 : Word16 exp;
704 : Word16 pitch_var_cur;
705 : Word16 voice_fac;
706 : Word16 fmerit_w;
707 : Word16 fmerit_m;
708 : Word16 *p_Ap;
709 : const Word16 *p_Aq;
710 : Word16 Ap[( M16k + 1 ) * NB_SUBFR];
711 : Word16 sub_gain[NB_SUBFR];
712 : Word16 exc16k[L_FRAME16k];
713 : Word16 qhf;
714 : Word16 dct_exc[L_FRAME], dct_hb[L_FRAME16k], filt_weight[L_SUBFR16k];
715 : Word16 hb_ener, g, hb_tonal[L_SUBFR16k], tonal_ener, hb_amb[L_SUBFR16k], inv_g;
716 : Word16 fb, fn, signum[L_SUBFR16k];
717 : Word16 alpha, beta, ener, tmp, scale, rev_filt_weight_coeff, qdct, q1, q2, q3, q4, shift;
718 : Word16 e_subfr1, e_subfr2;
719 : Word32 exc32[L_FRAME], dct_exc32[L_FRAME], dct_hb32[L_FRAME16k], exc16k32[L_FRAME16k];
720 : Word16 q_tmp;
721 : Word16 gamma;
722 0 : move16();
723 :
724 0 : Scale_sig( synth, L_FRAME, -3 ); /* Q_syn - 3 */
725 :
726 0 : pt1 = synth + 1; /* Q_syn - 3 */
727 0 : pt2 = synth; /* Q_syn - 3 */
728 0 : pt3 = til;
729 0 : pt4 = til0;
730 0 : FOR( i = 0; i < NB_SUBFR; i++ )
731 : {
732 0 : enr1 = Dot_product( pt2, pt2, L_SUBFR ); /*2*(Q_syn-3)+1 */
733 0 : enr2 = Dot_product( pt1, pt2, L_SUBFR - 1 ); /*2*(Q_syn-3)+1 */
734 :
735 0 : tmp1 = extract_h( enr1 ); /*2*(Q_syn-3) - 15 */
736 0 : tmp1 = s_max( 1, tmp1 );
737 0 : tmp2 = extract_h( enr2 ); /*2*(Q_syn-3) - 15 */
738 :
739 0 : exp = norm_s( tmp1 );
740 0 : tmp1 = div_s( shl( 1, sub( 14, exp ) ), tmp1 ); /*Q(29-exp-2*(Q_syn-3)-1) */
741 0 : L_tmp = L_mult( tmp2, tmp1 ); /*30-exp-2*(Q_syn-3)-1+2*(Q_syn-3)+1 - >30-exp */
742 0 : *pt3 = round_fx( L_shl( L_tmp, sub( exp, 1 ) ) ); /*13 */
743 0 : move16();
744 0 : *pt4++ = *pt3++;
745 0 : move16();
746 :
747 0 : pt1 += L_SUBFR;
748 0 : pt2 += L_SUBFR;
749 : }
750 :
751 0 : output_subfr = shr( output_frame, 2 ); /* Q0 */
752 :
753 0 : if ( NE_16( *amr_io_class, 7 ) )
754 : {
755 0 : core_type = 0;
756 0 : move16();
757 : }
758 :
759 : /* modify LF parameters for excitation weighting or sub-frame gains calculating */
760 0 : pitch_var_cur = 0;
761 0 : move16();
762 0 : pt6 = pitch_buf; /* Q5 */
763 0 : pt7 = pitch_buf + 1; /* Q5 */
764 0 : FOR( i = 0; i < 3; i++ )
765 : {
766 0 : tmp1 = abs_s( sub( *pt6++, *pt7++ ) ); /*Q5 */
767 0 : pitch_var_cur = add( pitch_var_cur, shr( tmp1, 1 ) ); /*Q6 -> Q5 */
768 : }
769 0 : test();
770 0 : IF( GT_16( hAmrwb_IO->frame_count_fx, FRAME_COUNT_HF_SYNTH ) && *amr_io_class == UNVOICED_CLAS )
771 : {
772 0 : hAmrwb_IO->frame_count_fx = 0;
773 0 : hAmrwb_IO->ne_min_fx = -7680; /* -30.0f in Q8 */
774 0 : move16();
775 0 : move16(); /*Q8; */
776 : }
777 : ELSE
778 : {
779 0 : hAmrwb_IO->frame_count_fx = s_min( hAmrwb_IO->frame_count_fx, 2 * FRAME_COUNT_HF_SYNTH - 1 ); /* Q0 */
780 0 : move16();
781 0 : hAmrwb_IO->frame_count_fx = add( hAmrwb_IO->frame_count_fx, 1 ); /* Q0 */
782 0 : move16();
783 0 : hAmrwb_IO->ne_min_fx = s_min( hAmrwb_IO->ne_min_fx, ng_ener_ST ); /* Q8 */
784 0 : move16();
785 : }
786 :
787 0 : pt6 = voice_factors;
788 0 : L_tmp = L_mult( *pt6++, 4096 /* 0.25 IN Q14 */ ); /* Q30 */
789 0 : FOR( i = 1; i < 4; i++ )
790 : {
791 0 : L_tmp = L_mac( L_tmp, *pt6++, 4096 /* 0.25 IN Q14 */ ); /* Q30 */
792 : }
793 :
794 0 : voice_fac = round_fx( L_tmp ); /* Q14 */
795 :
796 : /*fmerit_w = fmerit > 5734 ? 5734 : (fmerit < 2458 ? 2458 : fmerit); //Q14 */
797 :
798 0 : fmerit_w = s_min( fmerit, 5734 /* 0.35 IN Q14 */ ); /* Q14 */
799 0 : fmerit_w = s_max( fmerit_w, 2458 /* 0.15 IN Q14 */ ); /* Q14 */
800 :
801 0 : if ( EQ_16( core_type, 1 ) )
802 : {
803 0 : fmerit_w = shr( fmerit_w, 1 ); /* Q14 */
804 : }
805 :
806 0 : L_tmp = L_mult( fmerit_w, add_sat( 16384, voice_fac ) ); /* Q14 */
807 0 : fmerit_w = extract_l( L_shr( L_tmp, 15 ) ); /*Q14 */
808 : /**fmerit_w_sm = add(mult_r(*fmerit_w_sm, 29491), mult_r(fmerit_w, 3277)); //Q14 */
809 0 : hAmrwb_IO->fmerit_w_sm_fx = round_fx( L_mac( L_mult( hAmrwb_IO->fmerit_w_sm_fx, 29491 ), fmerit_w, 3277 ) ); /*Q14 */
810 0 : move16();
811 0 : fmerit_w = hAmrwb_IO->fmerit_w_sm_fx;
812 :
813 0 : move16();
814 :
815 0 : tmp1 = fmerit; /* Q14 */
816 0 : move16();
817 0 : if ( LT_16( fmerit, 8192 /* 0.5 in Q14 */ ) )
818 : {
819 0 : tmp1 = 16384; /* 1.0f in Q14 */
820 0 : move16();
821 : }
822 0 : fmerit_m = negate( add( -32768, tmp1 ) );
823 0 : hAmrwb_IO->fmerit_m_sm_fx = add( shr( hAmrwb_IO->fmerit_m_sm_fx, 1 ), shr( fmerit_m, 1 ) ); /*Q14 */
824 0 : move16();
825 0 : fmerit_m = hAmrwb_IO->fmerit_m_sm_fx; /* Q14 */
826 0 : move16();
827 :
828 0 : pt1 = til;
829 0 : FOR( i = 0; i < NB_SUBFR; i++ )
830 : {
831 0 : tmp = sub( pitch_var_cur, 320 );
832 0 : tmp = s_and( tmp, *pt1 );
833 0 : if ( tmp < 0 )
834 : {
835 0 : *pt1 = 1638; /* 0.2 in Q13 */
836 0 : move16();
837 : }
838 :
839 0 : tmp1 = sub( 8192 /* 1.0 in Q13 */, *pt1 ); /* Q13 */
840 0 : *pt1 = s_max( 6554 /* 0.8 in Q13 */, tmp1 ); /* Q13 */
841 0 : move16();
842 0 : tmp1 = add( hAmrwb_IO->ne_min_fx, 7680 /* 30.0 in Q30 */ ); /*Q8 */
843 0 : tmp1 = mult_r( tmp1, 7340 ); /*Q20 - > 0.007 //Q13 */
844 0 : *pt1 = add( *pt1, tmp1 );
845 0 : move16(); /*Q13 */
846 :
847 0 : L_tmp = L_mult0( *pt1, fmerit_m ); /*Q13+14 */
848 0 : *pt1++ = extract_l( L_shr( L_tmp, 14 ) ); /*Q13 */
849 0 : move16();
850 : }
851 : /* predict LPC coefficents and calculate sub-frame gains */
852 0 : p_Aq = Aq;
853 0 : p_Ap = Ap;
854 0 : pt1 = sub_gain;
855 0 : pt2 = til0;
856 0 : pt3 = til;
857 0 : pt6 = voice_factors;
858 0 : FOR( i = 0; i < NB_SUBFR; i++ )
859 : {
860 0 : envelope_fx( hAmrwb_IO, core_brate, p_Aq, p_Ap, pt1, *pt2, *pt3, *pt6 );
861 0 : pt1++;
862 0 : pt2++;
863 0 : pt3++;
864 0 : pt6++;
865 :
866 0 : p_Aq += ( M + 1 );
867 0 : p_Ap += ( M + 1 );
868 : }
869 :
870 0 : AdaptiveStartBand_fx( &start_band, core_brate, lsf_new, voice_fac, *amr_io_class, &hAmrwb_IO->voicing_flag_fx, &hAmrwb_IO->start_band_old_fx, &hAmrwb_IO->OptCrit_old_fx );
871 :
872 0 : q_tmp = Exp16Array( L_FRAME, exc );
873 0 : qdct = sub( q_tmp, 1 );
874 0 : Copy_Scale_sig_16_32_DEPREC( exc, exc32, L_FRAME, qdct ); /* Qexc + qdct */
875 :
876 0 : qdct = add( qdct, Q_exc );
877 0 : edct_fx( exc32, dct_exc32, L_FRAME, &qdct );
878 0 : q_tmp = Exp32Array( L_FRAME, dct_exc32 );
879 :
880 0 : q_tmp = sub( q_tmp, 16 );
881 0 : Copy_Scale_sig_32_16( dct_exc32, dct_exc, L_FRAME, q_tmp ); /* qdct + qtmp */
882 0 : qdct = add( qdct, q_tmp );
883 :
884 0 : set16_fx( dct_hb, 0, L_FRAME16k );
885 0 : pt1 = &dct_hb[200]; /* qdct */
886 0 : pt2 = &dct_exc[200]; /* qdct */
887 0 : FOR( i = 200; i < 240; i++ )
888 : {
889 0 : *pt1++ = *pt2++;
890 0 : move16(); /*qdct */
891 : }
892 0 : set16_fx( signum, 1, L_SUBFR16k );
893 0 : pt1 = dct_hb + 240;
894 0 : pt2 = dct_exc + start_band;
895 0 : pt3 = signum;
896 0 : FOR( i = 240; i < L_FRAME16k; i++ )
897 : {
898 0 : if ( *pt2 < 0 )
899 : {
900 0 : *pt3 = -1;
901 0 : move16();
902 : }
903 0 : *pt1++ = abs_s( *pt2++ );
904 0 : move16(); /*qdct */
905 0 : pt3++;
906 : }
907 0 : hb_ener = dot_prod_satcontr( &dct_hb[240], &dct_hb[240], qdct, qdct, &q1, L_SUBFR16k );
908 :
909 0 : L_tmp = L_shl( L_mult( start_band, 205 /* 0.00625f in Q15 */ ), 14 ); /*Q30 */
910 0 : tmp = round_fx( L_tmp ); /*Q14 */
911 0 : tmp = sub( 18022 /* 1.1f in Q14 */, tmp ); /*Q14 */
912 0 : fmerit_w = round_fx( L_shl( L_mult( fmerit_w, tmp ), 1 ) ); /*Q: 14+14+1+1-16 = 14 */
913 :
914 :
915 0 : L_tmp = L_deposit_l( fmerit_w ); /*Q14 */
916 0 : L_tmp = Isqrt( L_tmp ); /*Q(31-7) */
917 0 : tmp = round_fx( L_tmp ); /*Q8 */
918 0 : q2 = norm_s( tmp );
919 0 : alpha = div_s( shl( 1, sub( 14, q2 ) ), tmp ); /*Q(29-q2-8); */
920 0 : alpha = shl( alpha, sub( q2, 7 ) ); /*Q14 */
921 :
922 0 : beta = sub( 16384 /* 1.0f in Q14 */, fmerit_w ); /*Q14 */
923 :
924 0 : L_tmp = L_mult( alpha, 31130 /* 0.95f in Q15 */ ); /*Q30 */
925 0 : gamma = round_fx( L_tmp ); /*Q14 */
926 0 : gamma = sub( 17203 /* 1.05f in Q14 */, gamma ); /*Q14 */
927 0 : gamma = s_min( 16384 /* 1.0f in Q14 */, gamma ); /* Q14 */
928 0 : gamma = s_max( 4915 /* 0.3f in Q14 */, gamma ); /* Q14 */
929 :
930 0 : IF( LT_16( beta, 16384 /* 1 in Q14 */ ) )
931 : {
932 0 : L_tmp = 1; /*variable for tonal energy*/
933 0 : move32();
934 :
935 0 : pt1 = hb_amb;
936 0 : pt2 = hb_tonal;
937 0 : pt3 = &dct_hb[240];
938 0 : FOR( i = 0; i < 8; i++ )
939 : {
940 0 : fn = add( i, 8 ); /* Q0 */
941 0 : tmp1 = div_s( 1, fn ); /*Q15 */
942 0 : tmp = 0;
943 0 : move16();
944 0 : pt4 = &dct_hb[240];
945 0 : FOR( j = 0; j < fn; j++ )
946 : {
947 0 : tmp = add_sat( tmp, shr( *pt4++, 2 ) ); /*qdct-2 */
948 : }
949 0 : *pt1 = round_fx( L_shl( L_mult( tmp, tmp1 ), 2 ) ); /*qdct */
950 0 : move16();
951 0 : *pt2 = sub( *pt3, *pt1 ); /* qdct */
952 0 : move16();
953 0 : IF( *pt2 > 0 )
954 : {
955 0 : L_tmp = L_mac0( L_tmp, shr( *pt2, 1 ), shr( *pt2, 1 ) ); /*2*qdct-2 */
956 : }
957 0 : pt1++;
958 0 : pt2++;
959 0 : pt3++;
960 : }
961 0 : FOR( ; i < L_SUBFR16k - 8; i++ )
962 : {
963 0 : fb = sub( i, 7 ); /* Q0 */
964 0 : fn = add( fb, 15 ); /* Q0 */
965 0 : tmp = 0;
966 0 : move16();
967 0 : pt4 = &dct_hb[fb + 240];
968 0 : FOR( j = fb; j < fn; j++ )
969 : {
970 0 : tmp = add_sat( tmp, shr( *pt4++, 2 ) ); /*qdct-2 */
971 : }
972 0 : *pt1 = mult_r( tmp, 8738 );
973 0 : move16(); /* 8738 = 1/15 in Q17 qdct */
974 0 : *pt2 = sub( *pt3, *pt1 );
975 0 : move16();
976 0 : IF( *pt2 > 0 )
977 : {
978 0 : L_tmp = L_mac0_sat( L_tmp, shr( *pt2, 1 ), shr( *pt2, 1 ) ); /*2*qdct-2 */
979 : }
980 0 : pt1++;
981 0 : pt2++;
982 0 : pt3++;
983 : }
984 0 : FOR( ; i < L_SUBFR16k; i++ )
985 : {
986 0 : fb = sub( i, 7 ); /* Q0 */
987 0 : tmp = 0;
988 0 : move16();
989 0 : fn = sub( L_SUBFR16k, fb ); /* Q0 */
990 0 : tmp1 = div_s( 1, fn ); /*Q15 */
991 0 : pt4 = &dct_hb[fb + 240];
992 0 : FOR( j = fb; j < L_SUBFR16k; j++ )
993 : {
994 0 : tmp = add_sat( tmp, shr( *pt4++, 2 ) ); /*qdct-2 */
995 : }
996 0 : *pt1 = round_fx( L_shl( L_mult( tmp, tmp1 ), 2 ) ); /*qdct */
997 0 : move16();
998 0 : *pt2 = sub( *pt3, *pt1 );
999 0 : move16();
1000 0 : IF( *pt2 > 0 )
1001 : {
1002 0 : L_tmp = L_mac0_sat( L_tmp, shr( *pt2, 1 ), shr( *pt2, 1 ) ); /*2*qdct-2 */
1003 : }
1004 0 : pt1++;
1005 0 : pt2++;
1006 0 : pt3++;
1007 : }
1008 :
1009 : /*scaling of hb_ener is q1; tonal_ener<hb_ener, so scaling of tonal_ener can be q1 too*/
1010 0 : tonal_ener = round_fx( L_shr( L_tmp, sub( shl( qdct, 1 ), add( q1, 18 ) ) ) );
1011 0 : tmp = sub( hb_ener, tonal_ener ); /*q1 */
1012 0 : tmp1 = round_fx( L_shl( L_mult( beta, tonal_ener ), 1 ) ); /*q1 */
1013 0 : tmp1 = sub( hb_ener, tmp1 ); /*q1 */
1014 0 : tmp = div_s( tmp, s_max( tmp1, 1 ) ); /*Q15 */
1015 0 : g = shl( mult( beta, tmp ), 1 ); /*Q15 */
1016 0 : q2 = norm_s( g );
1017 0 : inv_g = div_s( shl( 1, sub( 14, q2 ) ), g ); /*Q(29-q2-15); */
1018 0 : inv_g = shl( inv_g, sub( q2, 2 ) ); /*Q12 */
1019 0 : pt1 = hb_tonal;
1020 0 : pt2 = hb_amb;
1021 0 : pt3 = &dct_hb[240];
1022 0 : pt4 = signum;
1023 0 : FOR( i = 0; i < L_SUBFR16k; i++ )
1024 : {
1025 0 : IF( *pt1 > 0 )
1026 : {
1027 0 : *pt1 = mult_r( *pt1, g ); /*qdct */
1028 0 : move16();
1029 : }
1030 0 : *pt2 = round_fx_sat( L_shl_sat( L_mult( *pt2, inv_g ), 3 ) ); /*qdct */
1031 0 : move16();
1032 0 : *pt3 = add_sat( *pt1, *pt2 );
1033 0 : move16();
1034 0 : *pt3 = extract_l( L_mult0( *pt3, *pt4 ) ); /*qdct */
1035 0 : move16();
1036 0 : pt1++;
1037 0 : pt2++;
1038 0 : pt3++;
1039 0 : pt4++;
1040 : }
1041 :
1042 0 : ener = dot_prod_satcontr( &dct_hb[240], &dct_hb[240], qdct, qdct, &q2, L_SUBFR16k ); /* q2 */
1043 0 : scale = div_s( shl( 1, 14 ), hb_ener ); /*Q(29-q1) */
1044 0 : L_tmp = L_mult( ener, scale ); /*30-q1+q2 */
1045 0 : q2 = sub( q1, q2 ); /*30-q2 */
1046 0 : scale = round_fx( Isqrt( L_shl( L_tmp, sub( q2, 24 ) ) ) ); /*Q12 */
1047 0 : scale = round_fx_sat( L_shl_sat( L_mult( scale, gamma ), 4 ) ); /*Q15 */
1048 : }
1049 : ELSE
1050 : {
1051 0 : scale = 32767; /*~1 in Q15 */
1052 0 : move16();
1053 : }
1054 :
1055 0 : IF( EQ_32( core_brate, ACELP_6k60 ) )
1056 : {
1057 0 : filt_weight_coeff = 60; /* Q0 */
1058 0 : move16();
1059 0 : rev_filt_weight_coeff = 555;
1060 0 : move16(); /* 1/(filt_weight_coeff-1) Q15 */
1061 : }
1062 0 : ELSE IF( EQ_32( core_brate, ACELP_8k85 ) )
1063 : {
1064 0 : filt_weight_coeff = 40; /* Q0 */
1065 0 : move16();
1066 0 : rev_filt_weight_coeff = 840; /* 1/(filt_weight_coeff-1) Q15 */
1067 0 : move16();
1068 : }
1069 : ELSE
1070 : {
1071 0 : filt_weight_coeff = 20; /* Q0 */
1072 0 : move16();
1073 0 : rev_filt_weight_coeff = 1725; /* 1/(filt_weight_coeff-1) Q15 */
1074 0 : move16();
1075 : }
1076 :
1077 0 : pt1 = filt_weight;
1078 0 : FOR( i = 0; i < filt_weight_coeff; i++ )
1079 : {
1080 0 : L_tmp = L_mult( -32735, rev_filt_weight_coeff ); /*Q31 */
1081 0 : L_tmp = L_shl( Mult_32_16( L_tmp, i ), 14 ); /*Q16+14 */
1082 0 : *pt1++ = add( round_fx( L_tmp ), 16384 );
1083 0 : move16(); /*Q14 */
1084 : }
1085 :
1086 0 : IF( EQ_32( core_brate, ACELP_23k85 ) )
1087 : {
1088 0 : pt1 = dct_hb + 240;
1089 0 : tmp = sub( filt_weight_coeff, 80 ); /* Q0 */
1090 0 : pt3 = filt_weight + tmp;
1091 0 : FOR( i = 240; i < L_FRAME16k; i++ )
1092 : {
1093 0 : *pt1 = mult_r( *pt1, scale ); /*qdct */
1094 0 : move16();
1095 :
1096 0 : IF( GE_16( i, sub( L_FRAME16k, filt_weight_coeff ) ) )
1097 : {
1098 0 : *pt1 = round_fx( L_shl( L_mult( *pt3, *pt1 ), 1 ) ); /*qdct */
1099 0 : move16();
1100 : }
1101 0 : pt1++;
1102 0 : pt3++;
1103 : }
1104 0 : pt1 = dct_hb + 200;
1105 0 : pt6 = filt_hp_fx;
1106 0 : FOR( i = 200; i < 256; i++ )
1107 : {
1108 0 : *pt1 = mult_r( *pt6++, *pt1 );
1109 0 : move16(); /*qdct */
1110 0 : pt1++;
1111 : }
1112 0 : pt1 = HF_corr_gain;
1113 0 : pt6 = hf_gain;
1114 0 : FOR( i = 0; i < NB_SUBFR; i++ )
1115 : {
1116 0 : tmp = *pt6++;
1117 0 : move16();
1118 0 : *pt1++ = HP_gain_fx[tmp]; /* Q15 */
1119 0 : move16();
1120 : }
1121 : }
1122 : ELSE
1123 : {
1124 0 : pt1 = dct_hb + 240;
1125 0 : tmp = sub( filt_weight_coeff, 80 ); /* Q0 */
1126 0 : pt3 = filt_weight + tmp;
1127 0 : FOR( i = 240; i < L_FRAME16k; i++ )
1128 : {
1129 0 : *pt1 = mult_r( *pt1, scale ); /*qdct */
1130 0 : IF( GT_16( i, 255 ) )
1131 : {
1132 0 : *pt1 = mult_r( 19505 /* 0.6 in Q15 */, *pt1 );
1133 0 : move16();
1134 : }
1135 :
1136 0 : IF( GE_16( i, sub( L_FRAME16k, filt_weight_coeff ) ) )
1137 : {
1138 0 : *pt1 = round_fx( L_shl( L_mult( *pt3, *pt1 ), 1 ) ); /*qdct */
1139 0 : move16();
1140 : }
1141 0 : pt1++;
1142 0 : pt3++;
1143 : }
1144 :
1145 0 : pt1 = dct_hb + 200;
1146 0 : pt6 = filt_hp_fx;
1147 0 : pt7 = deem_tab_fx; /* Q15 */
1148 0 : FOR( i = 200; i < 256; i++ )
1149 : {
1150 0 : *pt1 = mult_r( *pt6++, *pt1 );
1151 0 : move16(); /*qdct */
1152 0 : *pt1 = mult_r( *pt7++, *pt1 );
1153 0 : move16(); /* qdct */
1154 0 : pt1++;
1155 : }
1156 : }
1157 :
1158 0 : q_tmp = Exp16Array( L_FRAME16k, dct_hb );
1159 0 : qhf = sub( q_tmp, 1 );
1160 0 : Copy_Scale_sig_16_32_DEPREC( dct_hb, dct_hb32, L_FRAME16k, qhf ); /* qhf + qdct */
1161 0 : qhf = add( qhf, qdct );
1162 0 : edct_fx( dct_hb32, exc16k32, L_FRAME16k, &qhf );
1163 0 : q_tmp = Exp32Array( L_FRAME16k, exc16k32 );
1164 0 : q_tmp = sub( q_tmp, 16 );
1165 0 : Copy_Scale_sig_32_16( exc16k32, exc16k, L_FRAME16k, q_tmp ); /* qhf + qtmp */
1166 0 : qhf = add( qhf, q_tmp );
1167 :
1168 0 : ener = dot_prod_satcontr( exc, exc, Q_exc, Q_exc, &q1, L_FRAME );
1169 0 : tmp = dot_prod_satcontr( exc16k, exc16k, qhf, qhf, &q2, L_FRAME16k );
1170 :
1171 0 : pt6 = exc;
1172 0 : pt2 = exc16k;
1173 :
1174 0 : FOR( i = 0; i < NB_SUBFR; i++ )
1175 : {
1176 0 : e_subfr1 = dot_prod_satcontr( pt6, pt6, Q_exc, Q_exc, &q3, L_SUBFR );
1177 0 : e_subfr2 = dot_prod_satcontr( pt2, pt2, qhf, qhf, &q4, L_SUBFR16k );
1178 :
1179 0 : L_tmp = L_mult( e_subfr1, tmp ); /*Q(q2+q3+1) */
1180 0 : q3 = add( add( q2, q3 ), 1 );
1181 0 : shift = norm_l( L_tmp );
1182 0 : L_tmp = L_shl( L_tmp, shift ); /*Q(q3+shift); */
1183 0 : q3 = add( q3, shift );
1184 0 : scale = round_fx_sat( L_tmp ); /*Q(q3-16); */
1185 0 : q3 = sub( q3, 16 );
1186 0 : scale = div_s( shl( 1, 14 ), scale ); /*Q(29-q3) */
1187 0 : L_tmp = L_mult( scale, ener ); /*Q(29-q3+q1+1) */
1188 0 : shift = norm_l( L_tmp );
1189 0 : L_tmp = L_shl( L_tmp, shift ); /*Q(29-q3+q1+1+shift) */
1190 0 : scale = round_fx_sat( L_tmp ); /*Q(29-q3+q1+1+shift-16) */
1191 0 : L_tmp = L_mult( scale, e_subfr2 ); /*Q(29-q3+q1+1+shift-16+q4+1)=Q(15+q1-q3+q4+shift) */
1192 0 : q3 = sub( 15, q3 );
1193 0 : q3 = add( q3, q1 );
1194 0 : q3 = add( q3, shift );
1195 0 : q3 = add( q3, q4 );
1196 0 : scale = round_fx_sat( Isqrt( L_shl_sat( L_tmp, sub( 6, q3 ) ) ) ); /*Q12 */
1197 0 : pt6 += L_SUBFR;
1198 0 : FOR( j = 0; j < L_SUBFR16k; j++ )
1199 : {
1200 0 : *pt2 = round_fx_sat( L_shl_sat( L_mult( *pt2, scale ), 2 ) ); /*qhf-1 */
1201 0 : move16();
1202 0 : pt2++;
1203 : }
1204 : }
1205 0 : qhf = sub( qhf, 1 );
1206 :
1207 0 : p_Ap = Ap;
1208 0 : pt1 = exc16k;
1209 0 : pt2 = synth_out;
1210 0 : pt3 = sub_gain;
1211 0 : pt4 = HF_corr_gain;
1212 0 : pt5 = til0;
1213 0 : pt6 = voice_factors;
1214 0 : pt7 = exc;
1215 :
1216 0 : FOR( i = 0; i < NB_SUBFR; i++ )
1217 : {
1218 0 : hf_synthesis_amr_wb_fx( core_brate, output_subfr, p_Ap, pt1, pt2, hBWE_zero->mem_syn_hf_fx, hBWE_zero->delay_syn_hf_fx,
1219 0 : hBWE_zero->mem_hp_interp_fx, *pt3, *pt4, *pt5, *pt6, pt7, Q_exc, Q_out, qhf );
1220 0 : p_Ap += ( M + 1 );
1221 0 : pt1 += L_SUBFR16k;
1222 0 : pt2 += output_subfr;
1223 0 : pt3++;
1224 0 : pt4++;
1225 0 : pt5++;
1226 0 : pt6++;
1227 0 : pt7 += L_SUBFR;
1228 : }
1229 :
1230 0 : return;
1231 : }
1232 0 : static void hf_synthesis_amr_wb_fx(
1233 : const Word32 core_brate, /* i : core bitrate : Q0*/
1234 : const Word16 output_subfr, /* i : output sub-frame length : Q0*/
1235 : const Word16 Ap[], /* i : quantized Aq : Q12*/
1236 : Word16 exc16k[], /* i : excitation at 16 kHz : qhf*/
1237 : Word16 synth_out[], /* i/o: synthesis signal at output Fs : Q_out*/
1238 : Word16 *mem_syn_hf, /* i/o: HF synthesis memory : Q_out*/
1239 : Word16 *delay_syn_hf, /* i/o: HF synthesis memory : Q_out*/
1240 : Word16 *mem_hp_interp, /* i/o: interpol. memory : Q_out*/
1241 : Word16 p_r, /* i : sub-frame gain : Q12*/
1242 : Word16 HF_corr_gain, /* i : HF gain index : Q14*/
1243 : Word16 til, /* Q14 */
1244 : Word16 voice_factors, /* Q14 */
1245 : const Word16 exc[], /* i : excitation at 12.8 kHz : Qexc*/
1246 : const Word16 Q_exc, /*exc scaling*/
1247 : const Word16 Q_out, /*synth_out scaling*/
1248 : Word16 qhf /*exc16k scaling*/
1249 : )
1250 : {
1251 : Word16 i;
1252 : Word16 HF_syn[L_SUBFR16k], upsampled_HF_syn[L_SUBFR48k];
1253 : Word16 ener, tmp, scale, exc2385[L_SUBFR16k];
1254 : Word32 L_tmp;
1255 : Word16 q1, q2, q3, shift;
1256 : Word16 *pt1, *pt2, flag;
1257 0 : IF( EQ_32( core_brate, ACELP_23k85 ) )
1258 : {
1259 0 : ener = dot_prod_satcontr( exc, exc, Q_exc, Q_exc, &q1, L_SUBFR );
1260 0 : tmp = dot_prod_satcontr( exc16k, exc16k, qhf, qhf, &q2, L_SUBFR16k );
1261 :
1262 0 : L_tmp = L_mult( ener, 6554 /* 0.2 in Q15 */ ); /*Q(q1+16) */
1263 0 : q3 = norm_l( L_tmp );
1264 0 : L_tmp = L_shl( L_tmp, q3 ); /*Q(q1+q3+16) */
1265 0 : ener = extract_h( L_tmp ); /*Q(q1+q3); */
1266 0 : q1 = add( q1, q3 );
1267 :
1268 0 : scale = div_s( shl( 1, 14 ), ener ); /*Q(29-q1) */
1269 0 : L_tmp = L_mult( tmp, scale ); /*30-q1+q2 */
1270 0 : q2 = sub( q1, q2 ); /*30-q2 */
1271 0 : scale = round_fx_sat( Isqrt( L_shl_sat( L_tmp, sub( q2, 24 ) ) ) ); /*Q12 */
1272 0 : pt1 = exc16k;
1273 0 : pt2 = exc2385;
1274 0 : FOR( i = 0; i < L_SUBFR16k; i++ )
1275 : {
1276 0 : L_tmp = L_mult( *pt1++, HF_corr_gain ); /*qhf+15*/
1277 0 : L_tmp = Mult_32_16( L_tmp, scale ); /*qhf-1+12+1*/
1278 0 : *pt2++ = round_fx( L_shl( L_tmp, 1 ) ); /*qhf-3*/
1279 0 : move16();
1280 : }
1281 :
1282 0 : pt1 = exc16k;
1283 0 : FOR( i = 0; i < L_SUBFR16k; i++ )
1284 : {
1285 0 : *pt1 = mult_r( *pt1, p_r ); /*qhf-3*/
1286 0 : move16();
1287 0 : pt1++;
1288 : }
1289 :
1290 0 : qhf = sub( qhf, 3 );
1291 :
1292 0 : ener = dot_prod_satcontr( exc16k, exc16k, qhf, qhf, &q1, L_SUBFR16k );
1293 0 : tmp = dot_prod_satcontr( exc2385, exc2385, qhf, qhf, &q2, L_SUBFR16k );
1294 0 : L_tmp = L_mult( ener, 9830 ); /*Q(q1+16) */
1295 0 : q3 = norm_l( L_tmp );
1296 0 : L_tmp = L_shl( L_tmp, q3 ); /*Q(q1+q3+16) */
1297 0 : ener = extract_h( L_tmp ); /*Q(q1+q3); */
1298 0 : q1 = add( q1, q3 );
1299 :
1300 0 : scale = div_s( shl( 1, 14 ), ener ); /*Q(29-q1) */
1301 0 : L_tmp = L_mult( tmp, scale ); /*30-q1+q2 */
1302 0 : q2 = sub( q1, q2 ); /*30-q2 */
1303 0 : scale = round_fx_sat( Isqrt( L_shl_sat( L_tmp, sub( q2, 24 ) ) ) ); /*Q12 */
1304 0 : flag = negate( s_and( til, -0x8000 ) );
1305 0 : if ( GT_16( scale, 4096 /* 1.0f in Q12 */ ) )
1306 : {
1307 0 : flag = 1;
1308 0 : move16();
1309 : }
1310 0 : IF( flag )
1311 : {
1312 0 : Copy( exc2385, exc16k, L_SUBFR16k ); /* qhf */
1313 : }
1314 : ELSE
1315 : {
1316 0 : pt1 = exc16k;
1317 0 : pt2 = exc2385;
1318 0 : FOR( i = 0; i < L_SUBFR16k; i++ )
1319 : {
1320 0 : tmp = sub( 16348 /* 1 in Q14 */, shl( til, 1 ) ); /*Q14 */
1321 0 : L_tmp = L_mult( tmp, sub( 26214 /* 1.6f in Q14 */, shr( voice_factors, 1 ) ) ); /*Q29*/
1322 0 : tmp = round_fx( L_shr( L_tmp, 1 ) ); /*Q12*/
1323 0 : tmp = s_min( tmp, 4096 /* 1 in Q12 */ );
1324 0 : tmp = s_max( tmp, scale );
1325 0 : *pt1++ = round_fx( L_shl( L_mult( *pt2++, tmp ), 3 ) ) /*qhf*/;
1326 0 : move16();
1327 : }
1328 : }
1329 : }
1330 : ELSE
1331 : {
1332 0 : pt1 = exc16k;
1333 0 : FOR( i = 0; i < L_SUBFR16k; i++ )
1334 : {
1335 0 : *pt1 = mult_r( *pt1, p_r ); /*qhf-3*/
1336 0 : move16();
1337 0 : pt1++;
1338 : }
1339 :
1340 0 : qhf = sub( qhf, 3 );
1341 : }
1342 :
1343 0 : shift = sub( qhf, Q_out );
1344 0 : Syn_filt_s( shift, Ap, M, exc16k, HF_syn, L_SUBFR16k, mem_syn_hf, 1 ); /*Q_out=qhf-shift */
1345 :
1346 : /*-----------------------------------------------------------------*
1347 : * Resample to output sampling rate
1348 : * Synchronize LB and HB components (delay componsation)
1349 : * Add synthesised high band to speech synthesis
1350 : *-----------------------------------------------------------------*/
1351 :
1352 0 : delay_signal_fx( HF_syn, L_SUBFR16k, delay_syn_hf, NS2SA( 16000, DELAY_CLDFB_NS ) );
1353 :
1354 0 : IF( EQ_16( output_subfr, L_SUBFR48k ) ) /* 48kHz sampled output */
1355 : {
1356 : Word16 s;
1357 0 : s = s_max( s_min( sub( s_min( Find_Max_Norm16( HF_syn, L_SUBFR16k ), Find_Max_Norm16( mem_hp_interp, INTERP_3_1_MEM_LEN - 3 ) ), 3 ),
1358 0 : sub( Find_Max_Norm16( mem_hp_interp + INTERP_3_1_MEM_LEN - 3, 3 ), 1 ) ),
1359 : 0 );
1360 0 : Scale_sig( HF_syn, L_SUBFR16k, s ); /* Qout + s */
1361 0 : Scale_sig( mem_hp_interp, INTERP_3_1_MEM_LEN, s ); /* Qout + s */
1362 :
1363 0 : interpolate_3_over_1_allpass_fx( HF_syn, L_SUBFR16k, upsampled_HF_syn, mem_hp_interp );
1364 :
1365 0 : Scale_sig( upsampled_HF_syn, L_SUBFR48k, add( -s, -1 ) ); /* Qout - 1 */
1366 0 : Scale_sig( mem_hp_interp, INTERP_3_1_MEM_LEN, -s ); /* Qout */
1367 0 : Scale_sig( HF_syn, L_SUBFR16k, -s ); /* Qout */
1368 : }
1369 0 : ELSE IF( EQ_16( output_subfr, L_SUBFR32k ) ) /* 32kHz sampled output */
1370 : {
1371 : Word16 s;
1372 0 : s = s_max( sub( s_min( Find_Max_Norm16( HF_syn, L_SUBFR16k ), Find_Max_Norm16( mem_hp_interp, 2 * ALLPASSSECTIONS_STEEP ) ), 2 ), 0 );
1373 0 : Scale_sig( HF_syn, L_SUBFR16k, s ); /* Qout + s */
1374 0 : Scale_sig( mem_hp_interp, 2 * ALLPASSSECTIONS_STEEP, s ); /* Qout + s */
1375 :
1376 0 : Interpolate_allpass_steep_fx( HF_syn, mem_hp_interp, L_SUBFR16k, upsampled_HF_syn );
1377 :
1378 0 : Scale_sig( upsampled_HF_syn, 2 * L_SUBFR16k, -s ); /* Qout */
1379 0 : Scale_sig( mem_hp_interp, 2 * ALLPASSSECTIONS_STEEP, -s ); /* Qout */
1380 0 : Scale_sig( HF_syn, L_SUBFR16k, -s ); /* Qout */
1381 : }
1382 : ELSE /* 16kHz sampled output */
1383 : {
1384 0 : Copy( HF_syn, upsampled_HF_syn, L_SUBFR16k ); /* Qout */
1385 : }
1386 :
1387 0 : Vr_add( synth_out, upsampled_HF_syn, synth_out, output_subfr );
1388 :
1389 0 : return;
1390 : }
1391 :
1392 0 : static Word16 EnhanceClass_fx(
1393 : const Word16 qq_fx, /* Qx */
1394 : const Word16 pp_fx, /* Qx */
1395 : const Word16 tilt0_fx, /* i : spectrum tilt Q13*/
1396 : const Word16 tilt_fx, /* i : spectrum tilt Q13*/
1397 : const Word16 voice_factor_fx, /* i : voice factor Q15*/
1398 : Word16 *voice_fac_fx, /* i/o: smoothed voiced parameter Q15*/
1399 : Word16 *unvoicing_fx, /* i/o: unvoiced parameter Q15*/
1400 : Word16 *unvoicing_sm_fx, /* i/o: smoothed unvoiced parameter Q15*/
1401 : Word16 *unvoicing_flag /* i/o: unvoiced flag Q0*/
1402 : )
1403 : {
1404 : Word16 unvoicing_tmp_fx;
1405 : Word16 tmp, tmp1;
1406 : Word32 L_tmp;
1407 : #ifndef ISSUE_1866_replace_overflow_libdec
1408 : Flag Overflow;
1409 : #endif
1410 :
1411 : /* Decide (*unvoicing_flag) to allow BWE enhancement when qq>pp */
1412 : /**voice_fac_fx = add(mult_r(*voice_fac_fx, 24576), mult_r(voice_factor_fx, 8192)); //Q15 */
1413 0 : *voice_fac_fx = round_fx( L_mac( L_mult( *voice_fac_fx, 24576 /* 0.75 in Q15 */ ), voice_factor_fx, 8192 /* 0.25 in Q15 */ ) ); /*Q15 */
1414 0 : move16();
1415 :
1416 0 : tmp = mult_r( sub( 8192 /* 1.0f in Q13 */, tilt0_fx ), 16384 /* 1.0f in Q15 */ ); /*Q13 */
1417 :
1418 0 : L_tmp = L_sub( 32768 /* 1.0 in Q15 */, *voice_fac_fx ); /*Q15 */
1419 :
1420 0 : L_tmp = Mult_32_16( L_tmp, tmp ); /*Q13 */
1421 0 : tmp = extract_l( L_tmp ); /*Q13 */
1422 :
1423 0 : tmp1 = mult_r( tilt_fx, 21845 ); /*Q15->1/1.5 ->Q13+15-15->Q13 */
1424 0 : tmp1 = s_min( tmp1, 8192 /* 1.0f in Q13 */ );
1425 :
1426 0 : L_tmp = L_mult( tmp, tmp1 ); /*Q13+Q13+1 */
1427 0 : unvoicing_tmp_fx = extract_l( L_shr( L_tmp, 12 ) ); /*Q15 */
1428 :
1429 : /**unvoicing_fx = add(mult_r(16384, *unvoicing_fx), mult_r(16384, unvoicing_tmp_fx)); //Q15 */
1430 0 : *unvoicing_fx = round_fx( L_mac( L_mult( 16384 /* 0.5 in Q15 */, *unvoicing_fx ), 16384 /* 0.5 in Q15 */, unvoicing_tmp_fx ) ); /*Q15 */
1431 0 : move16();
1432 :
1433 0 : IF( GT_16( *unvoicing_sm_fx, *unvoicing_fx ) )
1434 : {
1435 : /**unvoicing_sm_fx = add(mult_r(29491, *unvoicing_sm_fx), mult_r(3277, *unvoicing_fx)); //Q15 */
1436 0 : *unvoicing_sm_fx = round_fx( L_mac( L_mult( 29491 /* 0.9 in Q15 */, *unvoicing_sm_fx ), 3277 /* 0.1 in Q15 */, *unvoicing_fx ) ); /*Q15 */
1437 0 : move16();
1438 : }
1439 : ELSE
1440 : {
1441 : /**unvoicing_sm_fx = add(mult_r(32440, *unvoicing_sm_fx), mult_r(328, *unvoicing_fx)); //Q15 */
1442 0 : *unvoicing_sm_fx = round_fx( L_mac( L_mult( 32440 /* 0.99 in Q15 */, *unvoicing_sm_fx ), 328 /* 0.01 in Q15 */, *unvoicing_fx ) ); /*Q15 */
1443 0 : move16();
1444 : }
1445 :
1446 : #ifdef ISSUE_1866_replace_overflow_libdec
1447 0 : if ( GT_16( sub_sat( *unvoicing_fx, *unvoicing_sm_fx ), 3277 /* 0.1 in Q15 */ ) )
1448 : #else
1449 : if ( GT_16( sub_o( *unvoicing_fx, *unvoicing_sm_fx, &Overflow ), 3277 /* 0.1 in Q15 */ ) )
1450 : #endif
1451 : {
1452 0 : *unvoicing_flag = 1;
1453 0 : move16();
1454 : }
1455 :
1456 : #ifdef ISSUE_1866_replace_overflow_libdec
1457 0 : if ( LT_16( sub_sat( *unvoicing_fx, *unvoicing_sm_fx ), 1638 /* 0.05 in Q15 */ ) )
1458 : #else
1459 : if ( LT_16( sub_o( *unvoicing_fx, *unvoicing_sm_fx, &Overflow ), 1638 /* 0.05 in Q15 */ ) )
1460 : #endif
1461 : {
1462 0 : *unvoicing_flag = 0;
1463 0 : move16();
1464 : }
1465 0 : test();
1466 0 : return ( *unvoicing_flag && GT_16( qq_fx, pp_fx ) );
1467 : }
1468 :
1469 0 : static void envelope_fx(
1470 : AMRWB_IO_DEC_HANDLE hAmrwb_IO,
1471 : const Word32 core_brate, /* i : core bitrate Q0*/
1472 : const Word16 Aq_dyn_scal[], /* i : de-quant. LPC coefficents, dynamic scaling Q12*/
1473 : Word16 Ap[], /* o : extended LPC coefficents, Q12*/
1474 : Word16 *sub_gain, /* o : sub-frame gain, Q12*/
1475 : Word16 tilt0, /* i : spectrum tilt, Q14*/
1476 : Word16 tilt, /* i : spectrum tilt, Q13*/
1477 : Word16 voice_factor /* i : voice factor, Q15*/
1478 : )
1479 : {
1480 :
1481 : Word16 px, py, rx, ry, pp, rr, qx, qy, qq; /*Q10*/
1482 : Word16 i, Unvoicing_flag;
1483 : Word16 alpha; /*Q14*/
1484 : Word16 est_level1, est_level2; /*Q10*/
1485 : Word32 L_tmp;
1486 : Word16 tmp, q1, q2, q3, shift;
1487 : Word16 As[3], k1, k2;
1488 : Word16 *pt1;
1489 : const Word16 *pt2, *pt3;
1490 : Word16 Aq[M + 1];
1491 :
1492 :
1493 : /* Aq has dynamic scaling
1494 : go back to Q12 to make sure there's no overflow while calculating qx,qy*/
1495 0 : shift = sub( norm_s( Aq_dyn_scal[0] ), 2 );
1496 0 : Copy_Scale_sig( Aq_dyn_scal, Aq, M + 1, shift ); /* Q12 + shift */
1497 :
1498 : /* LPC envelope weighting */
1499 0 : IF( EQ_32( core_brate, ACELP_6k60 ) )
1500 : {
1501 0 : weight_a_lc_fx( Aq, Ap, Gamma_29491_Tbl, M );
1502 : }
1503 : ELSE
1504 : {
1505 0 : weight_a_lc_fx( Aq, Ap, Gamma_19661_Tbl_fx, M );
1506 : }
1507 : /* Ap has dynamic scaling
1508 : go back to Q12 to make sure there's no overflow while calculating px,py*/
1509 0 : shift = sub( norm_s( Ap[0] ), 2 );
1510 0 : IF( shift != 0 )
1511 : {
1512 0 : Scale_sig( Ap, M + 1, shift ); /* Q12 + shift */
1513 : }
1514 :
1515 : /* LPC envelope level estimate */
1516 0 : L_tmp = 0;
1517 0 : move32();
1518 0 : pt1 = Ap; /* Q12 */
1519 0 : pt2 = exp_tab_p_fx; /* Q14 */
1520 0 : FOR( i = 0; i <= M; i++ )
1521 : {
1522 0 : L_tmp = L_mac( L_tmp, *pt1++, *pt2++ ); /* Q27 */
1523 : }
1524 0 : q1 = norm_l( L_tmp );
1525 0 : L_tmp = L_shl( L_tmp, q1 ); /*Q(27+q1)*/
1526 0 : px = round_fx( L_shr( L_tmp, 1 ) ); /*Q(10+q1)*/
1527 :
1528 0 : L_tmp = L_deposit_l( 0 );
1529 :
1530 0 : pt1 = Ap; /* Q12 */
1531 0 : pt2 = exp_tab_p_fx + 33; /* Q14 */
1532 0 : FOR( i = 0; i <= M; i++ )
1533 : {
1534 0 : L_tmp = L_mac( L_tmp, *pt1++, *pt2-- ); /* Q27 */
1535 : }
1536 0 : q2 = norm_l( L_tmp );
1537 0 : shift = sub( q1, q2 );
1538 0 : IF( shift >= 0 )
1539 : {
1540 0 : px = shr( px, shift );
1541 0 : L_tmp = L_shl( L_tmp, q2 ); /*Q(27+q2)*/
1542 0 : q1 = q2;
1543 0 : move16();
1544 : }
1545 : ELSE
1546 : {
1547 0 : L_tmp = L_shl( L_tmp, q1 ); /*Q(27+q1)*/
1548 : }
1549 0 : py = round_fx( L_shr( L_tmp, 1 ) ); /*Q(10+q1)*/
1550 :
1551 0 : L_tmp = L_deposit_l( 0 );
1552 0 : pt2 = Aq; /* Q12 */
1553 0 : pt3 = exp_tab_q_fx; /* Q14 */
1554 0 : FOR( i = 0; i <= M; i++ )
1555 : {
1556 0 : L_tmp = L_mac_sat( L_tmp, *pt2++, *pt3++ ); /* Q27 */
1557 : }
1558 0 : q2 = norm_l( L_tmp );
1559 0 : L_tmp = L_shl( L_tmp, q2 ); /*Q(27+q2)*/
1560 0 : rx = round_fx( L_shr( L_tmp, 1 ) ); /*Q(10+q2)*/
1561 :
1562 0 : L_tmp = L_deposit_l( 0 );
1563 0 : pt2 = Aq; /* Q12 */
1564 0 : pt3 = exp_tab_q_fx + 33; /* Q14 */
1565 0 : FOR( i = 0; i <= M; i++ )
1566 : {
1567 0 : L_tmp = L_mac_sat( L_tmp, *pt2++, *pt3-- ); /* Q14 */
1568 : }
1569 0 : q3 = norm_l( L_tmp );
1570 0 : shift = sub( q2, q3 );
1571 0 : IF( shift >= 0 )
1572 : {
1573 0 : rx = shr( rx, shift );
1574 0 : L_tmp = L_shl( L_tmp, q3 ); /*Q(27+q3)*/
1575 0 : q2 = q3;
1576 0 : move16();
1577 : }
1578 : ELSE
1579 : {
1580 0 : L_tmp = L_shl( L_tmp, q2 ); /*Q(27+q2)*/
1581 : }
1582 0 : ry = round_fx( L_shr( L_tmp, 1 ) ); /*Q(10+q2)*/
1583 :
1584 0 : L_tmp = L_mult( px, px );
1585 0 : L_tmp = L_mac( L_tmp, py, py ); /*Q(21+2*q1)*/
1586 0 : pp = round_fx_sat( Isqrt( L_shr( L_tmp, add( 11, shl( q1, 1 ) ) ) ) ); /*Q10*/
1587 0 : L_tmp = L_mult( rx, rx );
1588 0 : L_tmp = L_mac( L_tmp, ry, ry ); /*Q(21+2*q1)*/
1589 0 : rr = round_fx_sat( Isqrt( L_shr( L_tmp, add( 11, shl( q2, 1 ) ) ) ) ); /*Q10*/
1590 0 : Copy( Aq, As, 3 );
1591 0 : IF( EQ_16( shr( As[2], 1 ), -2048 /* -1.0f in Q11 */ ) )
1592 : {
1593 0 : k2 = -2458; /* -0.6f in Q12 */
1594 0 : move16();
1595 0 : k1 = 4055; /* 0.99f in Q12 */
1596 0 : move16();
1597 0 : if ( As[1] < 0 )
1598 : {
1599 0 : k1 = -k1; /* Q12 */
1600 0 : move16();
1601 : }
1602 : }
1603 : ELSE
1604 : {
1605 0 : k1 = add( 2048 /* 1 in Q11 */, shr( As[2], 1 ) ); /*Q11 */
1606 0 : q1 = 11;
1607 0 : move16();
1608 0 : q2 = norm_s( k1 );
1609 0 : k1 = ( shl( k1, q2 ) ); /*q1+q2 */
1610 0 : tmp = abs_s( k1 );
1611 0 : q1 = add( q1, q2 );
1612 0 : tmp = div_s( shl( 1, 14 ), tmp ); /*Q(29-q1) */
1613 0 : if ( k1 < 0 )
1614 : {
1615 0 : tmp = negate( tmp );
1616 : }
1617 :
1618 0 : L_tmp = L_mult( As[1], tmp ); /*Q(42-q1) */
1619 0 : q1 = sub( q1, 14 );
1620 0 : k1 = round_fx_sat( L_shl_sat( L_tmp, q1 ) ); /*Q12 */
1621 0 : k2 = As[2];
1622 0 : move16(); /*Q12 */
1623 0 : if ( GT_16( k2, 2458 /* 0.6f in Q12 */ ) )
1624 : {
1625 0 : k2 = 2458; /* 0.6f in Q12 */
1626 0 : move16();
1627 : }
1628 0 : if ( LT_16( k2, -2458 /* -0.6f in Q12 */ ) )
1629 : {
1630 0 : k2 = -2458; /* -0.6f in Q12 */
1631 0 : move16();
1632 : }
1633 0 : if ( GT_16( k1, 4055 /* 0.99f in Q12 */ ) )
1634 : {
1635 0 : k1 = 4055; /* 0.99f in Q12 */
1636 0 : move16();
1637 : }
1638 0 : if ( LT_16( k1, -4055 /* -0.99f in Q12 */ ) )
1639 : {
1640 0 : k1 = -4055; /* -0.99f in Q12 */
1641 0 : move16();
1642 : }
1643 : }
1644 0 : As[1] = add( 4096 /* 1 in Q12 */, k2 );
1645 0 : move16();
1646 0 : L_tmp = L_mult( As[1], k1 ); /*Q25 */
1647 0 : As[1] = round_fx( L_shl( L_tmp, 3 ) ); /*Q12 */
1648 0 : move16();
1649 0 : As[2] = k2;
1650 0 : move16(); /*Q12 */
1651 :
1652 0 : L_tmp = L_deposit_l( 0 );
1653 0 : pt1 = As; /* Q12 */
1654 0 : pt2 = exp_tab_q_fx; /* Q14 */
1655 0 : FOR( i = 0; i < 3; i++ )
1656 : {
1657 0 : L_tmp = L_mac( L_tmp, *pt1++, *pt2++ ); /* Q27 */
1658 : }
1659 0 : q1 = norm_l( L_tmp );
1660 0 : L_tmp = L_shl( L_tmp, q1 ); /*Q(27+q1)*/
1661 0 : qx = round_fx( L_shr( L_tmp, 1 ) ); /*Q(10+q1)*/
1662 :
1663 :
1664 0 : L_tmp = L_deposit_l( 0 );
1665 0 : pt1 = As; /* Q12 */
1666 0 : pt2 = exp_tab_q_fx + 33; /* Q14 */
1667 0 : FOR( i = 0; i < 3; i++ )
1668 : {
1669 0 : L_tmp = L_mac( L_tmp, *pt1++, *pt2-- ); /* Q27 */
1670 : }
1671 0 : q2 = norm_l( L_tmp );
1672 0 : shift = sub( q1, q2 );
1673 0 : IF( shift >= 0 )
1674 : {
1675 0 : qx = shr( qx, shift );
1676 0 : L_tmp = L_shl( L_tmp, q2 ); /*Q(27+q2)*/
1677 0 : q1 = q2;
1678 0 : move16();
1679 : }
1680 : ELSE
1681 : {
1682 0 : L_tmp = L_shl( L_tmp, q1 ); /*Q(27+q1)*/
1683 : }
1684 0 : qy = round_fx( L_shr( L_tmp, 1 ) ); /*Q(10+q1)*/
1685 :
1686 :
1687 0 : L_tmp = L_mult( qx, qx ); /* Q21 + 2q1 */
1688 0 : L_tmp = L_mac( L_tmp, qy, qy ); /* Q21 + 2q1 */
1689 0 : qq = round_fx( Isqrt( L_shr( L_tmp, add( 11, shl( q1, 1 ) ) ) ) ); /*Q10*/
1690 :
1691 0 : Unvoicing_flag = EnhanceClass_fx( rr, pp, tilt0, tilt, voice_factor, &hAmrwb_IO->voice_fac_amr_wb_hf, &hAmrwb_IO->unvoicing_fx, &hAmrwb_IO->unvoicing_sm_fx, &hAmrwb_IO->unvoicing_flag_fx ); /* Q0 */
1692 0 : alpha = 0;
1693 0 : move16();
1694 0 : IF( Unvoicing_flag )
1695 : {
1696 0 : IF( GT_16( rr, ( hAmrwb_IO->prev_r_fx ) ) )
1697 : {
1698 0 : rr = shr( add_sat( rr, ( hAmrwb_IO->prev_r_fx ) ), 1 );
1699 : }
1700 :
1701 0 : hAmrwb_IO->prev_r_fx = rr;
1702 0 : move16();
1703 :
1704 0 : L_tmp = L_mult( tilt, sub( 26214 /* 1.6f in Q14 */, shr( voice_factor, 1 ) ) ); /*Q28*/
1705 :
1706 0 : L_tmp = L_min( L_tmp, 268435456 /* 1 in Q28 */ );
1707 :
1708 0 : L_tmp = Mult_32_16( L_tmp, rr ); /*Q23*/
1709 0 : rr = round_fx( L_shl( L_tmp, 3 ) ); /*Q10*/
1710 0 : L_tmp = L_mult( tilt, sub( 26214 /* 1.6f in Q14 */, shr( voice_factor, 1 ) ) ); /*Q28*/
1711 0 : L_tmp = L_max( L_tmp, 268435456 /* 1 in Q28 */ );
1712 0 : L_tmp = Mult_32_16( L_tmp, qq ); /*Q23*/
1713 0 : qq = round_fx_sat( L_shl_sat( L_tmp, 3 ) ); /*Q10*/
1714 0 : rr = s_min( rr, qq ); /* Q10 */
1715 0 : rr = s_max( rr, pp ); /* Q10 */
1716 : }
1717 : ELSE
1718 : {
1719 0 : test();
1720 0 : IF( LT_16( rr, 1024 /* 1 in Q10 */ ) && LT_16( ( hAmrwb_IO->prev_r_fx ), 1024 /* 1 in Q10 */ ) )
1721 : {
1722 0 : L_tmp = L_mult( rr, rr ); /*Q21*/
1723 0 : tmp = round_fx( L_shl( L_tmp, 9 ) ); /*Q14*/
1724 0 : L_tmp = L_sub( 2097152 /* 1 in Q21 */, L_tmp ); /*Q21*/
1725 0 : alpha = round_fx( L_shl( L_tmp, 9 ) ); /*Q14*/
1726 0 : L_tmp = L_mult( alpha, ( hAmrwb_IO->prev_r_fx ) ); /*Q25*/
1727 0 : L_tmp = L_mac( L_tmp, tmp, rr ); /*Q25*/
1728 0 : rr = round_fx_sat( L_shl_sat( L_tmp, 1 ) ); /*Q10*/
1729 : }
1730 :
1731 0 : hAmrwb_IO->prev_r_fx = rr;
1732 0 : move16();
1733 :
1734 0 : L_tmp = L_mult( tilt, sub( 26214 /* 1.6f in Q14 */, shr( voice_factor, 1 ) ) ); /*Q28*/
1735 :
1736 0 : L_tmp = L_min( L_tmp, 268435456 /* 1 in Q28 */ );
1737 0 : L_tmp = Mult_32_16( L_tmp, qq ); /*Q23*/
1738 0 : est_level1 = round_fx( L_shl( L_tmp, 3 ) ); /*Q10*/
1739 :
1740 0 : tmp = pp;
1741 0 : move16();
1742 0 : tmp = s_min( tmp, qq );
1743 0 : rr = s_min( tmp, rr );
1744 :
1745 0 : L_tmp = L_mult( abs_s( sub( tilt, 8192 /* 1 in Q13 */ ) ), sub( 26214 /* 1.6 in Q14 */, shr( voice_factor, 1 ) ) ); /*Q28*/
1746 0 : L_tmp = L_add( L_tmp, 268435456 /* 1 in Q28 */ );
1747 0 : L_tmp = Mult_32_16( L_tmp, rr ); /*Q23*/
1748 0 : est_level2 = round_fx( L_shl( L_tmp, 3 ) ); /*Q10*/
1749 :
1750 0 : rr = s_min( est_level1, est_level2 );
1751 : }
1752 :
1753 :
1754 0 : q1 = norm_s( pp );
1755 0 : tmp = div_s( shl( 1, sub( 14, q1 ) ), pp ); /*Q(29-q1-10) */
1756 0 : L_tmp = L_mult( rr, tmp ); /*Q(30-q1-10+10) */
1757 :
1758 0 : *sub_gain = s_min( 20480 /* 5.0f in Q12 */, round_fx_sat( L_shl_sat( L_tmp, sub( q1, 2 ) ) ) ); /*Q12 */
1759 0 : move16();
1760 0 : return;
1761 : }
1762 :
1763 : /*---------------------------------------------------------------------*
1764 : * AdaptiveStartBand_fx()
1765 : *
1766 : * adaptively select the start band of bandwidth extension
1767 : *---------------------------------------------------------------------*/
1768 :
1769 0 : static void AdaptiveStartBand_fx(
1770 : Word16 *start_band, /* o : start point of copied band Q0*/
1771 : const Word32 core_rate, /* i : core bitrate Q0*/
1772 : const Word16 *lsf_fx, /* i : lsf frequency Q2*/
1773 : const Word16 voicing_fac_fx, /* i : voicing factors Q14*/
1774 : const Word16 clas, /* i : signal class (determined by FEC algorithm) Q0*/
1775 : Word16 *voicing_flag, /* Q0 */
1776 : Word16 *start_band_old, /* Q0 */
1777 : Word32 *OptCrit_old_fx /*i/o : Q15 */
1778 : )
1779 : {
1780 : Word16 i, pos, M2, voicing_flag_old;
1781 : Word16 lsf_diff_fx[M];
1782 : Word16 W_fx;
1783 : Word16 tmp1, tmp2;
1784 : Word32 L_tmp;
1785 0 : Word32 OptCrit_fx = 32768, Crit_fx;
1786 : Word16 *pt1, flag;
1787 : const Word16 *pt2, *pt3;
1788 :
1789 0 : move32(); // corresponding to initialization of OptCrit_fx
1790 : /*voicing switching flag : to avoid switching start band frequently in VOICED or AUDIO area*/
1791 0 : voicing_flag_old = *voicing_flag; /* Q0 */
1792 0 : move16();
1793 0 : test();
1794 0 : test();
1795 0 : test();
1796 0 : if ( GT_16( voicing_fac_fx, 6554 /* 0.4 in Q14 */ ) || ( GT_16( voicing_fac_fx, 4915 /* 0.3 in Q14 */ ) && GE_16( clas, VOICED_CLAS ) ) || EQ_16( clas, AUDIO_CLAS ) )
1797 : {
1798 0 : *voicing_flag = 1; /* Q0 */
1799 0 : move16();
1800 : }
1801 :
1802 0 : test();
1803 0 : if ( LT_16( voicing_fac_fx, 3277 /* 0.2 in Q14 */ ) && LT_16( clas, VOICED_CLAS ) )
1804 : {
1805 0 : *voicing_flag = 0;
1806 0 : move16();
1807 : }
1808 :
1809 : /* core_rate adaptive start band */
1810 0 : *start_band = 160;
1811 0 : move16();
1812 0 : IF( LT_32( core_rate, ACELP_23k05 ) )
1813 : {
1814 0 : pt1 = lsf_diff_fx + 1;
1815 0 : pt2 = lsf_fx + 1;
1816 0 : pt3 = lsf_fx;
1817 0 : FOR( i = 1; i < ( M - 1 ); i++ )
1818 : {
1819 0 : *pt1++ = sub( *pt2++, *pt3++ );
1820 0 : move16(); /*Q2 */
1821 : }
1822 0 : tmp1 = extract_l( Mult_32_16( core_rate, 27046 /* 0.00005 in Q29 */ ) ); /*Q14 */
1823 0 : L_tmp = L_shr( L_mult0( tmp1, 22370 /* 1/6000 in Q27 */ ), 15 ); /*Q27->1/6000 ->Q26 */
1824 0 : tmp2 = extract_l( L_tmp ); /*Q26 */
1825 0 : W_fx = mult_r( tmp1, tmp2 ); /*Q25 */
1826 :
1827 0 : IF( EQ_16( clas, AUDIO_CLAS ) )
1828 : {
1829 0 : W_fx = mult_r( W_fx, 24576 /* 0.75 in Q15 */ ); /*Q25 */
1830 : }
1831 :
1832 0 : pos = 2;
1833 0 : move16();
1834 0 : M2 = M - 2;
1835 0 : move16();
1836 0 : IF( EQ_16( *voicing_flag, 1 ) )
1837 : {
1838 0 : IF( LE_32( core_rate, ACELP_8k85 ) )
1839 : {
1840 0 : M2 = M - 8;
1841 0 : move16();
1842 : }
1843 0 : ELSE IF( LE_32( core_rate, ACELP_12k65 ) )
1844 : {
1845 0 : M2 = M - 6;
1846 0 : move16();
1847 : }
1848 0 : ELSE IF( LE_32( core_rate, ACELP_15k85 ) )
1849 : {
1850 0 : M2 = M - 4;
1851 0 : move16();
1852 : }
1853 : }
1854 :
1855 : /*do the procedure for i==2*/
1856 0 : L_tmp = L_max( L_msu( 171798692 /* 1 in Q2.56+25+1 */, lsf_fx[2], W_fx ), 171799 /* 0.001 in Q2.56+25+1 */ ); /* Q2.56+25+1 */
1857 0 : Crit_fx = Mult_32_16( L_tmp, lsf_diff_fx[2] ); /* Q2.56+25+1+2.56-15 = Q11+2.56+2.56 */
1858 :
1859 0 : OptCrit_fx = L_add( Crit_fx, 0 );
1860 0 : pos = 2;
1861 0 : move16();
1862 : /*----------------------------------------------------------------*/
1863 :
1864 0 : pt2 = &lsf_fx[3];
1865 0 : pt1 = &lsf_diff_fx[3];
1866 0 : FOR( i = 3; i < M2; i++ )
1867 : {
1868 0 : L_tmp = L_max( L_msu( 171798692 /* 1 in Q2.56+25+1 */, *pt2++, W_fx ), 171799 /* 0.001 in Q2.56+25+1 */ ); /* Q2.56+25+1 */
1869 :
1870 0 : Crit_fx = Mult_32_16( L_tmp, *pt1++ ); /* Q2.56+25+1+2.56-15 = Q11+2.56+2.56 */
1871 :
1872 0 : IF( LE_32( Crit_fx, OptCrit_fx ) )
1873 : {
1874 0 : OptCrit_fx = L_add( Crit_fx, 0 ); /* Q11+2.56+2.56 */
1875 0 : pos = i; /* Q0 */
1876 0 : move16();
1877 : }
1878 : }
1879 :
1880 0 : tmp1 = add( mult_r( lsf_fx[pos - 1], 256 ), mult_r( lsf_fx[pos], 256 ) ); /* Q0 */
1881 0 : *start_band = s_min( s_max( sub( tmp1, 40 ), 40 ), 160 ); /* Q0 */
1882 0 : move16();
1883 :
1884 0 : L_tmp = Mult_32_16( *OptCrit_old_fx, 22938 /* 0.7 in Q15 */ ); /* Q11+2.56+2.56 */
1885 0 : test();
1886 0 : test();
1887 0 : test();
1888 0 : test();
1889 0 : IF( NE_16( voicing_flag_old, *voicing_flag ) || ( *voicing_flag == 0 && LT_32( OptCrit_fx, *OptCrit_old_fx ) ) ||
1890 : ( LT_32( OptCrit_fx, L_tmp ) && GT_32( *OptCrit_old_fx, 858993 /* 64 in Q11+2.56+2.56 */ ) ) )
1891 : {
1892 0 : *OptCrit_old_fx = OptCrit_fx; /* Q15 */
1893 0 : move16();
1894 0 : test();
1895 0 : test();
1896 0 : if ( LT_16( abs_s( sub( ( *start_band ), ( *start_band_old ) ) ), 20 ) && EQ_16( *voicing_flag, 1 ) && EQ_16( voicing_flag_old, 1 ) )
1897 : {
1898 0 : *start_band = *start_band_old; /* Q0 */
1899 0 : move16();
1900 : }
1901 : }
1902 : ELSE
1903 : {
1904 0 : test();
1905 0 : if ( LT_32( OptCrit_fx, ( *OptCrit_old_fx ) ) && EQ_16( ( *voicing_flag ), 1 ) )
1906 : {
1907 0 : *OptCrit_old_fx = OptCrit_fx; /* Q15 */
1908 0 : move16();
1909 : }
1910 :
1911 0 : *start_band = *start_band_old; /* Q0 */
1912 0 : move16();
1913 : }
1914 :
1915 0 : IF( EQ_16( clas, AUDIO_CLAS ) )
1916 : {
1917 0 : *start_band = s_min( *start_band, 120 ); /* Q0 */
1918 0 : move16();
1919 : }
1920 :
1921 0 : flag = sub( s_and( *start_band, 0x0001 ), 1 );
1922 0 : IF( flag == 0 )
1923 : {
1924 0 : *start_band = sub( *start_band, 1 ); /* Q0 */
1925 0 : move16();
1926 : }
1927 : }
1928 :
1929 0 : *start_band_old = *start_band; /* Q0 */
1930 0 : move16();
1931 :
1932 0 : return;
1933 : }
|