view libtwamr/ex_ctrl.c @ 478:936a08cc73ce

doc/AMR-library-API: describe the decoder
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 19 May 2024 21:32:31 +0000
parents 3f27ca24c620
children
line wrap: on
line source

/*************************************************************************
*
*      GSM AMR-NB speech codec   R98   Version 7.6.0   December 12, 2001
*                                R99   Version 3.3.0                
*                                REL-4 Version 4.1.0                
*
********************************************************************************
*
*      File             : ex_ctrl.c
*      Purpose          : Excitation Control module in background noise
*
********************************************************************************
*/

/*
********************************************************************************
*                         MODULE INCLUDE FILE AND VERSION ID
********************************************************************************
*/
#include "namespace.h"
#include "ex_ctrl.h"

#include "typedef.h"
#include "basic_op.h"
#include "no_count.h"
#include "cnst.h"
#include "memops.h"
#include "gmed_n.h"
#include "sqrt_l.h"

/*
********************************************************************************
*                         LOCAL VARIABLES AND TABLES
********************************************************************************
*/
/*-----------------------------------------------------------------*
 *   Decoder constant parameters (defined in "cnst.h")             *
 *-----------------------------------------------------------------*
 *   L_FRAME       : Frame size.                                   *
 *   L_SUBFR       : Sub-frame size.                               *
 *-----------------------------------------------------------------*/

/*
********************************************************************************
*                         PUBLIC PROGRAM CODE
********************************************************************************
*/

/*
**************************************************************************
*
*  Function    : Ex_ctrl
*  Purpose     : Charaterice synthesis speech and detect background noise
*  Returns     : background noise decision; 0 = no bgn, 1 = bgn
*
**************************************************************************
*/
Word16 Ex_ctrl (Word16 excitation[],   /*i/o: Current subframe excitation   */
                Word16 excEnergy,      /* i : Exc. Energy, sqrt(totEx*totEx)*/
                Word16 exEnergyHist[], /* i : History of subframe energies  */
                Word16 voicedHangover, /* i : # of fr. after last voiced fr.*/
                Word16 prevBFI,        /* i : Set i previous BFI            */
                Word16 carefulFlag     /* i : Restrict dymamic in scaling   */
                )
{
   Word16 i, exp;
   Word16 testEnergy, scaleFactor, avgEnergy, prevEnergy;
   Word32 t0;

   /* get target level */
   avgEnergy = gmed_n(exEnergyHist, 9);                    move16();

   prevEnergy = shr( add (exEnergyHist[7], exEnergyHist[8]) ,1);

   test ();
   if ( sub (exEnergyHist[8], prevEnergy) < 0)
   {
      prevEnergy = exEnergyHist[8];         move16 ();
   }

   /* upscaling to avoid too rapid energy rises  for some cases */
   test (); test ();
   if ( sub (excEnergy, avgEnergy) < 0 && sub (excEnergy, 5) > 0)
   {
      testEnergy = shl(prevEnergy, 2);  /* testEnergy = 4*prevEnergy; */

      test (); test ();
      if ( sub (voicedHangover, 7) < 0 || prevBFI != 0 )
      {
         /* testEnergy = 3*prevEnergy */
         testEnergy = sub (testEnergy, prevEnergy);  
      }

      test ();
      if ( sub (avgEnergy, testEnergy) > 0)
      {
         avgEnergy = testEnergy;         move16 ();
      }

      /* scaleFactor=avgEnergy/excEnergy in Q0 (const 29 below)*/
      exp = norm_s (excEnergy);
      excEnergy = shl (excEnergy, exp);
      excEnergy = div_s ((Word16) 16383, excEnergy);
      t0 = L_mult (avgEnergy, excEnergy);
      t0 = L_shr (t0, sub (20, exp));  /* const=30 for t0 in Q0, 20 for Q10 */
      if ( L_sub(t0, 32767) > 0 )
      {
         t0 = 32767; move32 ();   /* saturate  */
      }
      scaleFactor = extract_l (t0); 

      /* test if scaleFactor > 3.0 */
      test (); test ();
      if ( carefulFlag != 0 && sub(scaleFactor, 3072) > 0 ) 
      {
         scaleFactor = 3072;              move16 ();
      }

      /* scale the excitation by scaleFactor */
      for (i = 0; i < L_SUBFR; i++)
      {
         t0 = L_mult (scaleFactor, excitation[i]);
         t0 = L_shr (t0, 11);
         excitation[i] = extract_l (t0);
      } 
   }

   return 0;
}