voAMRWBEnc.c revision c4ef4bb50d1407aec63358d4c14d1007ae0c4c1d
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
43extern "C" {
44#endif
45
46/* LPC interpolation coef {0.45, 0.8, 0.96, 1.0}; in Q15 */
47static Word16 interpol_frac[NB_SUBFR] = {14746, 26214, 31457, 32767};
48
49/* isp tables for initialization */
50static 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
56static 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 */
63static 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 */
70static 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 */
79void 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*-----------------------------------------------------------------*/
149void 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
1329static 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
1557int 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
1594VO_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
1689VO_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
1724VO_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
1780VO_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
1833VO_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
1888VO_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
1923VO_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