www.pudn.com > ETSI_ES_202_212_software.rar > CompCeps.c


/*===============================================================================
 *      ETSI ES 202 212   Distributed Speech Recognition
 *      Extended Advanced Front-End Feature Extraction Algorithm & Compression Algorithm
 *      Speech Reconstruction Algorithm.
 *      C-language software implementation                                      
 *      Version 1.1.1   October, 2003                                            
 *===============================================================================*/
/*-------------------------------------------------------------------------------
 *
 * FILE NAME: CompCeps.c
 * PURPOSE:   Calculating cepstral features and logE for the de-noised 
 *            input frame.
 *
 *-------------------------------------------------------------------------------*/
/*-----------------
 * File Inclusions
 *-----------------*/
#include 
#include 
#include 
#include 

#include "ParmInterface.h"
#include "CompCepsExports.h"
#include "16kHzProcExports.h"
#include "MelProcExports.h"
#include "rfft.h"

/*----------------------
 * Constant Definitions
 *----------------------*/
#define PI   3.14159265358979323846
#define PIx2 6.28318530717958647692

/*-------------------------------
 * Global Definitions and Macros
 *-------------------------------*/
#define CC_NUM_CHANNELS_WI8	 23
#define CC_PRE_EMPHASIS       0.90
#define CC_ENERGYFLOOR_FB   -10.0
#define CC_ENERGYFLOOR_logE -50.0
#define CC_FRAME_LENGTH     200
#define CC_FFT_LENGTH       256
#define CC_FFT_LENGTH_ORDER   8

struct CompCepsStructX
{
  X_INT16   SamplingFrequency;               //
  X_FLOAT32 StartingFrequency;               //
  X_FLOAT32 HammingWindow [CC_FRAME_LENGTH]; //
  X_FLOAT32 *pDCTMatrix;                     //
  MelFB_Window *FirstWindow;                 //
  BOOLEAN Noc0;                              //
  BOOLEAN Do16kHzProc;                       //
  DataFor16kProc *pData16k;                  //
};

/*------------
 * Prototypes
 *------------*/
static void WI8CompCeps (CompCepsStructX *CCX, X_FLOAT32 *curFrameFloatBuf,
						 X_FLOAT32 *cepOut, DataFor16kProc *pData16k);
static void InitializeHamming (X_FLOAT32 *win, X_INT16 len);
static void Window (X_FLOAT32 *data, X_FLOAT32 *win, X_INT16 len);
static void DCT (X_FLOAT32 *Data, X_FLOAT32 *Mx, X_INT16 NumCepstralCoeff, X_INT16 NumChannels);
static X_FLOAT32 *InitDCTMatrix (X_INT16 NumCepstralCoeff, X_INT16 NumChannels);

/*-----------
 * Functions
 *-----------*/
/*---------------------------------------------------------------------------
 * FUNCTION NAME: InitializeHamming
 *
 * PURPOSE:       Initializes Hamming window coefficients
 *
 * INPUT:
 *   win          Pointer to window buffer
 *   len          Window length
 *
 * OUTPUT
 *                Hamming window coefficients stored in window buffer pointed
 *                to by *win*
 *
 * RETURN VALUE
 *   none
 *
 *---------------------------------------------------------------------------*/
static void InitializeHamming (X_FLOAT32 *win, X_INT16 len)
{
  X_INT16 i;

  for (i=0 ; iCCX;

  //16kHz processing
  CCX->Do16kHzProc = This->Do16kHzProc;
  CCX->pData16k = This->pData16k;
  if (CCX->Do16kHzProc)
	CCX->pDCTMatrix = InitDCTMatrix (NUM_CEP_COEFF, CC_NUM_CHANNELS_WI8 + HP16k_MEL_USED);
  else
	CCX->pDCTMatrix = InitDCTMatrix (NUM_CEP_COEFF, CC_NUM_CHANNELS_WI8);
  CCX->Noc0 = This->Noc0;
  CCX->SamplingFrequency = This->SamplingFrequency;
  CCX->StartingFrequency = This->StartingFrequency;
  CCX->FirstWindow = CMelFBAlloc ();
  InitFFTWindows (CCX->FirstWindow, CCX->StartingFrequency,
				  CCX->SamplingFrequency, CC_FFT_LENGTH, CC_NUM_CHANNELS_WI8);
  ComputeTriangle (CCX->FirstWindow);  
  InitializeHamming (CCX->HammingWindow, CC_FRAME_LENGTH);
}

/*----------------------------------------------------------------------------
 * FUNCTION NAME: DoCompCeps
 *
 * PURPOSE: Cepstral computation for a frame
 *              
 *
 * INPUT:the current frame
 *        
 *
 * OUTPUT:NUM_CEP_COEFF + 1 coefficients (including c0) + LogEnergy
 *
 *
 * RETURN VALUE:TRUE  (a frame is always output)
 *   
 * WARNING !!!  :   The preceeding sample (index=-1) must be present in Data
 *---------------------------------------------------------------------------*/
extern BOOLEAN DoCompCeps (X_FLOAT32 *Data, X_FLOAT32 *Coef, FEParamsX *This) 
{
  CompCepsStructX *CCX = This->CCX;
  DataFor16kProc *pData16k = This->pData16k;
  
  WI8CompCeps (CCX, Data, Coef, pData16k);
  
  return TRUE;
}

/*----------------------------------------------------------------------------
 * FUNCTION NAME: DoCompCepsDelete
 *
 * PURPOSE:
 *              
 *
 * INPUT:
 *        
 *
 * OUTPUT:
 *
 *
 * RETURN VALUE:
 *   
 *
 *---------------------------------------------------------------------------*/
extern void DoCompCepsDelete (CompCepsStructX *CCX)
{
  if (CCX != NULL)
	{
	  ReleaseMelFBwindows (CCX->FirstWindow);
	  free (CCX);
	}

  return;
}

/*----------------------------------------------------------------------------
 * FUNCTION NAME: DoCompCepsDelete
 *
 * PURPOSE:
 *              
 *
 * INPUT:
 *        
 *
 * OUTPUT:
 *
 *
 * RETURN VALUE:
 *   
 *
 *---------------------------------------------------------------------------*/
void WI8CompCeps (CompCepsStructX *CCX, X_FLOAT32 *curBuffer, X_FLOAT32 *cepOut, DataFor16kProc *pData16k)
{
  X_FLOAT32 LogEnergy;
  X_FLOAT32 EnergyFloor_FB;
  X_FLOAT32 EnergyFloor_logE; 
  X_FLOAT32 *FloatBuffer;

  X_INT16 i;

  /*-------------------
   * 16 kHz processing
   *-------------------*/
  X_INT16   hp16kBandsSize;
  X_FLOAT32 hp16kBands [HP16k_MEL_USED];
  X_FLOAT32 *codeWeights;
  X_FLOAT32 *CodeForBands16k;
  X_FLOAT32 percCoded;
	
  FloatBuffer = (X_FLOAT32 *) malloc (sizeof (X_FLOAT32) * CC_FFT_LENGTH);
  if (FloatBuffer == NULL)
	{
	  fprintf (stderr, "ERROR:   Memory allocation error occured!\r\n");
	  exit(0);
	}

  if (CCX->Do16kHzProc)
	{
	  hp16kBandsSize  = HP16k_MEL_USED;
	  codeWeights     = Get16k_p_bufferCodeWeights (CCX->pData16k);
	  CodeForBands16k = Get16k_p_bufferCodeForBands16k (CCX->pData16k);
	  percCoded       = Get16k_percCoded (CCX->pData16k);
	}
  else 
	{
	  hp16kBandsSize  = 0;
	  codeWeights     = NULL;
	  CodeForBands16k = NULL;
	  percCoded       = 0.0;
	}
	  
  /*----------------
   * Initialization
   *----------------*/
  EnergyFloor_FB = (X_FLOAT32) exp ((double) CC_ENERGYFLOOR_FB);
  EnergyFloor_logE = (X_FLOAT32) exp ((double) CC_ENERGYFLOOR_logE);
  
  /*------------------
   * logE computation
   *------------------*/
  LogEnergy = 0.0;
  for (i=0 ; iDo16kHzProc)
	{
	  if (LogEnergy < EnergyFloor_logE)
		LogEnergy = CC_ENERGYFLOOR_logE;
	  else
		LogEnergy = (X_FLOAT32) log ((double)LogEnergy);
	}

  /*-------------------------------------------------
   * Pre-emphasis, notice that curBuffer[-1] is used
   *-------------------------------------------------*/
  for (i=0 ; iHammingWindow, CC_FRAME_LENGTH);

  /*--------------
   * Zero padding
   *--------------*/
  for (i=CC_FRAME_LENGTH ; iDo16kHzProc)
	{
	  X_FLOAT32 aux [3];

	  GetBandsForDecoding16k (FloatBuffer, aux, CC_FFT_LENGTH/2+1);
	  for (i=0 ; i<3 ; i++)
		{
		  if (aux [i] > EnergyFloor_FB)
			aux [i] = (X_FLOAT32) log ((double) aux [i]);
		  else
			aux [i] = CC_ENERGYFLOOR_FB;
		}
      // temporarily
      codeWeights [0] = 0.1; codeWeights [1] = 0.2; codeWeights [2] = 0.7;
      DecodeBands16k (hp16kBands, aux, CodeForBands16k, codeWeights);
    }

  /*---------------
   * Mel filtering
   *---------------*/
  DoMelFB (FloatBuffer, CCX->FirstWindow);

  /*-------------------
   * 16 kHz processing
   *-------------------*/
  if (CCX->Do16kHzProc)
	{
      X_FLOAT32 preemphs_correction = log (1.0 + CC_PRE_EMPHASIS);
	  X_FLOAT32 *hpBands;

	  hpBands = Get16k_p_hpBands (pData16k);

	  /*-----------------------------------------------------------
	   * SS HP bands -> including and rough preemphasis correction
	   *-----------------------------------------------------------*/
      for (i=CC_NUM_CHANNELS_WI8 ; i rough preemphasis correction
	   *------------------------------------------------*/
      for (i=0 ; iDo16kHzProc)
	{
	  /*--------------------------------------------
	   * mixing coded and SS HP bands in log domain
	   *--------------------------------------------*/
	  MergeSSandCoded (FloatBuffer, hp16kBands, CC_NUM_CHANNELS_WI8, &hp16kBandsSize, CCX->pData16k);

	  LogEnergy = CorrectEnergy (LogEnergy, hp16kBandsSize, FloatBuffer, CC_NUM_CHANNELS_WI8, CC_PRE_EMPHASIS);

	  if (LogEnergy < EnergyFloor_logE)
		LogEnergy = CC_ENERGYFLOOR_logE;
	  else
		LogEnergy = (X_FLOAT32) log ((double) LogEnergy);
	}

  /*---------------------------
   * Discrete Cosine Transform
   *---------------------------*/
  DCT (FloatBuffer, CCX->pDCTMatrix, NUM_CEP_COEFF, CC_NUM_CHANNELS_WI8 + hp16kBandsSize);

  /*--------------------------------------
   * Append logE after c0 or overwrite c0
   *--------------------------------------*/
  FloatBuffer[CC_NUM_CHANNELS_WI8 + hp16kBandsSize + NUM_CEP_COEFF - (CCX->Noc0 ? 1:0)] = LogEnergy;

  for (i=0 ; i