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