1 /*
2  ** Copyright 2003-2010, VisualOn, Inc.
3  **
4  ** Licensed under the Apache License, Version 2.0 (the "License");
5  ** you may not use this file except in compliance with the License.
6  ** You may obtain a copy of the License at
7  **
8  **     http://www.apache.org/licenses/LICENSE-2.0
9  **
10  ** Unless required by applicable law or agreed to in writing, software
11  ** distributed under the License is distributed on an "AS IS" BASIS,
12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  ** See the License for the specific language governing permissions and
14  ** limitations under the License.
15  */
16 
17 /***********************************************************************
18 *      File: voAMRWBEnc.c                                              *
19 *                                                                      *
20 *      Description: Performs the main encoder routine                  *
21 *                   Fixed-point C simulation of AMR WB ACELP coding    *
22 *		    algorithm with 20 msspeech frames for              *
23 *		    wideband speech signals.                           *
24 *                                                                      *
25 ************************************************************************/
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include "typedef.h"
30 #include "basic_op.h"
31 #include "oper_32b.h"
32 #include "math_op.h"
33 #include "cnst.h"
34 #include "acelp.h"
35 #include "cod_main.h"
36 #include "bits.h"
37 #include "main.h"
38 #include "voAMRWB.h"
39 #include "mem_align.h"
40 #include "cmnMemory.h"
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /* LPC interpolation coef {0.45, 0.8, 0.96, 1.0}; in Q15 */
47 static Word16 interpol_frac[NB_SUBFR] = {14746, 26214, 31457, 32767};
48 
49 /* isp tables for initialization */
50 static Word16 isp_init[M] =
51 {
52 	32138, 30274, 27246, 23170, 18205, 12540, 6393, 0,
53 	-6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475
54 };
55 
56 static Word16 isf_init[M] =
57 {
58 	1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192,
59 	9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840
60 };
61 
62 /* High Band encoding */
63 static const Word16 HP_gain[16] =
64 {
65 	3624, 4673, 5597, 6479, 7425, 8378, 9324, 10264,
66 	11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728
67 };
68 
69 /* Private function declaration */
70 static Word16 synthesis(
71 			Word16 Aq[],                          /* A(z)  : quantized Az               */
72 			Word16 exc[],                         /* (i)   : excitation at 12kHz        */
73 			Word16 Q_new,                         /* (i)   : scaling performed on exc   */
74 			Word16 synth16k[],                    /* (o)   : 16kHz synthesis signal     */
75 			Coder_State * st                      /* (i/o) : State structure            */
76 			);
77 
78 /* Codec some parameters initialization */
Reset_encoder(void * st,Word16 reset_all)79 void Reset_encoder(void *st, Word16 reset_all)
80 {
81 	Word16 i;
82 	Coder_State *cod_state;
83 	cod_state = (Coder_State *) st;
84 	Set_zero(cod_state->old_exc, PIT_MAX + L_INTERPOL);
85 	Set_zero(cod_state->mem_syn, M);
86 	Set_zero(cod_state->past_isfq, M);
87 	cod_state->mem_w0 = 0;
88 	cod_state->tilt_code = 0;
89 	cod_state->first_frame = 1;
90 	Init_gp_clip(cod_state->gp_clip);
91 	cod_state->L_gc_thres = 0;
92 	if (reset_all != 0)
93 	{
94 		/* Static vectors to zero */
95 		Set_zero(cod_state->old_speech, L_TOTAL - L_FRAME);
96 		Set_zero(cod_state->old_wsp, (PIT_MAX / OPL_DECIM));
97 		Set_zero(cod_state->mem_decim2, 3);
98 		/* routines initialization */
99 		Init_Decim_12k8(cod_state->mem_decim);
100 		Init_HP50_12k8(cod_state->mem_sig_in);
101 		Init_Levinson(cod_state->mem_levinson);
102 		Init_Q_gain2(cod_state->qua_gain);
103 		Init_Hp_wsp(cod_state->hp_wsp_mem);
104 		/* isp initialization */
105 		Copy(isp_init, cod_state->ispold, M);
106 		Copy(isp_init, cod_state->ispold_q, M);
107 		/* variable initialization */
108 		cod_state->mem_preemph = 0;
109 		cod_state->mem_wsp = 0;
110 		cod_state->Q_old = 15;
111 		cod_state->Q_max[0] = 15;
112 		cod_state->Q_max[1] = 15;
113 		cod_state->old_wsp_max = 0;
114 		cod_state->old_wsp_shift = 0;
115 		/* pitch ol initialization */
116 		cod_state->old_T0_med = 40;
117 		cod_state->ol_gain = 0;
118 		cod_state->ada_w = 0;
119 		cod_state->ol_wght_flg = 0;
120 		for (i = 0; i < 5; i++)
121 		{
122 			cod_state->old_ol_lag[i] = 40;
123 		}
124 		Set_zero(cod_state->old_hp_wsp, (L_FRAME / 2) / OPL_DECIM + (PIT_MAX / OPL_DECIM));
125 		Set_zero(cod_state->mem_syn_hf, M);
126 		Set_zero(cod_state->mem_syn_hi, M);
127 		Set_zero(cod_state->mem_syn_lo, M);
128 		Init_HP50_12k8(cod_state->mem_sig_out);
129 		Init_Filt_6k_7k(cod_state->mem_hf);
130 		Init_HP400_12k8(cod_state->mem_hp400);
131 		Copy(isf_init, cod_state->isfold, M);
132 		cod_state->mem_deemph = 0;
133 		cod_state->seed2 = 21845;
134 		Init_Filt_6k_7k(cod_state->mem_hf2);
135 		cod_state->gain_alpha = 32767;
136 		cod_state->vad_hist = 0;
137 		wb_vad_reset(cod_state->vadSt);
138 		dtx_enc_reset(cod_state->dtx_encSt, isf_init);
139 	}
140 	return;
141 }
142 
143 /*-----------------------------------------------------------------*
144 *   Funtion  coder                                                *
145 *            ~~~~~                                                *
146 *   ->Main coder routine.                                         *
147 *                                                                 *
148 *-----------------------------------------------------------------*/
coder(Word16 * mode,Word16 speech16k[],Word16 prms[],Word16 * ser_size,void * spe_state,Word16 allow_dtx)149 void coder(
150 		Word16 * mode,                        /* input :  used mode                             */
151 		Word16 speech16k[],                   /* input :  320 new speech samples (at 16 kHz)    */
152 		Word16 prms[],                        /* output:  output parameters                     */
153 		Word16 * ser_size,                    /* output:  bit rate of the used mode             */
154 		void *spe_state,                      /* i/o   :  State structure                       */
155 		Word16 allow_dtx                      /* input :  DTX ON/OFF                            */
156 	  )
157 {
158 	/* Coder states */
159 	Coder_State *st;
160 	/* Speech vector */
161 	Word16 old_speech[L_TOTAL];
162 	Word16 *new_speech, *speech, *p_window;
163 
164 	/* Weighted speech vector */
165 	Word16 old_wsp[L_FRAME + (PIT_MAX / OPL_DECIM)];
166 	Word16 *wsp;
167 
168 	/* Excitation vector */
169 	Word16 old_exc[(L_FRAME + 1) + PIT_MAX + L_INTERPOL];
170 	Word16 *exc;
171 
172 	/* LPC coefficients */
173 	Word16 r_h[M + 1], r_l[M + 1];         /* Autocorrelations of windowed speech  */
174 	Word16 rc[M];                          /* Reflection coefficients.             */
175 	Word16 Ap[M + 1];                      /* A(z) with spectral expansion         */
176 	Word16 ispnew[M];                      /* immittance spectral pairs at 4nd sfr */
177 	Word16 ispnew_q[M];                    /* quantized ISPs at 4nd subframe       */
178 	Word16 isf[M];                         /* ISF (frequency domain) at 4nd sfr    */
179 	Word16 *p_A, *p_Aq;                    /* ptr to A(z) for the 4 subframes      */
180 	Word16 A[NB_SUBFR * (M + 1)];          /* A(z) unquantized for the 4 subframes */
181 	Word16 Aq[NB_SUBFR * (M + 1)];         /* A(z)   quantized for the 4 subframes */
182 
183 	/* Other vectors */
184 	Word16 xn[L_SUBFR];                    /* Target vector for pitch search     */
185 	Word16 xn2[L_SUBFR];                   /* Target vector for codebook search  */
186 	Word16 dn[L_SUBFR];                    /* Correlation between xn2 and h1     */
187 	Word16 cn[L_SUBFR];                    /* Target vector in residual domain   */
188 	Word16 h1[L_SUBFR];                    /* Impulse response vector            */
189 	Word16 h2[L_SUBFR];                    /* Impulse response vector            */
190 	Word16 code[L_SUBFR];                  /* Fixed codebook excitation          */
191 	Word16 y1[L_SUBFR];                    /* Filtered adaptive excitation       */
192 	Word16 y2[L_SUBFR];                    /* Filtered adaptive excitation       */
193 	Word16 error[M + L_SUBFR];             /* error of quantization              */
194 	Word16 synth[L_SUBFR];                 /* 12.8kHz synthesis vector           */
195 	Word16 exc2[L_FRAME];                  /* excitation vector                  */
196 	Word16 buf[L_FRAME];                   /* VAD buffer                         */
197 
198 	/* Scalars */
199 	Word32 i, j, i_subfr, select, pit_flag, clip_gain, vad_flag;
200 	Word16 codec_mode;
201 	Word16 T_op, T_op2, T0, T0_min, T0_max, T0_frac, index;
202 	Word16 gain_pit, gain_code, g_coeff[4], g_coeff2[4];
203 	Word16 tmp, gain1, gain2, exp, Q_new, mu, shift, max;
204 	Word16 voice_fac;
205 	Word16 indice[8];
206 	Word32 L_tmp, L_gain_code, L_max, L_tmp1;
207 	Word16 code2[L_SUBFR];                         /* Fixed codebook excitation  */
208 	Word16 stab_fac, fac, gain_code_lo;
209 
210 	Word16 corr_gain;
211 	Word16 *vo_p0, *vo_p1, *vo_p2, *vo_p3;
212 
213 	st = (Coder_State *) spe_state;
214 
215 	*ser_size = nb_of_bits[*mode];
216 	codec_mode = *mode;
217 
218 	/*--------------------------------------------------------------------------*
219 	 *          Initialize pointers to speech vector.                           *
220 	 *                                                                          *
221 	 *                                                                          *
222 	 *                    |-------|-------|-------|-------|-------|-------|     *
223 	 *                     past sp   sf1     sf2     sf3     sf4    L_NEXT      *
224 	 *                    <-------  Total speech buffer (L_TOTAL)   ------>     *
225 	 *              old_speech                                                  *
226 	 *                    <-------  LPC analysis window (L_WINDOW)  ------>     *
227 	 *                    |       <-- present frame (L_FRAME) ---->             *
228 	 *                   p_window |       <----- new speech (L_FRAME) ---->     *
229 	 *                            |       |                                     *
230 	 *                          speech    |                                     *
231 	 *                                 new_speech                               *
232 	 *--------------------------------------------------------------------------*/
233 
234 	new_speech = old_speech + L_TOTAL - L_FRAME - L_FILT;         /* New speech     */
235 	speech = old_speech + L_TOTAL - L_FRAME - L_NEXT;             /* Present frame  */
236 	p_window = old_speech + L_TOTAL - L_WINDOW;
237 
238 	exc = old_exc + PIT_MAX + L_INTERPOL;
239 	wsp = old_wsp + (PIT_MAX / OPL_DECIM);
240 
241 	/* copy coder memory state into working space */
242 	Copy(st->old_speech, old_speech, L_TOTAL - L_FRAME);
243 	Copy(st->old_wsp, old_wsp, PIT_MAX / OPL_DECIM);
244 	Copy(st->old_exc, old_exc, PIT_MAX + L_INTERPOL);
245 
246 	/*---------------------------------------------------------------*
247 	 * Down sampling signal from 16kHz to 12.8kHz                    *
248 	 * -> The signal is extended by L_FILT samples (padded to zero)  *
249 	 * to avoid additional delay (L_FILT samples) in the coder.      *
250 	 * The last L_FILT samples are approximated after decimation and *
251 	 * are used (and windowed) only in autocorrelations.             *
252 	 *---------------------------------------------------------------*/
253 
254 	Decim_12k8(speech16k, L_FRAME16k, new_speech, st->mem_decim);
255 
256 	/* last L_FILT samples for autocorrelation window */
257 	Copy(st->mem_decim, code, 2 * L_FILT16k);
258 	Set_zero(error, L_FILT16k);            /* set next sample to zero */
259 	Decim_12k8(error, L_FILT16k, new_speech + L_FRAME, code);
260 
261 	/*---------------------------------------------------------------*
262 	 * Perform 50Hz HP filtering of input signal.                    *
263 	 *---------------------------------------------------------------*/
264 
265 	HP50_12k8(new_speech, L_FRAME, st->mem_sig_in);
266 
267 	/* last L_FILT samples for autocorrelation window */
268 	Copy(st->mem_sig_in, code, 6);
269 	HP50_12k8(new_speech + L_FRAME, L_FILT, code);
270 
271 	/*---------------------------------------------------------------*
272 	 * Perform fixed preemphasis through 1 - g z^-1                  *
273 	 * Scale signal to get maximum of precision in filtering         *
274 	 *---------------------------------------------------------------*/
275 
276 	mu = PREEMPH_FAC >> 1;              /* Q15 --> Q14 */
277 
278 	/* get max of new preemphased samples (L_FRAME+L_FILT) */
279 	L_tmp = new_speech[0] << 15;
280 	L_tmp -= (st->mem_preemph * mu)<<1;
281 	L_max = L_abs(L_tmp);
282 
283 	for (i = 1; i < L_FRAME + L_FILT; i++)
284 	{
285 		L_tmp = new_speech[i] << 15;
286 		L_tmp -= (new_speech[i - 1] * mu)<<1;
287 		L_tmp = L_abs(L_tmp);
288 		if(L_tmp > L_max)
289 		{
290 			L_max = L_tmp;
291 		}
292 	}
293 
294 	/* get scaling factor for new and previous samples */
295 	/* limit scaling to Q_MAX to keep dynamic for ringing in low signal */
296 	/* limit scaling to Q_MAX also to avoid a[0]<1 in syn_filt_32 */
297 	tmp = extract_h(L_max);
298 	if (tmp == 0)
299 	{
300 		shift = Q_MAX;
301 	} else
302 	{
303 		shift = norm_s(tmp) - 1;
304 		if (shift < 0)
305 		{
306 			shift = 0;
307 		}
308 		if (shift > Q_MAX)
309 		{
310 			shift = Q_MAX;
311 		}
312 	}
313 	Q_new = shift;
314 	if (Q_new > st->Q_max[0])
315 	{
316 		Q_new = st->Q_max[0];
317 	}
318 	if (Q_new > st->Q_max[1])
319 	{
320 		Q_new = st->Q_max[1];
321 	}
322 	exp = (Q_new - st->Q_old);
323 	st->Q_old = Q_new;
324 	st->Q_max[1] = st->Q_max[0];
325 	st->Q_max[0] = shift;
326 
327 	/* preemphasis with scaling (L_FRAME+L_FILT) */
328 	tmp = new_speech[L_FRAME - 1];
329 
330 	for (i = L_FRAME + L_FILT - 1; i > 0; i--)
331 	{
332 		L_tmp = new_speech[i] << 15;
333 		L_tmp -= (new_speech[i - 1] * mu)<<1;
334 		L_tmp = (L_tmp << Q_new);
335 		new_speech[i] = vo_round(L_tmp);
336 	}
337 
338 	L_tmp = new_speech[0] << 15;
339 	L_tmp -= (st->mem_preemph * mu)<<1;
340 	L_tmp = (L_tmp << Q_new);
341 	new_speech[0] = vo_round(L_tmp);
342 
343 	st->mem_preemph = tmp;
344 
345 	/* scale previous samples and memory */
346 
347 	Scale_sig(old_speech, L_TOTAL - L_FRAME - L_FILT, exp);
348 	Scale_sig(old_exc, PIT_MAX + L_INTERPOL, exp);
349 	Scale_sig(st->mem_syn, M, exp);
350 	Scale_sig(st->mem_decim2, 3, exp);
351 	Scale_sig(&(st->mem_wsp), 1, exp);
352 	Scale_sig(&(st->mem_w0), 1, exp);
353 
354 	/*------------------------------------------------------------------------*
355 	 *  Call VAD                                                              *
356 	 *  Preemphesis scale down signal in low frequency and keep dynamic in HF.*
357 	 *  Vad work slightly in futur (new_speech = speech + L_NEXT - L_FILT).   *
358 	 *------------------------------------------------------------------------*/
359 	Copy(new_speech, buf, L_FRAME);
360 
361 #ifdef ASM_OPT        /* asm optimization branch */
362 	Scale_sig_opt(buf, L_FRAME, 1 - Q_new);
363 #else
364 	Scale_sig(buf, L_FRAME, 1 - Q_new);
365 #endif
366 
367 	vad_flag = wb_vad(st->vadSt, buf);          /* Voice Activity Detection */
368 	if (vad_flag == 0)
369 	{
370 		st->vad_hist = (st->vad_hist + 1);
371 	} else
372 	{
373 		st->vad_hist = 0;
374 	}
375 
376 	/* DTX processing */
377 	if (allow_dtx != 0)
378 	{
379 		/* Note that mode may change here */
380 		tx_dtx_handler(st->dtx_encSt, vad_flag, mode);
381 		*ser_size = nb_of_bits[*mode];
382 	}
383 
384 	if(*mode != MRDTX)
385 	{
386 		Parm_serial(vad_flag, 1, &prms);
387 	}
388 	/*------------------------------------------------------------------------*
389 	 *  Perform LPC analysis                                                  *
390 	 *  ~~~~~~~~~~~~~~~~~~~~                                                  *
391 	 *   - autocorrelation + lag windowing                                    *
392 	 *   - Levinson-durbin algorithm to find a[]                              *
393 	 *   - convert a[] to isp[]                                               *
394 	 *   - convert isp[] to isf[] for quantization                            *
395 	 *   - quantize and code the isf[]                                        *
396 	 *   - convert isf[] to isp[] for interpolation                           *
397 	 *   - find the interpolated ISPs and convert to a[] for the 4 subframes  *
398 	 *------------------------------------------------------------------------*/
399 
400 	/* LP analysis centered at 4nd subframe */
401 	Autocorr(p_window, M, r_h, r_l);                        /* Autocorrelations */
402 	Lag_window(r_h, r_l);                                   /* Lag windowing    */
403 	Levinson(r_h, r_l, A, rc, st->mem_levinson);            /* Levinson Durbin  */
404 	Az_isp(A, ispnew, st->ispold);                          /* From A(z) to ISP */
405 
406 	/* Find the interpolated ISPs and convert to a[] for all subframes */
407 	Int_isp(st->ispold, ispnew, interpol_frac, A);
408 
409 	/* update ispold[] for the next frame */
410 	Copy(ispnew, st->ispold, M);
411 
412 	/* Convert ISPs to frequency domain 0..6400 */
413 	Isp_isf(ispnew, isf, M);
414 
415 	/* check resonance for pitch clipping algorithm */
416 	Gp_clip_test_isf(isf, st->gp_clip);
417 
418 	/*----------------------------------------------------------------------*
419 	 *  Perform PITCH_OL analysis                                           *
420 	 *  ~~~~~~~~~~~~~~~~~~~~~~~~~                                           *
421 	 * - Find the residual res[] for the whole speech frame                 *
422 	 * - Find the weighted input speech wsp[] for the whole speech frame    *
423 	 * - scale wsp[] to avoid overflow in pitch estimation                  *
424 	 * - Find open loop pitch lag for whole speech frame                    *
425 	 *----------------------------------------------------------------------*/
426 	p_A = A;
427 	for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
428 	{
429 		/* Weighting of LPC coefficients */
430 		Weight_a(p_A, Ap, GAMMA1, M);
431 
432 #ifdef ASM_OPT                    /* asm optimization branch */
433 		Residu_opt(Ap, &speech[i_subfr], &wsp[i_subfr], L_SUBFR);
434 #else
435 		Residu(Ap, &speech[i_subfr], &wsp[i_subfr], L_SUBFR);
436 #endif
437 
438 		p_A += (M + 1);
439 	}
440 
441 	Deemph2(wsp, TILT_FAC, L_FRAME, &(st->mem_wsp));
442 
443 	/* find maximum value on wsp[] for 12 bits scaling */
444 	max = 0;
445 	for (i = 0; i < L_FRAME; i++)
446 	{
447 		tmp = abs_s(wsp[i]);
448 		if(tmp > max)
449 		{
450 			max = tmp;
451 		}
452 	}
453 	tmp = st->old_wsp_max;
454 	if(max > tmp)
455 	{
456 		tmp = max;                         /* tmp = max(wsp_max, old_wsp_max) */
457 	}
458 	st->old_wsp_max = max;
459 
460 	shift = norm_s(tmp) - 3;
461 	if (shift > 0)
462 	{
463 		shift = 0;                         /* shift = 0..-3 */
464 	}
465 	/* decimation of wsp[] to search pitch in LF and to reduce complexity */
466 	LP_Decim2(wsp, L_FRAME, st->mem_decim2);
467 
468 	/* scale wsp[] in 12 bits to avoid overflow */
469 #ifdef  ASM_OPT                  /* asm optimization branch */
470 	Scale_sig_opt(wsp, L_FRAME / OPL_DECIM, shift);
471 #else
472 	Scale_sig(wsp, L_FRAME / OPL_DECIM, shift);
473 #endif
474 	/* scale old_wsp (warning: exp must be Q_new-Q_old) */
475 	exp = exp + (shift - st->old_wsp_shift);
476 	st->old_wsp_shift = shift;
477 
478 	Scale_sig(old_wsp, PIT_MAX / OPL_DECIM, exp);
479 	Scale_sig(st->old_hp_wsp, PIT_MAX / OPL_DECIM, exp);
480 
481 	scale_mem_Hp_wsp(st->hp_wsp_mem, exp);
482 
483 	/* Find open loop pitch lag for whole speech frame */
484 
485 	if(*ser_size == NBBITS_7k)
486 	{
487 		/* Find open loop pitch lag for whole speech frame */
488 		T_op = Pitch_med_ol(wsp, st, L_FRAME / OPL_DECIM);
489 	} else
490 	{
491 		/* Find open loop pitch lag for first 1/2 frame */
492 		T_op = Pitch_med_ol(wsp, st, (L_FRAME/2) / OPL_DECIM);
493 	}
494 
495 	if(st->ol_gain > 19661)       /* 0.6 in Q15 */
496 	{
497 		st->old_T0_med = Med_olag(T_op, st->old_ol_lag);
498 		st->ada_w = 32767;
499 	} else
500 	{
501 		st->ada_w = vo_mult(st->ada_w, 29491);
502 	}
503 
504 	if(st->ada_w < 26214)
505 		st->ol_wght_flg = 0;
506 	else
507 		st->ol_wght_flg = 1;
508 
509 	wb_vad_tone_detection(st->vadSt, st->ol_gain);
510 	T_op *= OPL_DECIM;
511 
512 	if(*ser_size != NBBITS_7k)
513 	{
514 		/* Find open loop pitch lag for second 1/2 frame */
515 		T_op2 = Pitch_med_ol(wsp + ((L_FRAME / 2) / OPL_DECIM), st, (L_FRAME/2) / OPL_DECIM);
516 
517 		if(st->ol_gain > 19661)   /* 0.6 in Q15 */
518 		{
519 			st->old_T0_med = Med_olag(T_op2, st->old_ol_lag);
520 			st->ada_w = 32767;
521 		} else
522 		{
523 			st->ada_w = mult(st->ada_w, 29491);
524 		}
525 
526 		if(st->ada_w < 26214)
527 			st->ol_wght_flg = 0;
528 		else
529 			st->ol_wght_flg = 1;
530 
531 		wb_vad_tone_detection(st->vadSt, st->ol_gain);
532 
533 		T_op2 *= OPL_DECIM;
534 
535 	} else
536 	{
537 		T_op2 = T_op;
538 	}
539 	/*----------------------------------------------------------------------*
540 	 *                              DTX-CNG                                 *
541 	 *----------------------------------------------------------------------*/
542 	if(*mode == MRDTX)            /* CNG mode */
543 	{
544 		/* Buffer isf's and energy */
545 #ifdef ASM_OPT                   /* asm optimization branch */
546 		Residu_opt(&A[3 * (M + 1)], speech, exc, L_FRAME);
547 #else
548 		Residu(&A[3 * (M + 1)], speech, exc, L_FRAME);
549 #endif
550 
551 		for (i = 0; i < L_FRAME; i++)
552 		{
553 			exc2[i] = shr(exc[i], Q_new);
554 		}
555 
556 		L_tmp = 0;
557 		for (i = 0; i < L_FRAME; i++)
558 			L_tmp += (exc2[i] * exc2[i])<<1;
559 
560 		L_tmp >>= 1;
561 
562 		dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
563 
564 		/* Quantize and code the ISFs */
565 		dtx_enc(st->dtx_encSt, isf, exc2, &prms);
566 
567 		/* Convert ISFs to the cosine domain */
568 		Isf_isp(isf, ispnew_q, M);
569 		Isp_Az(ispnew_q, Aq, M, 0);
570 
571 		for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
572 		{
573 			corr_gain = synthesis(Aq, &exc2[i_subfr], 0, &speech16k[i_subfr * 5 / 4], st);
574 		}
575 		Copy(isf, st->isfold, M);
576 
577 		/* reset speech coder memories */
578 		Reset_encoder(st, 0);
579 
580 		/*--------------------------------------------------*
581 		 * Update signal for next frame.                    *
582 		 * -> save past of speech[] and wsp[].              *
583 		 *--------------------------------------------------*/
584 
585 		Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
586 		Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
587 
588 		return;
589 	}
590 	/*----------------------------------------------------------------------*
591 	 *                               ACELP                                  *
592 	 *----------------------------------------------------------------------*/
593 
594 	/* Quantize and code the ISFs */
595 
596 	if (*ser_size <= NBBITS_7k)
597 	{
598 		Qpisf_2s_36b(isf, isf, st->past_isfq, indice, 4);
599 
600 		Parm_serial(indice[0], 8, &prms);
601 		Parm_serial(indice[1], 8, &prms);
602 		Parm_serial(indice[2], 7, &prms);
603 		Parm_serial(indice[3], 7, &prms);
604 		Parm_serial(indice[4], 6, &prms);
605 	} else
606 	{
607 		Qpisf_2s_46b(isf, isf, st->past_isfq, indice, 4);
608 
609 		Parm_serial(indice[0], 8, &prms);
610 		Parm_serial(indice[1], 8, &prms);
611 		Parm_serial(indice[2], 6, &prms);
612 		Parm_serial(indice[3], 7, &prms);
613 		Parm_serial(indice[4], 7, &prms);
614 		Parm_serial(indice[5], 5, &prms);
615 		Parm_serial(indice[6], 5, &prms);
616 	}
617 
618 	/* Check stability on isf : distance between old isf and current isf */
619 
620 	L_tmp = 0;
621 	for (i = 0; i < M - 1; i++)
622 	{
623 		tmp = vo_sub(isf[i], st->isfold[i]);
624 		L_tmp += (tmp * tmp)<<1;
625 	}
626 
627 	tmp = extract_h(L_shl2(L_tmp, 8));
628 
629 	tmp = vo_mult(tmp, 26214);                /* tmp = L_tmp*0.8/256 */
630 	tmp = vo_sub(20480, tmp);                 /* 1.25 - tmp (in Q14) */
631 
632 	stab_fac = shl(tmp, 1);
633 
634 	if (stab_fac < 0)
635 	{
636 		stab_fac = 0;
637 	}
638 	Copy(isf, st->isfold, M);
639 
640 	/* Convert ISFs to the cosine domain */
641 	Isf_isp(isf, ispnew_q, M);
642 
643 	if (st->first_frame != 0)
644 	{
645 		st->first_frame = 0;
646 		Copy(ispnew_q, st->ispold_q, M);
647 	}
648 	/* Find the interpolated ISPs and convert to a[] for all subframes */
649 
650 	Int_isp(st->ispold_q, ispnew_q, interpol_frac, Aq);
651 
652 	/* update ispold[] for the next frame */
653 	Copy(ispnew_q, st->ispold_q, M);
654 
655 	p_Aq = Aq;
656 	for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
657 	{
658 #ifdef ASM_OPT               /* asm optimization branch */
659 		Residu_opt(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
660 #else
661 		Residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
662 #endif
663 		p_Aq += (M + 1);
664 	}
665 
666 	/* Buffer isf's and energy for dtx on non-speech frame */
667 	if (vad_flag == 0)
668 	{
669 		for (i = 0; i < L_FRAME; i++)
670 		{
671 			exc2[i] = exc[i] >> Q_new;
672 		}
673 		L_tmp = 0;
674 		for (i = 0; i < L_FRAME; i++)
675 			L_tmp += (exc2[i] * exc2[i])<<1;
676 		L_tmp >>= 1;
677 
678 		dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
679 	}
680 	/* range for closed loop pitch search in 1st subframe */
681 
682 	T0_min = T_op - 8;
683 	if (T0_min < PIT_MIN)
684 	{
685 		T0_min = PIT_MIN;
686 	}
687 	T0_max = (T0_min + 15);
688 
689 	if(T0_max > PIT_MAX)
690 	{
691 		T0_max = PIT_MAX;
692 		T0_min = T0_max - 15;
693 	}
694 	/*------------------------------------------------------------------------*
695 	 *          Loop for every subframe in the analysis frame                 *
696 	 *------------------------------------------------------------------------*
697 	 *  To find the pitch and innovation parameters. The subframe size is     *
698 	 *  L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times.               *
699 	 *     - compute the target signal for pitch search                       *
700 	 *     - compute impulse response of weighted synthesis filter (h1[])     *
701 	 *     - find the closed-loop pitch parameters                            *
702 	 *     - encode the pitch dealy                                           *
703 	 *     - find 2 lt prediction (with / without LP filter for lt pred)      *
704 	 *     - find 2 pitch gains and choose the best lt prediction.            *
705 	 *     - find target vector for codebook search                           *
706 	 *     - update the impulse response h1[] for codebook search             *
707 	 *     - correlation between target vector and impulse response           *
708 	 *     - codebook search and encoding                                     *
709 	 *     - VQ of pitch and codebook gains                                   *
710 	 *     - find voicing factor and tilt of code for next subframe.          *
711 	 *     - update states of weighting filter                                *
712 	 *     - find excitation and synthesis speech                             *
713 	 *------------------------------------------------------------------------*/
714 	p_A = A;
715 	p_Aq = Aq;
716 	for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
717 	{
718 		pit_flag = i_subfr;
719 		if ((i_subfr == 2 * L_SUBFR) && (*ser_size > NBBITS_7k))
720 		{
721 			pit_flag = 0;
722 			/* range for closed loop pitch search in 3rd subframe */
723 			T0_min = (T_op2 - 8);
724 
725 			if (T0_min < PIT_MIN)
726 			{
727 				T0_min = PIT_MIN;
728 			}
729 			T0_max = (T0_min + 15);
730 			if (T0_max > PIT_MAX)
731 			{
732 				T0_max = PIT_MAX;
733 				T0_min = (T0_max - 15);
734 			}
735 		}
736 		/*-----------------------------------------------------------------------*
737 		 *                                                                       *
738 		 *        Find the target vector for pitch search:                       *
739 		 *        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                        *
740 		 *                                                                       *
741 		 *             |------|  res[n]                                          *
742 		 * speech[n]---| A(z) |--------                                          *
743 		 *             |------|       |   |--------| error[n]  |------|          *
744 		 *                   zero -- (-)--| 1/A(z) |-----------| W(z) |-- target *
745 		 *                   exc          |--------|           |------|          *
746 		 *                                                                       *
747 		 * Instead of subtracting the zero-input response of filters from        *
748 		 * the weighted input speech, the above configuration is used to         *
749 		 * compute the target vector.                                            *
750 		 *                                                                       *
751 		 *-----------------------------------------------------------------------*/
752 
753 		for (i = 0; i < M; i++)
754 		{
755 			error[i] = vo_sub(speech[i + i_subfr - M], st->mem_syn[i]);
756 		}
757 
758 #ifdef ASM_OPT              /* asm optimization branch */
759 		Residu_opt(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
760 #else
761 		Residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
762 #endif
763 		Syn_filt(p_Aq, &exc[i_subfr], error + M, L_SUBFR, error, 0);
764 		Weight_a(p_A, Ap, GAMMA1, M);
765 
766 #ifdef ASM_OPT             /* asm optimization branch */
767 		Residu_opt(Ap, error + M, xn, L_SUBFR);
768 #else
769 		Residu(Ap, error + M, xn, L_SUBFR);
770 #endif
771 		Deemph2(xn, TILT_FAC, L_SUBFR, &(st->mem_w0));
772 
773 		/*----------------------------------------------------------------------*
774 		 * Find approx. target in residual domain "cn[]" for inovation search.  *
775 		 *----------------------------------------------------------------------*/
776 		/* first half: xn[] --> cn[] */
777 		Set_zero(code, M);
778 		Copy(xn, code + M, L_SUBFR / 2);
779 		tmp = 0;
780 		Preemph2(code + M, TILT_FAC, L_SUBFR / 2, &tmp);
781 		Weight_a(p_A, Ap, GAMMA1, M);
782 		Syn_filt(Ap,code + M, code + M, L_SUBFR / 2, code, 0);
783 
784 #ifdef ASM_OPT                /* asm optimization branch */
785 		Residu_opt(p_Aq,code + M, cn, L_SUBFR / 2);
786 #else
787 		Residu(p_Aq,code + M, cn, L_SUBFR / 2);
788 #endif
789 
790 		/* second half: res[] --> cn[] (approximated and faster) */
791 		Copy(&exc[i_subfr + (L_SUBFR / 2)], cn + (L_SUBFR / 2), L_SUBFR / 2);
792 
793 		/*---------------------------------------------------------------*
794 		 * Compute impulse response, h1[], of weighted synthesis filter  *
795 		 *---------------------------------------------------------------*/
796 
797 		Set_zero(error, M + L_SUBFR);
798 		Weight_a(p_A, error + M, GAMMA1, M);
799 
800 		vo_p0 = error+M;
801 		vo_p3 = h1;
802 		for (i = 0; i < L_SUBFR; i++)
803 		{
804 			L_tmp = *vo_p0 << 14;        /* x4 (Q12 to Q14) */
805 			vo_p1 = p_Aq + 1;
806 			vo_p2 = vo_p0-1;
807 			for (j = 1; j <= M/4; j++)
808 			{
809 				L_tmp -= *vo_p1++ * *vo_p2--;
810 				L_tmp -= *vo_p1++ * *vo_p2--;
811 				L_tmp -= *vo_p1++ * *vo_p2--;
812 				L_tmp -= *vo_p1++ * *vo_p2--;
813 			}
814 			*vo_p3++ = *vo_p0++ = vo_round((L_tmp <<4));
815 		}
816 		/* deemph without division by 2 -> Q14 to Q15 */
817 		tmp = 0;
818 		Deemph2(h1, TILT_FAC, L_SUBFR, &tmp);   /* h1 in Q14 */
819 
820 		/* h2 in Q12 for codebook search */
821 		Copy(h1, h2, L_SUBFR);
822 
823 		/*---------------------------------------------------------------*
824 		 * scale xn[] and h1[] to avoid overflow in dot_product12()      *
825 		 *---------------------------------------------------------------*/
826 #ifdef  ASM_OPT                  /* asm optimization branch */
827 		Scale_sig_opt(h2, L_SUBFR, -2);
828 		Scale_sig_opt(xn, L_SUBFR, shift);     /* scaling of xn[] to limit dynamic at 12 bits */
829 		Scale_sig_opt(h1, L_SUBFR, 1 + shift);  /* set h1[] in Q15 with scaling for convolution */
830 #else
831 		Scale_sig(h2, L_SUBFR, -2);
832 		Scale_sig(xn, L_SUBFR, shift);     /* scaling of xn[] to limit dynamic at 12 bits */
833 		Scale_sig(h1, L_SUBFR, 1 + shift);  /* set h1[] in Q15 with scaling for convolution */
834 #endif
835 		/*----------------------------------------------------------------------*
836 		 *                 Closed-loop fractional pitch search                  *
837 		 *----------------------------------------------------------------------*/
838 		/* find closed loop fractional pitch  lag */
839 		if(*ser_size <= NBBITS_9k)
840 		{
841 			T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
842 					pit_flag, PIT_MIN, PIT_FR1_8b, L_SUBFR);
843 
844 			/* encode pitch lag */
845 			if (pit_flag == 0)             /* if 1st/3rd subframe */
846 			{
847 				/*--------------------------------------------------------------*
848 				 * The pitch range for the 1st/3rd subframe is encoded with     *
849 				 * 8 bits and is divided as follows:                            *
850 				 *   PIT_MIN to PIT_FR1-1  resolution 1/2 (frac = 0 or 2)       *
851 				 *   PIT_FR1 to PIT_MAX    resolution 1   (frac = 0)            *
852 				 *--------------------------------------------------------------*/
853 				if (T0 < PIT_FR1_8b)
854 				{
855 					index = ((T0 << 1) + (T0_frac >> 1) - (PIT_MIN<<1));
856 				} else
857 				{
858 					index = ((T0 - PIT_FR1_8b) + ((PIT_FR1_8b - PIT_MIN)*2));
859 				}
860 
861 				Parm_serial(index, 8, &prms);
862 
863 				/* find T0_min and T0_max for subframe 2 and 4 */
864 				T0_min = (T0 - 8);
865 				if (T0_min < PIT_MIN)
866 				{
867 					T0_min = PIT_MIN;
868 				}
869 				T0_max = T0_min + 15;
870 				if (T0_max > PIT_MAX)
871 				{
872 					T0_max = PIT_MAX;
873 					T0_min = (T0_max - 15);
874 				}
875 			} else
876 			{                              /* if subframe 2 or 4 */
877 				/*--------------------------------------------------------------*
878 				 * The pitch range for subframe 2 or 4 is encoded with 5 bits:  *
879 				 *   T0_min  to T0_max     resolution 1/2 (frac = 0 or 2)       *
880 				 *--------------------------------------------------------------*/
881 				i = (T0 - T0_min);
882 				index = (i << 1) + (T0_frac >> 1);
883 
884 				Parm_serial(index, 5, &prms);
885 			}
886 		} else
887 		{
888 			T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
889 					pit_flag, PIT_FR2, PIT_FR1_9b, L_SUBFR);
890 
891 			/* encode pitch lag */
892 			if (pit_flag == 0)             /* if 1st/3rd subframe */
893 			{
894 				/*--------------------------------------------------------------*
895 				 * The pitch range for the 1st/3rd subframe is encoded with     *
896 				 * 9 bits and is divided as follows:                            *
897 				 *   PIT_MIN to PIT_FR2-1  resolution 1/4 (frac = 0,1,2 or 3)   *
898 				 *   PIT_FR2 to PIT_FR1-1  resolution 1/2 (frac = 0 or 1)       *
899 				 *   PIT_FR1 to PIT_MAX    resolution 1   (frac = 0)            *
900 				 *--------------------------------------------------------------*/
901 
902 				if (T0 < PIT_FR2)
903 				{
904 					index = ((T0 << 2) + T0_frac) - (PIT_MIN << 2);
905 				} else if(T0 < PIT_FR1_9b)
906 				{
907 					index = ((((T0 << 1) + (T0_frac >> 1)) - (PIT_FR2<<1)) + ((PIT_FR2 - PIT_MIN)<<2));
908 				} else
909 				{
910 					index = (((T0 - PIT_FR1_9b) + ((PIT_FR2 - PIT_MIN)<<2)) + ((PIT_FR1_9b - PIT_FR2)<<1));
911 				}
912 
913 				Parm_serial(index, 9, &prms);
914 
915 				/* find T0_min and T0_max for subframe 2 and 4 */
916 
917 				T0_min = (T0 - 8);
918 				if (T0_min < PIT_MIN)
919 				{
920 					T0_min = PIT_MIN;
921 				}
922 				T0_max = T0_min + 15;
923 
924 				if (T0_max > PIT_MAX)
925 				{
926 					T0_max = PIT_MAX;
927 					T0_min = (T0_max - 15);
928 				}
929 			} else
930 			{                              /* if subframe 2 or 4 */
931 				/*--------------------------------------------------------------*
932 				 * The pitch range for subframe 2 or 4 is encoded with 6 bits:  *
933 				 *   T0_min  to T0_max     resolution 1/4 (frac = 0,1,2 or 3)   *
934 				 *--------------------------------------------------------------*/
935 				i = (T0 - T0_min);
936 				index = (i << 2) + T0_frac;
937 				Parm_serial(index, 6, &prms);
938 			}
939 		}
940 
941 		/*-----------------------------------------------------------------*
942 		 * Gain clipping test to avoid unstable synthesis on frame erasure *
943 		 *-----------------------------------------------------------------*/
944 
945 		clip_gain = 0;
946 		if((st->gp_clip[0] < 154) && (st->gp_clip[1] > 14746))
947 			clip_gain = 1;
948 
949 		/*-----------------------------------------------------------------*
950 		 * - find unity gain pitch excitation (adaptive codebook entry)    *
951 		 *   with fractional interpolation.                                *
952 		 * - find filtered pitch exc. y1[]=exc[] convolved with h1[])      *
953 		 * - compute pitch gain1                                           *
954 		 *-----------------------------------------------------------------*/
955 		/* find pitch exitation */
956 #ifdef ASM_OPT                  /* asm optimization branch */
957 		pred_lt4_asm(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1);
958 #else
959 		Pred_lt4(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1);
960 #endif
961 		if (*ser_size > NBBITS_9k)
962 		{
963 #ifdef ASM_OPT                   /* asm optimization branch */
964 			Convolve_asm(&exc[i_subfr], h1, y1, L_SUBFR);
965 #else
966 			Convolve(&exc[i_subfr], h1, y1, L_SUBFR);
967 #endif
968 			gain1 = G_pitch(xn, y1, g_coeff, L_SUBFR);
969 			/* clip gain if necessary to avoid problem at decoder */
970 			if ((clip_gain != 0) && (gain1 > GP_CLIP))
971 			{
972 				gain1 = GP_CLIP;
973 			}
974 			/* find energy of new target xn2[] */
975 			Updt_tar(xn, dn, y1, gain1, L_SUBFR);       /* dn used temporary */
976 		} else
977 		{
978 			gain1 = 0;
979 		}
980 		/*-----------------------------------------------------------------*
981 		 * - find pitch excitation filtered by 1st order LP filter.        *
982 		 * - find filtered pitch exc. y2[]=exc[] convolved with h1[])      *
983 		 * - compute pitch gain2                                           *
984 		 *-----------------------------------------------------------------*/
985 		/* find pitch excitation with lp filter */
986 		vo_p0 = exc + i_subfr-1;
987 		vo_p1 = code;
988 		/* find pitch excitation with lp filter */
989 		for (i = 0; i < L_SUBFR/2; i++)
990 		{
991 			L_tmp = 5898 * *vo_p0++;
992 			L_tmp1 = 5898 * *vo_p0;
993 			L_tmp += 20972 * *vo_p0++;
994 			L_tmp1 += 20972 * *vo_p0++;
995 			L_tmp1 += 5898 * *vo_p0--;
996 			L_tmp += 5898 * *vo_p0;
997 			*vo_p1++ = (L_tmp + 0x4000)>>15;
998 			*vo_p1++ = (L_tmp1 + 0x4000)>>15;
999 		}
1000 
1001 #ifdef ASM_OPT                 /* asm optimization branch */
1002 		Convolve_asm(code, h1, y2, L_SUBFR);
1003 #else
1004 		Convolve(code, h1, y2, L_SUBFR);
1005 #endif
1006 
1007 		gain2 = G_pitch(xn, y2, g_coeff2, L_SUBFR);
1008 
1009 		/* clip gain if necessary to avoid problem at decoder */
1010 		if ((clip_gain != 0) && (gain2 > GP_CLIP))
1011 		{
1012 			gain2 = GP_CLIP;
1013 		}
1014 		/* find energy of new target xn2[] */
1015 		Updt_tar(xn, xn2, y2, gain2, L_SUBFR);
1016 		/*-----------------------------------------------------------------*
1017 		 * use the best prediction (minimise quadratic error).             *
1018 		 *-----------------------------------------------------------------*/
1019 		select = 0;
1020 		if(*ser_size > NBBITS_9k)
1021 		{
1022 			L_tmp = 0L;
1023 			vo_p0 = dn;
1024 			vo_p1 = xn2;
1025 			for (i = 0; i < L_SUBFR/2; i++)
1026 			{
1027 				L_tmp += *vo_p0 * *vo_p0;
1028 				vo_p0++;
1029 				L_tmp -= *vo_p1 * *vo_p1;
1030 				vo_p1++;
1031 				L_tmp += *vo_p0 * *vo_p0;
1032 				vo_p0++;
1033 				L_tmp -= *vo_p1 * *vo_p1;
1034 				vo_p1++;
1035 			}
1036 
1037 			if (L_tmp <= 0)
1038 			{
1039 				select = 1;
1040 			}
1041 			Parm_serial(select, 1, &prms);
1042 		}
1043 		if (select == 0)
1044 		{
1045 			/* use the lp filter for pitch excitation prediction */
1046 			gain_pit = gain2;
1047 			Copy(code, &exc[i_subfr], L_SUBFR);
1048 			Copy(y2, y1, L_SUBFR);
1049 			Copy(g_coeff2, g_coeff, 4);
1050 		} else
1051 		{
1052 			/* no filter used for pitch excitation prediction */
1053 			gain_pit = gain1;
1054 			Copy(dn, xn2, L_SUBFR);        /* target vector for codebook search */
1055 		}
1056 		/*-----------------------------------------------------------------*
1057 		 * - update cn[] for codebook search                               *
1058 		 *-----------------------------------------------------------------*/
1059 		Updt_tar(cn, cn, &exc[i_subfr], gain_pit, L_SUBFR);
1060 
1061 #ifdef  ASM_OPT                           /* asm optimization branch */
1062 		Scale_sig_opt(cn, L_SUBFR, shift);     /* scaling of cn[] to limit dynamic at 12 bits */
1063 #else
1064 		Scale_sig(cn, L_SUBFR, shift);     /* scaling of cn[] to limit dynamic at 12 bits */
1065 #endif
1066 		/*-----------------------------------------------------------------*
1067 		 * - include fixed-gain pitch contribution into impulse resp. h1[] *
1068 		 *-----------------------------------------------------------------*/
1069 		tmp = 0;
1070 		Preemph(h2, st->tilt_code, L_SUBFR, &tmp);
1071 
1072 		if (T0_frac > 2)
1073 			T0 = (T0 + 1);
1074 		Pit_shrp(h2, T0, PIT_SHARP, L_SUBFR);
1075 		/*-----------------------------------------------------------------*
1076 		 * - Correlation between target xn2[] and impulse response h1[]    *
1077 		 * - Innovative codebook search                                    *
1078 		 *-----------------------------------------------------------------*/
1079 		cor_h_x(h2, xn2, dn);
1080 		if (*ser_size <= NBBITS_7k)
1081 		{
1082 			ACELP_2t64_fx(dn, cn, h2, code, y2, indice);
1083 
1084 			Parm_serial(indice[0], 12, &prms);
1085 		} else if(*ser_size <= NBBITS_9k)
1086 		{
1087 			ACELP_4t64_fx(dn, cn, h2, code, y2, 20, *ser_size, indice);
1088 
1089 			Parm_serial(indice[0], 5, &prms);
1090 			Parm_serial(indice[1], 5, &prms);
1091 			Parm_serial(indice[2], 5, &prms);
1092 			Parm_serial(indice[3], 5, &prms);
1093 		} else if(*ser_size <= NBBITS_12k)
1094 		{
1095 			ACELP_4t64_fx(dn, cn, h2, code, y2, 36, *ser_size, indice);
1096 
1097 			Parm_serial(indice[0], 9, &prms);
1098 			Parm_serial(indice[1], 9, &prms);
1099 			Parm_serial(indice[2], 9, &prms);
1100 			Parm_serial(indice[3], 9, &prms);
1101 		} else if(*ser_size <= NBBITS_14k)
1102 		{
1103 			ACELP_4t64_fx(dn, cn, h2, code, y2, 44, *ser_size, indice);
1104 
1105 			Parm_serial(indice[0], 13, &prms);
1106 			Parm_serial(indice[1], 13, &prms);
1107 			Parm_serial(indice[2], 9, &prms);
1108 			Parm_serial(indice[3], 9, &prms);
1109 		} else if(*ser_size <= NBBITS_16k)
1110 		{
1111 			ACELP_4t64_fx(dn, cn, h2, code, y2, 52, *ser_size, indice);
1112 
1113 			Parm_serial(indice[0], 13, &prms);
1114 			Parm_serial(indice[1], 13, &prms);
1115 			Parm_serial(indice[2], 13, &prms);
1116 			Parm_serial(indice[3], 13, &prms);
1117 		} else if(*ser_size <= NBBITS_18k)
1118 		{
1119 			ACELP_4t64_fx(dn, cn, h2, code, y2, 64, *ser_size, indice);
1120 
1121 			Parm_serial(indice[0], 2, &prms);
1122 			Parm_serial(indice[1], 2, &prms);
1123 			Parm_serial(indice[2], 2, &prms);
1124 			Parm_serial(indice[3], 2, &prms);
1125 			Parm_serial(indice[4], 14, &prms);
1126 			Parm_serial(indice[5], 14, &prms);
1127 			Parm_serial(indice[6], 14, &prms);
1128 			Parm_serial(indice[7], 14, &prms);
1129 		} else if(*ser_size <= NBBITS_20k)
1130 		{
1131 			ACELP_4t64_fx(dn, cn, h2, code, y2, 72, *ser_size, indice);
1132 
1133 			Parm_serial(indice[0], 10, &prms);
1134 			Parm_serial(indice[1], 10, &prms);
1135 			Parm_serial(indice[2], 2, &prms);
1136 			Parm_serial(indice[3], 2, &prms);
1137 			Parm_serial(indice[4], 10, &prms);
1138 			Parm_serial(indice[5], 10, &prms);
1139 			Parm_serial(indice[6], 14, &prms);
1140 			Parm_serial(indice[7], 14, &prms);
1141 		} else
1142 		{
1143 			ACELP_4t64_fx(dn, cn, h2, code, y2, 88, *ser_size, indice);
1144 
1145 			Parm_serial(indice[0], 11, &prms);
1146 			Parm_serial(indice[1], 11, &prms);
1147 			Parm_serial(indice[2], 11, &prms);
1148 			Parm_serial(indice[3], 11, &prms);
1149 			Parm_serial(indice[4], 11, &prms);
1150 			Parm_serial(indice[5], 11, &prms);
1151 			Parm_serial(indice[6], 11, &prms);
1152 			Parm_serial(indice[7], 11, &prms);
1153 		}
1154 		/*-------------------------------------------------------*
1155 		 * - Add the fixed-gain pitch contribution to code[].    *
1156 		 *-------------------------------------------------------*/
1157 		tmp = 0;
1158 		Preemph(code, st->tilt_code, L_SUBFR, &tmp);
1159 		Pit_shrp(code, T0, PIT_SHARP, L_SUBFR);
1160 		/*----------------------------------------------------------*
1161 		 *  - Compute the fixed codebook gain                       *
1162 		 *  - quantize fixed codebook gain                          *
1163 		 *----------------------------------------------------------*/
1164 		if(*ser_size <= NBBITS_9k)
1165 		{
1166 			index = Q_gain2(xn, y1, Q_new + shift, y2, code, g_coeff, L_SUBFR, 6,
1167 					&gain_pit, &L_gain_code, clip_gain, st->qua_gain);
1168 			Parm_serial(index, 6, &prms);
1169 		} else
1170 		{
1171 			index = Q_gain2(xn, y1, Q_new + shift, y2, code, g_coeff, L_SUBFR, 7,
1172 					&gain_pit, &L_gain_code, clip_gain, st->qua_gain);
1173 			Parm_serial(index, 7, &prms);
1174 		}
1175 		/* test quantized gain of pitch for pitch clipping algorithm */
1176 		Gp_clip_test_gain_pit(gain_pit, st->gp_clip);
1177 
1178 		L_tmp = L_shl(L_gain_code, Q_new);
1179 		gain_code = extract_h(L_add(L_tmp, 0x8000));
1180 
1181 		/*----------------------------------------------------------*
1182 		 * Update parameters for the next subframe.                 *
1183 		 * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced)           *
1184 		 *----------------------------------------------------------*/
1185 		/* find voice factor in Q15 (1=voiced, -1=unvoiced) */
1186 		Copy(&exc[i_subfr], exc2, L_SUBFR);
1187 
1188 #ifdef ASM_OPT                           /* asm optimization branch */
1189 		Scale_sig_opt(exc2, L_SUBFR, shift);
1190 #else
1191 		Scale_sig(exc2, L_SUBFR, shift);
1192 #endif
1193 		voice_fac = voice_factor(exc2, shift, gain_pit, code, gain_code, L_SUBFR);
1194 		/* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
1195 		st->tilt_code = ((voice_fac >> 2) + 8192);
1196 		/*------------------------------------------------------*
1197 		 * - Update filter's memory "mem_w0" for finding the    *
1198 		 *   target vector in the next subframe.                *
1199 		 * - Find the total excitation                          *
1200 		 * - Find synthesis speech to update mem_syn[].         *
1201 		 *------------------------------------------------------*/
1202 
1203 		/* y2 in Q9, gain_pit in Q14 */
1204 		L_tmp = (gain_code * y2[L_SUBFR - 1])<<1;
1205 		L_tmp = L_shl(L_tmp, (5 + shift));
1206 		L_tmp = L_negate(L_tmp);
1207 		L_tmp += (xn[L_SUBFR - 1] * 16384)<<1;
1208 		L_tmp -= (y1[L_SUBFR - 1] * gain_pit)<<1;
1209 		L_tmp = L_shl(L_tmp, (1 - shift));
1210 		st->mem_w0 = extract_h(L_add(L_tmp, 0x8000));
1211 
1212 		if (*ser_size >= NBBITS_24k)
1213 			Copy(&exc[i_subfr], exc2, L_SUBFR);
1214 
1215 		for (i = 0; i < L_SUBFR; i++)
1216 		{
1217 			/* code in Q9, gain_pit in Q14 */
1218 			L_tmp = (gain_code * code[i])<<1;
1219 			L_tmp = (L_tmp << 5);
1220 			L_tmp += (exc[i + i_subfr] * gain_pit)<<1;
1221 			L_tmp = L_shl2(L_tmp, 1);
1222 			exc[i + i_subfr] = extract_h(L_add(L_tmp, 0x8000));
1223 		}
1224 
1225 		Syn_filt(p_Aq,&exc[i_subfr], synth, L_SUBFR, st->mem_syn, 1);
1226 
1227 		if(*ser_size >= NBBITS_24k)
1228 		{
1229 			/*------------------------------------------------------------*
1230 			 * phase dispersion to enhance noise in low bit rate          *
1231 			 *------------------------------------------------------------*/
1232 			/* L_gain_code in Q16 */
1233 			VO_L_Extract(L_gain_code, &gain_code, &gain_code_lo);
1234 
1235 			/*------------------------------------------------------------*
1236 			 * noise enhancer                                             *
1237 			 * ~~~~~~~~~~~~~~                                             *
1238 			 * - Enhance excitation on noise. (modify gain of code)       *
1239 			 *   If signal is noisy and LPC filter is stable, move gain   *
1240 			 *   of code 1.5 dB toward gain of code threshold.            *
1241 			 *   This decrease by 3 dB noise energy variation.            *
1242 			 *------------------------------------------------------------*/
1243 			tmp = (16384 - (voice_fac >> 1));        /* 1=unvoiced, 0=voiced */
1244 			fac = vo_mult(stab_fac, tmp);
1245 			L_tmp = L_gain_code;
1246 			if(L_tmp < st->L_gc_thres)
1247 			{
1248 				L_tmp = vo_L_add(L_tmp, Mpy_32_16(gain_code, gain_code_lo, 6226));
1249 				if(L_tmp > st->L_gc_thres)
1250 				{
1251 					L_tmp = st->L_gc_thres;
1252 				}
1253 			} else
1254 			{
1255 				L_tmp = Mpy_32_16(gain_code, gain_code_lo, 27536);
1256 				if(L_tmp < st->L_gc_thres)
1257 				{
1258 					L_tmp = st->L_gc_thres;
1259 				}
1260 			}
1261 			st->L_gc_thres = L_tmp;
1262 
1263 			L_gain_code = Mpy_32_16(gain_code, gain_code_lo, (32767 - fac));
1264 			VO_L_Extract(L_tmp, &gain_code, &gain_code_lo);
1265 			L_gain_code = vo_L_add(L_gain_code, Mpy_32_16(gain_code, gain_code_lo, fac));
1266 
1267 			/*------------------------------------------------------------*
1268 			 * pitch enhancer                                             *
1269 			 * ~~~~~~~~~~~~~~                                             *
1270 			 * - Enhance excitation on voice. (HP filtering of code)      *
1271 			 *   On voiced signal, filtering of code by a smooth fir HP   *
1272 			 *   filter to decrease energy of code in low frequency.      *
1273 			 *------------------------------------------------------------*/
1274 
1275 			tmp = ((voice_fac >> 3) + 4096); /* 0.25=voiced, 0=unvoiced */
1276 
1277 			L_tmp = L_deposit_h(code[0]);
1278 			L_tmp -= (code[1] * tmp)<<1;
1279 			code2[0] = vo_round(L_tmp);
1280 
1281 			for (i = 1; i < L_SUBFR - 1; i++)
1282 			{
1283 				L_tmp = L_deposit_h(code[i]);
1284 				L_tmp -= (code[i + 1] * tmp)<<1;
1285 				L_tmp -= (code[i - 1] * tmp)<<1;
1286 				code2[i] = vo_round(L_tmp);
1287 			}
1288 
1289 			L_tmp = L_deposit_h(code[L_SUBFR - 1]);
1290 			L_tmp -= (code[L_SUBFR - 2] * tmp)<<1;
1291 			code2[L_SUBFR - 1] = vo_round(L_tmp);
1292 
1293 			/* build excitation */
1294 			gain_code = vo_round(L_shl(L_gain_code, Q_new));
1295 
1296 			for (i = 0; i < L_SUBFR; i++)
1297 			{
1298 				L_tmp = (code2[i] * gain_code)<<1;
1299 				L_tmp = (L_tmp << 5);
1300 				L_tmp += (exc2[i] * gain_pit)<<1;
1301 				L_tmp = (L_tmp << 1);
1302 				exc2[i] = vo_round(L_tmp);
1303 			}
1304 
1305 			corr_gain = synthesis(p_Aq, exc2, Q_new, &speech16k[i_subfr * 5 / 4], st);
1306 			Parm_serial(corr_gain, 4, &prms);
1307 		}
1308 		p_A += (M + 1);
1309 		p_Aq += (M + 1);
1310 	}                                      /* end of subframe loop */
1311 
1312 	/*--------------------------------------------------*
1313 	 * Update signal for next frame.                    *
1314 	 * -> save past of speech[], wsp[] and exc[].       *
1315 	 *--------------------------------------------------*/
1316 	Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
1317 	Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
1318 	Copy(&old_exc[L_FRAME], st->old_exc, PIT_MAX + L_INTERPOL);
1319 	return;
1320 }
1321 
1322 /*-----------------------------------------------------*
1323 * Function synthesis()                                *
1324 *                                                     *
1325 * Synthesis of signal at 16kHz with HF extension.     *
1326 *                                                     *
1327 *-----------------------------------------------------*/
1328 
synthesis(Word16 Aq[],Word16 exc[],Word16 Q_new,Word16 synth16k[],Coder_State * st)1329 static Word16 synthesis(
1330 		Word16 Aq[],                          /* A(z)  : quantized Az               */
1331 		Word16 exc[],                         /* (i)   : excitation at 12kHz        */
1332 		Word16 Q_new,                         /* (i)   : scaling performed on exc   */
1333 		Word16 synth16k[],                    /* (o)   : 16kHz synthesis signal     */
1334 		Coder_State * st                      /* (i/o) : State structure            */
1335 		)
1336 {
1337 	Word16 fac, tmp, exp;
1338 	Word16 ener, exp_ener;
1339 	Word32 L_tmp, i;
1340 
1341 	Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR];
1342 	Word16 synth[L_SUBFR];
1343 	Word16 HF[L_SUBFR16k];                 /* High Frequency vector      */
1344 	Word16 Ap[M + 1];
1345 
1346 	Word16 HF_SP[L_SUBFR16k];              /* High Frequency vector (from original signal) */
1347 
1348 	Word16 HP_est_gain, HP_calc_gain, HP_corr_gain;
1349 	Word16 dist_min, dist;
1350 	Word16 HP_gain_ind = 0;
1351 	Word16 gain1, gain2;
1352 	Word16 weight1, weight2;
1353 
1354 	/*------------------------------------------------------------*
1355 	 * speech synthesis                                           *
1356 	 * ~~~~~~~~~~~~~~~~                                           *
1357 	 * - Find synthesis speech corresponding to exc2[].           *
1358 	 * - Perform fixed deemphasis and hp 50hz filtering.          *
1359 	 * - Oversampling from 12.8kHz to 16kHz.                      *
1360 	 *------------------------------------------------------------*/
1361 	Copy(st->mem_syn_hi, synth_hi, M);
1362 	Copy(st->mem_syn_lo, synth_lo, M);
1363 
1364 #ifdef ASM_OPT                 /* asm optimization branch */
1365 	Syn_filt_32_asm(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
1366 #else
1367 	Syn_filt_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
1368 #endif
1369 
1370 	Copy(synth_hi + L_SUBFR, st->mem_syn_hi, M);
1371 	Copy(synth_lo + L_SUBFR, st->mem_syn_lo, M);
1372 
1373 #ifdef ASM_OPT                 /* asm optimization branch */
1374 	Deemph_32_asm(synth_hi + M, synth_lo + M, synth, &(st->mem_deemph));
1375 #else
1376 	Deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR, &(st->mem_deemph));
1377 #endif
1378 
1379 	HP50_12k8(synth, L_SUBFR, st->mem_sig_out);
1380 
1381 	/* Original speech signal as reference for high band gain quantisation */
1382 	for (i = 0; i < L_SUBFR16k; i++)
1383 	{
1384 		HF_SP[i] = synth16k[i];
1385 	}
1386 
1387 	/*------------------------------------------------------*
1388 	 * HF noise synthesis                                   *
1389 	 * ~~~~~~~~~~~~~~~~~~                                   *
1390 	 * - Generate HF noise between 5.5 and 7.5 kHz.         *
1391 	 * - Set energy of noise according to synthesis tilt.   *
1392 	 *     tilt > 0.8 ==> - 14 dB (voiced)                  *
1393 	 *     tilt   0.5 ==> - 6 dB  (voiced or noise)         *
1394 	 *     tilt < 0.0 ==>   0 dB  (noise)                   *
1395 	 *------------------------------------------------------*/
1396 	/* generate white noise vector */
1397 	for (i = 0; i < L_SUBFR16k; i++)
1398 	{
1399 		HF[i] = Random(&(st->seed2))>>3;
1400 	}
1401 	/* energy of excitation */
1402 #ifdef ASM_OPT                    /* asm optimization branch */
1403 	Scale_sig_opt(exc, L_SUBFR, -3);
1404 	Q_new = Q_new - 3;
1405 	ener = extract_h(Dot_product12_asm(exc, exc, L_SUBFR, &exp_ener));
1406 #else
1407 	Scale_sig(exc, L_SUBFR, -3);
1408 	Q_new = Q_new - 3;
1409 	ener = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp_ener));
1410 #endif
1411 
1412 	exp_ener = exp_ener - (Q_new + Q_new);
1413 	/* set energy of white noise to energy of excitation */
1414 #ifdef ASM_OPT              /* asm optimization branch */
1415 	tmp = extract_h(Dot_product12_asm(HF, HF, L_SUBFR16k, &exp));
1416 #else
1417 	tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
1418 #endif
1419 
1420 	if(tmp > ener)
1421 	{
1422 		tmp = (tmp >> 1);                 /* Be sure tmp < ener */
1423 		exp = (exp + 1);
1424 	}
1425 	L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
1426 	exp = (exp - exp_ener);
1427 	Isqrt_n(&L_tmp, &exp);
1428 	L_tmp = L_shl(L_tmp, (exp + 1));       /* L_tmp x 2, L_tmp in Q31 */
1429 	tmp = extract_h(L_tmp);                /* tmp = 2 x sqrt(ener_exc/ener_hf) */
1430 
1431 	for (i = 0; i < L_SUBFR16k; i++)
1432 	{
1433 		HF[i] = vo_mult(HF[i], tmp);
1434 	}
1435 
1436 	/* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */
1437 	HP400_12k8(synth, L_SUBFR, st->mem_hp400);
1438 
1439 	L_tmp = 1L;
1440 	for (i = 0; i < L_SUBFR; i++)
1441 		L_tmp += (synth[i] * synth[i])<<1;
1442 
1443 	exp = norm_l(L_tmp);
1444 	ener = extract_h(L_tmp << exp);   /* ener = r[0] */
1445 
1446 	L_tmp = 1L;
1447 	for (i = 1; i < L_SUBFR; i++)
1448 		L_tmp +=(synth[i] * synth[i - 1])<<1;
1449 
1450 	tmp = extract_h(L_tmp << exp);    /* tmp = r[1] */
1451 
1452 	if (tmp > 0)
1453 	{
1454 		fac = div_s(tmp, ener);
1455 	} else
1456 	{
1457 		fac = 0;
1458 	}
1459 
1460 	/* modify energy of white noise according to synthesis tilt */
1461 	gain1 = 32767 - fac;
1462 	gain2 = vo_mult(gain1, 20480);
1463 	gain2 = shl(gain2, 1);
1464 
1465 	if (st->vad_hist > 0)
1466 	{
1467 		weight1 = 0;
1468 		weight2 = 32767;
1469 	} else
1470 	{
1471 		weight1 = 32767;
1472 		weight2 = 0;
1473 	}
1474 	tmp = vo_mult(weight1, gain1);
1475 	tmp = add1(tmp, vo_mult(weight2, gain2));
1476 
1477 	if (tmp != 0)
1478 	{
1479 		tmp = (tmp + 1);
1480 	}
1481 	HP_est_gain = tmp;
1482 
1483 	if(HP_est_gain < 3277)
1484 	{
1485 		HP_est_gain = 3277;                /* 0.1 in Q15 */
1486 	}
1487 	/* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
1488 	Weight_a(Aq, Ap, 19661, M);            /* fac=0.6 */
1489 
1490 #ifdef ASM_OPT                /* asm optimization branch */
1491 	Syn_filt_asm(Ap, HF, HF, st->mem_syn_hf);
1492 	/* noise High Pass filtering (1ms of delay) */
1493 	Filt_6k_7k_asm(HF, L_SUBFR16k, st->mem_hf);
1494 	/* filtering of the original signal */
1495 	Filt_6k_7k_asm(HF_SP, L_SUBFR16k, st->mem_hf2);
1496 
1497 	/* check the gain difference */
1498 	Scale_sig_opt(HF_SP, L_SUBFR16k, -1);
1499 	ener = extract_h(Dot_product12_asm(HF_SP, HF_SP, L_SUBFR16k, &exp_ener));
1500 	/* set energy of white noise to energy of excitation */
1501 	tmp = extract_h(Dot_product12_asm(HF, HF, L_SUBFR16k, &exp));
1502 #else
1503 	Syn_filt(Ap, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
1504 	/* noise High Pass filtering (1ms of delay) */
1505 	Filt_6k_7k(HF, L_SUBFR16k, st->mem_hf);
1506 	/* filtering of the original signal */
1507 	Filt_6k_7k(HF_SP, L_SUBFR16k, st->mem_hf2);
1508 	/* check the gain difference */
1509 	Scale_sig(HF_SP, L_SUBFR16k, -1);
1510 	ener = extract_h(Dot_product12(HF_SP, HF_SP, L_SUBFR16k, &exp_ener));
1511 	/* set energy of white noise to energy of excitation */
1512 	tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
1513 #endif
1514 
1515 	if (tmp > ener)
1516 	{
1517 		tmp = (tmp >> 1);                 /* Be sure tmp < ener */
1518 		exp = (exp + 1);
1519 	}
1520 	L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
1521 	exp = vo_sub(exp, exp_ener);
1522 	Isqrt_n(&L_tmp, &exp);
1523 	L_tmp = L_shl(L_tmp, exp);             /* L_tmp, L_tmp in Q31 */
1524 	HP_calc_gain = extract_h(L_tmp);       /* tmp = sqrt(ener_input/ener_hf) */
1525 
1526 	/* st->gain_alpha *= st->dtx_encSt->dtxHangoverCount/7 */
1527 	L_tmp = (vo_L_mult(st->dtx_encSt->dtxHangoverCount, 4681) << 15);
1528 	st->gain_alpha = vo_mult(st->gain_alpha, extract_h(L_tmp));
1529 
1530 	if(st->dtx_encSt->dtxHangoverCount > 6)
1531 		st->gain_alpha = 32767;
1532 	HP_est_gain = HP_est_gain >> 1;     /* From Q15 to Q14 */
1533 	HP_corr_gain = add1(vo_mult(HP_calc_gain, st->gain_alpha), vo_mult((32767 - st->gain_alpha), HP_est_gain));
1534 
1535 	/* Quantise the correction gain */
1536 	dist_min = 32767;
1537 	for (i = 0; i < 16; i++)
1538 	{
1539 		dist = vo_mult((HP_corr_gain - HP_gain[i]), (HP_corr_gain - HP_gain[i]));
1540 		if (dist_min > dist)
1541 		{
1542 			dist_min = dist;
1543 			HP_gain_ind = i;
1544 		}
1545 	}
1546 	HP_corr_gain = HP_gain[HP_gain_ind];
1547 	/* return the quantised gain index when using the highest mode, otherwise zero */
1548 	return (HP_gain_ind);
1549 }
1550 
1551 /*************************************************
1552 *
1553 * Breif: Codec main function
1554 *
1555 **************************************************/
1556 
AMR_Enc_Encode(HAMRENC hCodec)1557 int AMR_Enc_Encode(HAMRENC hCodec)
1558 {
1559 	Word32 i;
1560 	Coder_State *gData = (Coder_State*)hCodec;
1561 	Word16 *signal;
1562 	Word16 packed_size = 0;
1563 	Word16 prms[NB_BITS_MAX];
1564 	Word16 coding_mode = 0, nb_bits, allow_dtx, mode, reset_flag;
1565 	mode = gData->mode;
1566 	coding_mode = gData->mode;
1567 	nb_bits = nb_of_bits[mode];
1568 	signal = (Word16 *)gData->inputStream;
1569 	allow_dtx = gData->allow_dtx;
1570 
1571 	/* check for homing frame */
1572 	reset_flag = encoder_homing_frame_test(signal);
1573 
1574 	for (i = 0; i < L_FRAME16k; i++)   /* Delete the 2 LSBs (14-bit input) */
1575 	{
1576 		*(signal + i) = (Word16) (*(signal + i) & 0xfffC);
1577 	}
1578 
1579 	coder(&coding_mode, signal, prms, &nb_bits, gData, allow_dtx);
1580 	packed_size = PackBits(prms, coding_mode, mode, gData);
1581 	if (reset_flag != 0)
1582 	{
1583 		Reset_encoder(gData, 1);
1584 	}
1585 	return packed_size;
1586 }
1587 
1588 /***************************************************************************
1589 *
1590 *Brief: Codec API function --- Initialize the codec and return a codec handle
1591 *
1592 ***************************************************************************/
1593 
voAMRWB_Init(VO_HANDLE * phCodec,VO_AUDIO_CODINGTYPE vType,VO_CODEC_INIT_USERDATA * pUserData)1594 VO_U32 VO_API voAMRWB_Init(VO_HANDLE * phCodec,                   /* o: the audio codec handle */
1595 						   VO_AUDIO_CODINGTYPE vType,             /* i: Codec Type ID */
1596 						   VO_CODEC_INIT_USERDATA * pUserData     /* i: init Parameters */
1597 						   )
1598 {
1599 	Coder_State *st;
1600 	FrameStream *stream;
1601 #ifdef USE_DEAULT_MEM
1602 	VO_MEM_OPERATOR voMemoprator;
1603 #endif
1604 	VO_MEM_OPERATOR *pMemOP;
1605 	int interMem = 0;
1606 
1607 	if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL )
1608 	{
1609 #ifdef USE_DEAULT_MEM
1610 		voMemoprator.Alloc = cmnMemAlloc;
1611 		voMemoprator.Copy = cmnMemCopy;
1612 		voMemoprator.Free = cmnMemFree;
1613 		voMemoprator.Set = cmnMemSet;
1614 		voMemoprator.Check = cmnMemCheck;
1615 		interMem = 1;
1616 		pMemOP = &voMemoprator;
1617 #else
1618 		*phCodec = NULL;
1619 		return VO_ERR_INVALID_ARG;
1620 #endif
1621 	}
1622 	else
1623 	{
1624 		pMemOP = (VO_MEM_OPERATOR *)pUserData->memData;
1625 	}
1626 	/*-------------------------------------------------------------------------*
1627 	 * Memory allocation for coder state.                                      *
1628 	 *-------------------------------------------------------------------------*/
1629 	if ((st = (Coder_State *)mem_malloc(pMemOP, sizeof(Coder_State), 32, VO_INDEX_ENC_AMRWB)) == NULL)
1630 	{
1631 		return VO_ERR_OUTOF_MEMORY;
1632 	}
1633 
1634 	st->vadSt = NULL;
1635 	st->dtx_encSt = NULL;
1636 	st->sid_update_counter = 3;
1637 	st->sid_handover_debt = 0;
1638 	st->prev_ft = TX_SPEECH;
1639 	st->inputStream = NULL;
1640 	st->inputSize = 0;
1641 
1642 	/* Default setting */
1643 	st->mode = VOAMRWB_MD2385;                        /* bit rate 23.85kbps */
1644 	st->frameType = VOAMRWB_RFC3267;                  /* frame type: RFC3267 */
1645 	st->allow_dtx = 0;                                /* disable DTX mode */
1646 
1647 	st->outputStream = NULL;
1648 	st->outputSize = 0;
1649 
1650 	st->stream = (FrameStream *)mem_malloc(pMemOP, sizeof(FrameStream), 32, VO_INDEX_ENC_AMRWB);
1651 	if(st->stream == NULL)
1652 		return VO_ERR_OUTOF_MEMORY;
1653 
1654 	st->stream->frame_ptr = (unsigned char *)mem_malloc(pMemOP, Frame_Maxsize, 32, VO_INDEX_ENC_AMRWB);
1655 	if(st->stream->frame_ptr == NULL)
1656 		return  VO_ERR_OUTOF_MEMORY;
1657 
1658 	stream = st->stream;
1659 	voAWB_InitFrameBuffer(stream);
1660 
1661 	wb_vad_init(&(st->vadSt), pMemOP);
1662 	dtx_enc_init(&(st->dtx_encSt), isf_init, pMemOP);
1663 
1664 	Reset_encoder((void *) st, 1);
1665 
1666 	if(interMem)
1667 	{
1668 		st->voMemoprator.Alloc = cmnMemAlloc;
1669 		st->voMemoprator.Copy = cmnMemCopy;
1670 		st->voMemoprator.Free = cmnMemFree;
1671 		st->voMemoprator.Set = cmnMemSet;
1672 		st->voMemoprator.Check = cmnMemCheck;
1673 		pMemOP = &st->voMemoprator;
1674 	}
1675 
1676 	st->pvoMemop = pMemOP;
1677 
1678 	*phCodec = (void *) st;
1679 
1680 	return VO_ERR_NONE;
1681 }
1682 
1683 /**********************************************************************************
1684 *
1685 * Brief: Codec API function: Input PCM data
1686 *
1687 ***********************************************************************************/
1688 
voAMRWB_SetInputData(VO_HANDLE hCodec,VO_CODECBUFFER * pInput)1689 VO_U32 VO_API voAMRWB_SetInputData(
1690 		VO_HANDLE hCodec,                   /* i/o: The codec handle which was created by Init function */
1691 		VO_CODECBUFFER * pInput             /*   i: The input buffer parameter  */
1692 		)
1693 {
1694 	Coder_State  *gData;
1695 	FrameStream  *stream;
1696 
1697 	if(NULL == hCodec)
1698 	{
1699 		return VO_ERR_INVALID_ARG;
1700 	}
1701 
1702 	gData = (Coder_State *)hCodec;
1703 	stream = gData->stream;
1704 
1705 	if(NULL == pInput || NULL == pInput->Buffer)
1706 	{
1707 		return VO_ERR_INVALID_ARG;
1708 	}
1709 
1710 	stream->set_ptr    = pInput->Buffer;
1711 	stream->set_len    = pInput->Length;
1712 	stream->frame_ptr  = stream->frame_ptr_bk;
1713 	stream->used_len   = 0;
1714 
1715 	return VO_ERR_NONE;
1716 }
1717 
1718 /**************************************************************************************
1719 *
1720 * Brief: Codec API function: Get the compression audio data frame by frame
1721 *
1722 ***************************************************************************************/
1723 
voAMRWB_GetOutputData(VO_HANDLE hCodec,VO_CODECBUFFER * pOutput,VO_AUDIO_OUTPUTINFO * pAudioFormat)1724 VO_U32 VO_API voAMRWB_GetOutputData(
1725 		VO_HANDLE hCodec,                    /* i: The Codec Handle which was created by Init function*/
1726 		VO_CODECBUFFER * pOutput,            /* o: The output audio data */
1727 		VO_AUDIO_OUTPUTINFO * pAudioFormat   /* o: The encoder module filled audio format and used the input size*/
1728 		)
1729 {
1730 	Coder_State* gData = (Coder_State*)hCodec;
1731 	VO_MEM_OPERATOR  *pMemOP;
1732 	FrameStream  *stream = (FrameStream *)gData->stream;
1733 	pMemOP = (VO_MEM_OPERATOR  *)gData->pvoMemop;
1734 
1735 	if(stream->framebuffer_len  < Frame_MaxByte)         /* check the work buffer len */
1736 	{
1737 		stream->frame_storelen = stream->framebuffer_len;
1738 		if(stream->frame_storelen)
1739 		{
1740 			pMemOP->Copy(VO_INDEX_ENC_AMRWB, stream->frame_ptr_bk , stream->frame_ptr , stream->frame_storelen);
1741 		}
1742 		if(stream->set_len > 0)
1743 		{
1744 			voAWB_UpdateFrameBuffer(stream, pMemOP);
1745 		}
1746 		if(stream->framebuffer_len < Frame_MaxByte)
1747 		{
1748 			if(pAudioFormat)
1749 				pAudioFormat->InputUsed = stream->used_len;
1750 			return VO_ERR_INPUT_BUFFER_SMALL;
1751 		}
1752 	}
1753 
1754 	gData->inputStream = stream->frame_ptr;
1755 	gData->outputStream = (unsigned short*)pOutput->Buffer;
1756 
1757 	gData->outputSize = AMR_Enc_Encode(gData);         /* encoder main function */
1758 
1759 	pOutput->Length = gData->outputSize;               /* get the output buffer length */
1760 	stream->frame_ptr += 640;                          /* update the work buffer ptr */
1761 	stream->framebuffer_len  -= 640;
1762 
1763 	if(pAudioFormat)                                   /* return output audio information */
1764 	{
1765 		pAudioFormat->Format.Channels = 1;
1766 		pAudioFormat->Format.SampleRate = 8000;
1767 		pAudioFormat->Format.SampleBits = 16;
1768 		pAudioFormat->InputUsed = stream->used_len;
1769 	}
1770 	return VO_ERR_NONE;
1771 }
1772 
1773 /*************************************************************************
1774 *
1775 * Brief: Codec API function---set the data by specified parameter ID
1776 *
1777 *************************************************************************/
1778 
1779 
voAMRWB_SetParam(VO_HANDLE hCodec,VO_S32 uParamID,VO_PTR pData)1780 VO_U32 VO_API voAMRWB_SetParam(
1781 		VO_HANDLE hCodec,   /* i/o: The Codec Handle which was created by Init function */
1782 		VO_S32 uParamID,    /*   i: The param ID */
1783 		VO_PTR pData        /*   i: The param value depend on the ID */
1784 		)
1785 {
1786 	Coder_State* gData = (Coder_State*)hCodec;
1787 	FrameStream *stream = (FrameStream *)(gData->stream);
1788 	int *lValue = (int*)pData;
1789 
1790 	switch(uParamID)
1791 	{
1792 		/* setting AMR-WB frame type*/
1793 		case VO_PID_AMRWB_FRAMETYPE:
1794 			if(*lValue < VOAMRWB_DEFAULT || *lValue > VOAMRWB_RFC3267)
1795 				return VO_ERR_WRONG_PARAM_ID;
1796 			gData->frameType = *lValue;
1797 			break;
1798 		/* setting AMR-WB bit rate */
1799 		case VO_PID_AMRWB_MODE:
1800 			{
1801 				if(*lValue < VOAMRWB_MD66 || *lValue > VOAMRWB_MD2385)
1802 					return VO_ERR_WRONG_PARAM_ID;
1803 				gData->mode = *lValue;
1804 			}
1805 			break;
1806 		/* enable or disable DTX mode */
1807 		case VO_PID_AMRWB_DTX:
1808 			gData->allow_dtx = (Word16)(*lValue);
1809 			break;
1810 
1811 		case VO_PID_COMMON_HEADDATA:
1812 			break;
1813         /* flush the work buffer */
1814 		case VO_PID_COMMON_FLUSH:
1815 			stream->set_ptr = NULL;
1816 			stream->frame_storelen = 0;
1817 			stream->framebuffer_len = 0;
1818 			stream->set_len = 0;
1819 			break;
1820 
1821 		default:
1822 			return VO_ERR_WRONG_PARAM_ID;
1823 	}
1824 	return VO_ERR_NONE;
1825 }
1826 
1827 /**************************************************************************
1828 *
1829 *Brief: Codec API function---Get the data by specified parameter ID
1830 *
1831 ***************************************************************************/
1832 
voAMRWB_GetParam(VO_HANDLE hCodec,VO_S32 uParamID,VO_PTR pData)1833 VO_U32 VO_API voAMRWB_GetParam(
1834 		VO_HANDLE hCodec,      /* i: The Codec Handle which was created by Init function */
1835 		VO_S32 uParamID,       /* i: The param ID */
1836 		VO_PTR pData           /* o: The param value depend on the ID */
1837 		)
1838 {
1839 	int    temp;
1840 	Coder_State* gData = (Coder_State*)hCodec;
1841 
1842 	if (gData==NULL)
1843 		return VO_ERR_INVALID_ARG;
1844 	switch(uParamID)
1845 	{
1846 		/* output audio format */
1847 		case VO_PID_AMRWB_FORMAT:
1848 			{
1849 				VO_AUDIO_FORMAT* fmt = (VO_AUDIO_FORMAT*)pData;
1850 				fmt->Channels   = 1;
1851 				fmt->SampleRate = 16000;
1852 				fmt->SampleBits = 16;
1853 				break;
1854 			}
1855         /* output audio channel number */
1856 		case VO_PID_AMRWB_CHANNELS:
1857 			temp = 1;
1858 			pData = (void *)(&temp);
1859 			break;
1860         /* output audio sample rate */
1861 		case VO_PID_AMRWB_SAMPLERATE:
1862 			temp = 16000;
1863 			pData = (void *)(&temp);
1864 			break;
1865 		/* output audio frame type */
1866 		case VO_PID_AMRWB_FRAMETYPE:
1867 			temp = gData->frameType;
1868 			pData = (void *)(&temp);
1869 			break;
1870 		/* output audio bit rate */
1871 		case VO_PID_AMRWB_MODE:
1872 			temp = gData->mode;
1873 			pData = (void *)(&temp);
1874 			break;
1875 		default:
1876 			return VO_ERR_WRONG_PARAM_ID;
1877 	}
1878 
1879 	return VO_ERR_NONE;
1880 }
1881 
1882 /***********************************************************************************
1883 *
1884 * Brief: Codec API function---Release the codec after all encoder operations are done
1885 *
1886 *************************************************************************************/
1887 
voAMRWB_Uninit(VO_HANDLE hCodec)1888 VO_U32 VO_API voAMRWB_Uninit(VO_HANDLE hCodec           /* i/o: Codec handle pointer */
1889 							 )
1890 {
1891 	Coder_State* gData = (Coder_State*)hCodec;
1892 	VO_MEM_OPERATOR *pMemOP;
1893 	pMemOP = gData->pvoMemop;
1894 
1895 	if(hCodec)
1896 	{
1897 		if(gData->stream)
1898 		{
1899 			if(gData->stream->frame_ptr_bk)
1900 			{
1901 				mem_free(pMemOP, gData->stream->frame_ptr_bk, VO_INDEX_ENC_AMRWB);
1902 				gData->stream->frame_ptr_bk = NULL;
1903 			}
1904 			mem_free(pMemOP, gData->stream, VO_INDEX_ENC_AMRWB);
1905 			gData->stream = NULL;
1906 		}
1907 		wb_vad_exit(&(((Coder_State *) gData)->vadSt), pMemOP);
1908 		dtx_enc_exit(&(((Coder_State *) gData)->dtx_encSt), pMemOP);
1909 
1910 		mem_free(pMemOP, hCodec, VO_INDEX_ENC_AMRWB);
1911 		hCodec = NULL;
1912 	}
1913 
1914 	return VO_ERR_NONE;
1915 }
1916 
1917 /********************************************************************************
1918 *
1919 * Brief: voGetAMRWBEncAPI gets the API handle of the codec
1920 *
1921 ********************************************************************************/
1922 
voGetAMRWBEncAPI(VO_AUDIO_CODECAPI * pEncHandle)1923 VO_S32 VO_API voGetAMRWBEncAPI(
1924 							   VO_AUDIO_CODECAPI * pEncHandle      /* i/o: Codec handle pointer */
1925 							   )
1926 {
1927 	if(NULL == pEncHandle)
1928 		return VO_ERR_INVALID_ARG;
1929 	pEncHandle->Init = voAMRWB_Init;
1930 	pEncHandle->SetInputData = voAMRWB_SetInputData;
1931 	pEncHandle->GetOutputData = voAMRWB_GetOutputData;
1932 	pEncHandle->SetParam = voAMRWB_SetParam;
1933 	pEncHandle->GetParam = voAMRWB_GetParam;
1934 	pEncHandle->Uninit = voAMRWB_Uninit;
1935 
1936 	return VO_ERR_NONE;
1937 }
1938 
1939 #ifdef __cplusplus
1940 }
1941 #endif
1942