198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Copyright (C) 2002-2006 Jean-Marc Valin
298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   File: nb_celp.c
398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   Redistribution and use in source and binary forms, with or without
598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   modification, are permitted provided that the following conditions
698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   are met:
798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   - Redistributions of source code must retain the above copyright
998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   notice, this list of conditions and the following disclaimer.
1098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
1198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   - Redistributions in binary form must reproduce the above copyright
1298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   notice, this list of conditions and the following disclaimer in the
1398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   documentation and/or other materials provided with the distribution.
1498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
1598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   - Neither the name of the Xiph.org Foundation nor the names of its
1698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   contributors may be used to endorse or promote products derived from
1798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   this software without specific prior written permission.
1898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
1998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
2398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project*/
3198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
3298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef HAVE_CONFIG_H
3398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "config.h"
3498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
3598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
3698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include <math.h>
3798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "nb_celp.h"
3898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "lpc.h"
3998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "lsp.h"
4098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "ltp.h"
4198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "quant_lsp.h"
4298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "cb_search.h"
4398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "filters.h"
4498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "stack_alloc.h"
4598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "vq.h"
4698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include <speex/speex_bits.h>
4798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "vbr.h"
4898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "arch.h"
4998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "math_approx.h"
5098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "os_support.h"
5198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include <speex/speex_callbacks.h>
5298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
5398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef VORBIS_PSYCHO
5498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "vorbis_psy.h"
5598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
5698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
5798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef M_PI
5898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define M_PI           3.14159265358979323846  /* pi */
5998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
6098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
6198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef NULL
6298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NULL 0
6398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
6498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
6598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SUBMODE(x) st->submodes[st->submodeID]->x
6698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
6798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Default size for the encoder and decoder stack (can be changed at compile time).
6898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   This does not apply when using variable-size arrays or alloca. */
6998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef NB_ENC_STACK
7098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NB_ENC_STACK (8000*sizeof(spx_sig_t))
7198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
7298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
7398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef NB_DEC_STACK
7498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NB_DEC_STACK (4000*sizeof(spx_sig_t))
7598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
7698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
7798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
7898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
7998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word32_t ol_gain_table[32]={18900, 25150, 33468, 44536, 59265, 78865, 104946, 139653, 185838, 247297, 329081, 437913, 582736, 775454, 1031906, 1373169, 1827293, 2431601, 3235761, 4305867, 5729870, 7624808, 10146425, 13501971, 17967238, 23909222, 31816294, 42338330, 56340132, 74972501, 99766822, 132760927};
8098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t exc_gain_quant_scal3_bound[7]={1841, 3883, 6051, 8062, 10444, 13580, 18560};
8198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t exc_gain_quant_scal3[8]={1002, 2680, 5086, 7016, 9108, 11781, 15380, 21740};
8298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t exc_gain_quant_scal1_bound[1]={14385};
8398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t exc_gain_quant_scal1[2]={11546, 17224};
8498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
8598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_MARGIN 16
8698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_DELTA1 6553
8798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_DELTA2 1638
8898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
8998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
9098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
9198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst float exc_gain_quant_scal3_bound[7]={0.112338f, 0.236980f, 0.369316f, 0.492054f, 0.637471f, 0.828874f, 1.132784f};
9298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst float exc_gain_quant_scal3[8]={0.061130f, 0.163546f, 0.310413f, 0.428220f, 0.555887f, 0.719055f, 0.938694f, 1.326874f};
9398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst float exc_gain_quant_scal1_bound[1]={0.87798f};
9498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst float exc_gain_quant_scal1[2]={0.70469f, 1.05127f};
9598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
9698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_MARGIN .002f
9798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_DELTA1 .2f
9898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_DELTA2 .05f
9998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
10098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
10198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
10298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef VORBIS_PSYCHO
10398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define EXTRA_BUFFER 100
10498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
10598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define EXTRA_BUFFER 0
10698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
10798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
10898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
10998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define sqr(x) ((x)*(x))
11098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
11198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectextern const spx_word16_t lag_window[];
11298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectextern const spx_word16_t lpc_window[];
11398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
11498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid *nb_encoder_init(const SpeexMode *m)
11598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
11698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   EncState *st;
11798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   const SpeexNBMode *mode;
11898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i;
11998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
12098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   mode=(const SpeexNBMode *)m->mode;
12198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st = (EncState*)speex_alloc(sizeof(EncState));
12298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (!st)
12398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return NULL;
12498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
12598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->stack = NULL;
12698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
12798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->stack = (char*)speex_alloc_scratch(NB_ENC_STACK);
12898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
12998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
13098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mode=m;
13198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
13298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->frameSize = mode->frameSize;
13398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->nbSubframes=mode->frameSize/mode->subframeSize;
13498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->subframeSize=mode->subframeSize;
13598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->windowSize = st->frameSize+st->subframeSize;
13698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->lpcSize = mode->lpcSize;
13798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->gamma1=mode->gamma1;
13898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->gamma2=mode->gamma2;
13998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->min_pitch=mode->pitchStart;
14098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->max_pitch=mode->pitchEnd;
14198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->lpc_floor = mode->lpc_floor;
14298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
14398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->submodes=mode->submodes;
14498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->submodeID=st->submodeSelect=mode->defaultSubmode;
14598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->bounded_pitch = 1;
14698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
14798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->encode_submode = 1;
14898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
14998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef VORBIS_PSYCHO
15098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->psy = vorbis_psy_init(8000, 256);
15198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->curve = (float*)speex_alloc(128*sizeof(float));
15298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->old_curve = (float*)speex_alloc(128*sizeof(float));
15398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->psy_window = (float*)speex_alloc(256*sizeof(float));
15498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
15598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
15698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->cumul_gain = 1024;
15798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
15898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Allocating input buffer */
15998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->winBuf = (spx_word16_t*)speex_alloc((st->windowSize-st->frameSize)*sizeof(spx_word16_t));
16098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Allocating excitation buffer */
16198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->excBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(spx_word16_t));
16298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->exc = st->excBuf + mode->pitchEnd + 2;
16398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->swBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(spx_word16_t));
16498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->sw = st->swBuf + mode->pitchEnd + 2;
16598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
16698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->window= lpc_window;
16798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
16898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Create the window for autocorrelation (lag-windowing) */
16998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->lagWindow = lag_window;
17098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
17198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->old_lsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
17298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
17398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->first = 1;
17498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<st->lpcSize;i++)
17598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
17698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
17798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
17898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
17998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mem_sw_whole = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
18098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mem_exc = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
18198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mem_exc2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
18298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
18398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
18498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->innov_rms_save = NULL;
18598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
18698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->pitch = (int*)speex_alloc((st->nbSubframes)*sizeof(int));
18798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
18898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
18998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->vbr = (VBRState*)speex_alloc(sizeof(VBRState));
19098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr_init(st->vbr);
19198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->vbr_quality = 8;
19298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->vbr_enabled = 0;
19398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->vbr_max = 0;
19498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->vad_enabled = 0;
19598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->dtx_enabled = 0;
19698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->dtx_count=0;
19798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->abr_enabled = 0;
19898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->abr_drift = 0;
19998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->abr_drift2 = 0;
20098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
20198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
20298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->plc_tuning = 2;
20398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->complexity=2;
20498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->sampling_rate=8000;
20598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->isWideband = 0;
20698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->highpass_enabled = 1;
20798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
20898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef ENABLE_VALGRIND
20998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VALGRIND_MAKE_READABLE(st, NB_ENC_STACK);
21098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
21198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return st;
21298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
21398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
21498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid nb_encoder_destroy(void *state)
21598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
21698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   EncState *st=(EncState *)state;
21798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Free all allocated memory */
21898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
21998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free_scratch(st->stack);
22098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
22198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
22298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->winBuf);
22398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->excBuf);
22498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->old_qlsp);
22598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->swBuf);
22698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
22798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->old_lsp);
22898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->mem_sp);
22998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->mem_sw);
23098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->mem_sw_whole);
23198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->mem_exc);
23298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->mem_exc2);
23398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->pi_gain);
23498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->pitch);
23598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
23698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
23798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr_destroy(st->vbr);
23898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->vbr);
23998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
24098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
24198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef VORBIS_PSYCHO
24298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vorbis_psy_destroy(st->psy);
24398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->curve);
24498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->old_curve);
24598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->psy_window);
24698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
24798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
24898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*Free state memory... should be last*/
24998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st);
25098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
25198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
25298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint nb_encode(void *state, void *vin, SpeexBits *bits)
25398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
25498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   EncState *st;
25598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i, sub, roots;
25698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int ol_pitch;
25798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t ol_pitch_coef;
25898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word32_t ol_gain;
25998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word16_t *ringing);
26098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word16_t *target);
26198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_sig_t *innov);
26298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word32_t *exc32);
26398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_mem_t *mem);
26498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *bw_lpc1);
26598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *bw_lpc2);
26698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *lpc);
26798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *lsp);
26898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *qlsp);
26998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *interp_lsp);
27098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *interp_qlsp);
27198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *interp_lpc);
27298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *interp_qlpc);
27398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   char *stack;
27498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word16_t *syn_resp);
27598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word16_t *real_exc);
27698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
27798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word32_t ener=0;
27898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t fine_gain;
27998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t *in = (spx_word16_t*)vin;
28098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
28198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st=(EncState *)state;
28298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   stack=st->stack;
28398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
28498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(lpc, st->lpcSize, spx_coef_t);
28598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(bw_lpc1, st->lpcSize, spx_coef_t);
28698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(bw_lpc2, st->lpcSize, spx_coef_t);
28798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(lsp, st->lpcSize, spx_lsp_t);
28898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(qlsp, st->lpcSize, spx_lsp_t);
28998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(interp_lsp, st->lpcSize, spx_lsp_t);
29098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
29198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(interp_lpc, st->lpcSize, spx_coef_t);
29298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(interp_qlpc, st->lpcSize, spx_coef_t);
29398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
29498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Move signals 1 frame towards the past */
29598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, st->max_pitch+2);
29698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SPEEX_MOVE(st->swBuf, st->swBuf+st->frameSize, st->max_pitch+2);
29798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
29898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->highpass_enabled)
29998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      highpass(in, in, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_INPUT, st->mem_hp);
30098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
30198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
30298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      VARDECL(spx_word16_t *w_sig);
30398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      VARDECL(spx_word16_t *autocorr);
30498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ALLOC(w_sig, st->windowSize, spx_word16_t);
30598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ALLOC(autocorr, st->lpcSize+1, spx_word16_t);
30698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Window for analysis */
30798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->windowSize-st->frameSize;i++)
30898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         w_sig[i] = EXTRACT16(SHR32(MULT16_16(st->winBuf[i],st->window[i]),SIG_SHIFT));
30998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (;i<st->windowSize;i++)
31098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         w_sig[i] = EXTRACT16(SHR32(MULT16_16(in[i-st->windowSize+st->frameSize],st->window[i]),SIG_SHIFT));
31198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute auto-correlation */
31298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize);
31398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */
31498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
31598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Lag windowing: equivalent to filtering in the power-spectrum domain */
31698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize+1;i++)
31798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]);
31898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
31998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Levinson-Durbin */
32098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      _spx_lpc(lpc, autocorr, st->lpcSize);
32198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* LPC to LSPs (x-domain) transform */
32298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack);
32398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Check if we found all the roots */
32498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (roots!=st->lpcSize)
32598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
32698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*If we can't find all LSP's, do some damage control and use previous filter*/
32798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
32898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
32998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            lsp[i]=st->old_lsp[i];
33098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
33198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
33298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
33398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
33498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
33598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
33698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
33798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */
33898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
33998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int diff = st->windowSize-st->frameSize;
34098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->first)
34198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
34298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            interp_lsp[i] = lsp[i];
34398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
34498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, st->nbSubframes, st->nbSubframes<<1);
34598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
34698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);
34798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
34898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute interpolated LPCs (unquantized) for whole frame*/
34998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);
35098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
35198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
35298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*Open-loop pitch*/
35398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (!st->submodes[st->submodeID] || (st->complexity>2 && SUBMODE(have_subframe_gain)<3) || SUBMODE(forced_pitch_gain) || SUBMODE(lbr_pitch) != -1
35498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
35598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project           || st->vbr_enabled || st->vad_enabled
35698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
35798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  )
35898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
35998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int nol_pitch[6];
36098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word16_t nol_pitch_coef[6];
36198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
36298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);
36398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
36498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
36598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SPEEX_COPY(st->sw, st->winBuf, diff);
36698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SPEEX_COPY(st->sw+diff, in, st->frameSize-diff);
36798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         filter_mem16(st->sw, bw_lpc1, bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole, stack);
36898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
36998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize,
37098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                               nol_pitch, nol_pitch_coef, 6, stack);
37198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         ol_pitch=nol_pitch[0];
37298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         ol_pitch_coef = nol_pitch_coef[0];
37398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*Try to remove pitch multiples*/
37498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=1;i<6;i++)
37598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
37698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
37798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],27853)) &&
37898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
37998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if ((nol_pitch_coef[i]>.85*nol_pitch_coef[0]) &&
38098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
38198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                (ABS(2*nol_pitch[i]-ol_pitch)<=2 || ABS(3*nol_pitch[i]-ol_pitch)<=3 ||
38298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                 ABS(4*nol_pitch[i]-ol_pitch)<=4 || ABS(5*nol_pitch[i]-ol_pitch)<=5))
38398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
38498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               /*ol_pitch_coef=nol_pitch_coef[i];*/
38598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               ol_pitch = nol_pitch[i];
38698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
38798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
38898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*if (ol_pitch>50)
38998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project           ol_pitch/=2;*/
39098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*ol_pitch_coef = sqrt(ol_pitch_coef);*/
39198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
39298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      } else {
39398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         ol_pitch=0;
39498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         ol_pitch_coef=0;
39598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
39698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
39798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*Compute "real" excitation*/
39898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_COPY(st->exc, st->winBuf, diff);
39998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_COPY(st->exc+diff, in, st->frameSize-diff);
40098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      fir_mem16(st->exc, interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc, stack);
40198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
40298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute open-loop excitation gain */
40398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
40498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word16_t g = compute_rms16(st->exc, st->frameSize);
40598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->submodeID!=1 && ol_pitch>0)
40698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ol_gain = MULT16_16(g, MULT16_16_Q14(QCONST16(1.1,14),
40798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                spx_sqrt(QCONST32(1.,28)-MULT16_32_Q15(QCONST16(.8,15),SHL32(MULT16_16(ol_pitch_coef,ol_pitch_coef),16)))));
40898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         else
40998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ol_gain = SHL32(EXTEND32(g),SIG_SHIFT);
41098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
41198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
41298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
41398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef VORBIS_PSYCHO
41498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SPEEX_MOVE(st->psy_window, st->psy_window+st->frameSize, 256-st->frameSize);
41598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SPEEX_COPY(&st->psy_window[256-st->frameSize], in, st->frameSize);
41698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   compute_curve(st->psy, st->psy_window, st->curve);
41798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*print_vec(st->curve, 128, "curve");*/
41898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->first)
41998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_COPY(st->old_curve, st->curve, 128);
42098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
42198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
42298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*VBR stuff*/
42398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
42498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->vbr && (st->vbr_enabled||st->vad_enabled))
42598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
42698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      float lsp_dist=0;
42798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
42898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         lsp_dist += (st->old_lsp[i] - lsp[i])*(st->old_lsp[i] - lsp[i]);
42998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_dist /= LSP_SCALING*LSP_SCALING;
43098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
43198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->abr_enabled)
43298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
43398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         float qual_change=0;
43498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->abr_drift2 * st->abr_drift > 0)
43598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
43698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /* Only adapt if long-term and short-term drift are the same sign */
43798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            qual_change = -.00001*st->abr_drift/(1+st->abr_count);
43898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (qual_change>.05)
43998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               qual_change=.05;
44098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (qual_change<-.05)
44198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               qual_change=-.05;
44298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
44398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->vbr_quality += qual_change;
44498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->vbr_quality>10)
44598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->vbr_quality=10;
44698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->vbr_quality<0)
44798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->vbr_quality=0;
44898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
44998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
45098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, GAIN_SCALING_1*ol_pitch_coef);
45198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*if (delta_qual<0)*/
45298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*  delta_qual*=.1*(3+st->vbr_quality);*/
45398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->vbr_enabled)
45498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
45598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t mode;
45698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int choice=0;
45798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         float min_diff=100;
45898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         mode = 8;
45998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         while (mode)
46098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
46198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            int v1;
46298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            float thresh;
46398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            v1=(int)floor(st->vbr_quality);
46498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (v1==10)
46598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               thresh = vbr_nb_thresh[mode][v1];
46698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            else
46798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1];
46898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (st->relative_quality > thresh &&
46998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                st->relative_quality-thresh<min_diff)
47098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
47198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               choice = mode;
47298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               min_diff = st->relative_quality-thresh;
47398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
47498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            mode--;
47598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
47698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         mode=choice;
47798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (mode==0)
47898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
47998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)
48098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
48198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               mode=1;
48298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->dtx_count=1;
48398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            } else {
48498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               mode=0;
48598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->dtx_count++;
48698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
48798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else {
48898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->dtx_count=0;
48998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
49098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
49198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);
49298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->vbr_max>0)
49398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
49498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            spx_int32_t rate;
49598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(state, SPEEX_GET_BITRATE, &rate);
49698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (rate > st->vbr_max)
49798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
49898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               rate = st->vbr_max;
49998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               speex_encoder_ctl(state, SPEEX_SET_BITRATE, &rate);
50098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
50198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
50298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
50398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->abr_enabled)
50498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
50598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            spx_int32_t bitrate;
50698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);
50798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->abr_drift+=(bitrate-st->abr_enabled);
50898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);
50998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->abr_count += 1.0;
51098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
51198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
51298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      } else {
51398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*VAD only case*/
51498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int mode;
51598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->relative_quality<2)
51698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
51798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)
51898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
51998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->dtx_count=1;
52098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               mode=1;
52198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            } else {
52298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               mode=0;
52398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->dtx_count++;
52498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
52598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else {
52698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->dtx_count = 0;
52798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            mode=st->submodeSelect;
52898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
52998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/
53098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->submodeID=mode;
53198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
53298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   } else {
53398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->relative_quality = -1;
53498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
53598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
53698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
53798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->encode_submode)
53898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
53998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* First, transmit a zero for narrowband */
54098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_bits_pack(bits, 0, 1);
54198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
54298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Transmit the sub-mode we use for this frame */
54398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);
54498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
54598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
54698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
54798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* If null mode (no transmission), just set a couple things to zero*/
54898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->submodes[st->submodeID] == NULL)
54998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
55098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->frameSize;i++)
55198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->exc[i]=st->sw[i]=VERY_SMALL;
55298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
55398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
55498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->mem_sw[i]=0;
55598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->first=1;
55698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->bounded_pitch = 1;
55798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
55898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize);
55998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
56098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Clear memory (no need to really compute it) */
56198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
56298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->mem_sp[i] = 0;
56398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return 0;
56498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
56598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
56698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
56798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* LSP Quantization */
56898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->first)
56998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
57098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
57198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->old_lsp[i] = lsp[i];
57298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
57398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
57498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
57598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*Quantize LSPs*/
57698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if 1 /*0 for unquantized*/
57798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits);
57898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
57998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<st->lpcSize;i++)
58098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project     qlsp[i]=lsp[i];
58198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
58298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
58398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*If we use low bit-rate pitch mode, transmit open-loop pitch*/
58498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (SUBMODE(lbr_pitch)!=-1)
58598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
58698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_bits_pack(bits, ol_pitch-st->min_pitch, 7);
58798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
58898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
58998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (SUBMODE(forced_pitch_gain))
59098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
59198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int quant;
59298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* This just damps the pitch a bit, because it tends to be too aggressive when forced */
59398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ol_pitch_coef = MULT16_16_Q15(QCONST16(.9,15), ol_pitch_coef);
59498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
59598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      quant = PSHR16(MULT16_16_16(15, ol_pitch_coef),GAIN_SHIFT);
59698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
59798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      quant = (int)floor(.5+15*ol_pitch_coef*GAIN_SCALING_1);
59898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
59998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (quant>15)
60098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         quant=15;
60198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (quant<0)
60298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         quant=0;
60398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_bits_pack(bits, quant, 4);
60498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT));
60598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
60698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
60798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
60898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*Quantize and transmit open-loop excitation gain*/
60998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
61098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
61198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int qe = scal_quant32(ol_gain, ol_gain_table, 32);
61298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*ol_gain = exp(qe/3.5)*SIG_SCALING;*/
61398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);
61498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_bits_pack(bits, qe, 5);
61598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
61698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
61798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
61898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int qe = (int)(floor(.5+3.5*log(ol_gain*1.0/SIG_SCALING)));
61998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (qe<0)
62098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qe=0;
62198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (qe>31)
62298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qe=31;
62398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ol_gain = exp(qe/3.5)*SIG_SCALING;
62498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_bits_pack(bits, qe, 5);
62598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
62698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
62798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
62898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
62998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
63098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Special case for first frame */
63198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->first)
63298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
63398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
63498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->old_qlsp[i] = qlsp[i];
63598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
63698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
63798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Target signal */
63898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(target, st->subframeSize, spx_word16_t);
63998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(innov, st->subframeSize, spx_sig_t);
64098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(exc32, st->subframeSize, spx_word32_t);
64198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(ringing, st->subframeSize, spx_word16_t);
64298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(syn_resp, st->subframeSize, spx_word16_t);
64398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(real_exc, st->subframeSize, spx_word16_t);
64498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(mem, st->lpcSize, spx_mem_t);
64598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
64698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Loop on sub-frames */
64798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (sub=0;sub<st->nbSubframes;sub++)
64898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
64998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int   offset;
65098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t *sw;
65198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t *exc;
65298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int pitch;
65398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int response_bound = st->subframeSize;
65498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
65598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Offset relative to start of frame */
65698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      offset = st->subframeSize*sub;
65798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Excitation */
65898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      exc=st->exc+offset;
65998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Weighted signal */
66098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      sw=st->sw+offset;
66198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
66298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* LSP interpolation (quantized and unquantized) */
66398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes);
66498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
66598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
66698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Make sure the filters are stable */
66798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);
66898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
66998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
67098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute interpolated LPCs (quantized and unquantized) */
67198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);
67298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
67398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_to_lpc(interp_qlsp, interp_qlpc, st->lpcSize, stack);
67498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
67598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute analysis filter gain at w=pi (for use in SB-CELP) */
67698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
67798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t pi_g=LPC_SCALING;
67898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i+=2)
67998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
68098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /*pi_g += -st->interp_qlpc[i] +  st->interp_qlpc[i+1];*/
68198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            pi_g = ADD32(pi_g, SUB32(EXTEND32(interp_qlpc[i+1]),EXTEND32(interp_qlpc[i])));
68298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
68398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->pi_gain[sub] = pi_g;
68498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
68598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
68698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef VORBIS_PSYCHO
68798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
68898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         float curr_curve[128];
68998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         float fact = ((float)sub+1.0f)/st->nbSubframes;
69098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<128;i++)
69198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            curr_curve[i] = (1.0f-fact)*st->old_curve[i] + fact*st->curve[i];
69298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         curve_to_lpc(st->psy, curr_curve, bw_lpc1, bw_lpc2, 10);
69398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
69498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
69598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */
69698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);
69798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->gamma2>=0)
69898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
69998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
70098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
70198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
70298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            bw_lpc2[i]=0;
70398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
70498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*print_vec(st->bw_lpc1, 10, "bw_lpc");*/
70598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
70698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
70798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*FIXME: This will break if we change the window size */
70898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_assert(st->windowSize-st->frameSize == st->subframeSize);
70998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (sub==0)
71098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
71198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->subframeSize;i++)
71298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            real_exc[i] = sw[i] = st->winBuf[i];
71398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      } else {
71498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->subframeSize;i++)
71598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)];
71698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
71798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      fir_mem16(real_exc, interp_qlpc, real_exc, st->subframeSize, st->lpcSize, st->mem_exc2, stack);
71898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
71998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->complexity==0)
72098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         response_bound >>= 1;
72198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      compute_impulse_response(interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, response_bound, st->lpcSize, stack);
72298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=response_bound;i<st->subframeSize;i++)
72398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         syn_resp[i]=VERY_SMALL;
72498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
72598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */
72698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
72798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         mem[i]=SHL32(st->mem_sp[i],1);
72898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->subframeSize;i++)
72998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         ringing[i] = VERY_SMALL;
73098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef SHORTCUTS2
73198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      iir_mem16(ringing, interp_qlpc, ringing, response_bound, st->lpcSize, mem, stack);
73298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
73398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         mem[i]=SHL32(st->mem_sw[i],1);
73498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      filter_mem16(ringing, st->bw_lpc1, st->bw_lpc2, ringing, response_bound, st->lpcSize, mem, stack);
73598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_MEMSET(&ringing[response_bound], 0, st->subframeSize-response_bound);
73698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
73798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      iir_mem16(ringing, interp_qlpc, ringing, st->subframeSize, st->lpcSize, mem, stack);
73898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
73998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         mem[i]=SHL32(st->mem_sw[i],1);
74098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      filter_mem16(ringing, bw_lpc1, bw_lpc2, ringing, st->subframeSize, st->lpcSize, mem, stack);
74198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
74298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
74398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute weighted signal */
74498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
74598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         mem[i]=st->mem_sw[i];
74698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack);
74798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
74898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->complexity==0)
74998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
75098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->mem_sw[i]=mem[i];
75198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
75298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute target signal (saturation prevents overflows on clipped input speech) */
75398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->subframeSize;i++)
75498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         target[i]=EXTRACT16(SATURATE(SUB32(sw[i],PSHR32(ringing[i],1)),32767));
75598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
75698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Reset excitation */
75798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_MEMSET(exc, 0, st->subframeSize);
75898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
75998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* If we have a long-term predictor (otherwise, something's wrong) */
76098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_assert (SUBMODE(ltp_quant));
76198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
76298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int pit_min, pit_max;
76398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Long-term prediction */
76498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (SUBMODE(lbr_pitch) != -1)
76598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
76698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /* Low bit-rate pitch handling */
76798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            int margin;
76898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            margin = SUBMODE(lbr_pitch);
76998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (margin)
77098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
77198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               if (ol_pitch < st->min_pitch+margin-1)
77298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  ol_pitch=st->min_pitch+margin-1;
77398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               if (ol_pitch > st->max_pitch-margin)
77498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  ol_pitch=st->max_pitch-margin;
77598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               pit_min = ol_pitch-margin+1;
77698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               pit_max = ol_pitch+margin;
77798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            } else {
77898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               pit_min=pit_max=ol_pitch;
77998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
78098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else {
78198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            pit_min = st->min_pitch;
78298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            pit_max = st->max_pitch;
78398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
78498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
78598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Force pitch to use only the current frame if needed */
78698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->bounded_pitch && pit_max>offset)
78798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            pit_max=offset;
78898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
78998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Perform pitch search */
79098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         pitch = SUBMODE(ltp_quant)(target, sw, interp_qlpc, bw_lpc1, bw_lpc2,
79198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                    exc32, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef,
79298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                    st->lpcSize, st->subframeSize, bits, stack,
79398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                    exc, syn_resp, st->complexity, 0, st->plc_tuning, &st->cumul_gain);
79498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
79598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->pitch[sub]=pitch;
79698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
79798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Quantization of innovation */
79898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_MEMSET(innov, 0, st->subframeSize);
79998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
80098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* FIXME: Make sure this is save from overflows (so far so good) */
80198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->subframeSize;i++)
80298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         real_exc[i] = EXTRACT16(SUB32(EXTEND32(real_exc[i]), PSHR32(exc32[i],SIG_SHIFT-1)));
80398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
80498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ener = SHL32(EXTEND32(compute_rms16(real_exc, st->subframeSize)),SIG_SHIFT);
80598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
80698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */
80798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
80898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
80998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t f = PDIV32(ener,PSHR32(ol_gain,SIG_SHIFT));
81098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (f<=32767)
81198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            fine_gain = f;
81298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         else
81398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            fine_gain = 32767;
81498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
81598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
81698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      fine_gain = PDIV32_16(ener,PSHR32(ol_gain,SIG_SHIFT));
81798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
81898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Calculate gain correction for the sub-frame (if any) */
81998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (SUBMODE(have_subframe_gain))
82098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
82198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int qe;
82298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (SUBMODE(have_subframe_gain)==3)
82398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
82498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            qe = scal_quant(fine_gain, exc_gain_quant_scal3_bound, 8);
82598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_bits_pack(bits, qe, 3);
82698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ener=MULT16_32_Q14(exc_gain_quant_scal3[qe],ol_gain);
82798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else {
82898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            qe = scal_quant(fine_gain, exc_gain_quant_scal1_bound, 2);
82998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_bits_pack(bits, qe, 1);
83098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ener=MULT16_32_Q14(exc_gain_quant_scal1[qe],ol_gain);
83198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
83298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      } else {
83398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         ener=ol_gain;
83498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
83598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
83698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*printf ("%f %f\n", ener, ol_gain);*/
83798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
83898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Normalize innovation */
83998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      signal_div(target, target, ener, st->subframeSize);
84098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
84198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Quantize innovation */
84298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_assert (SUBMODE(innovation_quant));
84398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
84498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Codebook search */
84598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2,
84698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
84798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook));
84898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
84998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* De-normalize innovation and update excitation */
85098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         signal_mul(innov, innov, ener, st->subframeSize);
85198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
85298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->subframeSize;i++)
85398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));
85498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
85598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */
85698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (SUBMODE(double_codebook)) {
85798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            char *tmp_stack=stack;
85898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            VARDECL(spx_sig_t *innov2);
85998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ALLOC(innov2, st->subframeSize, spx_sig_t);
86098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            SPEEX_MEMSET(innov2, 0, st->subframeSize);
86198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            for (i=0;i<st->subframeSize;i++)
86298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               target[i]=MULT16_16_P13(QCONST16(2.2f,13), target[i]);
86398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2,
86498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                      SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
86598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                      innov2, syn_resp, bits, stack, st->complexity, 0);
86698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize);
86798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            for (i=0;i<st->subframeSize;i++)
86898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               innov[i] = ADD32(innov[i],innov2[i]);
86998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            stack = tmp_stack;
87098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
87198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->subframeSize;i++)
87298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));
87398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->innov_rms_save)
87498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
87598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->innov_rms_save[sub] = compute_rms(innov, st->subframeSize);
87698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
87798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
87898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
87998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Final signal synthesis from excitation */
88098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      iir_mem16(exc, interp_qlpc, sw, st->subframeSize, st->lpcSize, st->mem_sp, stack);
88198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
88298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
88398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->complexity!=0)
88498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack);
88598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
88698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
88798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
88898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Store the LSPs for interpolation in the next frame */
88998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->submodeID>=1)
89098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
89198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
89298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->old_lsp[i] = lsp[i];
89398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
89498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->old_qlsp[i] = qlsp[i];
89598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
89698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
89798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef VORBIS_PSYCHO
89898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->submodeID>=1)
89998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_COPY(st->old_curve, st->curve, 128);
90098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
90198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
90298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->submodeID==1)
90398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
90498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
90598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->dtx_count)
90698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_bits_pack(bits, 15, 4);
90798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
90898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
90998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_bits_pack(bits, 0, 4);
91098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
91198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
91298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* The next frame will not be the first (Duh!) */
91398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->first = 0;
91498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize);
91598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
91698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0)
91798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->bounded_pitch = 1;
91898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   else
91998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->bounded_pitch = 0;
92098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
92198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return 1;
92298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
92398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
92498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid *nb_decoder_init(const SpeexMode *m)
92598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
92698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   DecState *st;
92798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   const SpeexNBMode *mode;
92898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i;
92998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
93098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   mode=(const SpeexNBMode*)m->mode;
93198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st = (DecState *)speex_alloc(sizeof(DecState));
93298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (!st)
93398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return NULL;
93498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
93598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->stack = NULL;
93698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
93798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->stack = (char*)speex_alloc_scratch(NB_DEC_STACK);
93898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
93998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
94098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mode=m;
94198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
94298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
94398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->encode_submode = 1;
94498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
94598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->first=1;
94698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Codec parameters, should eventually have several "modes"*/
94798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->frameSize = mode->frameSize;
94898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->nbSubframes=mode->frameSize/mode->subframeSize;
94998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->subframeSize=mode->subframeSize;
95098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->lpcSize = mode->lpcSize;
95198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->min_pitch=mode->pitchStart;
95298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->max_pitch=mode->pitchEnd;
95398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
95498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->submodes=mode->submodes;
95598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->submodeID=mode->defaultSubmode;
95698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
95798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->lpc_enh_enabled=1;
95898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
95998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->excBuf = (spx_word16_t*)speex_alloc((st->frameSize + 2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t));
96098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->exc = st->excBuf + 2*st->max_pitch + st->subframeSize + 6;
96198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SPEEX_MEMSET(st->excBuf, 0, st->frameSize + st->max_pitch);
96298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
96398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t));
96498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
96598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mem_sp = (spx_mem_t*)speex_alloc(st->lpcSize*sizeof(spx_mem_t));
96698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
96798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->last_pitch = 40;
96898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->count_lost=0;
96998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0;
97098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->pitch_gain_buf_idx = 0;
97198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->seed = 1000;
97298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
97398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->sampling_rate=8000;
97498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->last_ol_gain = 0;
97598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
97698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->user_callback.func = &speex_default_user_handler;
97798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->user_callback.data = NULL;
97898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<16;i++)
97998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->speex_callbacks[i].func = NULL;
98098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
98198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->voc_m1=st->voc_m2=st->voc_mean=0;
98298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->voc_offset=0;
98398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->dtx_enabled=0;
98498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->isWideband = 0;
98598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->highpass_enabled = 1;
98698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
98798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef ENABLE_VALGRIND
98898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VALGRIND_MAKE_READABLE(st, NB_DEC_STACK);
98998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
99098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return st;
99198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
99298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
99398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid nb_decoder_destroy(void *state)
99498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
99598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   DecState *st;
99698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st=(DecState*)state;
99798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
99898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
99998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free_scratch(st->stack);
100098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
100198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
100298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->excBuf);
100398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->interp_qlpc);
100498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->old_qlsp);
100598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->mem_sp);
100698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free (st->pi_gain);
100798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
100898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(state);
100998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
101098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
101198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define median3(a, b, c)	((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a))))
101298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
101398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
101498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t attenuation[10] = {32767, 31483, 27923, 22861, 17278, 12055, 7764, 4616, 2533, 1283};
101598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
101698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t attenuation[10] = {1., 0.961, 0.852, 0.698, 0.527, 0.368, 0.237, 0.141, 0.077, 0.039};
101798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
101898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
101998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
102098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
102198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
102298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i;
102398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int pitch_val;
102498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t pitch_gain;
102598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t fact;
102698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t gain_med;
102798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t innov_gain;
102898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t noise_gain;
102998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
103098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->count_lost<10)
103198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      fact = attenuation[st->count_lost];
103298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   else
103398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      fact = 0;
103498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
103598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]);
103698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (gain_med < st->last_pitch_gain)
103798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->last_pitch_gain = gain_med;
103898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
103998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
104098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   pitch_gain = st->last_pitch_gain;
104198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (pitch_gain>54)
104298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      pitch_gain = 54;
104398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   pitch_gain = SHL16(pitch_gain, 9);
104498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
104598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   pitch_gain = GAIN_SCALING_1*st->last_pitch_gain;
104698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (pitch_gain>.85)
104798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      pitch_gain=.85;
104898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
104998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   pitch_gain = MULT16_16_Q15(fact,pitch_gain) + VERY_SMALL;
105098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* FIXME: This was rms of innovation (not exc) */
105198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   innov_gain = compute_rms16(st->exc, st->frameSize);
105298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   noise_gain = MULT16_16_Q15(innov_gain, MULT16_16_Q15(fact, SUB16(Q15ONE,MULT16_16_Q15(pitch_gain,pitch_gain))));
105398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Shift all buffers by one frame */
105498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12);
105598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
105698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
105798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   pitch_val = st->last_pitch + SHR32((spx_int32_t)speex_rand(1+st->count_lost, &st->seed),SIG_SHIFT);
105898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (pitch_val > st->max_pitch)
105998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      pitch_val = st->max_pitch;
106098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (pitch_val < st->min_pitch)
106198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      pitch_val = st->min_pitch;
106298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<st->frameSize;i++)
106398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
106498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->exc[i]= MULT16_16_Q15(pitch_gain, (st->exc[i-pitch_val]+VERY_SMALL)) +
106598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_rand(noise_gain, &st->seed);
106698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
106798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
106898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   bw_lpc(QCONST16(.98,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize);
106998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   iir_mem16(&st->exc[-st->subframeSize], st->interp_qlpc, out, st->frameSize,
107098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project             st->lpcSize, st->mem_sp, stack);
107198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   highpass(out, out, st->frameSize, HIGHPASS_NARROWBAND|HIGHPASS_OUTPUT, st->mem_hp);
107298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
107398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->first = 0;
107498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->count_lost++;
107598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->pitch_gain_buf[st->pitch_gain_buf_idx++] = PSHR16(pitch_gain,9);
107698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->pitch_gain_buf_idx > 2) /* rollover */
107798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->pitch_gain_buf_idx = 0;
107898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
107998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
108098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Just so we don't need to carry the complete wideband mode information */
108198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic const int wb_skip_table[8] = {0, 36, 112, 192, 352, 0, 0, 0};
108298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
108398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint nb_decode(void *state, SpeexBits *bits, void *vout)
108498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
108598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   DecState *st;
108698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i, sub;
108798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int pitch;
108898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t pitch_gain[3];
108998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word32_t ol_gain=0;
109098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int ol_pitch=0;
109198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t ol_pitch_coef=0;
109298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int best_pitch=40;
109398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t best_pitch_gain=0;
109498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int wideband;
109598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int m;
109698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   char *stack;
109798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_sig_t *innov);
109898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word32_t *exc32);
109998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *ak);
110098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *qlsp);
110198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t pitch_average=0;
110298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
110398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t *out = (spx_word16_t*)vout;
110498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *interp_qlsp);
110598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
110698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st=(DecState*)state;
110798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   stack=st->stack;
110898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
110998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Check if we're in DTX mode*/
111098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (!bits && st->dtx_enabled)
111198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
111298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->submodeID=0;
111398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   } else
111498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
111598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* If bits is NULL, consider the packet to be lost (what could we do anyway) */
111698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (!bits)
111798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
111898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         nb_decode_lost(st, out, stack);
111998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         return 0;
112098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
112198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
112298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->encode_submode)
112398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
112498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
112598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Search for next narrowband block (handle requests, skip wideband blocks) */
112698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      do {
112798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (speex_bits_remaining(bits)<5)
112898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            return -1;
112998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         wideband = speex_bits_unpack_unsigned(bits, 1);
113098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (wideband) /* Skip wideband block (for compatibility) */
113198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
113298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            int submode;
113398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            int advance;
113498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
113598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/
113698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            advance = wb_skip_table[submode];
113798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (advance < 0)
113898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
113998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               speex_notify("Invalid mode encountered. The stream is corrupted.");
114098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               return -2;
114198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
114298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            advance -= (SB_SUBMODE_BITS+1);
114398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_bits_advance(bits, advance);
114498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
114598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (speex_bits_remaining(bits)<5)
114698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               return -1;
114798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            wideband = speex_bits_unpack_unsigned(bits, 1);
114898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (wideband)
114998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
115098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
115198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/
115298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               advance = wb_skip_table[submode];
115398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               if (advance < 0)
115498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               {
115598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  speex_notify("Invalid mode encountered. The stream is corrupted.");
115698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  return -2;
115798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               }
115898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               advance -= (SB_SUBMODE_BITS+1);
115998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               speex_bits_advance(bits, advance);
116098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               wideband = speex_bits_unpack_unsigned(bits, 1);
116198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               if (wideband)
116298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               {
116398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  speex_notify("More than two wideband layers found. The stream is corrupted.");
116498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  return -2;
116598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               }
116698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
116798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
116898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
116998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (speex_bits_remaining(bits)<4)
117098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            return -1;
117198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* FIXME: Check for overflow */
117298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         m = speex_bits_unpack_unsigned(bits, 4);
117398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (m==15) /* We found a terminator */
117498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
117598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            return -1;
117698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else if (m==14) /* Speex in-band request */
117798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
117898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            int ret = speex_inband_handler(bits, st->speex_callbacks, state);
117998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (ret)
118098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               return ret;
118198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else if (m==13) /* User in-band request */
118298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
118398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            int ret = st->user_callback.func(bits, state, st->user_callback.data);
118498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (ret)
118598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               return ret;
118698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else if (m>8) /* Invalid mode */
118798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
118898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_notify("Invalid mode encountered. The stream is corrupted.");
118998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            return -2;
119098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
119198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
119298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      } while (m>8);
119398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
119498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Get the sub-mode that was used */
119598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->submodeID = m;
119698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
119798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
119898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
119998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
120098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Shift all buffers by one frame */
120198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12);
120298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
120398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* If null mode (no transmission), just set a couple things to zero*/
120498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->submodes[st->submodeID] == NULL)
120598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
120698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      VARDECL(spx_coef_t *lpc);
120798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ALLOC(lpc, st->lpcSize, spx_coef_t);
120898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      bw_lpc(QCONST16(0.93f,15), st->interp_qlpc, lpc, st->lpcSize);
120998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
121098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word16_t innov_gain=0;
121198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* FIXME: This was innov, not exc */
121298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         innov_gain = compute_rms16(st->exc, st->frameSize);
121398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->frameSize;i++)
121498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->exc[i]=speex_rand(innov_gain, &st->seed);
121598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
121698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
121798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
121898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->first=1;
121998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
122098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Final signal synthesis from excitation */
122198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      iir_mem16(st->exc, lpc, out, st->frameSize, st->lpcSize, st->mem_sp, stack);
122298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
122398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->count_lost=0;
122498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return 0;
122598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
122698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
122798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(qlsp, st->lpcSize, spx_lsp_t);
122898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
122998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Unquantize LSPs */
123098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits);
123198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
123298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*Damp memory if a frame was lost and the LSP changed too much*/
123398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->count_lost)
123498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
123598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t fact;
123698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word32_t lsp_dist=0;
123798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
123898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         lsp_dist = ADD32(lsp_dist, EXTEND32(ABS(st->old_qlsp[i] - qlsp[i])));
123998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
124098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      fact = SHR16(19661,SHR32(lsp_dist,LSP_SHIFT+2));
124198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
124298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      fact = .6*exp(-.2*lsp_dist);
124398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
124498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
124598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->mem_sp[i] = MULT16_32_Q15(fact,st->mem_sp[i]);
124698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
124798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
124898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
124998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Handle first frame and lost-packet case */
125098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->first || st->count_lost)
125198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
125298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
125398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->old_qlsp[i] = qlsp[i];
125498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
125598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
125698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Get open-loop pitch estimation for low bit-rate pitch coding */
125798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (SUBMODE(lbr_pitch)!=-1)
125898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
125998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);
126098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
126198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
126298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (SUBMODE(forced_pitch_gain))
126398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
126498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int quant;
126598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      quant = speex_bits_unpack_unsigned(bits, 4);
126698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT));
126798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
126898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
126998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Get global excitation gain */
127098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
127198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int qe;
127298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qe = speex_bits_unpack_unsigned(bits, 5);
127398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
127498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* FIXME: Perhaps we could slightly lower the gain here when the output is going to saturate? */
127598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);
127698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
127798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ol_gain = SIG_SCALING*exp(qe/3.5);
127898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
127998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
128098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
128198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(ak, st->lpcSize, spx_coef_t);
128298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(innov, st->subframeSize, spx_sig_t);
128398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(exc32, st->subframeSize, spx_word32_t);
128498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
128598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->submodeID==1)
128698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
128798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int extra;
128898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      extra = speex_bits_unpack_unsigned(bits, 4);
128998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
129098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (extra==15)
129198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->dtx_enabled=1;
129298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
129398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->dtx_enabled=0;
129498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
129598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->submodeID>1)
129698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->dtx_enabled=0;
129798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
129898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*Loop on subframes */
129998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (sub=0;sub<st->nbSubframes;sub++)
130098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
130198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int offset;
130298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t *exc;
130398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t *sp;
130498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t *innov_save = NULL;
130598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t tmp;
130698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
130798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Offset relative to start of frame */
130898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      offset = st->subframeSize*sub;
130998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Excitation */
131098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      exc=st->exc+offset;
131198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Original signal */
131298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      sp=out+offset;
131398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->innov_save)
131498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         innov_save = st->innov_save+offset;
131598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
131698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
131798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Reset excitation */
131898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_MEMSET(exc, 0, st->subframeSize);
131998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
132098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*Adaptive codebook contribution*/
132198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_assert (SUBMODE(ltp_unquant));
132298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
132398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int pit_min, pit_max;
132498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Handle pitch constraints if any */
132598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (SUBMODE(lbr_pitch) != -1)
132698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
132798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            int margin;
132898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            margin = SUBMODE(lbr_pitch);
132998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (margin)
133098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
133198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* GT - need optimization?
133298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               if (ol_pitch < st->min_pitch+margin-1)
133398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  ol_pitch=st->min_pitch+margin-1;
133498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               if (ol_pitch > st->max_pitch-margin)
133598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  ol_pitch=st->max_pitch-margin;
133698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               pit_min = ol_pitch-margin+1;
133798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               pit_max = ol_pitch+margin;
133898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project*/
133998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               pit_min = ol_pitch-margin+1;
134098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               if (pit_min < st->min_pitch)
134198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project		  pit_min = st->min_pitch;
134298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               pit_max = ol_pitch+margin;
134398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               if (pit_max > st->max_pitch)
134498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project		  pit_max = st->max_pitch;
134598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            } else {
134698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               pit_min = pit_max = ol_pitch;
134798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
134898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else {
134998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            pit_min = st->min_pitch;
135098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            pit_max = st->max_pitch;
135198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
135298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
135398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
135498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
135598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),
135698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                 st->subframeSize, &pitch, &pitch_gain[0], bits, stack,
135798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                 st->count_lost, offset, st->last_pitch_gain, 0);
135898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
135998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Ensuring that things aren't blowing up as would happen if e.g. an encoder is
136098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         crafting packets to make us produce NaNs and slow down the decoder (vague DoS threat).
136198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         We can probably be even more aggressive and limit to 15000 or so. */
136298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         sanitize_values32(exc32, NEG32(QCONST32(32000,SIG_SHIFT-1)), QCONST32(32000,SIG_SHIFT-1), st->subframeSize);
136398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
136498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         tmp = gain_3tap_to_1tap(pitch_gain);
136598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
136698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         pitch_average += tmp;
136798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if ((tmp>best_pitch_gain&&ABS(2*best_pitch-pitch)>=3&&ABS(3*best_pitch-pitch)>=4&&ABS(4*best_pitch-pitch)>=5)
136898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project              || (tmp>MULT16_16_Q15(QCONST16(.6,15),best_pitch_gain)&&(ABS(best_pitch-2*pitch)<3||ABS(best_pitch-3*pitch)<4||ABS(best_pitch-4*pitch)<5))
136998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project              || (MULT16_16_Q15(QCONST16(.67,15),tmp)>best_pitch_gain&&(ABS(2*best_pitch-pitch)<3||ABS(3*best_pitch-pitch)<4||ABS(4*best_pitch-pitch)<5)) )
137098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
137198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            best_pitch = pitch;
137298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (tmp > best_pitch_gain)
137398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               best_pitch_gain = tmp;
137498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
137598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
137698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
137798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Unquantize the innovation */
137898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
137998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int q_energy;
138098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t ener;
138198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
138298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SPEEX_MEMSET(innov, 0, st->subframeSize);
138398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
138498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Decode sub-frame gain correction */
138598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (SUBMODE(have_subframe_gain)==3)
138698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
138798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            q_energy = speex_bits_unpack_unsigned(bits, 3);
138898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ener = MULT16_32_Q14(exc_gain_quant_scal3[q_energy],ol_gain);
138998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else if (SUBMODE(have_subframe_gain)==1)
139098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
139198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            q_energy = speex_bits_unpack_unsigned(bits, 1);
139298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ener = MULT16_32_Q14(exc_gain_quant_scal1[q_energy],ol_gain);
139398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else {
139498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ener = ol_gain;
139598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
139698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
139798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_assert (SUBMODE(innovation_unquant));
139898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
139998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /*Fixed codebook contribution*/
140098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);
140198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /* De-normalize innovation and update excitation */
140298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
140398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            signal_mul(innov, innov, ener, st->subframeSize);
140498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
140598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /* Decode second codebook (only for some modes) */
140698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (SUBMODE(double_codebook))
140798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
140898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               char *tmp_stack=stack;
140998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               VARDECL(spx_sig_t *innov2);
141098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               ALLOC(innov2, st->subframeSize, spx_sig_t);
141198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               SPEEX_MEMSET(innov2, 0, st->subframeSize);
141298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);
141398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize);
141498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               for (i=0;i<st->subframeSize;i++)
141598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  innov[i] = ADD32(innov[i], innov2[i]);
141698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               stack = tmp_stack;
141798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
141898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            for (i=0;i<st->subframeSize;i++)
141998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               exc[i]=EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));
142098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /*print_vec(exc, 40, "innov");*/
142198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (innov_save)
142298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
142398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               for (i=0;i<st->subframeSize;i++)
142498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT));
142598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
142698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
142798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
142898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*Vocoder mode*/
142998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->submodeID==1)
143098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
143198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            spx_word16_t g=ol_pitch_coef;
143298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            g=MULT16_16_P14(QCONST16(1.5f,14),(g-QCONST16(.2f,6)));
143398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (g<0)
143498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               g=0;
143598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (g>GAIN_SCALING)
143698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               g=GAIN_SCALING;
143798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
143898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            SPEEX_MEMSET(exc, 0, st->subframeSize);
143998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            while (st->voc_offset<st->subframeSize)
144098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
144198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               /* exc[st->voc_offset]= g*sqrt(2*ol_pitch)*ol_gain;
144298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  Not quite sure why we need the factor of two in the sqrt */
144398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               if (st->voc_offset>=0)
144498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                  exc[st->voc_offset]=MULT16_16(spx_sqrt(MULT16_16_16(2,ol_pitch)),EXTRACT16(PSHR32(MULT16_16(g,PSHR32(ol_gain,SIG_SHIFT)),6)));
144598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->voc_offset+=ol_pitch;
144698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
144798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->voc_offset -= st->subframeSize;
144898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
144998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            for (i=0;i<st->subframeSize;i++)
145098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
145198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               spx_word16_t exci=exc[i];
145298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               exc[i]= ADD16(ADD16(MULT16_16_Q15(QCONST16(.7f,15),exc[i]) , MULT16_16_Q15(QCONST16(.3f,15),st->voc_m1)),
145398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                             SUB16(MULT16_16_Q15(Q15_ONE-MULT16_16_16(QCONST16(.85f,9),g),EXTRACT16(PSHR32(innov[i],SIG_SHIFT))),
145498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                   MULT16_16_Q15(MULT16_16_16(QCONST16(.15f,9),g),EXTRACT16(PSHR32(st->voc_m2,SIG_SHIFT)))
145598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                  ));
145698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->voc_m1 = exci;
145798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->voc_m2=innov[i];
145898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->voc_mean = EXTRACT16(PSHR32(ADD32(MULT16_16(QCONST16(.8f,15),st->voc_mean), MULT16_16(QCONST16(.2f,15),exc[i])), 15));
145998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               exc[i]-=st->voc_mean;
146098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
146198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
146298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
146398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
146498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
146598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
146698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
146798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
146898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->lpc_enh_enabled && SUBMODE(comb_gain)>0 && !st->count_lost)
146998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
147098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      multicomb(st->exc-st->subframeSize, out, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);
147198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      multicomb(st->exc+st->subframeSize, out+2*st->subframeSize, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);
147298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   } else {
147398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_COPY(out, &st->exc[-st->subframeSize], st->frameSize);
147498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
147598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
147698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* If the last packet was lost, re-scale the excitation to obtain the same energy as encoded in ol_gain */
147798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->count_lost)
147898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
147998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t exc_ener;
148098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word32_t gain32;
148198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t gain;
148298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      exc_ener = compute_rms16 (st->exc, st->frameSize);
148398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      gain32 = PDIV32(ol_gain, ADD16(exc_ener,1));
148498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
148598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (gain32 > 32767)
148698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         gain32 = 32767;
148798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      gain = EXTRACT16(gain32);
148898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
148998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (gain32 > 2)
149098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         gain32=2;
149198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      gain = gain32;
149298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
149398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->frameSize;i++)
149498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
149598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->exc[i] = MULT16_16_Q14(gain, st->exc[i]);
149698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         out[i]=st->exc[i-st->subframeSize];
149798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
149898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
149998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
150098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*Loop on subframes */
150198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (sub=0;sub<st->nbSubframes;sub++)
150298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
150398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int offset;
150498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t *sp;
150598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t *exc;
150698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Offset relative to start of frame */
150798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      offset = st->subframeSize*sub;
150898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Original signal */
150998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      sp=out+offset;
151098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Excitation */
151198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      exc=st->exc+offset;
151298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
151398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* LSP interpolation (quantized and unquantized) */
151498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
151598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
151698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Make sure the LSP's are stable */
151798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
151898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
151998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute interpolated LPCs (unquantized) */
152098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack);
152198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
152298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute analysis filter at w=pi */
152398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
152498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t pi_g=LPC_SCALING;
152598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i+=2)
152698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
152798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /*pi_g += -st->interp_qlpc[i] +  st->interp_qlpc[i+1];*/
152898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            pi_g = ADD32(pi_g, SUB32(EXTEND32(ak[i+1]),EXTEND32(ak[i])));
152998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
153098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->pi_gain[sub] = pi_g;
153198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
153298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
153398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      iir_mem16(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize,
153498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                st->mem_sp, stack);
153598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
153698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
153798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->interp_qlpc[i] = ak[i];
153898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
153998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
154098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
154198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->highpass_enabled)
154298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      highpass(out, out, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_OUTPUT, st->mem_hp);
154398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*for (i=0;i<st->frameSize;i++)
154498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project     printf ("%d\n", (int)st->frame[i]);*/
154598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
154698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Tracking output level */
154798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->level = 1+PSHR32(ol_gain,SIG_SHIFT);
154898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->max_level = MAX16(MULT16_16_Q15(QCONST16(.99f,15), st->max_level), st->level);
154998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->min_level = MIN16(ADD16(1,MULT16_16_Q14(QCONST16(1.01f,14), st->min_level)), st->level);
155098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->max_level < st->min_level+1)
155198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->max_level = st->min_level+1;
155298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*printf ("%f %f %f %d\n", og, st->min_level, st->max_level, update);*/
155398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
155498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Store the LSPs for interpolation in the next frame */
155598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<st->lpcSize;i++)
155698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->old_qlsp[i] = qlsp[i];
155798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
155898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* The next frame will not be the first (Duh!) */
155998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->first = 0;
156098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->count_lost=0;
156198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->last_pitch = best_pitch;
156298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
156398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->last_pitch_gain = PSHR16(pitch_average,2);
156498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
156598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->last_pitch_gain = .25*pitch_average;
156698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
156798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->pitch_gain_buf[st->pitch_gain_buf_idx++] = st->last_pitch_gain;
156898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->pitch_gain_buf_idx > 2) /* rollover */
156998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->pitch_gain_buf_idx = 0;
157098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
157198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->last_ol_gain = ol_gain;
157298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
157398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return 0;
157498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
157598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
157698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint nb_encoder_ctl(void *state, int request, void *ptr)
157798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
157898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   EncState *st;
157998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st=(EncState*)state;
158098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   switch(request)
158198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
158298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_FRAME_SIZE:
158398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->frameSize;
158498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
158598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_LOW_MODE:
158698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_MODE:
158798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr);
158898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
158998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_LOW_MODE:
159098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_MODE:
159198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->submodeID;
159298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
159398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
159498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      case SPEEX_SET_VBR:
159598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->vbr_enabled = (*(spx_int32_t*)ptr);
159698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
159798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_VBR:
159898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->vbr_enabled;
159998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
160098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_VAD:
160198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->vad_enabled = (*(spx_int32_t*)ptr);
160298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
160398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_VAD:
160498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->vad_enabled;
160598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
160698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_DTX:
160798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->dtx_enabled = (*(spx_int32_t*)ptr);
160898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
160998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_DTX:
161098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->dtx_enabled;
161198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
161298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_ABR:
161398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->abr_enabled = (*(spx_int32_t*)ptr);
161498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->vbr_enabled = st->abr_enabled!=0;
161598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->vbr_enabled)
161698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
161798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t i=10;
161898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t rate, target;
161998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         float vbr_qual;
162098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         target = (*(spx_int32_t*)ptr);
162198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         while (i>=0)
162298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
162398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
162498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
162598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (rate <= target)
162698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               break;
162798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            i--;
162898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
162998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         vbr_qual=i;
163098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (vbr_qual<0)
163198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            vbr_qual=0;
163298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
163398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->abr_count=0;
163498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->abr_drift=0;
163598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->abr_drift2=0;
163698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
163798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
163898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
163998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_ABR:
164098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->abr_enabled;
164198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
164298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
164398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
164498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_VBR_QUALITY:
164598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->vbr_quality = (*(float*)ptr);
164698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
164798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_VBR_QUALITY:
164898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(float*)ptr) = st->vbr_quality;
164998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
165098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
165198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_QUALITY:
165298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
165398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int quality = (*(spx_int32_t*)ptr);
165498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (quality < 0)
165598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            quality = 0;
165698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (quality > 10)
165798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            quality = 10;
165898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->submodeSelect = st->submodeID = ((const SpeexNBMode*)(st->mode->mode))->quality_map[quality];
165998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
166098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
166198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_COMPLEXITY:
166298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->complexity = (*(spx_int32_t*)ptr);
166398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->complexity<0)
166498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->complexity=0;
166598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
166698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_COMPLEXITY:
166798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->complexity;
166898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
166998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_BITRATE:
167098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
167198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t i=10;
167298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t rate, target;
167398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         target = (*(spx_int32_t*)ptr);
167498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         while (i>=0)
167598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
167698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
167798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
167898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (rate <= target)
167998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               break;
168098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            i--;
168198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
168298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
168398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
168498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_BITRATE:
168598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->submodes[st->submodeID])
168698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         (*(spx_int32_t*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize;
168798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
168898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;
168998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
169098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_SAMPLING_RATE:
169198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->sampling_rate = (*(spx_int32_t*)ptr);
169298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
169398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_SAMPLING_RATE:
169498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr)=st->sampling_rate;
169598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
169698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_RESET_STATE:
169798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
169898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
169998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->bounded_pitch = 1;
170098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->first = 1;
170198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
170298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
170398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
170498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0;
170598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->frameSize+st->max_pitch+1;i++)
170698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->excBuf[i]=st->swBuf[i]=0;
170798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->windowSize-st->frameSize;i++)
170898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->winBuf[i]=0;
170998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
171098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
171198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_SUBMODE_ENCODING:
171298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->encode_submode = (*(spx_int32_t*)ptr);
171398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
171498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_SUBMODE_ENCODING:
171598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->encode_submode;
171698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
171798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_LOOKAHEAD:
171898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr)=(st->windowSize-st->frameSize);
171998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
172098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_PLC_TUNING:
172198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->plc_tuning = (*(spx_int32_t*)ptr);
172298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->plc_tuning>100)
172398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->plc_tuning=100;
172498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
172598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_PLC_TUNING:
172698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr)=(st->plc_tuning);
172798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
172898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
172998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_VBR_MAX_BITRATE:
173098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->vbr_max = (*(spx_int32_t*)ptr);
173198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
173298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_VBR_MAX_BITRATE:
173398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->vbr_max;
173498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
173598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
173698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_HIGHPASS:
173798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->highpass_enabled = (*(spx_int32_t*)ptr);
173898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
173998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_HIGHPASS:
174098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->highpass_enabled;
174198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
174298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
174398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* This is all internal stuff past this point */
174498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_PI_GAIN:
174598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
174698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
174798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t *g = (spx_word32_t*)ptr;
174898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->nbSubframes;i++)
174998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            g[i]=st->pi_gain[i];
175098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
175198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
175298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_EXC:
175398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
175498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
175598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->nbSubframes;i++)
175698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize);
175798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
175898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
175998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
176098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_RELATIVE_QUALITY:
176198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(float*)ptr)=st->relative_quality;
176298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
176398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
176498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_INNOVATION_SAVE:
176598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->innov_rms_save = (spx_word16_t*)ptr;
176698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
176798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_WIDEBAND:
176898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->isWideband = *((spx_int32_t*)ptr);
176998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
177098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_STACK:
177198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      *((char**)ptr) = st->stack;
177298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
177398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   default:
177498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_warning_int("Unknown nb_ctl request: ", request);
177598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return -1;
177698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
177798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return 0;
177898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
177998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
178098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint nb_decoder_ctl(void *state, int request, void *ptr)
178198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
178298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   DecState *st;
178398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st=(DecState*)state;
178498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   switch(request)
178598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
178698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_LOW_MODE:
178798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_MODE:
178898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->submodeID = (*(spx_int32_t*)ptr);
178998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
179098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_LOW_MODE:
179198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_MODE:
179298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->submodeID;
179398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
179498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_ENH:
179598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->lpc_enh_enabled = *((spx_int32_t*)ptr);
179698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
179798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_ENH:
179898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      *((spx_int32_t*)ptr) = st->lpc_enh_enabled;
179998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
180098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_FRAME_SIZE:
180198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->frameSize;
180298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
180398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_BITRATE:
180498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->submodes[st->submodeID])
180598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         (*(spx_int32_t*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize;
180698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
180798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;
180898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
180998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_SAMPLING_RATE:
181098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->sampling_rate = (*(spx_int32_t*)ptr);
181198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
181298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_SAMPLING_RATE:
181398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr)=st->sampling_rate;
181498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
181598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_HANDLER:
181698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
181798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SpeexCallback *c = (SpeexCallback*)ptr;
181898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->speex_callbacks[c->callback_id].func=c->func;
181998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->speex_callbacks[c->callback_id].data=c->data;
182098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->speex_callbacks[c->callback_id].callback_id=c->callback_id;
182198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
182298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
182398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_USER_HANDLER:
182498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
182598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SpeexCallback *c = (SpeexCallback*)ptr;
182698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->user_callback.func=c->func;
182798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->user_callback.data=c->data;
182898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->user_callback.callback_id=c->callback_id;
182998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
183098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
183198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_RESET_STATE:
183298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
183398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
183498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
183598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->mem_sp[i]=0;
183698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->frameSize + st->max_pitch + 1;i++)
183798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->excBuf[i]=0;
183898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
183998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
184098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_SUBMODE_ENCODING:
184198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->encode_submode = (*(spx_int32_t*)ptr);
184298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
184398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_SUBMODE_ENCODING:
184498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->encode_submode;
184598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
184698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_LOOKAHEAD:
184798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr)=st->subframeSize;
184898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
184998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_HIGHPASS:
185098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->highpass_enabled = (*(spx_int32_t*)ptr);
185198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
185298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_HIGHPASS:
185398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->highpass_enabled;
185498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
185598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* FIXME: Convert to fixed-point and re-enable even when float API is disabled */
185698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_FLOAT_API
185798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_ACTIVITY:
185898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
185998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      float ret;
186098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ret = log(st->level/st->min_level)/log(st->max_level/st->min_level);
186198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (ret>1)
186298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         ret = 1;
186398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Done in a strange way to catch NaNs as well */
186498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (!(ret > 0))
186598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         ret = 0;
186698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*printf ("%f %f %f %f\n", st->level, st->min_level, st->max_level, ret);*/
186798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = (int)(100*ret);
186898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
186998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   break;
187098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
187198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_PI_GAIN:
187298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
187398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
187498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t *g = (spx_word32_t*)ptr;
187598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->nbSubframes;i++)
187698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            g[i]=st->pi_gain[i];
187798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
187898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
187998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_EXC:
188098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
188198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
188298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->nbSubframes;i++)
188398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize);
188498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
188598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
188698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_DTX_STATUS:
188798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      *((spx_int32_t*)ptr) = st->dtx_enabled;
188898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
188998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_INNOVATION_SAVE:
189098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->innov_save = (spx_word16_t*)ptr;
189198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
189298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_WIDEBAND:
189398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->isWideband = *((spx_int32_t*)ptr);
189498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
189598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_STACK:
189698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      *((char**)ptr) = st->stack;
189798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
189898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   default:
189998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_warning_int("Unknown nb_ctl request: ", request);
190098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return -1;
190198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
190298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return 0;
190398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
1904