198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Copyright (C) 2002-2006 Jean-Marc Valin
298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   File: sb_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 "sb_celp.h"
3898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "filters.h"
3998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "lpc.h"
4098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "lsp.h"
4198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "stack_alloc.h"
4298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "cb_search.h"
4398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "quant_lsp.h"
4498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "vq.h"
4598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "ltp.h"
4698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "arch.h"
4798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "math_approx.h"
4898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "os_support.h"
4998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
5098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef NULL
5198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NULL 0
5298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
5398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
5498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Default size for the encoder and decoder stack (can be changed at compile time).
5598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   This does not apply when using variable-size arrays or alloca. */
5698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef SB_ENC_STACK
5798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SB_ENC_STACK (10000*sizeof(spx_sig_t))
5898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
5998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
6098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef SB_DEC_STACK
6198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SB_DEC_STACK (6000*sizeof(spx_sig_t))
6298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
6398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
6498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
6598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef DISABLE_WIDEBAND
6698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid *sb_encoder_init(const SpeexMode *m)
6798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
6898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_fatal("Wideband and Ultra-wideband are disabled");
6998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return NULL;
7098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
7198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid sb_encoder_destroy(void *state)
7298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
7398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_fatal("Wideband and Ultra-wideband are disabled");
7498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
7598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint sb_encode(void *state, void *vin, SpeexBits *bits)
7698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
7798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_fatal("Wideband and Ultra-wideband are disabled");
7898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return -2;
7998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
8098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid *sb_decoder_init(const SpeexMode *m)
8198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
8298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_fatal("Wideband and Ultra-wideband are disabled");
8398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return NULL;
8498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
8598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid sb_decoder_destroy(void *state)
8698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
8798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_fatal("Wideband and Ultra-wideband are disabled");
8898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
8998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint sb_decode(void *state, SpeexBits *bits, void *vout)
9098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
9198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_fatal("Wideband and Ultra-wideband are disabled");
9298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return -2;
9398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
9498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint sb_encoder_ctl(void *state, int request, void *ptr)
9598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
9698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_fatal("Wideband and Ultra-wideband are disabled");
9798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return -2;
9898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
9998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint sb_decoder_ctl(void *state, int request, void *ptr)
10098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
10198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_fatal("Wideband and Ultra-wideband are disabled");
10298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return -2;
10398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
10498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
10598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
10698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
10798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef M_PI
10898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define M_PI           3.14159265358979323846  /* pi */
10998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
11098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
11198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define sqr(x) ((x)*(x))
11298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
11398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SUBMODE(x) st->submodes[st->submodeID]->x
11498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
11598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
11698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic const spx_word16_t gc_quant_bound[16] = {125, 164, 215, 282, 370, 484, 635, 832, 1090, 1428, 1871, 2452, 3213, 4210, 5516, 7228};
11798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic const spx_word16_t fold_quant_bound[32] = {
11898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   39, 44, 50, 57, 64, 73, 83, 94,
11998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   106, 120, 136, 154, 175, 198, 225, 255,
12098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   288, 327, 370, 420, 476, 539, 611, 692,
12198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   784, 889, 1007, 1141, 1293, 1465, 1660, 1881};
12298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_MARGIN 410
12398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_DELTA1 6553
12498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_DELTA2 1638
12598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
12698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
12798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
12898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic const spx_word16_t gc_quant_bound[16] = {
12998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      0.97979, 1.28384, 1.68223, 2.20426, 2.88829, 3.78458, 4.95900, 6.49787,
13098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      8.51428, 11.15642, 14.61846, 19.15484, 25.09895, 32.88761, 43.09325, 56.46588};
13198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic const spx_word16_t fold_quant_bound[32] = {
13298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.30498, 0.34559, 0.39161, 0.44375, 0.50283, 0.56979, 0.64565, 0.73162,
13398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.82903, 0.93942, 1.06450, 1.20624, 1.36685, 1.54884, 1.75506, 1.98875,
13498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   2.25355, 2.55360, 2.89361, 3.27889, 3.71547, 4.21018, 4.77076, 5.40598,
13598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   6.12577, 6.94141, 7.86565, 8.91295, 10.09969, 11.44445, 12.96826, 14.69497};
13698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
13798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_MARGIN .05
13898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_DELTA1 .2
13998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LSP_DELTA2 .05
14098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
14198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
14298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
14398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define QMF_ORDER 64
14498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
14598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
14698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic const spx_word16_t h0[64] = {2, -7, -7, 18, 15, -39, -25, 75, 35, -130, -41, 212, 38, -327, -17, 483, -32, -689, 124, 956, -283, -1307, 543, 1780, -973, -2467, 1733, 3633, -3339, -6409, 9059, 30153, 30153, 9059, -6409, -3339, 3633, 1733, -2467, -973, 1780, 543, -1307, -283, 956, 124, -689, -32, 483, -17, -327, 38, 212, -41, -130, 35, 75, -25, -39, 15, 18, -7, -7, 2};
14798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
14898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
14998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic const float h0[64] = {
15098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   3.596189e-05f, -0.0001123515f,
15198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.0001104587f, 0.0002790277f,
15298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.0002298438f, -0.0005953563f,
15398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.0003823631f, 0.00113826f,
15498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.0005308539f, -0.001986177f,
15598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.0006243724f, 0.003235877f,
15698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.0005743159f, -0.004989147f,
15798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.0002584767f, 0.007367171f,
15898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.0004857935f, -0.01050689f,
15998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.001894714f, 0.01459396f,
16098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.004313674f, -0.01994365f,
16198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.00828756f, 0.02716055f,
16298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.01485397f, -0.03764973f,
16398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.026447f, 0.05543245f,
16498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.05095487f, -0.09779096f,
16598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.1382363f, 0.4600981f,
16698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.4600981f, 0.1382363f,
16798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.09779096f, -0.05095487f,
16898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.05543245f, 0.026447f,
16998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.03764973f, -0.01485397f,
17098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.02716055f, 0.00828756f,
17198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.01994365f, -0.004313674f,
17298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.01459396f, 0.001894714f,
17398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.01050689f, -0.0004857935f,
17498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.007367171f, -0.0002584767f,
17598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.004989147f, 0.0005743159f,
17698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.003235877f, -0.0006243724f,
17798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.001986177f, 0.0005308539f,
17898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.00113826f, -0.0003823631f,
17998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.0005953563f, 0.0002298438f,
18098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   0.0002790277f, -0.0001104587f,
18198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   -0.0001123515f, 3.596189e-05f
18298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project};
18398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
18498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
18598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
18698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectextern const spx_word16_t lag_window[];
18798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectextern const spx_word16_t lpc_window[];
18898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
18998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
19098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid *sb_encoder_init(const SpeexMode *m)
19198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
19298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i;
19398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_int32_t tmp;
19498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SBEncState *st;
19598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   const SpeexSBMode *mode;
19698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
19798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st = (SBEncState*)speex_alloc(sizeof(SBEncState));
19898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (!st)
19998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return NULL;
20098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mode = m;
20198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   mode = (const SpeexSBMode*)m->mode;
20298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
20398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
20498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->st_low = speex_encoder_init(mode->nb_mode);
20598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
20698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->stack = NULL;
20798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
20898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*st->stack = (char*)speex_alloc_scratch(SB_ENC_STACK);*/
20998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_encoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);
21098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
21198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
21298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->full_frame_size = 2*mode->frameSize;
21398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->frame_size = mode->frameSize;
21498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->subframeSize = mode->subframeSize;
21598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->nbSubframes = mode->frameSize/mode->subframeSize;
21698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->windowSize = st->frame_size+st->subframeSize;
21798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->lpcSize=mode->lpcSize;
21898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
21998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->encode_submode = 1;
22098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->submodes=mode->submodes;
22198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->submodeSelect = st->submodeID=mode->defaultSubmode;
22298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
22398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   tmp=9;
22498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_encoder_ctl(st->st_low, SPEEX_SET_QUALITY, &tmp);
22598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   tmp=1;
22698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp);
22798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
22898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->lpc_floor = mode->lpc_floor;
22998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->gamma1=mode->gamma1;
23098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->gamma2=mode->gamma2;
23198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->first=1;
23298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
23398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->high=(spx_word16_t*)speex_alloc((st->windowSize-st->frame_size)*sizeof(spx_word16_t));
23498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
23598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->h0_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
23698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->h1_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
23798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
23898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->window= lpc_window;
23998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
24098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->lagWindow = lag_window;
24198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
24298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->old_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
24398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
24498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t));
24598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
24698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t));
24798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->innov_rms_save = NULL;
24898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
24998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
25098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mem_sp2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
25198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
25298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
25398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<st->lpcSize;i++)
25498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
25598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
25698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
25798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->vbr_quality = 8;
25898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->vbr_enabled = 0;
25998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->vbr_max = 0;
26098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->vbr_max_high = 20000;  /* We just need a big value here */
26198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->vad_enabled = 0;
26298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->abr_enabled = 0;
26398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->relative_quality=0;
26498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
26598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
26698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->complexity=2;
26798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_encoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
26898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->sampling_rate*=2;
26998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef ENABLE_VALGRIND
27098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
27198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
27298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return st;
27398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
27498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
27598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid sb_encoder_destroy(void *state)
27698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
27798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SBEncState *st=(SBEncState*)state;
27898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
27998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_encoder_destroy(st->st_low);
28098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
28198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*speex_free_scratch(st->stack);*/
28298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
28398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
28498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->high);
28598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
28698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->h0_mem);
28798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->h1_mem);
28898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
28998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->old_lsp);
29098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->old_qlsp);
29198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->interp_qlpc);
29298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->pi_gain);
29398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->exc_rms);
29498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
29598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->mem_sp);
29698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->mem_sp2);
29798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->mem_sw);
29898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
29998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
30098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st);
30198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
30298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
30398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
30498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint sb_encode(void *state, void *vin, SpeexBits *bits)
30598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
30698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SBEncState *st;
30798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i, roots, sub;
30898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   char *stack;
30998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_mem_t *mem);
31098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_sig_t *innov);
31198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word16_t *target);
31298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word16_t *syn_resp);
31398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word32_t *low_pi_gain);
31498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t *low;
31598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t *high;
31698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word16_t *low_exc_rms);
31798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word16_t *low_innov_rms);
31898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   const SpeexSBMode *mode;
31998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_int32_t dtx;
32098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t *in = (spx_word16_t*)vin;
32198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t e_low=0, e_high=0;
32298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *lpc);
32398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *interp_lpc);
32498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *bw_lpc1);
32598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *bw_lpc2);
32698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *lsp);
32798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *qlsp);
32898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *interp_lsp);
32998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *interp_qlsp);
33098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
33198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st = (SBEncState*)state;
33298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   stack=st->stack;
33398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   mode = (const SpeexSBMode*)(st->mode->mode);
33498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   low = in;
33598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   high = in+st->frame_size;
33698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
33798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* High-band buffering / sync with low band */
33898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Compute the two sub-bands by filtering with QMF h0*/
33998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   qmf_decomp(in, h0, low, high, st->full_frame_size, QMF_ORDER, st->h0_mem, stack);
34098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
34198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
34298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->vbr_enabled || st->vad_enabled)
34398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
34498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Need to compute things here before the signal is trashed by the encoder */
34598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*FIXME: Are the two signals (low, high) in sync? */
34698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      e_low = compute_rms16(low, st->frame_size);
34798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      e_high = compute_rms16(high, st->frame_size);
34898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
34998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
35098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
35198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(low_innov_rms, st->nbSubframes, spx_word16_t);
35298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_encoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_rms);
35398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Encode the narrowband part*/
35498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_encode_native(st->st_low, low, bits);
35598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
35698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   high = high - (st->windowSize-st->frame_size);
35798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SPEEX_COPY(high, st->high, st->windowSize-st->frame_size);
35898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SPEEX_COPY(st->high, &high[st->frame_size], st->windowSize-st->frame_size);
35998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
36098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
36198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);
36298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t);
36398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
36498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms);
36598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
36698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx);
36798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
36898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (dtx==0)
36998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      dtx=1;
37098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   else
37198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      dtx=0;
37298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
37398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(lpc, st->lpcSize, spx_coef_t);
37498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(interp_lpc, st->lpcSize, spx_coef_t);
37598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(bw_lpc1, st->lpcSize, spx_coef_t);
37698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(bw_lpc2, st->lpcSize, spx_coef_t);
37798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
37898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(lsp, st->lpcSize, spx_lsp_t);
37998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(qlsp, st->lpcSize, spx_lsp_t);
38098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(interp_lsp, st->lpcSize, spx_lsp_t);
38198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
38298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
38398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
38498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      VARDECL(spx_word16_t *autocorr);
38598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      VARDECL(spx_word16_t *w_sig);
38698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ALLOC(autocorr, st->lpcSize+1, spx_word16_t);
38798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ALLOC(w_sig, st->windowSize, spx_word16_t);
38898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Window for analysis */
38998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* FIXME: This is a kludge */
39098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->subframeSize==80)
39198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
39298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->windowSize;i++)
39398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i>>1]),SIG_SHIFT));
39498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      } else {
39598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->windowSize;i++)
39698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i]),SIG_SHIFT));
39798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
39898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute auto-correlation */
39998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize);
40098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */
40198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
40298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Lag windowing: equivalent to filtering in the power-spectrum domain */
40398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize+1;i++)
40498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]);
40598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
40698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Levinson-Durbin */
40798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      _spx_lpc(lpc, autocorr, st->lpcSize);
40898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
40998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
41098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* LPC to LSPs (x-domain) transform */
41198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack);
41298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (roots!=st->lpcSize)
41398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
41498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      roots = lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA2, stack);
41598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (roots!=st->lpcSize) {
41698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*If we can't find all LSP's, do some damage control and use a flat filter*/
41798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
41898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
41998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            lsp[i]=st->old_lsp[i];
42098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
42198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
42298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
42398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
42498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
42598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* VBR code */
42698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if ((st->vbr_enabled || st->vad_enabled) && !dtx)
42798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
42898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      float ratio;
42998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->abr_enabled)
43098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
43198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         float qual_change=0;
43298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->abr_drift2 * st->abr_drift > 0)
43398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
43498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /* Only adapt if long-term and short-term drift are the same sign */
43598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            qual_change = -.00001*st->abr_drift/(1+st->abr_count);
43698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (qual_change>.1)
43798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               qual_change=.1;
43898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (qual_change<-.1)
43998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               qual_change=-.1;
44098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
44198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->vbr_quality += qual_change;
44298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->vbr_quality>10)
44398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->vbr_quality=10;
44498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->vbr_quality<0)
44598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->vbr_quality=0;
44698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
44798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
44898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
44998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ratio = 2*log((1.f+e_high)/(1.f+e_low));
45098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
45198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality);
45298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (ratio<-4)
45398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         ratio=-4;
45498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (ratio>2)
45598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         ratio=2;
45698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*if (ratio>-2)*/
45798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->vbr_enabled)
45898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
45998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t modeid;
46098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         modeid = mode->nb_modes-1;
46198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->relative_quality+=1.0*(ratio+2);
46298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project	 if (st->relative_quality<-1)
46398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->relative_quality=-1;
46498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         while (modeid)
46598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
46698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            int v1;
46798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            float thresh;
46898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            v1=(int)floor(st->vbr_quality);
46998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (v1==10)
47098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               thresh = mode->vbr_thresh[modeid][v1];
47198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            else
47298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               thresh = (st->vbr_quality-v1)   * mode->vbr_thresh[modeid][v1+1] +
47398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                        (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1];
47498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (st->relative_quality >= thresh && st->sampling_rate*st->submodes[modeid]->bits_per_frame/st->full_frame_size <= st->vbr_max_high)
47598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               break;
47698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            modeid--;
47798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
47898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid);
47998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->abr_enabled)
48098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
48198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            spx_int32_t bitrate;
48298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);
48398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->abr_drift+=(bitrate-st->abr_enabled);
48498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);
48598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->abr_count += 1.0;
48698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
48798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
48898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      } else {
48998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* VAD only */
49098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int modeid;
49198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->relative_quality<2.0)
49298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            modeid=1;
49398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         else
49498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            modeid=st->submodeSelect;
49598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/
49698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->submodeID=modeid;
49798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
49898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
49998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/
50098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
50198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
50298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
50398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->encode_submode)
50498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
50598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_bits_pack(bits, 1, 1);
50698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (dtx)
50798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_bits_pack(bits, 0, SB_SUBMODE_BITS);
50898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
50998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS);
51098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
51198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
51298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* If null mode (no transmission), just set a couple things to zero*/
51398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (dtx || st->submodes[st->submodeID] == NULL)
51498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
51598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->frame_size;i++)
51698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         high[i]=VERY_SMALL;
51798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
51898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
51998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->mem_sw[i]=0;
52098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->first=1;
52198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
52298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Final signal synthesis from excitation */
52398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      iir_mem16(high, st->interp_qlpc, high, st->frame_size, st->lpcSize, st->mem_sp, stack);
52498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
52598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (dtx)
52698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         return 0;
52798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
52898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         return 1;
52998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
53098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
53198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
53298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* LSP quantization */
53398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits);
53498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
53598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->first)
53698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
53798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
53898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->old_lsp[i] = lsp[i];
53998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
54098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->old_qlsp[i] = qlsp[i];
54198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
54298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
54398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(mem, st->lpcSize, spx_mem_t);
54498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(syn_resp, st->subframeSize, spx_word16_t);
54598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(innov, st->subframeSize, spx_sig_t);
54698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(target, st->subframeSize, spx_word16_t);
54798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
54898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (sub=0;sub<st->nbSubframes;sub++)
54998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
55098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      VARDECL(spx_word16_t *exc);
55198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      VARDECL(spx_word16_t *res);
55298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      VARDECL(spx_word16_t *sw);
55398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t *sp;
55498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t filter_ratio;     /*Q7*/
55598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int offset;
55698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word32_t rl, rh;           /*Q13*/
55798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t eh=0;
55898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
55998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      offset = st->subframeSize*sub;
56098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      sp=high+offset;
56198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ALLOC(exc, st->subframeSize, spx_word16_t);
56298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ALLOC(res, st->subframeSize, spx_word16_t);
56398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ALLOC(sw, st->subframeSize, spx_word16_t);
56498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
56598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* LSP interpolation (quantized and unquantized) */
56698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes);
56798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
56898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
56998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);
57098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
57198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
57298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);
57398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_to_lpc(interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
57498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
57598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);
57698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
57798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
57898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band
57998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         filters */
58098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->pi_gain[sub]=LPC_SCALING;
58198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      rh = LPC_SCALING;
58298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i+=2)
58398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
58498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         rh += st->interp_qlpc[i+1] - st->interp_qlpc[i];
58598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->pi_gain[sub] += st->interp_qlpc[i] + st->interp_qlpc[i+1];
58698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
58798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
58898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      rl = low_pi_gain[sub];
58998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
59098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767));
59198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
59298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      filter_ratio=(rl+.01)/(rh+.01);
59398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
59498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
59598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute "real excitation" */
59698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      fir_mem16(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2, stack);
59798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute energy of low-band and high-band excitation */
59898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
59998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      eh = compute_rms16(exc, st->subframeSize);
60098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
60198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */
60298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t g;   /*Q7*/
60398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word16_t el;  /*Q0*/
60498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         el = low_innov_rms[sub];
60598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
60698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Gain to use if we want to use the low-band excitation for high-band */
60798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         g=PDIV32(MULT16_16(filter_ratio,eh),EXTEND32(ADD16(1,el)));
60898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
60998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if 0
61098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
61198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            char *tmp_stack=stack;
61298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            float *tmp_sig;
61398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            float g2;
61498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ALLOC(tmp_sig, st->subframeSize, spx_sig_t);
61598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            for (i=0;i<st->lpcSize;i++)
61698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               mem[i]=st->mem_sp[i];
61798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            iir_mem2(st->low_innov+offset, st->interp_qlpc, tmp_sig, st->subframeSize, st->lpcSize, mem);
61898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            g2 = compute_rms(sp, st->subframeSize)/(.01+compute_rms(tmp_sig, st->subframeSize));
61998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /*fprintf (stderr, "gains: %f %f\n", g, g2);*/
62098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            g = g2;
62198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            stack = tmp_stack;
62298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
62398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
62498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
62598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*print_vec(&g, 1, "gain factor");*/
62698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Gain quantization */
62798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
62898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            int quant = scal_quant(g, fold_quant_bound, 32);
62998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            /*speex_warning_int("tata", quant);*/
63098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (quant<0)
63198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               quant=0;
63298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (quant>31)
63398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               quant=31;
63498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_bits_pack(bits, quant, 5);
63598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
63698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->innov_rms_save)
63798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
63898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->innov_rms_save[sub] = eh;
63998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
64098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->exc_rms[sub] = eh;
64198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      } else {
64298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word16_t gc;       /*Q7*/
64398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t scale;    /*Q14*/
64498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word16_t el;       /*Q0*/
64598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         el = low_exc_rms[sub]; /*Q0*/
64698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
64798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         gc = PDIV32_16(MULT16_16(filter_ratio,1+eh),1+el);
64898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
64998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* This is a kludge that cleans up a historical bug */
65098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->subframeSize==80)
65198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            gc = MULT16_16_P15(QCONST16(0.70711f,15),gc);
65298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*printf ("%f %f %f %f\n", el, eh, filter_ratio, gc);*/
65398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
65498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            int qgc = scal_quant(gc, gc_quant_bound, 16);
65598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_bits_pack(bits, qgc, 4);
65698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]);
65798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
65898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->subframeSize==80)
65998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            gc = MULT16_16_P14(QCONST16(1.4142f,14), gc);
66098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
66198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         scale = SHL32(MULT16_16(PDIV32_16(SHL32(EXTEND32(gc),SIG_SHIFT-6),filter_ratio),(1+el)),6);
66298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
66398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         compute_impulse_response(st->interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack);
66498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
66598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
66698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Reset excitation */
66798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->subframeSize;i++)
66898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            res[i]=VERY_SMALL;
66998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
67098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */
67198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
67298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            mem[i]=st->mem_sp[i];
67398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         iir_mem16(res, st->interp_qlpc, res, st->subframeSize, st->lpcSize, mem, stack);
67498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
67598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
67698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            mem[i]=st->mem_sw[i];
67798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         filter_mem16(res, bw_lpc1, bw_lpc2, res, st->subframeSize, st->lpcSize, mem, stack);
67898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
67998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Compute weighted signal */
68098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
68198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            mem[i]=st->mem_sw[i];
68298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack);
68398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
68498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Compute target signal */
68598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->subframeSize;i++)
68698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            target[i]=SUB16(sw[i],res[i]);
68798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
68898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         signal_div(target, target, scale, st->subframeSize);
68998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
69098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /* Reset excitation */
69198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SPEEX_MEMSET(innov, 0, st->subframeSize);
69298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
69398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*print_vec(target, st->subframeSize, "\ntarget");*/
69498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2,
69598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                   SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
69698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                   innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook));
69798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*print_vec(target, st->subframeSize, "after");*/
69898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
69998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         signal_mul(innov, innov, scale, st->subframeSize);
70098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
70198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (SUBMODE(double_codebook)) {
70298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            char *tmp_stack=stack;
70398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            VARDECL(spx_sig_t *innov2);
70498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ALLOC(innov2, st->subframeSize, spx_sig_t);
70598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            SPEEX_MEMSET(innov2, 0, st->subframeSize);
70698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            for (i=0;i<st->subframeSize;i++)
70798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               target[i]=MULT16_16_P13(QCONST16(2.5f,13), target[i]);
70898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
70998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2,
71098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                      SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
71198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                      innov2, syn_resp, bits, stack, st->complexity, 0);
71298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize);
71398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
71498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            for (i=0;i<st->subframeSize;i++)
71598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               innov[i] = ADD32(innov[i],innov2[i]);
71698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            stack = tmp_stack;
71798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
71898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->subframeSize;i++)
71998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            exc[i] = PSHR32(innov[i],SIG_SHIFT);
72098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
72198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->innov_rms_save)
72298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
72398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->innov_rms_save[sub] = MULT16_16_Q15(QCONST16(.70711f, 15), compute_rms(innov, st->subframeSize));
72498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
72598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->exc_rms[sub] = compute_rms16(exc, st->subframeSize);
72698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
72798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
72898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
72998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
73098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
73198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*Keep the previous memory*/
73298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
73398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         mem[i]=st->mem_sp[i];
73498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Final signal synthesis from excitation */
73598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      iir_mem16(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp, stack);
73698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
73798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
73898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack);
73998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
74098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
74198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<st->lpcSize;i++)
74298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->old_lsp[i] = lsp[i];
74398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<st->lpcSize;i++)
74498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->old_qlsp[i] = qlsp[i];
74598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
74698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->first=0;
74798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
74898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return 1;
74998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
75098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
75198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
75298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
75398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
75498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
75598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid *sb_decoder_init(const SpeexMode *m)
75698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
75798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_int32_t tmp;
75898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SBDecState *st;
75998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   const SpeexSBMode *mode;
76098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st = (SBDecState*)speex_alloc(sizeof(SBDecState));
76198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (!st)
76298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return NULL;
76398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mode = m;
76498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   mode=(const SpeexSBMode*)m->mode;
76598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->encode_submode = 1;
76698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
76798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->st_low = speex_decoder_init(mode->nb_mode);
76898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
76998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->stack = NULL;
77098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
77198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK);*/
77298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_decoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);
77398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
77498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
77598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->full_frame_size = 2*mode->frameSize;
77698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->frame_size = mode->frameSize;
77798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->subframeSize = mode->subframeSize;
77898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->nbSubframes = mode->frameSize/mode->subframeSize;
77998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->lpcSize=mode->lpcSize;
78098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
78198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->sampling_rate*=2;
78298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   tmp=1;
78398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp);
78498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
78598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->submodes=mode->submodes;
78698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->submodeID=mode->defaultSubmode;
78798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
78898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->first=1;
78998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
79098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->g0_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
79198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->g1_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
79298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
79398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->excBuf = (spx_word16_t*)speex_alloc((st->subframeSize)*sizeof(spx_word16_t));
79498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
79598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
79698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t));
79798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
79898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
79998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t));
80098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->mem_sp = (spx_mem_t*)speex_alloc((2*st->lpcSize)*sizeof(spx_mem_t));
80198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
80298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->innov_save = NULL;
80398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
80498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
80598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->lpc_enh_enabled=0;
80698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->seed = 1000;
80798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
80898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef ENABLE_VALGRIND
80998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
81098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
81198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return st;
81298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
81398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
81498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid sb_decoder_destroy(void *state)
81598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
81698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SBDecState *st;
81798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st = (SBDecState*)state;
81898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_decoder_destroy(st->st_low);
81998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
82098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*speex_free_scratch(st->stack);*/
82198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
82298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
82398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->g0_mem);
82498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->g1_mem);
82598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->excBuf);
82698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->old_qlsp);
82798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->interp_qlpc);
82898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->pi_gain);
82998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->exc_rms);
83098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(st->mem_sp);
83198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
83298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_free(state);
83398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
83498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
83598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic void sb_decode_lost(SBDecState *st, spx_word16_t *out, int dtx, char *stack)
83698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
83798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i;
83898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int saved_modeid=0;
83998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
84098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (dtx)
84198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
84298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      saved_modeid=st->submodeID;
84398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->submodeID=1;
84498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   } else {
84598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      bw_lpc(QCONST16(0.99f,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize);
84698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
84798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
84898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->first=1;
84998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
85098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
85198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Final signal synthesis from excitation */
85298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (!dtx)
85398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
85498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->last_ener =  MULT16_16_Q15(QCONST16(.9f,15),st->last_ener);
85598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
85698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<st->frame_size;i++)
85798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      out[i+st->frame_size] = speex_rand(st->last_ener, &st->seed);
85898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
85998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize,
86098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->mem_sp, stack);
86198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
86298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
86398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Reconstruct the original */
86498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
86598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (dtx)
86698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
86798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->submodeID=saved_modeid;
86898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
86998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
87098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return;
87198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
87298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
87398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint sb_decode(void *state, SpeexBits *bits, void *vout)
87498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
87598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i, sub;
87698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SBDecState *st;
87798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int wideband;
87898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int ret;
87998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   char *stack;
88098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word32_t *low_pi_gain);
88198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_word16_t *low_exc_rms);
88298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_coef_t *ak);
88398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *qlsp);
88498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VARDECL(spx_lsp_t *interp_qlsp);
88598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_int32_t dtx;
88698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   const SpeexSBMode *mode;
88798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t *out = (spx_word16_t*)vout;
88898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word16_t *low_innov_alias;
88998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   spx_word32_t exc_ener_sum = 0;
89098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
89198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st = (SBDecState*)state;
89298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   stack=st->stack;
89398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   mode = (const SpeexSBMode*)(st->mode->mode);
89498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
89598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   low_innov_alias = out+st->frame_size;
89698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_decoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_alias);
89798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Decode the low-band */
89898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ret = speex_decode_native(st->st_low, bits, out);
89998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
90098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx);
90198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
90298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* If error decoding the narrowband part, propagate error */
90398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (ret!=0)
90498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
90598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return ret;
90698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
90798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
90898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (!bits)
90998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
91098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      sb_decode_lost(st, out, dtx, stack);
91198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return 0;
91298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
91398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
91498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->encode_submode)
91598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
91698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
91798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*Check "wideband bit"*/
91898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (speex_bits_remaining(bits)>0)
91998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         wideband = speex_bits_peek(bits);
92098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
92198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         wideband = 0;
92298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (wideband)
92398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
92498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*Regular wideband frame, read the submode*/
92598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         wideband = speex_bits_unpack_unsigned(bits, 1);
92698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
92798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      } else
92898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
92998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         /*Was a narrowband frame, set "null submode"*/
93098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->submodeID = 0;
93198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
93298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL)
93398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
93498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_notify("Invalid mode encountered. The stream is corrupted.");
93598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         return -2;
93698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
93798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
93898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
93998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* If null mode (no transmission), just set a couple things to zero*/
94098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->submodes[st->submodeID] == NULL)
94198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
94298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (dtx)
94398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
94498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         sb_decode_lost(st, out, 1, stack);
94598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         return 0;
94698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
94798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
94898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->frame_size;i++)
94998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         out[st->frame_size+i]=VERY_SMALL;
95098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
95198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->first=1;
95298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
95398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Final signal synthesis from excitation */
95498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize, st->mem_sp, stack);
95598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
95698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
95798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
95898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return 0;
95998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
96098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
96198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
96298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);
96398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t);
96498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
96598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms);
96698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
96798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(qlsp, st->lpcSize, spx_lsp_t);
96898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
96998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits);
97098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
97198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (st->first)
97298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
97398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
97498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->old_qlsp[i] = qlsp[i];
97598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
97698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
97798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ALLOC(ak, st->lpcSize, spx_coef_t);
97898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
97998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (sub=0;sub<st->nbSubframes;sub++)
98098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
98198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      VARDECL(spx_word32_t *exc);
98298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t *innov_save=NULL;
98398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t *sp;
98498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t filter_ratio;
98598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word16_t el=0;
98698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      int offset;
98798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      spx_word32_t rl=0,rh=0;
98898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
98998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      offset = st->subframeSize*sub;
99098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      sp=out+st->frame_size+offset;
99198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ALLOC(exc, st->subframeSize, spx_word32_t);
99298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Pointer for saving innovation */
99398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->innov_save)
99498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
99598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         innov_save = st->innov_save+2*offset;
99698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SPEEX_MEMSET(innov_save, 0, 2*st->subframeSize);
99798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
99898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
99998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* LSP interpolation */
100098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
100198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
100298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
100398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
100498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* LSP to LPC */
100598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack);
100698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
100798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Calculate reponse ratio between the low and high filter in the middle
100898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         of the band (4000 Hz) */
100998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
101098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->pi_gain[sub]=LPC_SCALING;
101198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         rh = LPC_SCALING;
101298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i+=2)
101398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
101498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            rh += ak[i+1] - ak[i];
101598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->pi_gain[sub] += ak[i] + ak[i+1];
101698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
101798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
101898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         rl = low_pi_gain[sub];
101998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT
102098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767));
102198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else
102298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         filter_ratio=(rl+.01)/(rh+.01);
102398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
102498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
102598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      SPEEX_MEMSET(exc, 0, st->subframeSize);
102698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (!SUBMODE(innovation_unquant))
102798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
102898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t g;
102998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int quant;
103098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
103198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         quant = speex_bits_unpack_unsigned(bits, 5);
103298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         g= spx_exp(MULT16_16(QCONST16(.125f,11),(quant-10)));
103398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
103498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         g = PDIV32(g, filter_ratio);
103598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
103698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->subframeSize;i+=2)
103798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
103898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            exc[i]=SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i]),SHL32(g,6)),SIG_SHIFT);
103998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            exc[i+1]=NEG32(SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i+1]),SHL32(g,6)),SIG_SHIFT));
104098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
104198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
104298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      } else {
104398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word16_t gc;
104498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t scale;
104598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int qgc = speex_bits_unpack_unsigned(bits, 4);
104698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
104798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         el = low_exc_rms[sub];
104898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]);
104998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
105098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (st->subframeSize==80)
105198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            gc = MULT16_16_P14(QCONST16(1.4142f,14),gc);
105298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
105398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         scale = SHL32(PDIV32(SHL32(MULT16_16(gc, el),3), filter_ratio),SIG_SHIFT-3);
105498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize,
105598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                     bits, stack, &st->seed);
105698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
105798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         signal_mul(exc,exc,scale,st->subframeSize);
105898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
105998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (SUBMODE(double_codebook)) {
106098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            char *tmp_stack=stack;
106198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            VARDECL(spx_sig_t *innov2);
106298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ALLOC(innov2, st->subframeSize, spx_sig_t);
106398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            SPEEX_MEMSET(innov2, 0, st->subframeSize);
106498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize,
106598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project                                        bits, stack, &st->seed);
106698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize);
106798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            for (i=0;i<st->subframeSize;i++)
106898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               exc[i] = ADD32(exc[i],innov2[i]);
106998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            stack = tmp_stack;
107098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
107198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
107298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
107398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
107498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->innov_save)
107598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
107698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->subframeSize;i++)
107798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            innov_save[2*i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT));
107898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
107998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
108098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      iir_mem16(st->excBuf, st->interp_qlpc, sp, st->subframeSize, st->lpcSize,
108198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->mem_sp, stack);
108298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->subframeSize;i++)
108398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->excBuf[i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT));
108498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      for (i=0;i<st->lpcSize;i++)
108598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->interp_qlpc[i] = ak[i];
108698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->exc_rms[sub] = compute_rms16(st->excBuf, st->subframeSize);
108798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      exc_ener_sum = ADD32(exc_ener_sum, DIV32(MULT16_16(st->exc_rms[sub],st->exc_rms[sub]), st->nbSubframes));
108898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
108998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->last_ener = spx_sqrt(exc_ener_sum);
109098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
109198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
109298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<st->lpcSize;i++)
109398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->old_qlsp[i] = qlsp[i];
109498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
109598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st->first=0;
109698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
109798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return 0;
109898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
109998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
110098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
110198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint sb_encoder_ctl(void *state, int request, void *ptr)
110298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
110398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SBEncState *st;
110498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st=(SBEncState*)state;
110598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   switch(request)
110698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
110798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_FRAME_SIZE:
110898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->full_frame_size;
110998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
111098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_HIGH_MODE:
111198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr);
111298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
111398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_LOW_MODE:
111498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
111598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
111698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_DTX:
111798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr);
111898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
111998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_DTX:
112098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr);
112198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
112298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_LOW_MODE:
112398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
112498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
112598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_MODE:
112698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr);
112798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
112898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
112998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_VBR:
113098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->vbr_enabled = (*(spx_int32_t*)ptr);
113198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr);
113298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
113398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_VBR:
113498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->vbr_enabled;
113598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
113698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_VAD:
113798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->vad_enabled = (*(spx_int32_t*)ptr);
113898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr);
113998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
114098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_VAD:
114198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->vad_enabled;
114298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
114398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
114498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
114598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_VBR_QUALITY:
114698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
114798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t q;
114898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         float qual = (*(float*)ptr)+.6;
114998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->vbr_quality = (*(float*)ptr);
115098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (qual>10)
115198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            qual=10;
115298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         q=(int)floor(.5+*(float*)ptr);
115398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (q>10)
115498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            q=10;
115598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual);
115698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q);
115798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         break;
115898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
115998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_VBR_QUALITY:
116098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(float*)ptr) = st->vbr_quality;
116198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
116298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
116398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
116498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_ABR:
116598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->abr_enabled = (*(spx_int32_t*)ptr);
116698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->vbr_enabled = st->abr_enabled!=0;
116798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled);
116898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->vbr_enabled)
116998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
117098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t i=10, rate, target;
117198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         float vbr_qual;
117298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         target = (*(spx_int32_t*)ptr);
117398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         while (i>=0)
117498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
117598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
117698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
117798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (rate <= target)
117898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               break;
117998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            i--;
118098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
118198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         vbr_qual=i;
118298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (vbr_qual<0)
118398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            vbr_qual=0;
118498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
118598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->abr_count=0;
118698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->abr_drift=0;
118798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->abr_drift2=0;
118898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
118998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
119098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
119198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_ABR:
119298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->abr_enabled;
119398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
119498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
119598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
119698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_QUALITY:
119798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
119898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t nb_qual;
119998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int quality = (*(spx_int32_t*)ptr);
120098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (quality < 0)
120198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            quality = 0;
120298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (quality > 10)
120398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            quality = 10;
120498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->submodeSelect = st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];
120598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
120698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
120798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
120898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
120998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_COMPLEXITY:
121098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr);
121198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->complexity = (*(spx_int32_t*)ptr);
121298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->complexity<1)
121398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->complexity=1;
121498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
121598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_COMPLEXITY:
121698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->complexity;
121798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
121898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_BITRATE:
121998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
122098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t i=10;
122198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t rate, target;
122298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         target = (*(spx_int32_t*)ptr);
122398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         while (i>=0)
122498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
122598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
122698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
122798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (rate <= target)
122898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               break;
122998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            i--;
123098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
123198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
123298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
123398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_BITRATE:
123498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, request, ptr);
123598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*fprintf (stderr, "before: %d\n", (*(int*)ptr));*/
123698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->submodes[st->submodeID])
123798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
123898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
123998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
124098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*fprintf (stderr, "after: %d\n", (*(int*)ptr));*/
124198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
124298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_SAMPLING_RATE:
124398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
124498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t tmp=(*(spx_int32_t*)ptr);
124598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->sampling_rate = tmp;
124698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         tmp>>=1;
124798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
124898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
124998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
125098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_SAMPLING_RATE:
125198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr)=st->sampling_rate;
125298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
125398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_RESET_STATE:
125498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
125598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
125698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->first = 1;
125798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
125898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
125998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->lpcSize;i++)
126098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0;
126198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<QMF_ORDER;i++)
126298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->h0_mem[i]=st->h1_mem[i]=0;
126398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
126498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
126598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_SUBMODE_ENCODING:
126698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->encode_submode = (*(spx_int32_t*)ptr);
126798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr);
126898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
126998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_SUBMODE_ENCODING:
127098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->encode_submode;
127198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
127298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_LOOKAHEAD:
127398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);
127498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr) + QMF_ORDER - 1;
127598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
127698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_PLC_TUNING:
127798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_SET_PLC_TUNING, ptr);
127898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
127998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_PLC_TUNING:
128098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_GET_PLC_TUNING, ptr);
128198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
128298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
128398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_VBR_MAX_BITRATE:
128498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
128598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->vbr_max = (*(spx_int32_t*)ptr);
128698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (SPEEX_SET_VBR_MAX_BITRATE<1)
128798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         {
128898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &st->vbr_max);
128998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->vbr_max_high = 17600;
129098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         } else {
129198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            spx_int32_t low_rate;
129298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (st->vbr_max >= 42200)
129398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
129498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->vbr_max_high = 17600;
129598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            } else if (st->vbr_max >= 27800)
129698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
129798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->vbr_max_high = 9600;
129898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            } else if (st->vbr_max > 20600)
129998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            {
130098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->vbr_max_high = 5600;
130198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            } else {
130298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->vbr_max_high = 1800;
130398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            }
130498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            if (st->subframeSize==80)
130598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project               st->vbr_max_high = 1800;
130698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            low_rate = st->vbr_max - st->vbr_max_high;
130798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &low_rate);
130898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         }
130998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
131098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
131198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_VBR_MAX_BITRATE:
131298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->vbr_max;
131398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
131498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
131598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_HIGHPASS:
131698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);
131798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
131898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_HIGHPASS:
131998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);
132098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
132198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
132298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
132398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* This is all internal stuff past this point */
132498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_PI_GAIN:
132598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
132698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
132798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t *g = (spx_word32_t*)ptr;
132898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->nbSubframes;i++)
132998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            g[i]=st->pi_gain[i];
133098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
133198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
133298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_EXC:
133398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
133498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
133598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->nbSubframes;i++)
133698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ((spx_word16_t*)ptr)[i] = st->exc_rms[i];
133798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
133898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
133998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
134098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_RELATIVE_QUALITY:
134198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(float*)ptr)=st->relative_quality;
134298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
134398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
134498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_INNOVATION_SAVE:
134598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->innov_rms_save = (spx_word16_t*)ptr;
134698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
134798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_WIDEBAND:
134898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);
134998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
135098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_STACK:
135198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      *((char**)ptr) = st->stack;
135298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
135398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   default:
135498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_warning_int("Unknown nb_ctl request: ", request);
135598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return -1;
135698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
135798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return 0;
135898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
135998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
136098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint sb_decoder_ctl(void *state, int request, void *ptr)
136198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
136298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SBDecState *st;
136398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   st=(SBDecState*)state;
136498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   switch(request)
136598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
136698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_HIGH_MODE:
136798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->submodeID = (*(spx_int32_t*)ptr);
136898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
136998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_LOW_MODE:
137098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
137198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
137298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_LOW_MODE:
137398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
137498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
137598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_FRAME_SIZE:
137698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->full_frame_size;
137798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
137898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_ENH:
137998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, request, ptr);
138098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->lpc_enh_enabled = *((spx_int32_t*)ptr);
138198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
138298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_ENH:
138398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      *((spx_int32_t*)ptr) = st->lpc_enh_enabled;
138498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
138598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_MODE:
138698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_QUALITY:
138798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
138898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t nb_qual;
138998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int quality = (*(spx_int32_t*)ptr);
139098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (quality < 0)
139198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            quality = 0;
139298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (quality > 10)
139398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            quality = 10;
139498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];
139598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
139698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_decoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
139798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
139898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
139998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_BITRATE:
140098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, request, ptr);
140198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (st->submodes[st->submodeID])
140298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
140398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
140498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
140598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
140698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_SAMPLING_RATE:
140798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
140898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_int32_t tmp=(*(spx_int32_t*)ptr);
140998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->sampling_rate = tmp;
141098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         tmp>>=1;
141198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
141298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
141398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
141498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_SAMPLING_RATE:
141598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr)=st->sampling_rate;
141698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
141798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_HANDLER:
141898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr);
141998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
142098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_USER_HANDLER:
142198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr);
142298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
142398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_RESET_STATE:
142498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
142598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
142698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<2*st->lpcSize;i++)
142798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->mem_sp[i]=0;
142898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<QMF_ORDER;i++)
142998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            st->g0_mem[i]=st->g1_mem[i]=0;
143098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         st->last_ener=0;
143198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
143298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
143398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_SUBMODE_ENCODING:
143498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->encode_submode = (*(spx_int32_t*)ptr);
143598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr);
143698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
143798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_SUBMODE_ENCODING:
143898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = st->encode_submode;
143998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
144098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_LOOKAHEAD:
144198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);
144298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr);
144398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
144498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_HIGHPASS:
144598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);
144698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
144798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_HIGHPASS:
144898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);
144998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
145098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_ACTIVITY:
145198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_GET_ACTIVITY, ptr);
145298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
145398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_PI_GAIN:
145498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
145598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
145698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         spx_word32_t *g = (spx_word32_t*)ptr;
145798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->nbSubframes;i++)
145898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            g[i]=st->pi_gain[i];
145998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
146098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
146198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_EXC:
146298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
146398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         int i;
146498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         for (i=0;i<st->nbSubframes;i++)
146598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            ((spx_word16_t*)ptr)[i] = st->exc_rms[i];
146698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
146798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
146898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_DTX_STATUS:
146998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr);
147098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
147198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_INNOVATION_SAVE:
147298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      st->innov_save = (spx_word16_t*)ptr;
147398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
147498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_SET_WIDEBAND:
147598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);
147698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
147798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   case SPEEX_GET_STACK:
147898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      *((char**)ptr) = st->stack;
147998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      break;
148098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   default:
148198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      speex_warning_int("Unknown nb_ctl request: ", request);
148298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      return -1;
148398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
148498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return 0;
148598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
148698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
148798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
148898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
1489