198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Copyright (C) 2003 Epic Games (written by Jean-Marc Valin) 298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Copyright (C) 2004-2006 Epic Games 398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project File: preprocess.c 598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Preprocessor with denoising based on the algorithm by Ephraim and Malah 698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Redistribution and use in source and binary forms, with or without 898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project modification, are permitted provided that the following conditions are 998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project met: 1098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1. Redistributions of source code must retain the above copyright notice, 1298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project this list of conditions and the following disclaimer. 1398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 2. Redistributions in binary form must reproduce the above copyright 1598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project notice, this list of conditions and the following disclaimer in the 1698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project documentation and/or other materials provided with the distribution. 1798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 3. The name of the author may not be used to endorse or promote products 1998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project derived from this software without specific prior written permission. 2098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 2198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 2598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 2798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 3098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project POSSIBILITY OF SUCH DAMAGE. 3298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project*/ 3398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 3498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 3598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* 3698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Recommended papers: 3798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 3898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Y. Ephraim and D. Malah, "Speech enhancement using minimum mean-square error 3998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project short-time spectral amplitude estimator". IEEE Transactions on Acoustics, 4098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Speech and Signal Processing, vol. ASSP-32, no. 6, pp. 1109-1121, 1984. 4198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 4298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Y. Ephraim and D. Malah, "Speech enhancement using minimum mean-square error 4398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project log-spectral amplitude estimator". IEEE Transactions on Acoustics, Speech and 4498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Signal Processing, vol. ASSP-33, no. 2, pp. 443-445, 1985. 4598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 4698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project I. Cohen and B. Berdugo, "Speech enhancement for non-stationary noise environments". 4798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Signal Processing, vol. 81, no. 2, pp. 2403-2418, 2001. 4898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 4998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Stefan Gustafsson, Rainer Martin, Peter Jax, and Peter Vary. "A psychoacoustic 5098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project approach to combined acoustic echo cancellation and noise reduction". IEEE 5198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Transactions on Speech and Audio Processing, 2002. 5298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project J.-M. Valin, J. Rouat, and F. Michaud, "Microphone array post-filter for separation 5498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project of simultaneous non-stationary sources". In Proceedings IEEE International 5598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Conference on Acoustics, Speech, and Signal Processing, 2004. 5698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project*/ 5798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef HAVE_CONFIG_H 5998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "config.h" 6098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 6198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 6298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include <math.h> 6398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "speex/speex_preprocess.h" 6498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "speex/speex_echo.h" 6598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "arch.h" 6698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "fftwrap.h" 6798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "filterbank.h" 6898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "math_approx.h" 6998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "os_support.h" 7098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 7198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef M_PI 7298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define M_PI 3.14159263 7398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 7498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 7598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LOUDNESS_EXP 5.f 7698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define AMP_SCALE .001f 7798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define AMP_SCALE_1 1000.f 7898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 7998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NB_BANDS 24 8098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 8198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SPEECH_PROB_START_DEFAULT QCONST16(0.35f,15) 8298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SPEECH_PROB_CONTINUE_DEFAULT QCONST16(0.20f,15) 8398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NOISE_SUPPRESS_DEFAULT -15 8498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define ECHO_SUPPRESS_DEFAULT -40 8598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define ECHO_SUPPRESS_ACTIVE_DEFAULT -15 8698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 8798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef NULL 8898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NULL 0 8998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 9098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 9198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SQR(x) ((x)*(x)) 9298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SQR16(x) (MULT16_16((x),(x))) 9398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SQR16_Q15(x) (MULT16_16_Q15((x),(x))) 9498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 9598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 9698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic inline spx_word16_t DIV32_16_Q8(spx_word32_t a, spx_word32_t b) 9798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 9898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (SHR32(a,7) >= b) 9998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 10098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return 32767; 10198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 10298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (b>=QCONST32(1,23)) 10398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 10498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a = SHR32(a,8); 10598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b = SHR32(b,8); 10698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 10798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (b>=QCONST32(1,19)) 10898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 10998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a = SHR32(a,4); 11098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b = SHR32(b,4); 11198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 11298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (b>=QCONST32(1,15)) 11398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 11498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a = SHR32(a,4); 11598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b = SHR32(b,4); 11698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 11798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a = SHL32(a,8); 11898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return PDIV32_16(a,b); 11998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 12098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 12198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 12298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic inline spx_word16_t DIV32_16_Q15(spx_word32_t a, spx_word32_t b) 12398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 12498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (SHR32(a,15) >= b) 12598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 12698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return 32767; 12798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 12898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (b>=QCONST32(1,23)) 12998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 13098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a = SHR32(a,8); 13198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b = SHR32(b,8); 13298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 13398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (b>=QCONST32(1,19)) 13498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 13598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a = SHR32(a,4); 13698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b = SHR32(b,4); 13798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 13898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (b>=QCONST32(1,15)) 13998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 14098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a = SHR32(a,4); 14198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b = SHR32(b,4); 14298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 14398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a = SHL32(a,15)-a; 14498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return DIV32_16(a,b); 14598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 14698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 14798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SNR_SCALING 256.f 14898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SNR_SCALING_1 0.0039062f 14998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SNR_SHIFT 8 15098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define FRAC_SCALING 32767.f 15298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define FRAC_SCALING_1 3.0518e-05 15398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define FRAC_SHIFT 1 15498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define EXPIN_SCALING 2048.f 15698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define EXPIN_SCALING_1 0.00048828f 15798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define EXPIN_SHIFT 11 15898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define EXPOUT_SCALING_1 1.5259e-05 15998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 16098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NOISE_SHIFT 7 16198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 16298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 16398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 16498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define DIV32_16_Q8(a,b) ((a)/(b)) 16598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define DIV32_16_Q15(a,b) ((a)/(b)) 16698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SNR_SCALING 1.f 16798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SNR_SCALING_1 1.f 16898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SNR_SHIFT 0 16998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define FRAC_SCALING 1.f 17098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define FRAC_SCALING_1 1.f 17198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define FRAC_SHIFT 0 17298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NOISE_SHIFT 0 17398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define EXPIN_SCALING 1.f 17598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define EXPIN_SCALING_1 1.f 17698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define EXPOUT_SCALING_1 1.f 17798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 17998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 18098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/** Speex pre-processor state. */ 18198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstruct SpeexPreprocessState_ { 18298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Basic info */ 18398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int frame_size; /**< Number of samples processed each time */ 18498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int ps_size; /**< Number of points in the power spectrum */ 18598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int sampling_rate; /**< Sampling rate of the input/output */ 18698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int nbands; 18798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project FilterBank *bank; 18898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 18998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Parameters */ 19098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int denoise_enabled; 19198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int vad_enabled; 19298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int dereverb_enabled; 19398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t reverb_decay; 19498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t reverb_level; 19598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t speech_prob_start; 19698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t speech_prob_continue; 19798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int noise_suppress; 19898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int echo_suppress; 19998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int echo_suppress_active; 20098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SpeexEchoState *echo_state; 20198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t speech_prob; /**< Probability last frame was speech */ 20398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* DSP-related arrays */ 20598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *frame; /**< Processing frame (2*ps_size) */ 20698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *ft; /**< Processing frame in freq domain (2*ps_size) */ 20798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *ps; /**< Current power spectrum */ 20898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *gain2; /**< Adjusted gains */ 20998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *gain_floor; /**< Minimum gain allowed */ 21098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *window; /**< Analysis/Synthesis window */ 21198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *noise; /**< Noise estimate */ 21298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *reverb_estimate; /**< Estimate of reverb energy */ 21398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *old_ps; /**< Power spectrum for last frame */ 21498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *gain; /**< Ephraim Malah gain */ 21598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *prior; /**< A-priori SNR */ 21698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *post; /**< A-posteriori SNR */ 21798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *S; /**< Smoothed power spectrum */ 21998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *Smin; /**< See Cohen paper */ 22098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *Stmp; /**< See Cohen paper */ 22198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int *update_prob; /**< Probability of speech presence for noise update */ 22298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 22398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *zeta; /**< Smoothed a priori SNR */ 22498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *echo_noise; 22598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *residual_echo; 22698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 22798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Misc */ 22898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *inbuf; /**< Input buffer (overlapped analysis) */ 22998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *outbuf; /**< Output buffer (for overlap and add) */ 23098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 23198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* AGC stuff, only for floating point for now */ 23298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef FIXED_POINT 23398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int agc_enabled; 23498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float agc_level; 23598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float loudness_accum; 23698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float *loudness_weight; /**< Perceptual loudness curve */ 23798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float loudness; /**< Loudness estimate */ 23898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float agc_gain; /**< Current AGC gain */ 23998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float max_gain; /**< Maximum gain allowed */ 24098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float max_increase_step; /**< Maximum increase in gain from one frame to another */ 24198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float max_decrease_step; /**< Maximum decrease in gain from one frame to another */ 24298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float prev_loudness; /**< Loudness of previous frame */ 24398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float init_max; /**< Current gain limit during initialisation */ 24498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 24598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int nb_adapt; /**< Number of frames used for adaptation so far */ 24698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int was_speech; 24798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int min_count; /**< Number of frames processed so far */ 24898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project void *fft_lookup; /**< Lookup table for the FFT */ 24998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 25098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int frame_shift; 25198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 25298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}; 25398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 25498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 25598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic void conj_window(spx_word16_t *w, int len) 25698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 25798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 25898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 25998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 26098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp; 26198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 26298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t x = DIV32_16(MULT16_16(32767,i),len); 26398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 26498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t x = DIV32_16(MULT16_16(QCONST16(4.f,13),i),len); 26598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 26698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int inv=0; 26798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (x<QCONST16(1.f,13)) 26898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 26998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else if (x<QCONST16(2.f,13)) 27098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 27198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x=QCONST16(2.f,13)-x; 27298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project inv=1; 27398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else if (x<QCONST16(3.f,13)) 27498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 27598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x=x-QCONST16(2.f,13); 27698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project inv=1; 27798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 27898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x=QCONST16(2.f,13)-x+QCONST16(2.f,13); /* 4 - x */ 27998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 28098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x = MULT16_16_Q14(QCONST16(1.271903f,14), x); 28198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(SHL32(EXTEND32(x),2)))); 28298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (inv) 28398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp=SUB16(Q15_ONE,tmp); 28498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project w[i]=spx_sqrt(SHL32(EXTEND32(tmp),15)); 28598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 28698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 28798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 28898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 28998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 29098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* This function approximates the gain function 29198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x) 29298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project which multiplied by xi/(1+xi) is the optimal gain 29398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project in the loudness domain ( sqrt[amplitude] ) 29498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Input in Q11 format, output in Q15 29598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project*/ 29698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic inline spx_word32_t hypergeom_gain(spx_word32_t xx) 29798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 29898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int ind; 29998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t frac; 30098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Q13 table */ 30198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project static const spx_word16_t table[21] = { 30298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 6730, 8357, 9868, 11267, 12563, 13770, 14898, 30398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15959, 16961, 17911, 18816, 19682, 20512, 21311, 30498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 22082, 22827, 23549, 24250, 24931, 25594, 26241}; 30598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ind = SHR32(xx,10); 30698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (ind<0) 30798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return Q15_ONE; 30898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (ind>19) 30998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return ADD32(EXTEND32(Q15_ONE),EXTEND32(DIV32_16(QCONST32(.1296,23), SHR32(xx,EXPIN_SHIFT-SNR_SHIFT)))); 31098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project frac = SHL32(xx-SHL32(ind,10),5); 31198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return SHL32(DIV32_16(PSHR32(MULT16_16(Q15_ONE-frac,table[ind]) + MULT16_16(frac,table[ind+1]),7),(spx_sqrt(SHL32(xx,15)+6711))),7); 31298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 31398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic inline spx_word16_t qcurve(spx_word16_t x) 31598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 31698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x = MAX16(x, 1); 31798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return DIV32_16(SHL32(EXTEND32(32767),9),ADD16(512,MULT16_16_Q15(QCONST16(.60f,15),DIV32_16(32767,x)))); 31898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 31998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 32098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Compute the gain floor based on different floors for the background noise and residual echo */ 32198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len) 32298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 32398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 32498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 32598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (noise_suppress > effective_echo_suppress) 32698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 32798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t noise_gain, gain_ratio; 32898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project noise_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),noise_suppress)),1))); 32998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),effective_echo_suppress-noise_suppress)),1))); 33098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 33198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */ 33298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 33398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_floor[i] = MULT16_16_Q15(noise_gain, 33498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_sqrt(SHL32(EXTEND32(DIV32_16_Q15(PSHR32(noise[i],NOISE_SHIFT) + MULT16_32_Q15(gain_ratio,echo[i]), 33598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]) )),15))); 33698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 33798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t echo_gain, gain_ratio; 33898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project echo_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),effective_echo_suppress)),1))); 33998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),noise_suppress-effective_echo_suppress)),1))); 34098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 34198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */ 34298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 34398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_floor[i] = MULT16_16_Q15(echo_gain, 34498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_sqrt(SHL32(EXTEND32(DIV32_16_Q15(MULT16_32_Q15(gain_ratio,PSHR32(noise[i],NOISE_SHIFT)) + echo[i], 34598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]) )),15))); 34698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 34798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 34898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 34998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 35098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* This function approximates the gain function 35198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x) 35298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project which multiplied by xi/(1+xi) is the optimal gain 35398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project in the loudness domain ( sqrt[amplitude] ) 35498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project*/ 35598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic inline spx_word32_t hypergeom_gain(spx_word32_t xx) 35698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 35798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int ind; 35898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float integer, frac; 35998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float x; 36098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project static const float table[21] = { 36198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 0.82157f, 1.02017f, 1.20461f, 1.37534f, 1.53363f, 1.68092f, 1.81865f, 36298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1.94811f, 2.07038f, 2.18638f, 2.29688f, 2.40255f, 2.50391f, 2.60144f, 36398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 2.69551f, 2.78647f, 2.87458f, 2.96015f, 3.04333f, 3.12431f, 3.20326f}; 36498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x = EXPIN_SCALING_1*xx; 36598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project integer = floor(2*x); 36698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ind = (int)integer; 36798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (ind<0) 36898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return FRAC_SCALING; 36998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (ind>19) 37098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return FRAC_SCALING*(1+.1296/x); 37198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project frac = 2*x-integer; 37298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return FRAC_SCALING*((1-frac)*table[ind] + frac*table[ind+1])/sqrt(x+.0001f); 37398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 37498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 37598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic inline spx_word16_t qcurve(spx_word16_t x) 37698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 37798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return 1.f/(1.f+.15f/(SNR_SCALING_1*x)); 37898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 37998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 38098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len) 38198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 38298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 38398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float echo_floor; 38498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float noise_floor; 38598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 38698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project noise_floor = exp(.2302585f*noise_suppress); 38798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project echo_floor = exp(.2302585f*effective_echo_suppress); 38898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 38998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Compute the gain floor based on different floors for the background noise and residual echo */ 39098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 39198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_floor[i] = FRAC_SCALING*sqrt(noise_floor*PSHR32(noise[i],NOISE_SHIFT) + echo_floor*echo[i])/sqrt(1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]); 39298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 39398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 39498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 39598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectEXPORT SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate) 39698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 39798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 39898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N, N3, N4, M; 39998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 40098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SpeexPreprocessState *st = (SpeexPreprocessState *)speex_alloc(sizeof(SpeexPreprocessState)); 40198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->frame_size = frame_size; 40298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 40398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Round ps_size down to the nearest power of two */ 40498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if 0 40598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project i=1; 40698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ps_size = st->frame_size; 40798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project while(1) 40898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 40998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->ps_size & ~i) 41098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 41198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ps_size &= ~i; 41298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project i<<=1; 41398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 41498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 41598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 41698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 41798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 41898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 41998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->ps_size < 3*st->frame_size/4) 42098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ps_size = st->ps_size * 3 / 2; 42198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 42298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ps_size = st->frame_size; 42398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 42498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 42598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project N = st->ps_size; 42698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project N3 = 2*N - st->frame_size; 42798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project N4 = st->frame_size - N3; 42898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 42998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->sampling_rate = sampling_rate; 43098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->denoise_enabled = 1; 43198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->vad_enabled = 0; 43298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->dereverb_enabled = 0; 43398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->reverb_decay = 0; 43498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->reverb_level = 0; 43598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->noise_suppress = NOISE_SUPPRESS_DEFAULT; 43698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->echo_suppress = ECHO_SUPPRESS_DEFAULT; 43798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->echo_suppress_active = ECHO_SUPPRESS_ACTIVE_DEFAULT; 43898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 43998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->speech_prob_start = SPEECH_PROB_START_DEFAULT; 44098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->speech_prob_continue = SPEECH_PROB_CONTINUE_DEFAULT; 44198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 44298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->echo_state = NULL; 44398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 44498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->nbands = NB_BANDS; 44598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project M = st->nbands; 44698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->bank = filterbank_new(M, sampling_rate, N, 1); 44798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 44898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->frame = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); 44998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->window = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); 45098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ft = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); 45198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 45298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); 45398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); 45498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->echo_noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); 45598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->residual_echo = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); 45698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->reverb_estimate = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); 45798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->old_ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); 45898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->prior = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); 45998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->post = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); 46098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); 46198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain2 = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); 46298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain_floor = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); 46398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->zeta = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); 46498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 46598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->S = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); 46698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->Smin = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); 46798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->Stmp = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); 46898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->update_prob = (int*)speex_alloc(N*sizeof(int)); 46998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 47098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->inbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t)); 47198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->outbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t)); 47298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 47398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project conj_window(st->window, 2*N3); 47498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=2*N3;i<2*st->ps_size;i++) 47598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->window[i]=Q15_ONE; 47698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 47798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (N4>0) 47898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 47998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=N3-1;i>=0;i--) 48098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 48198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->window[i+N3+N4]=st->window[i+N3]; 48298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->window[i+N3]=1; 48398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 48498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 48598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N+M;i++) 48698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 48798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->noise[i]=QCONST32(1.f,NOISE_SHIFT); 48898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->reverb_estimate[i]=0; 48998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->old_ps[i]=1; 49098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain[i]=Q15_ONE; 49198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->post[i]=SHL16(1, SNR_SHIFT); 49298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->prior[i]=SHL16(1, SNR_SHIFT); 49398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 49498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 49598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 49698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->update_prob[i] = 1; 49798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N3;i++) 49898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 49998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->inbuf[i]=0; 50098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->outbuf[i]=0; 50198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 50298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef FIXED_POINT 50398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_enabled = 0; 50498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_level = 8000; 50598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->loudness_weight = (float*)speex_alloc(N*sizeof(float)); 50698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 50798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 50898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float ff=((float)i)*.5*sampling_rate/((float)N); 50998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*st->loudness_weight[i] = .5f*(1.f/(1.f+ff/8000.f))+1.f*exp(-.5f*(ff-3800.f)*(ff-3800.f)/9e5f);*/ 51098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->loudness_weight[i] = .35f-.35f*ff/16000.f+.73f*exp(-.5f*(ff-3800)*(ff-3800)/9e5f); 51198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->loudness_weight[i]<.01f) 51298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->loudness_weight[i]=.01f; 51398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->loudness_weight[i] *= st->loudness_weight[i]; 51498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 51598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*st->loudness = pow(AMP_SCALE*st->agc_level,LOUDNESS_EXP);*/ 51698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->loudness = 1e-15; 51798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_gain = 1; 51898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->max_gain = 30; 51998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->max_increase_step = exp(0.11513f * 12.*st->frame_size / st->sampling_rate); 52098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->max_decrease_step = exp(-0.11513f * 40.*st->frame_size / st->sampling_rate); 52198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->prev_loudness = 1; 52298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->init_max = 1; 52398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 52498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->was_speech = 0; 52598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 52698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->fft_lookup = spx_fft_init(2*N); 52798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 52898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->nb_adapt=0; 52998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->min_count=0; 53098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return st; 53198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 53298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 53398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectEXPORT void speex_preprocess_state_destroy(SpeexPreprocessState *st) 53498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 53598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->frame); 53698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->ft); 53798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->ps); 53898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->gain2); 53998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->gain_floor); 54098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->window); 54198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->noise); 54298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->reverb_estimate); 54398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->old_ps); 54498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->gain); 54598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->prior); 54698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->post); 54798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef FIXED_POINT 54898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->loudness_weight); 54998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 55098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->echo_noise); 55198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->residual_echo); 55298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 55398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->S); 55498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->Smin); 55598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->Stmp); 55698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->update_prob); 55798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->zeta); 55898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 55998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->inbuf); 56098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st->outbuf); 56198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 56298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_fft_destroy(st->fft_lookup); 56398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filterbank_destroy(st->bank); 56498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_free(st); 56598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 56698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 56798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* FIXME: The AGC doesn't work yet with fixed-point*/ 56898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef FIXED_POINT 56998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx_word16_t *ft) 57098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 57198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 57298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N = st->ps_size; 57398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float target_gain; 57498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float loudness=1.f; 57598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float rate; 57698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 57798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=2;i<N;i++) 57898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 57998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project loudness += 2.f*N*st->ps[i]* st->loudness_weight[i]; 58098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 58198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project loudness=sqrt(loudness); 58298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*if (loudness < 2*pow(st->loudness, 1.0/LOUDNESS_EXP) && 58398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project loudness*2 > pow(st->loudness, 1.0/LOUDNESS_EXP))*/ 58498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (Pframe>.3f) 58598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 58698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*rate=2.0f*Pframe*Pframe/(1+st->nb_loudness_adapt);*/ 58798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project rate = .03*Pframe*Pframe; 58898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->loudness = (1-rate)*st->loudness + (rate)*pow(AMP_SCALE*loudness, LOUDNESS_EXP); 58998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->loudness_accum = (1-rate)*st->loudness_accum + rate; 59098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->init_max < st->max_gain && st->nb_adapt > 20) 59198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->init_max *= 1.f + .1f*Pframe*Pframe; 59298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 59398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*printf ("%f %f %f %f\n", Pframe, loudness, pow(st->loudness, 1.0f/LOUDNESS_EXP), st->loudness2);*/ 59498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 59598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project target_gain = AMP_SCALE*st->agc_level*pow(st->loudness/(1e-4+st->loudness_accum), -1.0f/LOUDNESS_EXP); 59698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 59798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if ((Pframe>.5 && st->nb_adapt > 20) || target_gain < st->agc_gain) 59898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 59998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (target_gain > st->max_increase_step*st->agc_gain) 60098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project target_gain = st->max_increase_step*st->agc_gain; 60198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (target_gain < st->max_decrease_step*st->agc_gain && loudness < 10*st->prev_loudness) 60298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project target_gain = st->max_decrease_step*st->agc_gain; 60398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (target_gain > st->max_gain) 60498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project target_gain = st->max_gain; 60598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (target_gain > st->init_max) 60698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project target_gain = st->init_max; 60798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 60898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_gain = target_gain; 60998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 61098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*fprintf (stderr, "%f %f %f\n", loudness, (float)AMP_SCALE_1*pow(st->loudness, 1.0f/LOUDNESS_EXP), st->agc_gain);*/ 61198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 61298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<2*N;i++) 61398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ft[i] *= st->agc_gain; 61498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->prev_loudness = loudness; 61598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 61698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 61798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 61898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic void preprocess_analysis(SpeexPreprocessState *st, spx_int16_t *x) 61998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 62098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 62198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N = st->ps_size; 62298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N3 = 2*N - st->frame_size; 62398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N4 = st->frame_size - N3; 62498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *ps=st->ps; 62598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 62698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* 'Build' input frame */ 62798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N3;i++) 62898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->frame[i]=st->inbuf[i]; 62998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<st->frame_size;i++) 63098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->frame[N3+i]=x[i]; 63198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 63298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Update inbuf */ 63398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N3;i++) 63498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->inbuf[i]=x[N4+i]; 63598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 63698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Windowing */ 63798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<2*N;i++) 63898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]); 63998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 64098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 64198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 64298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t max_val=0; 64398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<2*N;i++) 64498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project max_val = MAX16(max_val, ABS16(st->frame[i])); 64598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->frame_shift = 14-spx_ilog2(EXTEND32(max_val)); 64698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<2*N;i++) 64798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->frame[i] = SHL16(st->frame[i], st->frame_shift); 64898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 64998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 65098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 65198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Perform FFT */ 65298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_fft(st->fft_lookup, st->frame, st->ft); 65398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 65498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Power spectrum */ 65598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ps[0]=MULT16_16(st->ft[0],st->ft[0]); 65698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=1;i<N;i++) 65798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ps[i]=MULT16_16(st->ft[2*i-1],st->ft[2*i-1]) + MULT16_16(st->ft[2*i],st->ft[2*i]); 65898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 65998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ps[i] = PSHR32(st->ps[i], 2*st->frame_shift); 66098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 66198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filterbank_compute_bank32(st->bank, ps, ps+N); 66298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 66398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 66498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic void update_noise_prob(SpeexPreprocessState *st) 66598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 66698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 66798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int min_range; 66898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N = st->ps_size; 66998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 67098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=1;i<N-1;i++) 67198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->S[i] = MULT16_32_Q15(QCONST16(.8f,15),st->S[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i-1]) 67298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project + MULT16_32_Q15(QCONST16(.1f,15),st->ps[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i+1]); 67398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->S[0] = MULT16_32_Q15(QCONST16(.8f,15),st->S[0]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[0]); 67498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->S[N-1] = MULT16_32_Q15(QCONST16(.8f,15),st->S[N-1]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[N-1]); 67598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 67698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->nb_adapt==1) 67798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 67898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 67998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->Smin[i] = st->Stmp[i] = 0; 68098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 68198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 68298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->nb_adapt < 100) 68398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project min_range = 15; 68498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else if (st->nb_adapt < 1000) 68598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project min_range = 50; 68698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else if (st->nb_adapt < 10000) 68798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project min_range = 150; 68898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else 68998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project min_range = 300; 69098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->min_count > min_range) 69198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 69298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->min_count = 0; 69398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 69498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 69598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->Smin[i] = MIN32(st->Stmp[i], st->S[i]); 69698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->Stmp[i] = st->S[i]; 69798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 69898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 69998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 70098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 70198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->Smin[i] = MIN32(st->Smin[i], st->S[i]); 70298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->Stmp[i] = MIN32(st->Stmp[i], st->S[i]); 70398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 70498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 70598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 70698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 70798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (MULT16_32_Q15(QCONST16(.4f,15),st->S[i]) > st->Smin[i]) 70898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->update_prob[i] = 1; 70998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else 71098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->update_prob[i] = 0; 71198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*fprintf (stderr, "%f ", st->S[i]/st->Smin[i]);*/ 71298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*fprintf (stderr, "%f ", st->update_prob[i]);*/ 71398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 71498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 71598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 71698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 71798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NOISE_OVERCOMPENS 1. 71898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 71998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len); 72098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 72198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectEXPORT int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo) 72298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 72398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return speex_preprocess_run(st, x); 72498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 72598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 72698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectEXPORT int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x) 72798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 72898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 72998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int M; 73098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N = st->ps_size; 73198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N3 = 2*N - st->frame_size; 73298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N4 = st->frame_size - N3; 73398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *ps=st->ps; 73498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t Zframe; 73598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t Pframe; 73698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t beta, beta_1; 73798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t effective_echo_suppress; 73898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 73998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->nb_adapt++; 74098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->nb_adapt>20000) 74198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->nb_adapt = 20000; 74298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->min_count++; 74398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 74498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt)); 74598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project beta_1 = Q15_ONE-beta; 74698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project M = st->nbands; 74798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Deal with residual echo if provided */ 74898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->echo_state) 74998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 75098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_echo_get_residual(st->echo_state, st->residual_echo, N); 75198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef FIXED_POINT 75298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* If there are NaNs or ridiculous values, it'll show up in the DC and we just reset everything to zero */ 75398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (!(st->residual_echo[0] >=0 && st->residual_echo[0]<N*1e9f)) 75498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 75598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 75698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->residual_echo[i] = 0; 75798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 75898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 75998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 76098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->echo_noise[i] = MAX32(MULT16_32_Q15(QCONST16(.6f,15),st->echo_noise[i]), st->residual_echo[i]); 76198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filterbank_compute_bank32(st->bank, st->echo_noise, st->echo_noise+N); 76298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 76398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N+M;i++) 76498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->echo_noise[i] = 0; 76598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 76698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project preprocess_analysis(st, x); 76798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 76898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project update_noise_prob(st); 76998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 77098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Noise estimation always updated for the 10 first frames */ 77198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*if (st->nb_adapt<10) 77298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 77398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=1;i<N-1;i++) 77498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->update_prob[i] = 0; 77598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 77698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project */ 77798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 77898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Update the noise estimate for the frequencies where it can be */ 77998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 78098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 78198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i], NOISE_SHIFT)) 78298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->noise[i] = MAX32(EXTEND32(0),MULT16_32_Q15(beta_1,st->noise[i]) + MULT16_32_Q15(beta,SHL32(st->ps[i],NOISE_SHIFT))); 78398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 78498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filterbank_compute_bank32(st->bank, st->noise, st->noise+N); 78598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 78698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Special case for first frame */ 78798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->nb_adapt==1) 78898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N+M;i++) 78998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->old_ps[i] = ps[i]; 79098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 79198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Compute a posteriori SNR */ 79298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N+M;i++) 79398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 79498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t gamma; 79598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 79698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Total noise estimate including residual echo and reverberation */ 79798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t tot_noise = ADD32(ADD32(ADD32(EXTEND32(1), PSHR32(st->noise[i],NOISE_SHIFT)) , st->echo_noise[i]) , st->reverb_estimate[i]); 79898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 79998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* A posteriori SNR = ps/noise - 1*/ 80098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->post[i] = SUB16(DIV32_16_Q8(ps[i],tot_noise), QCONST16(1.f,SNR_SHIFT)); 80198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->post[i]=MIN16(st->post[i], QCONST16(100.f,SNR_SHIFT)); 80298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 80398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Computing update gamma = .1 + .9*(old/(old+noise))^2 */ 80498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gamma = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.89f,15),SQR16_Q15(DIV32_16_Q15(st->old_ps[i],ADD32(st->old_ps[i],tot_noise)))); 80598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 80698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* A priori SNR update = gamma*max(0,post) + (1-gamma)*old/noise */ 80798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->prior[i] = EXTRACT16(PSHR32(ADD32(MULT16_16(gamma,MAX16(0,st->post[i])), MULT16_16(Q15_ONE-gamma,DIV32_16_Q8(st->old_ps[i],tot_noise))), 15)); 80898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->prior[i]=MIN16(st->prior[i], QCONST16(100.f,SNR_SHIFT)); 80998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 81098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 81198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*print_vec(st->post, N+M, "");*/ 81298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 81398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Recursive average of the a priori SNR. A bit smoothed for the psd components */ 81498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->zeta[0] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[0]), MULT16_16(QCONST16(.3f,15),st->prior[0])),15); 81598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=1;i<N-1;i++) 81698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->zeta[i] = PSHR32(ADD32(ADD32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.15f,15),st->prior[i])), 81798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project MULT16_16(QCONST16(.075f,15),st->prior[i-1])), MULT16_16(QCONST16(.075f,15),st->prior[i+1])),15); 81898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=N-1;i<N+M;i++) 81998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->zeta[i] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.3f,15),st->prior[i])),15); 82098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 82198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Speech probability of presence for the entire frame is based on the average filterbank a priori SNR */ 82298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Zframe = 0; 82398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=N;i<N+M;i++) 82498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Zframe = ADD32(Zframe, EXTEND32(st->zeta[i])); 82598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Pframe = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.899f,15),qcurve(DIV32_16(Zframe,st->nbands))); 82698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 82798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project effective_echo_suppress = EXTRACT16(PSHR32(ADD32(MULT16_16(SUB16(Q15_ONE,Pframe), st->echo_suppress), MULT16_16(Pframe, st->echo_suppress_active)),15)); 82898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 82998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project compute_gain_floor(st->noise_suppress, effective_echo_suppress, st->noise+N, st->echo_noise+N, st->gain_floor+N, M); 83098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 83198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Compute Ephraim & Malah gain speech probability of presence for each critical band (Bark scale) 83298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Technically this is actually wrong because the EM gaim assumes a slightly different probability 83398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project distribution */ 83498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=N;i<N+M;i++) 83598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 83698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* See EM and Cohen papers*/ 83798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t theta; 83898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Gain from hypergeometric function */ 83998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t MM; 84098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Weiner filter gain */ 84198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t prior_ratio; 84298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* a priority probability of speech presence based on Bark sub-band alone */ 84398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t P1; 84498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Speech absence a priori probability (considering sub-band and frame) */ 84598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t q; 84698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 84798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp; 84898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 84998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 85098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT))); 85198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT)); 85298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 85398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project MM = hypergeom_gain(theta); 85498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Gain with bound */ 85598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain[i] = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM))); 85698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Save old Bark power spectrum */ 85798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]); 85898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 85998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project P1 = QCONST16(.199f,15)+MULT16_16_Q15(QCONST16(.8f,15),qcurve (st->zeta[i])); 86098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project q = Q15_ONE-MULT16_16_Q15(Pframe,P1); 86198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 86298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project theta = MIN32(theta, EXTEND32(32767)); 86398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*Q8*/tmp = MULT16_16_Q15((SHL32(1,SNR_SHIFT)+st->prior[i]),EXTRACT16(MIN32(Q15ONE,SHR32(spx_exp(-EXTRACT16(theta)),1)))); 86498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = MIN16(QCONST16(3.,SNR_SHIFT), tmp); /* Prevent overflows in the next line*/ 86598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*Q8*/tmp = EXTRACT16(PSHR32(MULT16_16(PDIV32_16(SHL32(EXTEND32(q),8),(Q15_ONE-q)),tmp),8)); 86698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain2[i]=DIV32_16(SHL32(EXTEND32(32767),SNR_SHIFT), ADD16(256,tmp)); 86798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 86898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain2[i]=1/(1.f + (q/(1.f-q))*(1+st->prior[i])*exp(-theta)); 86998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 87098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 87198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Convert the EM gains and speech prob to linear frequency */ 87298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2); 87398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filterbank_compute_psd16(st->bank,st->gain+N, st->gain); 87498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 87598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Use 1 for linear gain resolution (best) or 0 for Bark gain resolution (faster) */ 87698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (1) 87798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 87898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filterbank_compute_psd16(st->bank,st->gain_floor+N, st->gain_floor); 87998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 88098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Compute gain according to the Ephraim-Malah algorithm -- linear frequency */ 88198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 88298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 88398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t MM; 88498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t theta; 88598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t prior_ratio; 88698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp; 88798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t p; 88898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t g; 88998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 89098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Wiener filter gain */ 89198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT))); 89298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT)); 89398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 89498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Optimal estimator for loudness domain */ 89598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project MM = hypergeom_gain(theta); 89698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* EM gain with bound */ 89798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM))); 89898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Interpolated speech probability of presence */ 89998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project p = st->gain2[i]; 90098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 90198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Constrain the gain to be close to the Bark scale gain */ 90298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (MULT16_16_Q15(QCONST16(.333f,15),g) > st->gain[i]) 90398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g = MULT16_16(3,st->gain[i]); 90498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain[i] = g; 90598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 90698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Save old power spectrum */ 90798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]); 90898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 90998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Apply gain floor */ 91098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->gain[i] < st->gain_floor[i]) 91198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain[i] = st->gain_floor[i]; 91298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 91398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Exponential decay model for reverberation (unused) */ 91498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*st->reverb_estimate[i] = st->reverb_decay*st->reverb_estimate[i] + st->reverb_decay*st->reverb_level*st->gain[i]*st->gain[i]*st->ps[i];*/ 91598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 91698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Take into account speech probability of presence (loudness domain MMSE estimator) */ 91798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* gain2 = [p*sqrt(gain)+(1-p)*sqrt(gain _floor) ]^2 */ 91898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15))); 91998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain2[i]=SQR16_Q15(tmp); 92098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 92198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Use this if you want a log-domain MMSE estimator instead */ 92298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*st->gain2[i] = pow(st->gain[i], p) * pow(st->gain_floor[i],1.f-p);*/ 92398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 92498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 92598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=N;i<N+M;i++) 92698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 92798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp; 92898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t p = st->gain2[i]; 92998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain[i] = MAX16(st->gain[i], st->gain_floor[i]); 93098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15))); 93198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain2[i]=SQR16_Q15(tmp); 93298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 93398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2); 93498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 93598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 93698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* If noise suppression is off, don't apply the gain (but then why call this in the first place!) */ 93798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (!st->denoise_enabled) 93898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 93998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N+M;i++) 94098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->gain2[i]=Q15_ONE; 94198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 94298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 94398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Apply computed gain */ 94498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=1;i<N;i++) 94598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 94698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ft[2*i-1] = MULT16_16_P15(st->gain2[i],st->ft[2*i-1]); 94798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ft[2*i] = MULT16_16_P15(st->gain2[i],st->ft[2*i]); 94898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 94998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ft[0] = MULT16_16_P15(st->gain2[0],st->ft[0]); 95098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->ft[2*N-1] = MULT16_16_P15(st->gain2[N-1],st->ft[2*N-1]); 95198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 95298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*FIXME: This *will* not work for fixed-point */ 95398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef FIXED_POINT 95498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->agc_enabled) 95598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_compute_agc(st, Pframe, st->ft); 95698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 95798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 95898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Inverse FFT with 1/N scaling */ 95998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_ifft(st->fft_lookup, st->ft, st->frame); 96098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Scale back to original (lower) amplitude */ 96198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<2*N;i++) 96298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->frame[i] = PSHR16(st->frame[i], st->frame_shift); 96398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 96498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*FIXME: This *will* not work for fixed-point */ 96598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef FIXED_POINT 96698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->agc_enabled) 96798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 96898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float max_sample=0; 96998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<2*N;i++) 97098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (fabs(st->frame[i])>max_sample) 97198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project max_sample = fabs(st->frame[i]); 97298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (max_sample>28000.f) 97398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 97498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float damp = 28000.f/max_sample; 97598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<2*N;i++) 97698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->frame[i] *= damp; 97798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 97898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 97998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 98098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 98198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Synthesis window (for WOLA) */ 98298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<2*N;i++) 98398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]); 98498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 98598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Perform overlap and add */ 98698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N3;i++) 98798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x[i] = st->outbuf[i] + st->frame[i]; 98898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N4;i++) 98998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x[N3+i] = st->frame[N3+i]; 99098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 99198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Update outbuf */ 99298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N3;i++) 99398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->outbuf[i] = st->frame[st->frame_size+i]; 99498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 99598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* FIXME: This VAD is a kludge */ 99698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->speech_prob = Pframe; 99798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->vad_enabled) 99898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 99998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->speech_prob > st->speech_prob_start || (st->was_speech && st->speech_prob > st->speech_prob_continue)) 100098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 100198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->was_speech=1; 100298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return 1; 100398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else 100498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 100598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->was_speech=0; 100698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return 0; 100798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 100898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 100998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return 1; 101098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 101198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 101298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 101398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectEXPORT void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x) 101498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 101598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 101698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N = st->ps_size; 101798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N3 = 2*N - st->frame_size; 101898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int M; 101998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *ps=st->ps; 102098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 102198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project M = st->nbands; 102298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->min_count++; 102398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 102498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project preprocess_analysis(st, x); 102598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 102698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project update_noise_prob(st); 102798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 102898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=1;i<N-1;i++) 102998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 103098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i],NOISE_SHIFT)) 103198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 103298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->noise[i] = MULT16_32_Q15(QCONST16(.95f,15),st->noise[i]) + MULT16_32_Q15(QCONST16(.05f,15),SHL32(st->ps[i],NOISE_SHIFT)); 103398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 103498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 103598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 103698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N3;i++) 103798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->outbuf[i] = MULT16_16_Q15(x[st->frame_size-N3+i],st->window[st->frame_size+i]); 103898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 103998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Save old power spectrum */ 104098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N+M;i++) 104198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->old_ps[i] = ps[i]; 104298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 104398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 104498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->reverb_estimate[i] = MULT16_32_Q15(st->reverb_decay, st->reverb_estimate[i]); 104598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 104698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 104798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 104898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectEXPORT int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) 104998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 105098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 105198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SpeexPreprocessState *st; 105298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st=(SpeexPreprocessState*)state; 105398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project switch(request) 105498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 105598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_DENOISE: 105698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->denoise_enabled = (*(spx_int32_t*)ptr); 105798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 105898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_DENOISE: 105998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = st->denoise_enabled; 106098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 106198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef FIXED_POINT 106298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_AGC: 106398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_enabled = (*(spx_int32_t*)ptr); 106498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 106598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_AGC: 106698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = st->agc_enabled; 106798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 106898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_FLOAT_API 106998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_AGC_LEVEL: 107098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_level = (*(float*)ptr); 107198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->agc_level<1) 107298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_level=1; 107398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->agc_level>32768) 107498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_level=32768; 107598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 107698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_AGC_LEVEL: 107798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(float*)ptr) = st->agc_level; 107898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 107998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_FLOAT_API */ 108098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_AGC_INCREMENT: 108198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->max_increase_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate); 108298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 108398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_AGC_INCREMENT: 108498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_increase_step)*st->sampling_rate/st->frame_size); 108598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 108698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_AGC_DECREMENT: 108798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->max_decrease_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate); 108898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 108998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_AGC_DECREMENT: 109098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_decrease_step)*st->sampling_rate/st->frame_size); 109198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 109298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_AGC_MAX_GAIN: 109398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->max_gain = exp(0.11513f * (*(spx_int32_t*)ptr)); 109498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 109598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_AGC_MAX_GAIN: 109698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_gain)); 109798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 109898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 109998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_VAD: 110098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // Disabled by mlebeau, we don't want this in the launched Google Mobile App for iPhone. 110198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project //speex_warning("The VAD has been replaced by a hack pending a complete rewrite"); 110298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->vad_enabled = (*(spx_int32_t*)ptr); 110398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 110498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_VAD: 110598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = st->vad_enabled; 110698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 110798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 110898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_DEREVERB: 110998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->dereverb_enabled = (*(spx_int32_t*)ptr); 111098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<st->ps_size;i++) 111198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->reverb_estimate[i]=0; 111298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 111398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_DEREVERB: 111498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = st->dereverb_enabled; 111598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 111698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 111798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_DEREVERB_LEVEL: 111898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* FIXME: Re-enable when de-reverberation is actually enabled again */ 111998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*st->reverb_level = (*(float*)ptr);*/ 112098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 112198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_DEREVERB_LEVEL: 112298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* FIXME: Re-enable when de-reverberation is actually enabled again */ 112398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*(*(float*)ptr) = st->reverb_level;*/ 112498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 112598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 112698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_DEREVERB_DECAY: 112798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* FIXME: Re-enable when de-reverberation is actually enabled again */ 112898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*st->reverb_decay = (*(float*)ptr);*/ 112998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 113098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_DEREVERB_DECAY: 113198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* FIXME: Re-enable when de-reverberation is actually enabled again */ 113298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*(*(float*)ptr) = st->reverb_decay;*/ 113398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 113498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 113598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_PROB_START: 113698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); 113798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->speech_prob_start = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); 113898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 113998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_PROB_START: 114098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100); 114198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 114298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 114398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_PROB_CONTINUE: 114498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); 114598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->speech_prob_continue = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); 114698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 114798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_PROB_CONTINUE: 114898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_continue, 100); 114998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 115098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 115198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_NOISE_SUPPRESS: 115298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->noise_suppress = -ABS(*(spx_int32_t*)ptr); 115398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 115498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_NOISE_SUPPRESS: 115598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = st->noise_suppress; 115698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 115798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS: 115898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->echo_suppress = -ABS(*(spx_int32_t*)ptr); 115998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 116098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS: 116198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = st->echo_suppress; 116298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 116398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE: 116498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->echo_suppress_active = -ABS(*(spx_int32_t*)ptr); 116598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 116698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE: 116798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = st->echo_suppress_active; 116898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 116998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_ECHO_STATE: 117098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->echo_state = (SpeexEchoState*)ptr; 117198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 117298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_ECHO_STATE: 117398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(SpeexEchoState**)ptr) = (SpeexEchoState*)st->echo_state; 117498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 117598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef FIXED_POINT 117698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_AGC_LOUDNESS: 117798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = pow(st->loudness, 1.0/LOUDNESS_EXP); 117898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 117998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_AGC_GAIN: 118098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->agc_gain)); 118198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 118298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 118398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_PSD_SIZE: 118498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE: 118598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = st->ps_size; 118698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 118798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_PSD: 118898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=0;i<st->ps_size;i++) 118998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ((spx_int32_t *)ptr)[i] = (spx_int32_t) st->ps[i]; 119098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 119198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_NOISE_PSD: 119298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=0;i<st->ps_size;i++) 119398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ((spx_int32_t *)ptr)[i] = (spx_int32_t) PSHR32(st->noise[i], NOISE_SHIFT); 119498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 119598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_PROB: 119698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob, 100); 119798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 119898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef FIXED_POINT 119998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_SET_AGC_TARGET: 120098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_level = (*(spx_int32_t*)ptr); 120198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->agc_level<1) 120298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_level=1; 120398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (st->agc_level>32768) 120498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project st->agc_level=32768; 120598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 120698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project case SPEEX_PREPROCESS_GET_AGC_TARGET: 120798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (*(spx_int32_t*)ptr) = st->agc_level; 120898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 120998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 121098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project default: 121198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_warning_int("Unknown speex_preprocess_ctl request: ", request); 121298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return -1; 121398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 121498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return 0; 121598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 121698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 121798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_DEBUG 121898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectlong long spx_mips=0; 121998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 122098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1221