1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/***********************************************************************
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*      File: voAMRWBEnc.c                                              *
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                      *
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*      Description: Performs the main encoder routine                  *
21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                   Fixed-point C simulation of AMR WB ACELP coding    *
225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen*           algorithm with 20 msspeech frames for              *
235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen*           wideband speech signals.                           *
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                      *
25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard************************************************************************/
26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <stdio.h>
28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <stdlib.h>
29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h"
30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "oper_32b.h"
32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "math_op.h"
33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "cnst.h"
34e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "acelp.h"
35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "cod_main.h"
36e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "bits.h"
37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "main.h"
38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "voAMRWB.h"
39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "mem_align.h"
40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "cmnMemory.h"
41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
4284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED(x) (void)(x)
4384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber
44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef __cplusplus
45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardextern "C" {
46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* LPC interpolation coef {0.45, 0.8, 0.96, 1.0}; in Q15 */
49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 interpol_frac[NB_SUBFR] = {14746, 26214, 31457, 32767};
50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* isp tables for initialization */
52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 isp_init[M] =
53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    32138, 30274, 27246, 23170, 18205, 12540, 6393, 0,
555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    -6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475
56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard};
57e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 isf_init[M] =
59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192,
615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840
62e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard};
63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* High Band encoding */
65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic const Word16 HP_gain[16] =
66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    3624, 4673, 5597, 6479, 7425, 8378, 9324, 10264,
685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728
69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard};
70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* Private function declaration */
72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 synthesis(
735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Word16 Aq[],                          /* A(z)  : quantized Az               */
745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Word16 exc[],                         /* (i)   : excitation at 12kHz        */
755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Word16 Q_new,                         /* (i)   : scaling performed on exc   */
765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Word16 synth16k[],                    /* (o)   : 16kHz synthesis signal     */
775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Coder_State * st                      /* (i/o) : State structure            */
785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            );
79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* Codec some parameters initialization */
81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid Reset_encoder(void *st, Word16 reset_all)
82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 i;
845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Coder_State *cod_state;
855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    cod_state = (Coder_State *) st;
865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Set_zero(cod_state->old_exc, PIT_MAX + L_INTERPOL);
875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Set_zero(cod_state->mem_syn, M);
885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Set_zero(cod_state->past_isfq, M);
895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    cod_state->mem_w0 = 0;
905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    cod_state->tilt_code = 0;
915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    cod_state->first_frame = 1;
925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Init_gp_clip(cod_state->gp_clip);
935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    cod_state->L_gc_thres = 0;
945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (reset_all != 0)
955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* Static vectors to zero */
975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Set_zero(cod_state->old_speech, L_TOTAL - L_FRAME);
985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Set_zero(cod_state->old_wsp, (PIT_MAX / OPL_DECIM));
995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Set_zero(cod_state->mem_decim2, 3);
1005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* routines initialization */
1015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Init_Decim_12k8(cod_state->mem_decim);
1025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Init_HP50_12k8(cod_state->mem_sig_in);
1035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Init_Levinson(cod_state->mem_levinson);
1045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Init_Q_gain2(cod_state->qua_gain);
1055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Init_Hp_wsp(cod_state->hp_wsp_mem);
1065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* isp initialization */
1075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(isp_init, cod_state->ispold, M);
1085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(isp_init, cod_state->ispold_q, M);
1095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* variable initialization */
1105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->mem_preemph = 0;
1115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->mem_wsp = 0;
1125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->Q_old = 15;
1135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->Q_max[0] = 15;
1145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->Q_max[1] = 15;
1155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->old_wsp_max = 0;
1165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->old_wsp_shift = 0;
1175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* pitch ol initialization */
1185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->old_T0_med = 40;
1195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->ol_gain = 0;
1205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->ada_w = 0;
1215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->ol_wght_flg = 0;
1225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (i = 0; i < 5; i++)
1235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
1245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            cod_state->old_ol_lag[i] = 40;
1255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
1265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Set_zero(cod_state->old_hp_wsp, (L_FRAME / 2) / OPL_DECIM + (PIT_MAX / OPL_DECIM));
1275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Set_zero(cod_state->mem_syn_hf, M);
1285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Set_zero(cod_state->mem_syn_hi, M);
1295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Set_zero(cod_state->mem_syn_lo, M);
1305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Init_HP50_12k8(cod_state->mem_sig_out);
1315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Init_Filt_6k_7k(cod_state->mem_hf);
1325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Init_HP400_12k8(cod_state->mem_hp400);
1335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(isf_init, cod_state->isfold, M);
1345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->mem_deemph = 0;
1355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->seed2 = 21845;
1365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Init_Filt_6k_7k(cod_state->mem_hf2);
1375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->gain_alpha = 32767;
1385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cod_state->vad_hist = 0;
1395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        wb_vad_reset(cod_state->vadSt);
1405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        dtx_enc_reset(cod_state->dtx_encSt, isf_init);
1415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
1425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return;
143e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
144e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
145e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*-----------------------------------------------------------------*
146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*   Funtion  coder                                                *
147e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*            ~~~~~                                                *
148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*   ->Main coder routine.                                         *
149e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                 *
150e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*-----------------------------------------------------------------*/
151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid coder(
1525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 * mode,                        /* input :  used mode                             */
1535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 speech16k[],                   /* input :  320 new speech samples (at 16 kHz)    */
1545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 prms[],                        /* output:  output parameters                     */
1555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 * ser_size,                    /* output:  bit rate of the used mode             */
1565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        void *spe_state,                      /* i/o   :  State structure                       */
1575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 allow_dtx                      /* input :  DTX ON/OFF                            */
1585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen      )
159e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
1605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Coder states */
1615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Coder_State *st;
1625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Speech vector */
1635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 old_speech[L_TOTAL];
1645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 *new_speech, *speech, *p_window;
1655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
1665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Weighted speech vector */
1675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 old_wsp[L_FRAME + (PIT_MAX / OPL_DECIM)];
1685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 *wsp;
1695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
1705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Excitation vector */
1715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 old_exc[(L_FRAME + 1) + PIT_MAX + L_INTERPOL];
1725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 *exc;
1735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
1745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* LPC coefficients */
1755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 r_h[M + 1], r_l[M + 1];         /* Autocorrelations of windowed speech  */
1765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 rc[M];                          /* Reflection coefficients.             */
1775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 Ap[M + 1];                      /* A(z) with spectral expansion         */
1785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 ispnew[M];                      /* immittance spectral pairs at 4nd sfr */
1795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 ispnew_q[M];                    /* quantized ISPs at 4nd subframe       */
1805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 isf[M];                         /* ISF (frequency domain) at 4nd sfr    */
1815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 *p_A, *p_Aq;                    /* ptr to A(z) for the 4 subframes      */
1825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 A[NB_SUBFR * (M + 1)];          /* A(z) unquantized for the 4 subframes */
1835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 Aq[NB_SUBFR * (M + 1)];         /* A(z)   quantized for the 4 subframes */
1845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
1855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Other vectors */
1865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 xn[L_SUBFR];                    /* Target vector for pitch search     */
1875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 xn2[L_SUBFR];                   /* Target vector for codebook search  */
1885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 dn[L_SUBFR];                    /* Correlation between xn2 and h1     */
1895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 cn[L_SUBFR];                    /* Target vector in residual domain   */
1905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 h1[L_SUBFR];                    /* Impulse response vector            */
1915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 h2[L_SUBFR];                    /* Impulse response vector            */
1925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 code[L_SUBFR];                  /* Fixed codebook excitation          */
1935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 y1[L_SUBFR];                    /* Filtered adaptive excitation       */
1945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 y2[L_SUBFR];                    /* Filtered adaptive excitation       */
1955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 error[M + L_SUBFR];             /* error of quantization              */
1965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 synth[L_SUBFR];                 /* 12.8kHz synthesis vector           */
1975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 exc2[L_FRAME];                  /* excitation vector                  */
1985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 buf[L_FRAME];                   /* VAD buffer                         */
1995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Scalars */
2015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word32 i, j, i_subfr, select, pit_flag, clip_gain, vad_flag;
2025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 codec_mode;
2035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 T_op, T_op2, T0, T0_min, T0_max, T0_frac, index;
2045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 gain_pit, gain_code, g_coeff[4], g_coeff2[4];
2055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 tmp, gain1, gain2, exp, Q_new, mu, shift, max;
2065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 voice_fac;
2075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 indice[8];
2085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word32 L_tmp, L_gain_code, L_max, L_tmp1;
2095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 code2[L_SUBFR];                         /* Fixed codebook excitation  */
2105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 stab_fac, fac, gain_code_lo;
2115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 corr_gain;
2135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 *vo_p0, *vo_p1, *vo_p2, *vo_p3;
2145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st = (Coder_State *) spe_state;
2165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    *ser_size = nb_of_bits[*mode];
2185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    codec_mode = *mode;
2195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*--------------------------------------------------------------------------*
2215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *          Initialize pointers to speech vector.                           *
2225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                                                                          *
2235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                                                                          *
2245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                    |-------|-------|-------|-------|-------|-------|     *
2255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                     past sp   sf1     sf2     sf3     sf4    L_NEXT      *
2265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                    <-------  Total speech buffer (L_TOTAL)   ------>     *
2275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *              old_speech                                                  *
2285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                    <-------  LPC analysis window (L_WINDOW)  ------>     *
2295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                    |       <-- present frame (L_FRAME) ---->             *
2305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                   p_window |       <----- new speech (L_FRAME) ---->     *
2315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                            |       |                                     *
2325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                          speech    |                                     *
2335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                                 new_speech                               *
2345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *--------------------------------------------------------------------------*/
2355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    new_speech = old_speech + L_TOTAL - L_FRAME - L_FILT;         /* New speech     */
2375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    speech = old_speech + L_TOTAL - L_FRAME - L_NEXT;             /* Present frame  */
2385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    p_window = old_speech + L_TOTAL - L_WINDOW;
2395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    exc = old_exc + PIT_MAX + L_INTERPOL;
2415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    wsp = old_wsp + (PIT_MAX / OPL_DECIM);
2425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* copy coder memory state into working space */
2445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(st->old_speech, old_speech, L_TOTAL - L_FRAME);
2455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(st->old_wsp, old_wsp, PIT_MAX / OPL_DECIM);
2465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(st->old_exc, old_exc, PIT_MAX + L_INTERPOL);
2475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*---------------------------------------------------------------*
2495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * Down sampling signal from 16kHz to 12.8kHz                    *
2505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * -> The signal is extended by L_FILT samples (padded to zero)  *
2515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * to avoid additional delay (L_FILT samples) in the coder.      *
2525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * The last L_FILT samples are approximated after decimation and *
2535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * are used (and windowed) only in autocorrelations.             *
2545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *---------------------------------------------------------------*/
2555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Decim_12k8(speech16k, L_FRAME16k, new_speech, st->mem_decim);
2575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* last L_FILT samples for autocorrelation window */
2595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(st->mem_decim, code, 2 * L_FILT16k);
2605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Set_zero(error, L_FILT16k);            /* set next sample to zero */
2615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Decim_12k8(error, L_FILT16k, new_speech + L_FRAME, code);
2625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*---------------------------------------------------------------*
2645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * Perform 50Hz HP filtering of input signal.                    *
2655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *---------------------------------------------------------------*/
2665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    HP50_12k8(new_speech, L_FRAME, st->mem_sig_in);
2685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* last L_FILT samples for autocorrelation window */
2705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(st->mem_sig_in, code, 6);
2715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    HP50_12k8(new_speech + L_FRAME, L_FILT, code);
2725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*---------------------------------------------------------------*
2745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * Perform fixed preemphasis through 1 - g z^-1                  *
2755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * Scale signal to get maximum of precision in filtering         *
2765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *---------------------------------------------------------------*/
2775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    mu = PREEMPH_FAC >> 1;              /* Q15 --> Q14 */
2795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* get max of new preemphased samples (L_FRAME+L_FILT) */
2815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = new_speech[0] << 15;
2825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp -= (st->mem_preemph * mu)<<1;
2835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_max = L_abs(L_tmp);
2845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 1; i < L_FRAME + L_FILT; i++)
2865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
2875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = new_speech[i] << 15;
2885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp -= (new_speech[i - 1] * mu)<<1;
2895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = L_abs(L_tmp);
2905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(L_tmp > L_max)
2915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
2925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_max = L_tmp;
2935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
2945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
2955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
2965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* get scaling factor for new and previous samples */
2975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* limit scaling to Q_MAX to keep dynamic for ringing in low signal */
2985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* limit scaling to Q_MAX also to avoid a[0]<1 in syn_filt_32 */
2995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = extract_h(L_max);
3005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (tmp == 0)
3015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
3025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        shift = Q_MAX;
3035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    } else
3045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
3055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        shift = norm_s(tmp) - 1;
3065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if (shift < 0)
3075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
3085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            shift = 0;
3095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
3105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if (shift > Q_MAX)
3115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
3125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            shift = Q_MAX;
3135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
3145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
3155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Q_new = shift;
3165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (Q_new > st->Q_max[0])
3175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
3185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Q_new = st->Q_max[0];
3195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
3205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (Q_new > st->Q_max[1])
3215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
3225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Q_new = st->Q_max[1];
3235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
3245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    exp = (Q_new - st->Q_old);
3255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->Q_old = Q_new;
3265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->Q_max[1] = st->Q_max[0];
3275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->Q_max[0] = shift;
3285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
3295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* preemphasis with scaling (L_FRAME+L_FILT) */
3305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = new_speech[L_FRAME - 1];
3315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
3325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = L_FRAME + L_FILT - 1; i > 0; i--)
3335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
3345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = new_speech[i] << 15;
3355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp -= (new_speech[i - 1] * mu)<<1;
3365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = (L_tmp << Q_new);
3375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        new_speech[i] = vo_round(L_tmp);
3385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
3395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
3405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = new_speech[0] << 15;
3415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp -= (st->mem_preemph * mu)<<1;
3425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = (L_tmp << Q_new);
3435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    new_speech[0] = vo_round(L_tmp);
3445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
3455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->mem_preemph = tmp;
3465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
3475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* scale previous samples and memory */
3485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
3495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(old_speech, L_TOTAL - L_FRAME - L_FILT, exp);
3505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(old_exc, PIT_MAX + L_INTERPOL, exp);
3515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(st->mem_syn, M, exp);
3525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(st->mem_decim2, 3, exp);
3535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(&(st->mem_wsp), 1, exp);
3545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(&(st->mem_w0), 1, exp);
3555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
3565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*------------------------------------------------------------------------*
3575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *  Call VAD                                                              *
3585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *  Preemphesis scale down signal in low frequency and keep dynamic in HF.*
3595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *  Vad work slightly in futur (new_speech = speech + L_NEXT - L_FILT).   *
3605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *------------------------------------------------------------------------*/
3615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(new_speech, buf, L_FRAME);
362e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
363e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT        /* asm optimization branch */
3645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig_opt(buf, L_FRAME, 1 - Q_new);
365e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
3665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(buf, L_FRAME, 1 - Q_new);
367e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
368e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
3695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    vad_flag = wb_vad(st->vadSt, buf);          /* Voice Activity Detection */
3705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (vad_flag == 0)
3715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
3725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->vad_hist = (st->vad_hist + 1);
3735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    } else
3745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
3755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->vad_hist = 0;
3765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
3775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
3785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* DTX processing */
3795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (allow_dtx != 0)
3805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
3815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* Note that mode may change here */
3825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tx_dtx_handler(st->dtx_encSt, vad_flag, mode);
3835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        *ser_size = nb_of_bits[*mode];
3845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
3855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
3865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(*mode != MRDTX)
3875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
3885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(vad_flag, 1, &prms);
3895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
3905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*------------------------------------------------------------------------*
3915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *  Perform LPC analysis                                                  *
3925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *  ~~~~~~~~~~~~~~~~~~~~                                                  *
3935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *   - autocorrelation + lag windowing                                    *
3945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *   - Levinson-durbin algorithm to find a[]                              *
3955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *   - convert a[] to isp[]                                               *
3965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *   - convert isp[] to isf[] for quantization                            *
3975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *   - quantize and code the isf[]                                        *
3985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *   - convert isf[] to isp[] for interpolation                           *
3995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *   - find the interpolated ISPs and convert to a[] for the 4 subframes  *
4005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *------------------------------------------------------------------------*/
4015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* LP analysis centered at 4nd subframe */
4035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Autocorr(p_window, M, r_h, r_l);                        /* Autocorrelations */
4045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Lag_window(r_h, r_l);                                   /* Lag windowing    */
4055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Levinson(r_h, r_l, A, rc, st->mem_levinson);            /* Levinson Durbin  */
4065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Az_isp(A, ispnew, st->ispold);                          /* From A(z) to ISP */
4075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Find the interpolated ISPs and convert to a[] for all subframes */
4095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Int_isp(st->ispold, ispnew, interpol_frac, A);
4105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* update ispold[] for the next frame */
4125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(ispnew, st->ispold, M);
4135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Convert ISPs to frequency domain 0..6400 */
4155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Isp_isf(ispnew, isf, M);
4165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* check resonance for pitch clipping algorithm */
4185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Gp_clip_test_isf(isf, st->gp_clip);
4195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*----------------------------------------------------------------------*
4215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *  Perform PITCH_OL analysis                                           *
4225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *  ~~~~~~~~~~~~~~~~~~~~~~~~~                                           *
4235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * - Find the residual res[] for the whole speech frame                 *
4245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * - Find the weighted input speech wsp[] for the whole speech frame    *
4255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * - scale wsp[] to avoid overflow in pitch estimation                  *
4265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * - Find open loop pitch lag for whole speech frame                    *
4275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *----------------------------------------------------------------------*/
4285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    p_A = A;
4295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
4305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
4315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* Weighting of LPC coefficients */
4325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Weight_a(p_A, Ap, GAMMA1, M);
433e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
434e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                    /* asm optimization branch */
4355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu_opt(Ap, &speech[i_subfr], &wsp[i_subfr], L_SUBFR);
436e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
4375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu(Ap, &speech[i_subfr], &wsp[i_subfr], L_SUBFR);
438e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
439e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
4405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p_A += (M + 1);
4415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
4425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Deemph2(wsp, TILT_FAC, L_FRAME, &(st->mem_wsp));
4445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* find maximum value on wsp[] for 12 bits scaling */
4465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    max = 0;
4475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 0; i < L_FRAME; i++)
4485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
4495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tmp = abs_s(wsp[i]);
4505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(tmp > max)
4515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
4525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            max = tmp;
4535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
4545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
4555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = st->old_wsp_max;
4565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(max > tmp)
4575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
4585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tmp = max;                         /* tmp = max(wsp_max, old_wsp_max) */
4595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
4605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->old_wsp_max = max;
4615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    shift = norm_s(tmp) - 3;
4635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (shift > 0)
4645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
4655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        shift = 0;                         /* shift = 0..-3 */
4665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
4675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* decimation of wsp[] to search pitch in LF and to reduce complexity */
4685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    LP_Decim2(wsp, L_FRAME, st->mem_decim2);
4695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* scale wsp[] in 12 bits to avoid overflow */
471e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef  ASM_OPT                  /* asm optimization branch */
4725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig_opt(wsp, L_FRAME / OPL_DECIM, shift);
473e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
4745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(wsp, L_FRAME / OPL_DECIM, shift);
475e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
4765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* scale old_wsp (warning: exp must be Q_new-Q_old) */
4775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    exp = exp + (shift - st->old_wsp_shift);
4785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->old_wsp_shift = shift;
4795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(old_wsp, PIT_MAX / OPL_DECIM, exp);
4815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(st->old_hp_wsp, PIT_MAX / OPL_DECIM, exp);
4825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    scale_mem_Hp_wsp(st->hp_wsp_mem, exp);
4845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Find open loop pitch lag for whole speech frame */
4865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(*ser_size == NBBITS_7k)
4885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
4895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* Find open loop pitch lag for whole speech frame */
4905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        T_op = Pitch_med_ol(wsp, st, L_FRAME / OPL_DECIM);
4915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    } else
4925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
4935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* Find open loop pitch lag for first 1/2 frame */
4945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        T_op = Pitch_med_ol(wsp, st, (L_FRAME/2) / OPL_DECIM);
4955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
4965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
4975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(st->ol_gain > 19661)       /* 0.6 in Q15 */
4985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
4995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->old_T0_med = Med_olag(T_op, st->old_ol_lag);
5005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->ada_w = 32767;
5015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    } else
5025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
5035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->ada_w = vo_mult(st->ada_w, 29491);
5045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
5055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(st->ada_w < 26214)
5075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->ol_wght_flg = 0;
5085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    else
5095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->ol_wght_flg = 1;
5105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    wb_vad_tone_detection(st->vadSt, st->ol_gain);
5125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    T_op *= OPL_DECIM;
5135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(*ser_size != NBBITS_7k)
5155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
5165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* Find open loop pitch lag for second 1/2 frame */
5175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        T_op2 = Pitch_med_ol(wsp + ((L_FRAME / 2) / OPL_DECIM), st, (L_FRAME/2) / OPL_DECIM);
5185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(st->ol_gain > 19661)   /* 0.6 in Q15 */
5205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
5215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            st->old_T0_med = Med_olag(T_op2, st->old_ol_lag);
5225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            st->ada_w = 32767;
5235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else
5245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
5255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            st->ada_w = mult(st->ada_w, 29491);
5265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
5275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(st->ada_w < 26214)
5295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            st->ol_wght_flg = 0;
5305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        else
5315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            st->ol_wght_flg = 1;
5325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        wb_vad_tone_detection(st->vadSt, st->ol_gain);
5345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        T_op2 *= OPL_DECIM;
5365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    } else
5385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
5395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        T_op2 = T_op;
5405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
5415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*----------------------------------------------------------------------*
5425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                              DTX-CNG                                 *
5435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *----------------------------------------------------------------------*/
5445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(*mode == MRDTX)            /* CNG mode */
5455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
5465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* Buffer isf's and energy */
547e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                   /* asm optimization branch */
5485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu_opt(&A[3 * (M + 1)], speech, exc, L_FRAME);
549e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
5505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu(&A[3 * (M + 1)], speech, exc, L_FRAME);
551e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
552e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
5535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (i = 0; i < L_FRAME; i++)
5545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
5555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            exc2[i] = shr(exc[i], Q_new);
5565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
557e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
5585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = 0;
5595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (i = 0; i < L_FRAME; i++)
5605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp += (exc2[i] * exc2[i])<<1;
5615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp >>= 1;
5635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
5655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* Quantize and code the ISFs */
5675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        dtx_enc(st->dtx_encSt, isf, exc2, &prms);
5685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* Convert ISFs to the cosine domain */
5705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Isf_isp(isf, ispnew_q, M);
5715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Isp_Az(ispnew_q, Aq, M, 0);
5725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
5745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
5755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            corr_gain = synthesis(Aq, &exc2[i_subfr], 0, &speech16k[i_subfr * 5 / 4], st);
5765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
5775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(isf, st->isfold, M);
5785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* reset speech coder memories */
5805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Reset_encoder(st, 0);
5815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*--------------------------------------------------*
5835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * Update signal for next frame.                    *
5845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * -> save past of speech[] and wsp[].              *
5855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *--------------------------------------------------*/
5865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
5885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
5895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        return;
5915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
5925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*----------------------------------------------------------------------*
5935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *                               ACELP                                  *
5945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *----------------------------------------------------------------------*/
5955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Quantize and code the ISFs */
5975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
5985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (*ser_size <= NBBITS_7k)
5995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
6005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Qpisf_2s_36b(isf, isf, st->past_isfq, indice, 4);
6015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[0], 8, &prms);
6035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[1], 8, &prms);
6045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[2], 7, &prms);
6055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[3], 7, &prms);
6065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[4], 6, &prms);
6075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    } else
6085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
6095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Qpisf_2s_46b(isf, isf, st->past_isfq, indice, 4);
6105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[0], 8, &prms);
6125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[1], 8, &prms);
6135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[2], 6, &prms);
6145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[3], 7, &prms);
6155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[4], 7, &prms);
6165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[5], 5, &prms);
6175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Parm_serial(indice[6], 5, &prms);
6185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
6195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Check stability on isf : distance between old isf and current isf */
6215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = 0;
6235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 0; i < M - 1; i++)
6245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
6255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tmp = vo_sub(isf[i], st->isfold[i]);
6265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp += (tmp * tmp)<<1;
6275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
6285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = extract_h(L_shl2(L_tmp, 8));
6305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = vo_mult(tmp, 26214);                /* tmp = L_tmp*0.8/256 */
6325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = vo_sub(20480, tmp);                 /* 1.25 - tmp (in Q14) */
6335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    stab_fac = shl(tmp, 1);
6355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (stab_fac < 0)
6375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
6385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        stab_fac = 0;
6395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
6405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(isf, st->isfold, M);
6415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Convert ISFs to the cosine domain */
6435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Isf_isp(isf, ispnew_q, M);
6445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (st->first_frame != 0)
6465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
6475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->first_frame = 0;
6485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(ispnew_q, st->ispold_q, M);
6495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
6505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Find the interpolated ISPs and convert to a[] for all subframes */
6515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Int_isp(st->ispold_q, ispnew_q, interpol_frac, Aq);
6535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* update ispold[] for the next frame */
6555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(ispnew_q, st->ispold_q, M);
6565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    p_Aq = Aq;
6585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
6595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
660e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT               /* asm optimization branch */
6615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu_opt(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
662e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
6635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
664e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
6655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p_Aq += (M + 1);
6665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
6675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Buffer isf's and energy for dtx on non-speech frame */
6695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (vad_flag == 0)
6705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
6715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (i = 0; i < L_FRAME; i++)
6725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
6735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            exc2[i] = exc[i] >> Q_new;
6745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
6755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = 0;
67658996b6fa078bde4b8a68891962b43383848c190Marco Nelissen        for (i = 0; i < L_FRAME; i++) {
67758996b6fa078bde4b8a68891962b43383848c190Marco Nelissen            Word32 tmp = L_mult(exc2[i], exc2[i]); // (exc2[i] * exc2[i])<<1;
67858996b6fa078bde4b8a68891962b43383848c190Marco Nelissen            L_tmp = L_add(L_tmp, tmp);
67958996b6fa078bde4b8a68891962b43383848c190Marco Nelissen        }
6805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp >>= 1;
6815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
6835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
6845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* range for closed loop pitch search in 1st subframe */
6855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    T0_min = T_op - 8;
6875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (T0_min < PIT_MIN)
6885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
6895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        T0_min = PIT_MIN;
6905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
6915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    T0_max = (T0_min + 15);
6925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
6935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(T0_max > PIT_MAX)
6945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
6955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        T0_max = PIT_MAX;
6965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        T0_min = T0_max - 15;
6975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
6985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*------------------------------------------------------------------------*
6995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *          Loop for every subframe in the analysis frame                 *
7005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *------------------------------------------------------------------------*
7015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *  To find the pitch and innovation parameters. The subframe size is     *
7025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *  L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times.               *
7035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - compute the target signal for pitch search                       *
7045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - compute impulse response of weighted synthesis filter (h1[])     *
7055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - find the closed-loop pitch parameters                            *
7065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - encode the pitch dealy                                           *
7075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - find 2 lt prediction (with / without LP filter for lt pred)      *
7085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - find 2 pitch gains and choose the best lt prediction.            *
7095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - find target vector for codebook search                           *
7105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - update the impulse response h1[] for codebook search             *
7115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - correlation between target vector and impulse response           *
7125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - codebook search and encoding                                     *
7135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - VQ of pitch and codebook gains                                   *
7145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - find voicing factor and tilt of code for next subframe.          *
7155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - update states of weighting filter                                *
7165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     - find excitation and synthesis speech                             *
7175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *------------------------------------------------------------------------*/
7185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    p_A = A;
7195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    p_Aq = Aq;
7205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
7215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
7225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        pit_flag = i_subfr;
7235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if ((i_subfr == 2 * L_SUBFR) && (*ser_size > NBBITS_7k))
7245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
7255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            pit_flag = 0;
7265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /* range for closed loop pitch search in 3rd subframe */
7275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            T0_min = (T_op2 - 8);
7285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
7295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            if (T0_min < PIT_MIN)
7305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
7315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                T0_min = PIT_MIN;
7325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
7335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            T0_max = (T0_min + 15);
7345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            if (T0_max > PIT_MAX)
7355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
7365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                T0_max = PIT_MAX;
7375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                T0_min = (T0_max - 15);
7385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
7395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
7405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*-----------------------------------------------------------------------*
7415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *                                                                       *
7425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *        Find the target vector for pitch search:                       *
7435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                        *
7445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *                                                                       *
7455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *             |------|  res[n]                                          *
7465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * speech[n]---| A(z) |--------                                          *
7475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *             |------|       |   |--------| error[n]  |------|          *
7485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *                   zero -- (-)--| 1/A(z) |-----------| W(z) |-- target *
7495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *                   exc          |--------|           |------|          *
7505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *                                                                       *
7515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * Instead of subtracting the zero-input response of filters from        *
7525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * the weighted input speech, the above configuration is used to         *
7535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * compute the target vector.                                            *
7545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *                                                                       *
7555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *-----------------------------------------------------------------------*/
7565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
7575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (i = 0; i < M; i++)
7585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
7595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            error[i] = vo_sub(speech[i + i_subfr - M], st->mem_syn[i]);
7605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
761e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
762e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT              /* asm optimization branch */
7635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu_opt(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
764e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
7655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
766e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
7675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Syn_filt(p_Aq, &exc[i_subfr], error + M, L_SUBFR, error, 0);
7685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Weight_a(p_A, Ap, GAMMA1, M);
769e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
770e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT             /* asm optimization branch */
7715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu_opt(Ap, error + M, xn, L_SUBFR);
772e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
7735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu(Ap, error + M, xn, L_SUBFR);
774e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
7755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Deemph2(xn, TILT_FAC, L_SUBFR, &(st->mem_w0));
7765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
7775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*----------------------------------------------------------------------*
7785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * Find approx. target in residual domain "cn[]" for inovation search.  *
7795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *----------------------------------------------------------------------*/
7805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* first half: xn[] --> cn[] */
7815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Set_zero(code, M);
7825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(xn, code + M, L_SUBFR / 2);
7835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tmp = 0;
7845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Preemph2(code + M, TILT_FAC, L_SUBFR / 2, &tmp);
7855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Weight_a(p_A, Ap, GAMMA1, M);
7865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Syn_filt(Ap,code + M, code + M, L_SUBFR / 2, code, 0);
787e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
788e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                /* asm optimization branch */
7895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu_opt(p_Aq,code + M, cn, L_SUBFR / 2);
790e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
7915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Residu(p_Aq,code + M, cn, L_SUBFR / 2);
792e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
793e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
7945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* second half: res[] --> cn[] (approximated and faster) */
7955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(&exc[i_subfr + (L_SUBFR / 2)], cn + (L_SUBFR / 2), L_SUBFR / 2);
7965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
7975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*---------------------------------------------------------------*
7985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * Compute impulse response, h1[], of weighted synthesis filter  *
7995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *---------------------------------------------------------------*/
8005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
8015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Set_zero(error, M + L_SUBFR);
8025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Weight_a(p_A, error + M, GAMMA1, M);
8035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
8045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        vo_p0 = error+M;
8055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        vo_p3 = h1;
8065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (i = 0; i < L_SUBFR; i++)
8075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
8085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp = *vo_p0 << 14;        /* x4 (Q12 to Q14) */
8095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            vo_p1 = p_Aq + 1;
8105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            vo_p2 = vo_p0-1;
8115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            for (j = 1; j <= M/4; j++)
8125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
8135d453222ae6dcc10efedb1e4805247d7c22a4168Marco Nelissen                L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
8145d453222ae6dcc10efedb1e4805247d7c22a4168Marco Nelissen                L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
8155d453222ae6dcc10efedb1e4805247d7c22a4168Marco Nelissen                L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
8165d453222ae6dcc10efedb1e4805247d7c22a4168Marco Nelissen                L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
8175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
8185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            *vo_p3++ = *vo_p0++ = vo_round((L_tmp <<4));
8195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
8205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* deemph without division by 2 -> Q14 to Q15 */
8215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tmp = 0;
8225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Deemph2(h1, TILT_FAC, L_SUBFR, &tmp);   /* h1 in Q14 */
8235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
8245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* h2 in Q12 for codebook search */
8255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(h1, h2, L_SUBFR);
8265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
8275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*---------------------------------------------------------------*
8285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * scale xn[] and h1[] to avoid overflow in dot_product12()      *
8295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *---------------------------------------------------------------*/
830e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef  ASM_OPT                  /* asm optimization branch */
8315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Scale_sig_opt(h2, L_SUBFR, -2);
8325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Scale_sig_opt(xn, L_SUBFR, shift);     /* scaling of xn[] to limit dynamic at 12 bits */
8335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Scale_sig_opt(h1, L_SUBFR, 1 + shift);  /* set h1[] in Q15 with scaling for convolution */
834e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
8355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Scale_sig(h2, L_SUBFR, -2);
8365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Scale_sig(xn, L_SUBFR, shift);     /* scaling of xn[] to limit dynamic at 12 bits */
8375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Scale_sig(h1, L_SUBFR, 1 + shift);  /* set h1[] in Q15 with scaling for convolution */
838e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
8395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*----------------------------------------------------------------------*
8405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *                 Closed-loop fractional pitch search                  *
8415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *----------------------------------------------------------------------*/
8425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* find closed loop fractional pitch  lag */
8435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(*ser_size <= NBBITS_9k)
8445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
8455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
8465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    pit_flag, PIT_MIN, PIT_FR1_8b, L_SUBFR);
8475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
8485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /* encode pitch lag */
8495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            if (pit_flag == 0)             /* if 1st/3rd subframe */
8505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
8515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                /*--------------------------------------------------------------*
8525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 * The pitch range for the 1st/3rd subframe is encoded with     *
8535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 * 8 bits and is divided as follows:                            *
8545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *   PIT_MIN to PIT_FR1-1  resolution 1/2 (frac = 0 or 2)       *
8555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *   PIT_FR1 to PIT_MAX    resolution 1   (frac = 0)            *
8565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *--------------------------------------------------------------*/
8575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                if (T0 < PIT_FR1_8b)
8585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
8595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    index = ((T0 << 1) + (T0_frac >> 1) - (PIT_MIN<<1));
8605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                } else
8615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
8625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    index = ((T0 - PIT_FR1_8b) + ((PIT_FR1_8b - PIT_MIN)*2));
8635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                }
8645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
8655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                Parm_serial(index, 8, &prms);
8665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
8675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                /* find T0_min and T0_max for subframe 2 and 4 */
8685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                T0_min = (T0 - 8);
8695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                if (T0_min < PIT_MIN)
8705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
8715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    T0_min = PIT_MIN;
8725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                }
8735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                T0_max = T0_min + 15;
8745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                if (T0_max > PIT_MAX)
8755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
8765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    T0_max = PIT_MAX;
8775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    T0_min = (T0_max - 15);
8785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                }
8795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            } else
8805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {                              /* if subframe 2 or 4 */
8815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                /*--------------------------------------------------------------*
8825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 * The pitch range for subframe 2 or 4 is encoded with 5 bits:  *
8835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *   T0_min  to T0_max     resolution 1/2 (frac = 0 or 2)       *
8845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *--------------------------------------------------------------*/
8855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                i = (T0 - T0_min);
8865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                index = (i << 1) + (T0_frac >> 1);
8875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
8885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                Parm_serial(index, 5, &prms);
8895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
8905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else
8915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
8925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
8935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    pit_flag, PIT_FR2, PIT_FR1_9b, L_SUBFR);
8945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
8955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /* encode pitch lag */
8965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            if (pit_flag == 0)             /* if 1st/3rd subframe */
8975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
8985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                /*--------------------------------------------------------------*
8995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 * The pitch range for the 1st/3rd subframe is encoded with     *
9005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 * 9 bits and is divided as follows:                            *
9015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *   PIT_MIN to PIT_FR2-1  resolution 1/4 (frac = 0,1,2 or 3)   *
9025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *   PIT_FR2 to PIT_FR1-1  resolution 1/2 (frac = 0 or 1)       *
9035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *   PIT_FR1 to PIT_MAX    resolution 1   (frac = 0)            *
9045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *--------------------------------------------------------------*/
9055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
9065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                if (T0 < PIT_FR2)
9075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
9085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    index = ((T0 << 2) + T0_frac) - (PIT_MIN << 2);
9095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                } else if(T0 < PIT_FR1_9b)
9105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
9115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    index = ((((T0 << 1) + (T0_frac >> 1)) - (PIT_FR2<<1)) + ((PIT_FR2 - PIT_MIN)<<2));
9125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                } else
9135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
9145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    index = (((T0 - PIT_FR1_9b) + ((PIT_FR2 - PIT_MIN)<<2)) + ((PIT_FR1_9b - PIT_FR2)<<1));
9155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                }
9165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
9175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                Parm_serial(index, 9, &prms);
9185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
9195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                /* find T0_min and T0_max for subframe 2 and 4 */
9205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
9215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                T0_min = (T0 - 8);
9225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                if (T0_min < PIT_MIN)
9235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
9245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    T0_min = PIT_MIN;
9255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                }
9265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                T0_max = T0_min + 15;
9275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
9285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                if (T0_max > PIT_MAX)
9295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
9305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    T0_max = PIT_MAX;
9315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    T0_min = (T0_max - 15);
9325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                }
9335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            } else
9345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {                              /* if subframe 2 or 4 */
9355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                /*--------------------------------------------------------------*
9365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 * The pitch range for subframe 2 or 4 is encoded with 6 bits:  *
9375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *   T0_min  to T0_max     resolution 1/4 (frac = 0,1,2 or 3)   *
9385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                 *--------------------------------------------------------------*/
9395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                i = (T0 - T0_min);
9405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                index = (i << 2) + T0_frac;
9415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                Parm_serial(index, 6, &prms);
9425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
9435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
9445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
9455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*-----------------------------------------------------------------*
9465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * Gain clipping test to avoid unstable synthesis on frame erasure *
9475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *-----------------------------------------------------------------*/
9485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
9495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        clip_gain = 0;
9505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if((st->gp_clip[0] < 154) && (st->gp_clip[1] > 14746))
9515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            clip_gain = 1;
9525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
9535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*-----------------------------------------------------------------*
9545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - find unity gain pitch excitation (adaptive codebook entry)    *
9555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *   with fractional interpolation.                                *
9565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - find filtered pitch exc. y1[]=exc[] convolved with h1[])      *
9575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - compute pitch gain1                                           *
9585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *-----------------------------------------------------------------*/
9595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* find pitch exitation */
960e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                  /* asm optimization branch */
9615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        pred_lt4_asm(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1);
962e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
9635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Pred_lt4(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1);
964e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
9655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if (*ser_size > NBBITS_9k)
9665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
967e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                   /* asm optimization branch */
9685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Convolve_asm(&exc[i_subfr], h1, y1, L_SUBFR);
969e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
9705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Convolve(&exc[i_subfr], h1, y1, L_SUBFR);
971b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard#endif
9725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            gain1 = G_pitch(xn, y1, g_coeff, L_SUBFR);
9735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /* clip gain if necessary to avoid problem at decoder */
9745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            if ((clip_gain != 0) && (gain1 > GP_CLIP))
9755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
9765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                gain1 = GP_CLIP;
9775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
9785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /* find energy of new target xn2[] */
9795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Updt_tar(xn, dn, y1, gain1, L_SUBFR);       /* dn used temporary */
9805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else
9815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
9825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            gain1 = 0;
9835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
9845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*-----------------------------------------------------------------*
9855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - find pitch excitation filtered by 1st order LP filter.        *
9865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - find filtered pitch exc. y2[]=exc[] convolved with h1[])      *
9875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - compute pitch gain2                                           *
9885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *-----------------------------------------------------------------*/
9895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* find pitch excitation with lp filter */
9905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        vo_p0 = exc + i_subfr-1;
9915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        vo_p1 = code;
9925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* find pitch excitation with lp filter */
9935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (i = 0; i < L_SUBFR/2; i++)
9945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
9955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp = 5898 * *vo_p0++;
9965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp1 = 5898 * *vo_p0;
9975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp += 20972 * *vo_p0++;
9985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp1 += 20972 * *vo_p0++;
9995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp1 += 5898 * *vo_p0--;
10005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp += 5898 * *vo_p0;
10015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            *vo_p1++ = (L_tmp + 0x4000)>>15;
10025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            *vo_p1++ = (L_tmp1 + 0x4000)>>15;
10035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
1004e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1005e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                 /* asm optimization branch */
10065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Convolve_asm(code, h1, y2, L_SUBFR);
1007e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
10085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Convolve(code, h1, y2, L_SUBFR);
1009b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard#endif
1010e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
10115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        gain2 = G_pitch(xn, y2, g_coeff2, L_SUBFR);
10125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
10135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* clip gain if necessary to avoid problem at decoder */
10145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if ((clip_gain != 0) && (gain2 > GP_CLIP))
10155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
10165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            gain2 = GP_CLIP;
10175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
10185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* find energy of new target xn2[] */
10195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Updt_tar(xn, xn2, y2, gain2, L_SUBFR);
10205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*-----------------------------------------------------------------*
10215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * use the best prediction (minimise quadratic error).             *
10225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *-----------------------------------------------------------------*/
10235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        select = 0;
10245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(*ser_size > NBBITS_9k)
10255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
10265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp = 0L;
10275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            vo_p0 = dn;
10285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            vo_p1 = xn2;
10295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            for (i = 0; i < L_SUBFR/2; i++)
10305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
103125bf5e20ef69cc8944c72d0eb6a4fb58d4bacbfdMarco Nelissen                L_tmp = L_add(L_tmp, *vo_p0 * *vo_p0);
10325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                vo_p0++;
103325bf5e20ef69cc8944c72d0eb6a4fb58d4bacbfdMarco Nelissen                L_tmp = L_sub(L_tmp, *vo_p1 * *vo_p1);
10345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                vo_p1++;
103525bf5e20ef69cc8944c72d0eb6a4fb58d4bacbfdMarco Nelissen                L_tmp = L_add(L_tmp, *vo_p0 * *vo_p0);
10365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                vo_p0++;
103725bf5e20ef69cc8944c72d0eb6a4fb58d4bacbfdMarco Nelissen                L_tmp = L_sub(L_tmp, *vo_p1 * *vo_p1);
10385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                vo_p1++;
10395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
10405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
10415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            if (L_tmp <= 0)
10425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
10435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                select = 1;
10445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
10455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(select, 1, &prms);
10465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
10475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if (select == 0)
10485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
10495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /* use the lp filter for pitch excitation prediction */
10505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            gain_pit = gain2;
10515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Copy(code, &exc[i_subfr], L_SUBFR);
10525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Copy(y2, y1, L_SUBFR);
10535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Copy(g_coeff2, g_coeff, 4);
10545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else
10555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
10565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /* no filter used for pitch excitation prediction */
10575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            gain_pit = gain1;
10585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Copy(dn, xn2, L_SUBFR);        /* target vector for codebook search */
10595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
10605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*-----------------------------------------------------------------*
10615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - update cn[] for codebook search                               *
10625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *-----------------------------------------------------------------*/
10635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Updt_tar(cn, cn, &exc[i_subfr], gain_pit, L_SUBFR);
1064e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1065e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef  ASM_OPT                           /* asm optimization branch */
10665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Scale_sig_opt(cn, L_SUBFR, shift);     /* scaling of cn[] to limit dynamic at 12 bits */
1067e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
10685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Scale_sig(cn, L_SUBFR, shift);     /* scaling of cn[] to limit dynamic at 12 bits */
1069e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
10705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*-----------------------------------------------------------------*
10715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - include fixed-gain pitch contribution into impulse resp. h1[] *
10725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *-----------------------------------------------------------------*/
10735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tmp = 0;
10745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Preemph(h2, st->tilt_code, L_SUBFR, &tmp);
10755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
10765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if (T0_frac > 2)
10775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            T0 = (T0 + 1);
10785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Pit_shrp(h2, T0, PIT_SHARP, L_SUBFR);
10795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*-----------------------------------------------------------------*
10805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - Correlation between target xn2[] and impulse response h1[]    *
10815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - Innovative codebook search                                    *
10825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *-----------------------------------------------------------------*/
10835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        cor_h_x(h2, xn2, dn);
10845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if (*ser_size <= NBBITS_7k)
10855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
10865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            ACELP_2t64_fx(dn, cn, h2, code, y2, indice);
10875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
10885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[0], 12, &prms);
10895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else if(*ser_size <= NBBITS_9k)
10905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
10915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            ACELP_4t64_fx(dn, cn, h2, code, y2, 20, *ser_size, indice);
10925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
10935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[0], 5, &prms);
10945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[1], 5, &prms);
10955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[2], 5, &prms);
10965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[3], 5, &prms);
10975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else if(*ser_size <= NBBITS_12k)
10985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
10995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            ACELP_4t64_fx(dn, cn, h2, code, y2, 36, *ser_size, indice);
11005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
11015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[0], 9, &prms);
11025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[1], 9, &prms);
11035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[2], 9, &prms);
11045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[3], 9, &prms);
11055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else if(*ser_size <= NBBITS_14k)
11065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
11075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            ACELP_4t64_fx(dn, cn, h2, code, y2, 44, *ser_size, indice);
11085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
11095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[0], 13, &prms);
11105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[1], 13, &prms);
11115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[2], 9, &prms);
11125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[3], 9, &prms);
11135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else if(*ser_size <= NBBITS_16k)
11145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
11155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            ACELP_4t64_fx(dn, cn, h2, code, y2, 52, *ser_size, indice);
11165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
11175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[0], 13, &prms);
11185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[1], 13, &prms);
11195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[2], 13, &prms);
11205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[3], 13, &prms);
11215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else if(*ser_size <= NBBITS_18k)
11225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
11235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            ACELP_4t64_fx(dn, cn, h2, code, y2, 64, *ser_size, indice);
11245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
11255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[0], 2, &prms);
11265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[1], 2, &prms);
11275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[2], 2, &prms);
11285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[3], 2, &prms);
11295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[4], 14, &prms);
11305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[5], 14, &prms);
11315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[6], 14, &prms);
11325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[7], 14, &prms);
11335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else if(*ser_size <= NBBITS_20k)
11345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
11355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            ACELP_4t64_fx(dn, cn, h2, code, y2, 72, *ser_size, indice);
11365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
11375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[0], 10, &prms);
11385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[1], 10, &prms);
11395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[2], 2, &prms);
11405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[3], 2, &prms);
11415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[4], 10, &prms);
11425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[5], 10, &prms);
11435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[6], 14, &prms);
11445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[7], 14, &prms);
11455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else
11465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
11475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            ACELP_4t64_fx(dn, cn, h2, code, y2, 88, *ser_size, indice);
11485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
11495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[0], 11, &prms);
11505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[1], 11, &prms);
11515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[2], 11, &prms);
11525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[3], 11, &prms);
11535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[4], 11, &prms);
11545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[5], 11, &prms);
11555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[6], 11, &prms);
11565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(indice[7], 11, &prms);
11575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
11585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*-------------------------------------------------------*
11595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - Add the fixed-gain pitch contribution to code[].    *
11605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *-------------------------------------------------------*/
11615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tmp = 0;
11625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Preemph(code, st->tilt_code, L_SUBFR, &tmp);
11635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Pit_shrp(code, T0, PIT_SHARP, L_SUBFR);
11645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*----------------------------------------------------------*
11655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *  - Compute the fixed codebook gain                       *
11665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *  - quantize fixed codebook gain                          *
11675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *----------------------------------------------------------*/
11685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(*ser_size <= NBBITS_9k)
11695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
11705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            index = Q_gain2(xn, y1, Q_new + shift, y2, code, g_coeff, L_SUBFR, 6,
11715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    &gain_pit, &L_gain_code, clip_gain, st->qua_gain);
11725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(index, 6, &prms);
11735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        } else
11745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
11755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            index = Q_gain2(xn, y1, Q_new + shift, y2, code, g_coeff, L_SUBFR, 7,
11765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    &gain_pit, &L_gain_code, clip_gain, st->qua_gain);
11775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(index, 7, &prms);
11785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
11795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* test quantized gain of pitch for pitch clipping algorithm */
11805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Gp_clip_test_gain_pit(gain_pit, st->gp_clip);
11815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
11825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = L_shl(L_gain_code, Q_new);
11835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        gain_code = extract_h(L_add(L_tmp, 0x8000));
11845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
11855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*----------------------------------------------------------*
11865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * Update parameters for the next subframe.                 *
11875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced)           *
11885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *----------------------------------------------------------*/
11895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* find voice factor in Q15 (1=voiced, -1=unvoiced) */
11905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Copy(&exc[i_subfr], exc2, L_SUBFR);
1191e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1192e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                           /* asm optimization branch */
11935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Scale_sig_opt(exc2, L_SUBFR, shift);
1194e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
11955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Scale_sig(exc2, L_SUBFR, shift);
1196e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
11975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        voice_fac = voice_factor(exc2, shift, gain_pit, code, gain_code, L_SUBFR);
11985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
11995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->tilt_code = ((voice_fac >> 2) + 8192);
12005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /*------------------------------------------------------*
12015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - Update filter's memory "mem_w0" for finding the    *
12025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *   target vector in the next subframe.                *
12035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - Find the total excitation                          *
12045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         * - Find synthesis speech to update mem_syn[].         *
12055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen         *------------------------------------------------------*/
12065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* y2 in Q9, gain_pit in Q14 */
12085d453222ae6dcc10efedb1e4805247d7c22a4168Marco Nelissen        L_tmp = L_mult(gain_code, y2[L_SUBFR - 1]);
12095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = L_shl(L_tmp, (5 + shift));
12105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = L_negate(L_tmp);
12115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp += (xn[L_SUBFR - 1] * 16384)<<1;
12125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp -= (y1[L_SUBFR - 1] * gain_pit)<<1;
12135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = L_shl(L_tmp, (1 - shift));
12145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->mem_w0 = extract_h(L_add(L_tmp, 0x8000));
12155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if (*ser_size >= NBBITS_24k)
12175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Copy(&exc[i_subfr], exc2, L_SUBFR);
12185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (i = 0; i < L_SUBFR; i++)
12205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
122158996b6fa078bde4b8a68891962b43383848c190Marco Nelissen            Word32 tmp;
12225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /* code in Q9, gain_pit in Q14 */
12235d453222ae6dcc10efedb1e4805247d7c22a4168Marco Nelissen            L_tmp = L_mult(gain_code, code[i]);
12245d453222ae6dcc10efedb1e4805247d7c22a4168Marco Nelissen            L_tmp = L_shl(L_tmp, 5);
122558996b6fa078bde4b8a68891962b43383848c190Marco Nelissen            tmp = L_mult(exc[i + i_subfr], gain_pit); // (exc[i + i_subfr] * gain_pit)<<1
122658996b6fa078bde4b8a68891962b43383848c190Marco Nelissen            L_tmp = L_add(L_tmp, tmp);
12275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp = L_shl2(L_tmp, 1);
12285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            exc[i + i_subfr] = extract_h(L_add(L_tmp, 0x8000));
12295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
12305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Syn_filt(p_Aq,&exc[i_subfr], synth, L_SUBFR, st->mem_syn, 1);
12325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(*ser_size >= NBBITS_24k)
12345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
12355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /*------------------------------------------------------------*
12365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             * phase dispersion to enhance noise in low bit rate          *
12375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             *------------------------------------------------------------*/
12385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /* L_gain_code in Q16 */
12395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            VO_L_Extract(L_gain_code, &gain_code, &gain_code_lo);
12405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /*------------------------------------------------------------*
12425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             * noise enhancer                                             *
12435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             * ~~~~~~~~~~~~~~                                             *
12445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             * - Enhance excitation on noise. (modify gain of code)       *
12455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             *   If signal is noisy and LPC filter is stable, move gain   *
12465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             *   of code 1.5 dB toward gain of code threshold.            *
12475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             *   This decrease by 3 dB noise energy variation.            *
12485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             *------------------------------------------------------------*/
12495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            tmp = (16384 - (voice_fac >> 1));        /* 1=unvoiced, 0=voiced */
12505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            fac = vo_mult(stab_fac, tmp);
12515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp = L_gain_code;
12525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            if(L_tmp < st->L_gc_thres)
12535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
12545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                L_tmp = vo_L_add(L_tmp, Mpy_32_16(gain_code, gain_code_lo, 6226));
12555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                if(L_tmp > st->L_gc_thres)
12565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
12575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    L_tmp = st->L_gc_thres;
12585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                }
12595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            } else
12605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
12615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                L_tmp = Mpy_32_16(gain_code, gain_code_lo, 27536);
12625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                if(L_tmp < st->L_gc_thres)
12635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                {
12645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    L_tmp = st->L_gc_thres;
12655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                }
12665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
12675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            st->L_gc_thres = L_tmp;
12685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_gain_code = Mpy_32_16(gain_code, gain_code_lo, (32767 - fac));
12705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            VO_L_Extract(L_tmp, &gain_code, &gain_code_lo);
12715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_gain_code = vo_L_add(L_gain_code, Mpy_32_16(gain_code, gain_code_lo, fac));
12725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /*------------------------------------------------------------*
12745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             * pitch enhancer                                             *
12755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             * ~~~~~~~~~~~~~~                                             *
12765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             * - Enhance excitation on voice. (HP filtering of code)      *
12775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             *   On voiced signal, filtering of code by a smooth fir HP   *
12785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             *   filter to decrease energy of code in low frequency.      *
12795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen             *------------------------------------------------------------*/
12805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            tmp = ((voice_fac >> 3) + 4096); /* 0.25=voiced, 0=unvoiced */
12825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp = L_deposit_h(code[0]);
12845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp -= (code[1] * tmp)<<1;
12855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            code2[0] = vo_round(L_tmp);
12865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            for (i = 1; i < L_SUBFR - 1; i++)
12885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
12895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                L_tmp = L_deposit_h(code[i]);
12905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                L_tmp -= (code[i + 1] * tmp)<<1;
12915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                L_tmp -= (code[i - 1] * tmp)<<1;
12925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                code2[i] = vo_round(L_tmp);
12935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
12945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp = L_deposit_h(code[L_SUBFR - 1]);
12965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_tmp -= (code[L_SUBFR - 2] * tmp)<<1;
12975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            code2[L_SUBFR - 1] = vo_round(L_tmp);
12985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
12995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            /* build excitation */
13005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            gain_code = vo_round(L_shl(L_gain_code, Q_new));
13015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
13025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            for (i = 0; i < L_SUBFR; i++)
13035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
1304033b6f7ffdb1ac9e1d2a652e3f5998bf442c0f7bMarco Nelissen                L_tmp = L_mult(code2[i], gain_code);
1305033b6f7ffdb1ac9e1d2a652e3f5998bf442c0f7bMarco Nelissen                L_tmp = L_shl(L_tmp, 5);
1306033b6f7ffdb1ac9e1d2a652e3f5998bf442c0f7bMarco Nelissen                L_tmp = L_add(L_tmp, L_mult(exc2[i], gain_pit));
1307033b6f7ffdb1ac9e1d2a652e3f5998bf442c0f7bMarco Nelissen                L_tmp = L_shl(L_tmp, 1);
130858996b6fa078bde4b8a68891962b43383848c190Marco Nelissen                exc2[i] = voround(L_tmp);
13095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
13105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
13115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            corr_gain = synthesis(p_Aq, exc2, Q_new, &speech16k[i_subfr * 5 / 4], st);
13125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            Parm_serial(corr_gain, 4, &prms);
13135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
13145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p_A += (M + 1);
13155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p_Aq += (M + 1);
13165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }                                      /* end of subframe loop */
13175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
13185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*--------------------------------------------------*
13195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * Update signal for next frame.                    *
13205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * -> save past of speech[], wsp[] and exc[].       *
13215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *--------------------------------------------------*/
13225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
13235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
13245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(&old_exc[L_FRAME], st->old_exc, PIT_MAX + L_INTERPOL);
13255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return;
1326e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1327e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1328e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*-----------------------------------------------------*
1329e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function synthesis()                                *
1330e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                     *
1331e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Synthesis of signal at 16kHz with HF extension.     *
1332e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                     *
1333e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*-----------------------------------------------------*/
1334e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1335e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 synthesis(
13365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 Aq[],                          /* A(z)  : quantized Az               */
13375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 exc[],                         /* (i)   : excitation at 12kHz        */
13385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 Q_new,                         /* (i)   : scaling performed on exc   */
13395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 synth16k[],                    /* (o)   : 16kHz synthesis signal     */
13405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Coder_State * st                      /* (i/o) : State structure            */
13415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        )
1342e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
13435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 fac, tmp, exp;
13445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 ener, exp_ener;
13455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word32 L_tmp, i;
13465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
13475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR];
13485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 synth[L_SUBFR];
13495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 HF[L_SUBFR16k];                 /* High Frequency vector      */
13505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 Ap[M + 1];
13515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
13525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 HF_SP[L_SUBFR16k];              /* High Frequency vector (from original signal) */
13535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
13545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 HP_est_gain, HP_calc_gain, HP_corr_gain;
13555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 dist_min, dist;
13565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 HP_gain_ind = 0;
13575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 gain1, gain2;
13585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 weight1, weight2;
13595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
13605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*------------------------------------------------------------*
13615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * speech synthesis                                           *
13625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * ~~~~~~~~~~~~~~~~                                           *
13635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * - Find synthesis speech corresponding to exc2[].           *
13645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * - Perform fixed deemphasis and hp 50hz filtering.          *
13655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * - Oversampling from 12.8kHz to 16kHz.                      *
13665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *------------------------------------------------------------*/
13675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(st->mem_syn_hi, synth_hi, M);
13685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(st->mem_syn_lo, synth_lo, M);
1369e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1370e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                 /* asm optimization branch */
13715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Syn_filt_32_asm(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
1372e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
13735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Syn_filt_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
1374e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
1375e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
13765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(synth_hi + L_SUBFR, st->mem_syn_hi, M);
13775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Copy(synth_lo + L_SUBFR, st->mem_syn_lo, M);
1378e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1379e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                 /* asm optimization branch */
13805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Deemph_32_asm(synth_hi + M, synth_lo + M, synth, &(st->mem_deemph));
1381e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
13825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR, &(st->mem_deemph));
1383e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
1384e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
13855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    HP50_12k8(synth, L_SUBFR, st->mem_sig_out);
13865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
13875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Original speech signal as reference for high band gain quantisation */
13885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 0; i < L_SUBFR16k; i++)
13895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
13905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        HF_SP[i] = synth16k[i];
13915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
13925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
13935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*------------------------------------------------------*
13945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * HF noise synthesis                                   *
13955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * ~~~~~~~~~~~~~~~~~~                                   *
13965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * - Generate HF noise between 5.5 and 7.5 kHz.         *
13975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * - Set energy of noise according to synthesis tilt.   *
13985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     tilt > 0.8 ==> - 14 dB (voiced)                  *
13995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     tilt   0.5 ==> - 6 dB  (voiced or noise)         *
14005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *     tilt < 0.0 ==>   0 dB  (noise)                   *
14015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *------------------------------------------------------*/
14025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* generate white noise vector */
14035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 0; i < L_SUBFR16k; i++)
14045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
14055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        HF[i] = Random(&(st->seed2))>>3;
14065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
14075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* energy of excitation */
1408e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                    /* asm optimization branch */
14095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig_opt(exc, L_SUBFR, -3);
14105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Q_new = Q_new - 3;
14115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    ener = extract_h(Dot_product12_asm(exc, exc, L_SUBFR, &exp_ener));
1412e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
14135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(exc, L_SUBFR, -3);
14145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Q_new = Q_new - 3;
14155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    ener = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp_ener));
1416e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
1417e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
14185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    exp_ener = exp_ener - (Q_new + Q_new);
14195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* set energy of white noise to energy of excitation */
1420e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT              /* asm optimization branch */
14215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = extract_h(Dot_product12_asm(HF, HF, L_SUBFR16k, &exp));
1422e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
14235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
1424e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
1425e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
14265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(tmp > ener)
14275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
14285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tmp = (tmp >> 1);                 /* Be sure tmp < ener */
14295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        exp = (exp + 1);
14305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
14315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
14325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    exp = (exp - exp_ener);
14335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Isqrt_n(&L_tmp, &exp);
14345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = L_shl(L_tmp, (exp + 1));       /* L_tmp x 2, L_tmp in Q31 */
14355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = extract_h(L_tmp);                /* tmp = 2 x sqrt(ener_exc/ener_hf) */
14365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 0; i < L_SUBFR16k; i++)
14385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
14395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        HF[i] = vo_mult(HF[i], tmp);
14405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
14415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */
14435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    HP400_12k8(synth, L_SUBFR, st->mem_hp400);
14445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = 1L;
14465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 0; i < L_SUBFR; i++)
14475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp += (synth[i] * synth[i])<<1;
14485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    exp = norm_l(L_tmp);
14505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    ener = extract_h(L_tmp << exp);   /* ener = r[0] */
14515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = 1L;
14535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 1; i < L_SUBFR; i++)
14545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp +=(synth[i] * synth[i - 1])<<1;
14555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = extract_h(L_tmp << exp);    /* tmp = r[1] */
14575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (tmp > 0)
14595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
14605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        fac = div_s(tmp, ener);
14615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    } else
14625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
14635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        fac = 0;
14645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
14655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* modify energy of white noise according to synthesis tilt */
14675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    gain1 = 32767 - fac;
14685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    gain2 = vo_mult(gain1, 20480);
14695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    gain2 = shl(gain2, 1);
14705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (st->vad_hist > 0)
14725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
14735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        weight1 = 0;
14745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        weight2 = 32767;
14755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    } else
14765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
14775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        weight1 = 32767;
14785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        weight2 = 0;
14795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
14805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = vo_mult(weight1, gain1);
14815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = add1(tmp, vo_mult(weight2, gain2));
14825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (tmp != 0)
14845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
14855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tmp = (tmp + 1);
14865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
14875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    HP_est_gain = tmp;
14885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
14895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(HP_est_gain < 3277)
14905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
14915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        HP_est_gain = 3277;                /* 0.1 in Q15 */
14925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
14935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
14945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Weight_a(Aq, Ap, 19661, M);            /* fac=0.6 */
1495e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1496e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                /* asm optimization branch */
14975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Syn_filt_asm(Ap, HF, HF, st->mem_syn_hf);
14985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* noise High Pass filtering (1ms of delay) */
14995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Filt_6k_7k_asm(HF, L_SUBFR16k, st->mem_hf);
15005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* filtering of the original signal */
15015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Filt_6k_7k_asm(HF_SP, L_SUBFR16k, st->mem_hf2);
15025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
15035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* check the gain difference */
15045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig_opt(HF_SP, L_SUBFR16k, -1);
15055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    ener = extract_h(Dot_product12_asm(HF_SP, HF_SP, L_SUBFR16k, &exp_ener));
15065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* set energy of white noise to energy of excitation */
15075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = extract_h(Dot_product12_asm(HF, HF, L_SUBFR16k, &exp));
1508e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
15095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Syn_filt(Ap, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
15105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* noise High Pass filtering (1ms of delay) */
15115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Filt_6k_7k(HF, L_SUBFR16k, st->mem_hf);
15125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* filtering of the original signal */
15135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Filt_6k_7k(HF_SP, L_SUBFR16k, st->mem_hf2);
15145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* check the gain difference */
15155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Scale_sig(HF_SP, L_SUBFR16k, -1);
15165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    ener = extract_h(Dot_product12(HF_SP, HF_SP, L_SUBFR16k, &exp_ener));
15175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* set energy of white noise to energy of excitation */
15185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
1519e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
1520e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
15215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (tmp > ener)
15225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
15235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        tmp = (tmp >> 1);                 /* Be sure tmp < ener */
15245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        exp = (exp + 1);
15255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
15265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
15275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    exp = vo_sub(exp, exp_ener);
15285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Isqrt_n(&L_tmp, &exp);
15295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = L_shl(L_tmp, exp);             /* L_tmp, L_tmp in Q31 */
15305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    HP_calc_gain = extract_h(L_tmp);       /* tmp = sqrt(ener_input/ener_hf) */
15315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
15325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* st->gain_alpha *= st->dtx_encSt->dtxHangoverCount/7 */
15335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tmp = (vo_L_mult(st->dtx_encSt->dtxHangoverCount, 4681) << 15);
15345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->gain_alpha = vo_mult(st->gain_alpha, extract_h(L_tmp));
15355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
15365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(st->dtx_encSt->dtxHangoverCount > 6)
15375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->gain_alpha = 32767;
15385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    HP_est_gain = HP_est_gain >> 1;     /* From Q15 to Q14 */
15395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    HP_corr_gain = add1(vo_mult(HP_calc_gain, st->gain_alpha), vo_mult((32767 - st->gain_alpha), HP_est_gain));
15405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
15415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Quantise the correction gain */
15425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    dist_min = 32767;
15435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 0; i < 16; i++)
15445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
15455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        dist = vo_mult((HP_corr_gain - HP_gain[i]), (HP_corr_gain - HP_gain[i]));
15465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if (dist_min > dist)
15475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
15485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            dist_min = dist;
15495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            HP_gain_ind = i;
15505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
15515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
15525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    HP_corr_gain = HP_gain[HP_gain_ind];
15535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* return the quantised gain index when using the highest mode, otherwise zero */
15545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return (HP_gain_ind);
1555e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1556e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1557e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*************************************************
1558e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1559b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* Breif: Codec main function
1560e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1561e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************/
1562e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1563e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardint AMR_Enc_Encode(HAMRENC hCodec)
1564e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
15655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word32 i;
15665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Coder_State *gData = (Coder_State*)hCodec;
15675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 *signal;
15685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 packed_size = 0;
15695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 prms[NB_BITS_MAX];
15705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 coding_mode = 0, nb_bits, allow_dtx, mode, reset_flag;
15715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    mode = gData->mode;
15725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    coding_mode = gData->mode;
15735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    nb_bits = nb_of_bits[mode];
15745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    signal = (Word16 *)gData->inputStream;
15755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    allow_dtx = gData->allow_dtx;
15765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
15775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* check for homing frame */
15785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    reset_flag = encoder_homing_frame_test(signal);
15795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
15805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 0; i < L_FRAME16k; i++)   /* Delete the 2 LSBs (14-bit input) */
15815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
15825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        *(signal + i) = (Word16) (*(signal + i) & 0xfffC);
15835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
15845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
15855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    coder(&coding_mode, signal, prms, &nb_bits, gData, allow_dtx);
15865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    packed_size = PackBits(prms, coding_mode, mode, gData);
15875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (reset_flag != 0)
15885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
15895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Reset_encoder(gData, 1);
15905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
15915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return packed_size;
1592e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1593e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1594e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/***************************************************************************
1595e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1596e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*Brief: Codec API function --- Initialize the codec and return a codec handle
1597e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1598e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard***************************************************************************/
1599e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1600e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardVO_U32 VO_API voAMRWB_Init(VO_HANDLE * phCodec,                   /* o: the audio codec handle */
16015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                           VO_AUDIO_CODINGTYPE vType,             /* i: Codec Type ID */
16025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                           VO_CODEC_INIT_USERDATA * pUserData     /* i: init Parameters */
16035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                           )
1604e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
16055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Coder_State *st;
16065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    FrameStream *stream;
1607e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef USE_DEAULT_MEM
16085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    VO_MEM_OPERATOR voMemoprator;
1609e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
16105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    VO_MEM_OPERATOR *pMemOP;
161184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        UNUSED(vType);
161284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber
16135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    int interMem = 0;
1614e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
16155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL )
16165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
1617e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef USE_DEAULT_MEM
16185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        voMemoprator.Alloc = cmnMemAlloc;
16195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        voMemoprator.Copy = cmnMemCopy;
16205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        voMemoprator.Free = cmnMemFree;
16215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        voMemoprator.Set = cmnMemSet;
16225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        voMemoprator.Check = cmnMemCheck;
16235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        interMem = 1;
16245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        pMemOP = &voMemoprator;
1625e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
16265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        *phCodec = NULL;
16275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        return VO_ERR_INVALID_ARG;
1628e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
16295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
16305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    else
16315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
16325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        pMemOP = (VO_MEM_OPERATOR *)pUserData->memData;
16335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
16345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /*-------------------------------------------------------------------------*
16355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     * Memory allocation for coder state.                                      *
16365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen     *-------------------------------------------------------------------------*/
16375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if ((st = (Coder_State *)mem_malloc(pMemOP, sizeof(Coder_State), 32, VO_INDEX_ENC_AMRWB)) == NULL)
16385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
16395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        return VO_ERR_OUTOF_MEMORY;
16405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
16415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->vadSt = NULL;
16435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->dtx_encSt = NULL;
16445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->sid_update_counter = 3;
16455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->sid_handover_debt = 0;
16465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->prev_ft = TX_SPEECH;
16475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->inputStream = NULL;
16485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->inputSize = 0;
16495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Default setting */
16515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->mode = VOAMRWB_MD2385;                        /* bit rate 23.85kbps */
16525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->frameType = VOAMRWB_RFC3267;                  /* frame type: RFC3267 */
16535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->allow_dtx = 0;                                /* disable DTX mode */
16545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->outputStream = NULL;
16565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->outputSize = 0;
16575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->stream = (FrameStream *)mem_malloc(pMemOP, sizeof(FrameStream), 32, VO_INDEX_ENC_AMRWB);
16595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(st->stream == NULL)
16605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        return VO_ERR_OUTOF_MEMORY;
16615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->stream->frame_ptr = (unsigned char *)mem_malloc(pMemOP, Frame_Maxsize, 32, VO_INDEX_ENC_AMRWB);
16635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(st->stream->frame_ptr == NULL)
16645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        return  VO_ERR_OUTOF_MEMORY;
16655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    stream = st->stream;
16675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    voAWB_InitFrameBuffer(stream);
16685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    wb_vad_init(&(st->vadSt), pMemOP);
16705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    dtx_enc_init(&(st->dtx_encSt), isf_init, pMemOP);
16715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Reset_encoder((void *) st, 1);
16735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(interMem)
16755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
16765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->voMemoprator.Alloc = cmnMemAlloc;
16775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->voMemoprator.Copy = cmnMemCopy;
16785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->voMemoprator.Free = cmnMemFree;
16795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->voMemoprator.Set = cmnMemSet;
16805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        st->voMemoprator.Check = cmnMemCheck;
16815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        pMemOP = &st->voMemoprator;
16825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
16835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    st->pvoMemop = pMemOP;
16855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    *phCodec = (void *) st;
16875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
16885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return VO_ERR_NONE;
1689e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1690e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1691e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**********************************************************************************
1692e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1693e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Brief: Codec API function: Input PCM data
1694e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1695e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard***********************************************************************************/
1696e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1697e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardVO_U32 VO_API voAMRWB_SetInputData(
16985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_HANDLE hCodec,                   /* i/o: The codec handle which was created by Init function */
16995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_CODECBUFFER * pInput             /*   i: The input buffer parameter  */
17005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        )
1701e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
17025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Coder_State  *gData;
17035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    FrameStream  *stream;
1704e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(NULL == hCodec)
17065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
17075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        return VO_ERR_INVALID_ARG;
17085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
1709e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    gData = (Coder_State *)hCodec;
17115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    stream = gData->stream;
1712e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(NULL == pInput || NULL == pInput->Buffer)
17145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
17155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        return VO_ERR_INVALID_ARG;
17165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
1717e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    stream->set_ptr    = pInput->Buffer;
17195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    stream->set_len    = pInput->Length;
17205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    stream->frame_ptr  = stream->frame_ptr_bk;
17215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    stream->used_len   = 0;
1722e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return VO_ERR_NONE;
1724e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1725e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1726e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**************************************************************************************
1727e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1728e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Brief: Codec API function: Get the compression audio data frame by frame
1729e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1730e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard***************************************************************************************/
1731e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1732e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardVO_U32 VO_API voAMRWB_GetOutputData(
17335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_HANDLE hCodec,                    /* i: The Codec Handle which was created by Init function*/
17345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_CODECBUFFER * pOutput,            /* o: The output audio data */
17355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_AUDIO_OUTPUTINFO * pAudioFormat   /* o: The encoder module filled audio format and used the input size*/
17365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        )
1737e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
17385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Coder_State* gData = (Coder_State*)hCodec;
17395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    VO_MEM_OPERATOR  *pMemOP;
17405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    FrameStream  *stream = (FrameStream *)gData->stream;
17415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    pMemOP = (VO_MEM_OPERATOR  *)gData->pvoMemop;
17425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
17435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(stream->framebuffer_len  < Frame_MaxByte)         /* check the work buffer len */
17445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
17455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        stream->frame_storelen = stream->framebuffer_len;
17465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(stream->frame_storelen)
17475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
17485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            pMemOP->Copy(VO_INDEX_ENC_AMRWB, stream->frame_ptr_bk , stream->frame_ptr , stream->frame_storelen);
17495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
17505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(stream->set_len > 0)
17515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
17525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            voAWB_UpdateFrameBuffer(stream, pMemOP);
17535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
17545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(stream->framebuffer_len < Frame_MaxByte)
17555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
17565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            if(pAudioFormat)
17575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                pAudioFormat->InputUsed = stream->used_len;
17585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            return VO_ERR_INPUT_BUFFER_SMALL;
17595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
17605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
17615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
17625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    gData->inputStream = stream->frame_ptr;
17635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    gData->outputStream = (unsigned short*)pOutput->Buffer;
17645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
17655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    gData->outputSize = AMR_Enc_Encode(gData);         /* encoder main function */
17665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
17675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    pOutput->Length = gData->outputSize;               /* get the output buffer length */
17685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    stream->frame_ptr += 640;                          /* update the work buffer ptr */
17695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    stream->framebuffer_len  -= 640;
17705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
17715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(pAudioFormat)                                   /* return output audio information */
17725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
17735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        pAudioFormat->Format.Channels = 1;
17745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        pAudioFormat->Format.SampleRate = 8000;
17755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        pAudioFormat->Format.SampleBits = 16;
17765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        pAudioFormat->InputUsed = stream->used_len;
17775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
17785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return VO_ERR_NONE;
1779e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1780e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1781e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*************************************************************************
1782e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1783e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Brief: Codec API function---set the data by specified parameter ID
1784e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1785e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*************************************************************************/
1786e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1787e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1788e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardVO_U32 VO_API voAMRWB_SetParam(
17895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_HANDLE hCodec,   /* i/o: The Codec Handle which was created by Init function */
17905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_S32 uParamID,    /*   i: The param ID */
17915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_PTR pData        /*   i: The param value depend on the ID */
17925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        )
1793e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
17945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Coder_State* gData = (Coder_State*)hCodec;
17955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    FrameStream *stream = (FrameStream *)(gData->stream);
17965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    int *lValue = (int*)pData;
17975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
17985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    switch(uParamID)
17995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
18005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* setting AMR-WB frame type*/
18015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        case VO_PID_AMRWB_FRAMETYPE:
18025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            if(*lValue < VOAMRWB_DEFAULT || *lValue > VOAMRWB_RFC3267)
18035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                return VO_ERR_WRONG_PARAM_ID;
18045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            gData->frameType = *lValue;
18055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            break;
18065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* setting AMR-WB bit rate */
18075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        case VO_PID_AMRWB_MODE:
18085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
18095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                if(*lValue < VOAMRWB_MD66 || *lValue > VOAMRWB_MD2385)
18105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                    return VO_ERR_WRONG_PARAM_ID;
18115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                gData->mode = *lValue;
18125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
18135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            break;
18145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* enable or disable DTX mode */
18155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        case VO_PID_AMRWB_DTX:
18165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            gData->allow_dtx = (Word16)(*lValue);
18175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            break;
18185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
18195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        case VO_PID_COMMON_HEADDATA:
18205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            break;
1821e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard        /* flush the work buffer */
18225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        case VO_PID_COMMON_FLUSH:
18235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            stream->set_ptr = NULL;
18245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            stream->frame_storelen = 0;
18255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            stream->framebuffer_len = 0;
18265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            stream->set_len = 0;
18275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            break;
18285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
18295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        default:
18305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            return VO_ERR_WRONG_PARAM_ID;
18315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
18325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return VO_ERR_NONE;
1833e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1834e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1835e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**************************************************************************
1836e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1837e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*Brief: Codec API function---Get the data by specified parameter ID
1838e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1839e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard***************************************************************************/
1840e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1841e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardVO_U32 VO_API voAMRWB_GetParam(
18425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_HANDLE hCodec,      /* i: The Codec Handle which was created by Init function */
18435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_S32 uParamID,       /* i: The param ID */
18445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        VO_PTR pData           /* o: The param value depend on the ID */
18455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        )
1846e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
18475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    int    temp;
18485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Coder_State* gData = (Coder_State*)hCodec;
18495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
18505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if (gData==NULL)
18515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        return VO_ERR_INVALID_ARG;
18525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    switch(uParamID)
18535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
18545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* output audio format */
18555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        case VO_PID_AMRWB_FORMAT:
18565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
18575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                VO_AUDIO_FORMAT* fmt = (VO_AUDIO_FORMAT*)pData;
18585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                fmt->Channels   = 1;
18595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                fmt->SampleRate = 16000;
18605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                fmt->SampleBits = 16;
18615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                break;
18625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
1863e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard        /* output audio channel number */
18645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        case VO_PID_AMRWB_CHANNELS:
18655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            temp = 1;
18665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            pData = (void *)(&temp);
18675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            break;
1868e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard        /* output audio sample rate */
18695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        case VO_PID_AMRWB_SAMPLERATE:
18705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            temp = 16000;
18715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            pData = (void *)(&temp);
18725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            break;
18735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* output audio frame type */
18745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        case VO_PID_AMRWB_FRAMETYPE:
18755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            temp = gData->frameType;
18765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            pData = (void *)(&temp);
18775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            break;
18785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        /* output audio bit rate */
18795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        case VO_PID_AMRWB_MODE:
18805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            temp = gData->mode;
18815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            pData = (void *)(&temp);
18825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            break;
18835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        default:
18845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            return VO_ERR_WRONG_PARAM_ID;
18855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
18865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
18875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return VO_ERR_NONE;
1888e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1889e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1890e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/***********************************************************************************
1891e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1892e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Brief: Codec API function---Release the codec after all encoder operations are done
1893e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1894e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*************************************************************************************/
1895e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1896e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardVO_U32 VO_API voAMRWB_Uninit(VO_HANDLE hCodec           /* i/o: Codec handle pointer */
18975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                             )
1898e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
18995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Coder_State* gData = (Coder_State*)hCodec;
19005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    VO_MEM_OPERATOR *pMemOP;
19015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    pMemOP = gData->pvoMemop;
19025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
19035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(hCodec)
19045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
19055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(gData->stream)
19065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
19075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            if(gData->stream->frame_ptr_bk)
19085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            {
19095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                mem_free(pMemOP, gData->stream->frame_ptr_bk, VO_INDEX_ENC_AMRWB);
19105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                gData->stream->frame_ptr_bk = NULL;
19115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            }
19125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            mem_free(pMemOP, gData->stream, VO_INDEX_ENC_AMRWB);
19135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            gData->stream = NULL;
19145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
19155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        wb_vad_exit(&(((Coder_State *) gData)->vadSt), pMemOP);
19165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        dtx_enc_exit(&(((Coder_State *) gData)->dtx_encSt), pMemOP);
19175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
19185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        mem_free(pMemOP, hCodec, VO_INDEX_ENC_AMRWB);
19195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        hCodec = NULL;
19205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
19215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
19225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return VO_ERR_NONE;
1923e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1924e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1925e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/********************************************************************************
1926e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1927e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Brief: voGetAMRWBEncAPI gets the API handle of the codec
1928e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
1929e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard********************************************************************************/
1930e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1931e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardVO_S32 VO_API voGetAMRWBEncAPI(
19325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                               VO_AUDIO_CODECAPI * pEncHandle      /* i/o: Codec handle pointer */
19335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen                               )
1934e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
19355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    if(NULL == pEncHandle)
19365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        return VO_ERR_INVALID_ARG;
19375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    pEncHandle->Init = voAMRWB_Init;
19385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    pEncHandle->SetInputData = voAMRWB_SetInputData;
19395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    pEncHandle->GetOutputData = voAMRWB_GetOutputData;
19405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    pEncHandle->SetParam = voAMRWB_SetParam;
19415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    pEncHandle->GetParam = voAMRWB_GetParam;
19425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    pEncHandle->Uninit = voAMRWB_Uninit;
19435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen
19445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return VO_ERR_NONE;
1945e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1946e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1947e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef __cplusplus
1948e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1949e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
1950