198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Copyright (C) 2002 Jean-Marc Valin
298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   File: vbr.c
398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   VBR-related routines
598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   Redistribution and use in source and binary forms, with or without
798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   modification, are permitted provided that the following conditions
898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   are met:
998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
1098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   - Redistributions of source code must retain the above copyright
1198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   notice, this list of conditions and the following disclaimer.
1298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
1398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   - Redistributions in binary form must reproduce the above copyright
1498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   notice, this list of conditions and the following disclaimer in the
1598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   documentation and/or other materials provided with the distribution.
1698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
1798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   - Neither the name of the Xiph.org Foundation nor the names of its
1898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   contributors may be used to endorse or promote products derived from
1998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   this software without specific prior written permission.
2098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
2198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
2598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
3398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project*/
3498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
3598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef HAVE_CONFIG_H
3698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "config.h"
3798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif
3898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
3998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "vbr.h"
4098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include <math.h>
4198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
4298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
4398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define sqr(x) ((x)*(x))
4498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
4598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define MIN_ENERGY 6000
4698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NOISE_POW .3
4798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
4898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef DISABLE_VBR
4998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
5098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst float vbr_nb_thresh[9][11]={
5198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /*   CNG   */
5298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   { 4.0f,  2.5f,  2.0f,  1.2f,  0.5f,  0.0f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /*  2 kbps */
5398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {10.0f,  6.5f,  5.2f,  4.5f,  3.9f,  3.5f,  3.0f,  2.5f,  2.3f,  1.8f,  1.0f}, /*  6 kbps */
5498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {11.0f,  8.8f,  7.5f,  6.5f,  5.0f,  3.9f,  3.9f,  3.9f,  3.5f,  3.0f,  1.0f}, /*  8 kbps */
5598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {11.0f, 11.0f,  9.9f,  8.5f,  7.0f,  6.0f,  4.5f,  4.0f,  4.0f,  4.0f,  2.0f}, /* 11 kbps */
5698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {11.0f, 11.0f, 11.0f, 11.0f,  9.5f,  8.5f,  8.0f,  7.0f,  6.0f,  5.0f,  3.0f}, /* 15 kbps */
5798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f,  9.5f,  8.5f,  7.0f,  6.0f,  5.0f}, /* 18 kbps */
5898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f,  9.8f,  9.5f,  7.5f}, /* 24 kbps */
5998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   { 7.0f,  4.5f,  3.7f,  3.0f,  2.5f,  2.0f,  1.8f,  1.5f,  1.0f,  0.0f,  0.0f}  /*  4 kbps */
6098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project};
6198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
6298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
6398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst float vbr_hb_thresh[5][11]={
6498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */
6598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /*  2 kbps */
6698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {11.0f, 11.0f,  9.5f,  8.5f,  7.5f,  6.0f,  5.0f,  3.9f,  3.0f,  2.0f,  1.0f}, /*  6 kbps */
6798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {11.0f, 11.0f, 11.0f, 11.0f, 11.0f,  9.5f,  8.7f,  7.8f,  7.0f,  6.5f,  4.0f}, /* 10 kbps */
6898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f,  9.8f,  7.5f,  5.5f}  /* 18 kbps */
6998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project};
7098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
7198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst float vbr_uhb_thresh[2][11]={
7298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */
7398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   { 3.9f,  2.5f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f, -1.0f}  /*  2 kbps */
7498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project};
7598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
7698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid vbr_init(VBRState *vbr)
7798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
7898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i;
7998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
8098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->average_energy=0;
8198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->last_energy=1;
8298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->accum_sum=0;
8398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->energy_alpha=.1;
8498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->soft_pitch=0;
8598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->last_pitch_coef=0;
8698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->last_quality=0;
8798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
8898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->noise_accum = .05*pow(MIN_ENERGY, NOISE_POW);
8998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->noise_accum_count=.05;
9098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count;
9198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->consec_noise=0;
9298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
9398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
9498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<VBR_MEMORY_SIZE;i++)
9598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      vbr->last_log_energy[i] = log(MIN_ENERGY);
9698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
9798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
9898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
9998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*
10098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  This function should analyse the signal and decide how critical the
10198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  coding error will be perceptually. The following factors should be
10298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  taken into account:
10398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
10498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  -Attacks (positive energy derivative) should be coded with more bits
10598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
10698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  -Stationary voiced segments should receive more bits
10798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
10898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  -Segments with (very) low absolute energy should receive less bits (maybe
10998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  only shaped noise?)
11098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
11198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  -DTX for near-zero energy?
11298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
11398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  -Stationary fricative segments should have less bits
11498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
11598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  -Temporal masking: when energy slope is decreasing, decrease the bit-rate
11698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
11798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  -Decrease bit-rate for males (low pitch)?
11898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
11998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  -(wideband only) less bits in the high-band when signal is very
12098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project  non-stationary (harder to notice high-frequency noise)???
12198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
12298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project*/
12398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
12498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectfloat vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef)
12598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
12698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int i;
12798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   float ener=0, ener1=0, ener2=0;
12898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   float qual=7;
12998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   int va;
13098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   float log_energy;
13198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   float non_st=0;
13298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   float voicing;
13398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   float pow_ener;
13498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
13598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<len>>1;i++)
13698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ener1 += ((float)sig[i])*sig[i];
13798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
13898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=len>>1;i<len;i++)
13998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      ener2 += ((float)sig[i])*sig[i];
14098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   ener=ener1+ener2;
14198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
14298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   log_energy = log(ener+MIN_ENERGY);
14398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=0;i<VBR_MEMORY_SIZE;i++)
14498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      non_st += sqr(log_energy-vbr->last_log_energy[i]);
14598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   non_st =  non_st/(30*VBR_MEMORY_SIZE);
14698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (non_st>1)
14798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      non_st=1;
14898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
14998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   voicing = 3*(pitch_coef-.4)*fabs(pitch_coef-.4);
15098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->average_energy = (1-vbr->energy_alpha)*vbr->average_energy + vbr->energy_alpha*ener;
15198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count;
15298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   pow_ener = pow(ener,NOISE_POW);
15398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (vbr->noise_accum_count<.06 && ener>MIN_ENERGY)
15498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      vbr->noise_accum = .05*pow_ener;
15598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
15698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if ((voicing<.3 && non_st < .2 && pow_ener < 1.2*vbr->noise_level)
15798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project       || (voicing<.3 && non_st < .05 && pow_ener < 1.5*vbr->noise_level)
15898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project       || (voicing<.4 && non_st < .05 && pow_ener < 1.2*vbr->noise_level)
15998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project       || (voicing<0 && non_st < .05))
16098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
16198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      float tmp;
16298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      va = 0;
16398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      vbr->consec_noise++;
16498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (pow_ener > 3*vbr->noise_level)
16598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         tmp = 3*vbr->noise_level;
16698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      else
16798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         tmp = pow_ener;
16898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (vbr->consec_noise>=4)
16998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
17098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         vbr->noise_accum = .95*vbr->noise_accum + .05*tmp;
17198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         vbr->noise_accum_count = .95*vbr->noise_accum_count + .05;
17298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
17398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   } else {
17498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      va = 1;
17598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      vbr->consec_noise=0;
17698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
17798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
17898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (pow_ener < vbr->noise_level && ener>MIN_ENERGY)
17998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
18098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      vbr->noise_accum = .95*vbr->noise_accum + .05*pow_ener;
18198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      vbr->noise_accum_count = .95*vbr->noise_accum_count + .05;
18298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
18398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
18498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /* Checking for very low absolute energy */
18598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (ener < 30000)
18698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
18798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual -= .7;
18898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (ener < 10000)
18998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qual-=.7;
19098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (ener < 3000)
19198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qual-=.7;
19298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   } else {
19398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      float short_diff, long_diff;
19498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      short_diff = log((ener+1)/(1+vbr->last_energy));
19598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      long_diff = log((ener+1)/(1+vbr->average_energy));
19698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /*fprintf (stderr, "%f %f\n", short_diff, long_diff);*/
19798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
19898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (long_diff<-5)
19998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         long_diff=-5;
20098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (long_diff>2)
20198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         long_diff=2;
20298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
20398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (long_diff>0)
20498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qual += .6*long_diff;
20598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (long_diff<0)
20698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qual += .5*long_diff;
20798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (short_diff>0)
20898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      {
20998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         if (short_diff>5)
21098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project            short_diff=5;
21198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qual += .5*short_diff;
21298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      }
21398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      /* Checking for energy increases */
21498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (ener2 > 1.6*ener1)
21598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qual += .5;
21698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
21798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->last_energy = ener;
21898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->soft_pitch = .6*vbr->soft_pitch + .4*pitch_coef;
21998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   qual += 2.2*((pitch_coef-.4) + (vbr->soft_pitch-.4));
22098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
22198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (qual < vbr->last_quality)
22298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual = .5*qual + .5*vbr->last_quality;
22398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (qual<4)
22498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual=4;
22598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (qual>10)
22698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual=10;
22798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
22898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*
22998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (vbr->consec_noise>=2)
23098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual-=1.3;
23198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (vbr->consec_noise>=5)
23298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual-=1.3;
23398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (vbr->consec_noise>=12)
23498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual-=1.3;
23598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   */
23698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (vbr->consec_noise>=3)
23798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual=4;
23898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
23998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (vbr->consec_noise)
24098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual -= 1.0 * (log(3.0 + vbr->consec_noise)-log(3));
24198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (qual<0)
24298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual=0;
24398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
24498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (ener<60000)
24598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   {
24698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (vbr->consec_noise>2)
24798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3));
24898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (ener<10000&&vbr->consec_noise>2)
24998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3));
25098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      if (qual<0)
25198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project         qual=0;
25298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual += .3*log(.0001+ener/60000.0);
25398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   }
25498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   if (qual<-1)
25598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      qual=-1;
25698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
25798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*printf ("%f %f %f %f %d\n", qual, voicing, non_st, pow_ener/(.01+vbr->noise_level), va);*/
25898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
25998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->last_pitch_coef = pitch_coef;
26098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->last_quality = qual;
26198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
26298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   for (i=VBR_MEMORY_SIZE-1;i>0;i--)
26398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project      vbr->last_log_energy[i] = vbr->last_log_energy[i-1];
26498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   vbr->last_log_energy[0] = log_energy;
26598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
26698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   /*printf ("VBR: %f %f %f %d %f\n", (float)(log_energy-log(vbr->average_energy+MIN_ENERGY)), non_st, voicing, va, vbr->noise_level);*/
26798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
26898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project   return qual;
26998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
27098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
27198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid vbr_destroy(VBRState *vbr)
27298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{
27398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}
27498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project
27598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif /* #ifndef DISABLE_VBR */
276