www.pudn.com > ETSI_ES_202_212_software.rar > VAD.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: VAD.c * PURPOSE: Logic for the frame dropping VAD. VAD flag is set * according to parameters (SpeechFoundSpec, SpeechFoundMel, * SpeechFoundVar) calculated in NoiseSup.c. * *-------------------------------------------------------------------------------*/ /*----------------- * File Inclusions *-----------------*/ #include#include #include "ParmInterface.h" #include "VADExports.h" /*---------------- * VAD Definitions *-----------------*/ struct VADStructX { int Focus; //Position of circular buffer int HangOver; //Hangover length int FlushFocus; //Position in circular buffer when emptying at end (uses Focus as start/endpoint) int H_CountDown; //Main hangover countdown int V_CountDown; //Short hangover countdown int DangerWillRobinson; //No output flag float **OutBuffer; // }; #define PRINTVAD 0 #define PRINTNULLS 0 #define BUFFER_SIZE 7 // Number of frames in analysis buffer #define HANGOVERV 23 // Number of frames by which VAD will stay on after speech #define H_TRIGGER 4 // Number of speech frames required to trigger hangover NB Must be <= BUFFER_SIZE!! #define VANGOVER 5 // Number of frames for short hangover, triggered by 3 frames of speech #define V_TRIGGER 3 // Number of speech frames required to trigger VAD #define SANGOVER 50 // Number of frames for safety hangover /*---------------------------------------------------------------------------- * FUNCTION NAME: focalpoint * * PURPOSE: CONTROL VAD BUFFER * * INPUT: * Focus current focal point * offset change in focal point * * OUTPUT: * None * * * RETURN VALUE: * temp new focal point within Buffer boundary * * *---------------------------------------------------------------------------*/ int focalpoint (int Focus, int offset) { int temp; temp = Focus + offset; if (temp > (BUFFER_SIZE-1)) temp = temp - BUFFER_SIZE; if (temp < 0) temp = temp + BUFFER_SIZE; return (temp); } /*---------------------------------------------------------------------------- * FUNCTION NAME: DoVADAlloc * * PURPOSE: Allocation of memory to VAD structure * * * INPUT: * None * * * OUTPUT: * None * * * RETURN VALUE: * VADX Pointer to VADStructX * * *---------------------------------------------------------------------------*/ extern VADStructX *DoVADAlloc (void) { VADStructX *VADX = calloc (1, sizeof (VADStructX)); return VADX; } /*---------------------------------------------------------------------------- * FUNCTION NAME: DoVADInit * * PURPOSE: Initialises VAD structure * * * INPUT: * This Pointer to front end parameter structure * * * OUTPUT: * This Pointer to front end parameter structure * * * RETURN VALUE: * None * * *---------------------------------------------------------------------------*/ extern void DoVADInit (FEParamsX *This) { int i ; VADStructX *VADX = This->VADX; VADX->Focus = 0; VADX->HangOver = HANGOVERV; VADX->H_CountDown = 0; VADX->V_CountDown = 0; VADX->DangerWillRobinson = 1; VADX->FlushFocus = -1; VADX->OutBuffer = calloc (BUFFER_SIZE, sizeof (VADX->OutBuffer[0])) ; if (VADX->OutBuffer == NULL) { fprintf (stderr, "Allocation error Outbuffer\n"); exit(0); } for (i=0 ; i OutBuffer[i] = calloc (NUM_CEP_COEFF+2, sizeof (VADX->OutBuffer[0][0])) ; if (VADX->OutBuffer[i] == NULL) { fprintf (stderr, "Allocation error Outbuffer\n"); exit(0); } } } /*---------------------------------------------------------------------------- * FUNCTION NAME: DoVADDelete * * PURPOSE: Free VAD structure * * * INPUT: * VADX Pointer to VAD structure * * * OUTPUT: * VADX Pointer to empty VAD structure * * * RETURN VALUE: * None * * *---------------------------------------------------------------------------*/ extern void DoVADDelete (VADStructX *VADX) { int i; for (i=0 ; i OutBuffer[i] != NULL) free (VADX->OutBuffer[i]) ; } if (VADX->OutBuffer != NULL) free (VADX->OutBuffer) ; if (VADX != NULL) free (VADX); } /*---------------------------------------------------------------------------- * FUNCTION NAME: DoVADProc * * PURPOSE: Identifies speech and non-speech frames * * * INPUT: * FeatureBuffer Buffer of features * This Pointer to front end parameter structure * * * OUTPUT: * FeatureBuffer Buffer of features * This Pointer to front end parameter structure * * * RETURN VALUE: * TRUE Once buffer is full * FALSE For first 10 frames * * *---------------------------------------------------------------------------*/ extern BOOLEAN DoVADProc (X_FLOAT32 *FeatureBuffer, FEParamsX *This) { VADStructX *VADX = This->VADX; int i; int Sum; int Trigger; int Refocus; int Focus = VADX->Focus; int HangOver = VADX->HangOver; int H_CountDown = VADX->H_CountDown; int V_CountDown = VADX->V_CountDown; int DangerWillRobinson = VADX->DangerWillRobinson; float **OutBuffer = VADX->OutBuffer; /*------------------ * *------------------*/ Focus++; if (Focus == BUFFER_SIZE) Focus = 0; for (i=0 ; i SpeechFoundSpec || This->SpeechFoundMel || This->SpeechFoundVar || This->SpeechFoundVADNS) { OutBuffer[Focus][NUM_CEP_COEFF+1] = 1; } else { OutBuffer[Focus][NUM_CEP_COEFF+1] = 0; } //+3 due to changes in lookahead if (This->FrameCounter > (BUFFER_SIZE+3)) { Sum=0;Trigger=0; for (i=0 ; i Trigger) { Trigger = Sum; } Sum = 0; } } if (Sum > Trigger) { Trigger = Sum; } if (Trigger>=H_TRIGGER) { H_CountDown = HangOver; DangerWillRobinson = 0; if (This->FrameCounter <= 35) HangOver = SANGOVER; } if (H_CountDown && Trigger < V_TRIGGER) { H_CountDown--; } if (Trigger >= V_TRIGGER) { V_CountDown = VANGOVER; } if (V_CountDown && Trigger < V_TRIGGER) { V_CountDown--; } Refocus = focalpoint (Focus, 1); for (i=0 ; i<=NUM_CEP_COEFF+1 ; i++) FeatureBuffer[i] = OutBuffer[Refocus][i]; if (V_CountDown || H_CountDown || Trigger >= V_TRIGGER) { FeatureBuffer[NUM_CEP_COEFF+1] = 1.0; } else { FeatureBuffer[NUM_CEP_COEFF+1] = 0.0; if (PRINTNULLS) fprintf (stderr, "%d,", This->FrameCounter-(BUFFER_SIZE+3)); } This->VAD = (int)FeatureBuffer[NUM_CEP_COEFF+1]; VADX->Focus = Focus; VADX->HangOver = HangOver; VADX->H_CountDown = H_CountDown; VADX->V_CountDown = V_CountDown; VADX->DangerWillRobinson = DangerWillRobinson; return TRUE; } else { VADX->Focus = Focus; VADX->HangOver = HangOver; VADX->H_CountDown = H_CountDown; VADX->V_CountDown = V_CountDown; VADX->DangerWillRobinson = DangerWillRobinson; return FALSE; } } /*---------------------------------------------------------------------------- * FUNCTION NAME: DoVADFlush * * PURPOSE: Flush remaining data from VAD Buffer * * * INPUT: * FeatureBuffer Buffer of features * This Pointer to front end parameter structure * * * OUTPUT: * FeatureBuffer Buffer of features * This Pointer to front end parameter structure * * * RETURN VALUE: * TRUE When VAD buffer is being flushed * FALSE When flushing is complete * * *---------------------------------------------------------------------------*/ extern BOOLEAN DoVADFlush (X_FLOAT32 *FeatureBuffer, FEParamsX *This) { VADStructX *VADX = This->VADX; int i; int Sum; int Trigger; int Refocus; int Focus = VADX->Focus; int HangOver = VADX->HangOver; int H_CountDown = VADX->H_CountDown; int V_CountDown = VADX->V_CountDown; int DangerWillRobinson = VADX->DangerWillRobinson; float **OutBuffer = VADX->OutBuffer; // Last frame output from loop if (VADX->FlushFocus == -1) VADX->FlushFocus = Focus; // Move forward one step Focus++; if (Focus == BUFFER_SIZE) Focus = 0; if (Focus != VADX->FlushFocus) { // Flush remaining data // Need to keep the counter incrementing! This->FrameCounter++; // +3 due to changes in lookahead if (This->FrameCounter > (BUFFER_SIZE+3)) { Sum = 0; Trigger = 0; for (i=0 ; i Trigger) { Trigger = Sum; } Sum = 0; } } if (Sum > Trigger) { Trigger = Sum; } if (Trigger >= H_TRIGGER) { H_CountDown=HangOver; DangerWillRobinson = 0; if (This->FrameCounter <= 35) HangOver = SANGOVER; } if (H_CountDown&&Trigger < V_TRIGGER) { H_CountDown--; } if (Trigger >= V_TRIGGER) { V_CountDown = VANGOVER; } if (V_CountDown&&Trigger < V_TRIGGER) { V_CountDown--; } Refocus = focalpoint (Focus, 1); for (i=0 ; i<=NUM_CEP_COEFF+1 ; i++) FeatureBuffer[i] = OutBuffer[Refocus][i]; if (V_CountDown || H_CountDown || Trigger>=V_TRIGGER) { FeatureBuffer[NUM_CEP_COEFF+1] = 1.0; } else { FeatureBuffer[NUM_CEP_COEFF+1] = 0.0; if (PRINTNULLS) fprintf (stderr, "%d,", This->FrameCounter-(BUFFER_SIZE+3)); } /*------------------ * Output result *------------------*/ This->VAD = (int)FeatureBuffer[NUM_CEP_COEFF+1]; } VADX->Focus = Focus; VADX->HangOver = HangOver; VADX->H_CountDown = H_CountDown; VADX->V_CountDown = V_CountDown; VADX->DangerWillRobinson = DangerWillRobinson; return TRUE; } else { return FALSE; } }