www.pudn.com > CryptoPhone-src-031122.zip > adapt.c


/* Copyright 2001,2002,2003 NAH6 
 * All Rights Reserved 
 * 
 * Parts Copyright DoD, Parts Copyright Starium 
 * 
 */ 
          /*LINTLIBRARY*/ 
          /*PROTOLIB1*/ 
 
#include  
#include  
/*#include "main.h"*/ 
#include "celpfilt.h" 
#include "adapt.h" 
#include "submult.h" 
#include "del_tab.h" 
#include "acb_parm.h" 
#include "delay.h" 
#include "bwexp.h" 
#include "setarray.h" 
#include "acb_code.h" 
#include "movarray.h" 
#include "con_adap.h" 
 
#ifdef INTG 
int	fraction = FALSE; 
int	neigh = FALSE; 
#else /* INTG */ 
#ifdef FULL 
int	fraction = TRUE; 
int	neigh = FALSE; 
#else /* FULL --  
	if no compile-time options are specified, the hierarchical  
	search below is used (FS1016 method) */ 
int	fraction = FALSE; 
int	neigh = TRUE; 
int	NeighborhoodRange = 3; 
#endif /* FULL */ 
#endif /* INTG */ 
 
#define START 		B_PTR - SF_LEN + 1 
 
/*  Length of truncated impulse response */ 
/*	IR values past 30 are nearly zero */ 
#define LEN_TRUNC_H	30 
 
static void CalcPointers( 
int 	even,  
int 	PrevDelayPtr,  
int 	*MinDelayPtr,  
int 	*MaxDelayPtr); 
 
static void TopMatch( 
float 	match[MAX_NUM_ADAPT],  
int 	MinDelayPtr,  
int 	MaxDelayPtr,  
int 	*BestDelayPtr); 
 
static void SelectDelay( 
int 	*BestDelayPtr,  
int 	SubMult[256][4],  
float 	match[MAX_NUM_ADAPT],  
int 	MinDelayPtr,  
int 	MaxDelayPtr); 
 
static void Neighborhood( 
float 	lp_imp[SF_LEN],  
float 	residual[RES_LEN],  
float 	match[MAX_NUM_ADAPT],  
int 	MinDelayPtr,  
int 	MaxDelayPtr,  
float	DelayTable[], 
float 	AdaptCB[MAX_ABUF_LEN],  
int 	*BestDelayPtr,  
float 	gain[MAX_NUM_ADAPT]); 
 
static void CalcIntAdaptParms( 
float	AdaptCB[MAX_ABUF_LEN], 
float	pc_imp[SF_LEN], 
int	MinDelayPtr, 
int	MaxDelayPtr, 
float	DelayTable[MAX_NUM_ADAPT], 
float	residual[RES_LEN], 
float	gain[MAX_NUM_ADAPT], 
float	match[MAX_NUM_ADAPT]); 
 
static void CalcFracAdaptParms( 
float	AdaptCB[MAX_ABUF_LEN], 
float	pc_imp[SF_LEN], 
int	MinDelayPtr, 
int	MaxDelayPtr, 
float	DelayTable[MAX_NUM_ADAPT], 
float	residual[RES_LEN], 
float	gain[MAX_NUM_ADAPT], 
float	match[MAX_NUM_ADAPT]); 
 
static void FindAdaptResidual( 
float	speech[SF_LEN], 
float	AdaptCB[MAX_ABUF_LEN], 
float	pc[ORDER+1], 
float	AdaptGain, 
float	AdaptDelay, 
float	residual[RES_LEN]); 
 
/* 
 
*************************************************************************** 
*                                                                         * 
* ROUTINE 
*		AdaptiveAnalysis 
* 
* FUNCTION 
*		Subframe adaptive codebook search 
* SYNOPSIS 
*		AdaptiveAnalysis(speech_in, pc, h, AdaptCB,  
*			residual_in, AdaptDelay, AdaptGain, residual_out) 
* 
*   formal 
* 
*                       data    I/O 
*       name            type    type    function 
*       ------------------------------------------------------------------- 
*	SpeechIn	float	 i	Subframe of speech 
*	pc		float	 i	Predictor Coefficients (PCs) 
*	pc_imp		float	 i	Impulse response of PCs 
*	AdaptCB		float	 i	Adaptive codebook vector 
*	residual_in	float	 i	Residual from LPC analysis 
*	AdaptDelay	float	 o	pitch delay parameter to TX 
*	AdaptGain	float	 o	pitch gain parameter to TX 
*	residual_out	float	 o	residual remaining after comparison 
* 
**************************************************************************/ 
 
void AdaptiveAnalysis( 
float 	SpeechIn[SF_LEN],  
float 	pc[ORDER],  
float 	pc_imp[SF_LEN],  
float 	AdaptCB[MAX_ABUF_LEN],  
float 	residual_in[RES_LEN],  
float 	*AdaptDelay,  
float 	*AdaptGain,  
float 	residual_out[RES_LEN]) 
{ 
	float	match[MAX_NUM_ADAPT], gain[MAX_NUM_ADAPT]; 
	int	MaxDelayPtr, MinDelayPtr, BestDelayPtr; 
static 	int	even=FALSE, PrevDelayPtr=1, first=TRUE; 
	int	index; 
	float	TempAdaptCB[B_PTR]; 
#ifdef NEW_ACB 
	int	i, Delay; 
	float	pcexp[ORDER+1];    /* !!OUTOFBOUNDS!! without the '+1' */ 
#endif 
 
/*  Update temporary adaptive codebook */ 
	SetArray(B_PTR, 0.0, TempAdaptCB); 
	MoveArray(ACB_SIZE, AdaptCB, &TempAdaptCB[B_PTR-(ACB_SIZE)-SF_LEN]); 
 
/*  Set up initial conditions on first subframe */ 
	if (first)	{ 
	  first = FALSE; 
	  *AdaptGain = 0.0; 
	  *AdaptDelay = MIN_DELAY; 
	} 
 
/*  Calculate adaptive gain and delay for subsequent subframes */ 
	else	{ 
 
   
/*  Determine allowable pointer range for full/delta searches on */ 
/*	even/odd subframes */ 
	  CalcPointers(even, PrevDelayPtr, &MinDelayPtr, &MaxDelayPtr); 
 
/*  Initialize arrays */ 
	  SetArray(MAX_NUM_ADAPT, 0.0, match); 
	  SetArray(MAX_NUM_ADAPT, 0.0, gain); 
 
/*  Calculate gain and match scores for integer adaptive delays */ 
	  CalcIntAdaptParms(TempAdaptCB, pc_imp, MinDelayPtr, MaxDelayPtr,  
		DelayTable, residual_in, gain, match); 
 
	  if (fraction) 
/*  Calculate gain and match scores for fractional delays */ 
	    CalcFracAdaptParms(TempAdaptCB, pc_imp, MinDelayPtr, MaxDelayPtr,  
		DelayTable, residual_in, gain, match); 
 
/*  Determine top match score from those computed */ 
	  TopMatch(match, MinDelayPtr, MaxDelayPtr, &BestDelayPtr); 
 
/*  Select shortest delay */ 
	  if(!even) 
	    SelectDelay(&BestDelayPtr, submult, match, MinDelayPtr,  
		MaxDelayPtr); 
 
	  if(neigh)	{ 
/*  Find best neighborhood match */ 
	    Neighborhood(pc_imp, residual_in, match, MinDelayPtr, MaxDelayPtr,  
		DelayTable, TempAdaptCB, &BestDelayPtr, gain); 
	  } 
 
/*  Assign pitch (adaptive codebook) parameters */ 
	  *AdaptGain = gain[BestDelayPtr]; 
	  *AdaptDelay = DelayTable[BestDelayPtr]; 
 
/*  Save pointer to detrmine delta delay */ 
	  PrevDelayPtr = BestDelayPtr; 
 
/*  Encode adaptive gain (quantize) */ 
	  *AdaptGain = ACBGainEncode(*AdaptGain, &index); 
 
#ifdef NEW_ACB 
/*  ACB contribution to LP Impulse Response */ 
	  if(*AdaptDelay < SF_LEN)	{ 
/*  Lay out pulses at multiples of the pitch period	*/ 
	    Delay = (int)(*AdaptDelay); 
	    SetArray(SF_LEN, 0.0, pc_imp); 
	    pc_imp[0] = 1.0; 
	    for(i=Delay;i NUM_FULL_ADELAYS-1)	{ 
	    *MaxDelayPtr = NUM_FULL_ADELAYS - 1; 
	    *MinDelayPtr = NUM_FULL_ADELAYS - NUM_DELTA_ADELAYS; 
	  } 
	} 
/*  Full range coding on odd subframes */ 
	else	{ 
	  *MinDelayPtr = 0; 
	  *MaxDelayPtr = NUM_FULL_ADELAYS - 1; 
	} 
 
} 
 
/* 
 
************************************************************************* 
*                                                                         * 
* ROUTINE 
*		TopMatch 
* 
* FUNCTION 
*		Find pointer to top (MSPE) match score (BestDelayPtr) 
*		search for best match score (max -error term) 
* SYNOPSIS 
*		TopMatch(match, MinDelayPtr, MaxDelayPtr, BestDelayPtr) 
* 
*   formal 
* 
*                       data    I/O 
*       name            type    type    function 
*       ------------------------------------------------------------------- 
*	match		float	 i	Match score array 
*	MinDelayPtr	int	 i	Pointer to minimum delay to search 
*	MaxDelayPtr	int	 i	Pointer to maximum delay to search 
*	BestDelayPtr	int	 o	Pointer to best delay 
* 
**************************************************************************/ 
 
void TopMatch( 
float 	match[MAX_NUM_ADAPT],  
int 	MinDelayPtr,  
int 	MaxDelayPtr,  
int 	*BestDelayPtr) 
{ 
int	i; 
float	emax; 
 
	*BestDelayPtr = MinDelayPtr; 
 
	emax = match[*BestDelayPtr]; 
 
	for(i=MinDelayPtr; i<=MaxDelayPtr; i++)	{ 
	  if (match[i] > emax)	{ 
	    *BestDelayPtr = i; 
	    emax = match[*BestDelayPtr]; 
	  } 
	} 
} 
 
/* 
 
************************************************************************* 
*                                                                         * 
* ROUTINE 
*		SelectDelay 
* 
* FUNCTION 
*		Select shortest delay of 2, 3, or 4 submultiples 
*		if its match is within 1 dB of MSPE to favor 
		smooth "pitch" 
* SYNOPSIS 
*		SelectDelay(BestDelayPtr, SubMult, match,  
*		              MinDelayPtr, MaxDelayPtr) 
* 
*   formal 
* 
*                       data    I/O 
*       name            type    type    function 
*       ------------------------------------------------------------------- 
*	BestDelayPtr	int	i/o	Pointer to delay with top match score 
*	SubMult		int	 i	Sumbmultiples array 
*	match		float	 i	Match score array for each delay 
*	MinDelayPtr	int	 i	Pointer to minimum delay to search 
*	MaxDelayPtr	int	 i	Pointer to maximum delay to search 
* 
**************************************************************************/ 
void SelectDelay( 
int 	*BestDelayPtr,  
int 	SubMult[256][4],  
float 	match[MAX_NUM_ADAPT],  
int 	MinDelayPtr,  
int 	MaxDelayPtr) 
{ 
int	i; 
int	SubMultPtr, BigPtr; 
int	Best; 
 
/*  Initialize */ 
	Best = *BestDelayPtr; 
 
/*  For each submultiple (2, 3, & 4) */ 
	for(i=1; i<=SubMult[*BestDelayPtr][0]; i++)	{ 
 
/*  Find best neighborhood match for given submultiple */ 
	  BigPtr = SubMult[*BestDelayPtr][i]; 
	  for(SubMultPtr = max(SubMult[*BestDelayPtr][i]-8, MinDelayPtr); 
		SubMultPtr <= min(SubMult[*BestDelayPtr][i]+8, MaxDelayPtr);  
		SubMultPtr++)	{ 
	    if(match[SubMultPtr] > match[BigPtr]) 
	      BigPtr = SubMultPtr; 
	  } 
 
/*  Select submultiple match if within 1 dB MSPE match */ 
	  if(match[BigPtr] >= (0.88*match[*BestDelayPtr])) 
	    Best = BigPtr; 
 
	} 
 
	*BestDelayPtr = Best; 
} 
 
/* 
 
************************************************************************* 
*                                                                         * 
* ROUTINE 
*		Neighborhood 
* 
* FUNCTION 
*		Search BestDelayPtr's neighboring delays (to be used with  
*		earlier stages of searching).  Find gain and match  
*		score for neighboring delays and find best neighborhood  
*		match (could use end-point correction on unity spaced delays) 
* SYNOPSIS 
*		Neighborhood(lp_imp, residual, match, MinDelayPtr, MaxDelayPtr 
				DelayTable, AdaptCB, BestDelayPtr, gain) 
* 
*   formal 
* 
*                       data    I/O 
*       name            type    type    function 
*       ------------------------------------------------------------------- 
*	lp_imp		float	 i	LP impulse response 
*	residual	float	 i	Residual from LPC analysis 
*	match		float	 i	Adaptive Codebook match score array 
*	MinDelayPtr	int	 i	Pointer to minimum delay to search 
*	MaxDelayPtr	int	 i	Pointer to maximum delay to search 
*	DelayTable	float	 i	Table of integer and fractional delays 
*	AdaptCB		float	 i	Adaptive codebook 
*	BestDelayPtr	int	 o	Pointer to best delay 
*	gain		float	 o	Adaptive Codebook gain array 
* 
**************************************************************************/ 
void Neighborhood( 
float 	lp_imp[SF_LEN],  
float 	residual[RES_LEN],  
float 	match[MAX_NUM_ADAPT],  
int 	MinDelayPtr,  
int 	MaxDelayPtr,  
float	DelayTable[], 
float 	AdaptCB[MAX_ABUF_LEN],  
int 	*BestDelayPtr,  
float 	gain[MAX_NUM_ADAPT]) 
{ 
int	i; 
int	BigPtr; 
int	IntDelay; 
float	FracDelay; 
float	AdaptCBShift[MAX_A_LEN]; 
 
	BigPtr = *BestDelayPtr; 
 
	for(i=max(*BestDelayPtr - NeighborhoodRange, MinDelayPtr);  
		i<=min(*BestDelayPtr + NeighborhoodRange, MaxDelayPtr); i++){ 
	  if (i != *BestDelayPtr)	{ 
	    IntDelay = (int)(DelayTable[i]); 
	    FracDelay = DelayTable[i] - IntDelay; 
	    if(fabs(FracDelay) < .0001)	 
/*	      CalcACBParms(&AdaptCB[START - IntDelay-1], SF_LEN, lp_imp,  
		TRUE, IntDelay, LEN_TRUNC_H, residual, &match[i], &gain[i]); 
*/; 
	    else	{ 
	      delay(AdaptCB, B_PTR, START, SF_LEN, FracDelay, IntDelay, -4, 3,  
		5,  &AdaptCBShift[0]); 
	      CalcACBParms(AdaptCBShift, SF_LEN, lp_imp, TRUE, 69,  
		LEN_TRUNC_H, residual, &match[i], &gain[i]); 
	    } 
	    if (match[i] > match[*BestDelayPtr]) 
	      BigPtr = i; 
	  } 
	} 
	 
	*BestDelayPtr = BigPtr; 
} 
 
/* 
 
************************************************************************* 
*                                                                          
* ROUTINE 
*		CalcIntAdaptParms 
* 
* FUNCTION 
*		Calculate gain and match score for integer adaptive delays 
* SYNOPSIS 
*		CalcIntAdaptParms(AdaptCB, pc_imp, MinDelayPtr, MaxDelayPtr, *			DelayTable, residual, gain, match) 
* 
*   formal 
* 
*                       data    I/O 
*       name            type    type    function 
*       ------------------------------------------------------------------- 
*	AdaptCB		float	 i	Adaptive Codebook 
*	pc_imp		float	 i	Impulse response of PCs 
*	MinDelayPtr	int	 i	Pointer to minimum delay to search 
*	MaxDelayPtr	int	 i	Pointer to maximum delay to search 
*	DelayTable	float	 i	Adaptive delay coding table 
*	residual	float	 i	Residual from LPC analysis 
*	gain		float	 o	Gain array 
*	match		float	 o	Match score array 
* 
************************************************************************** 
* 
*	Uses end-point correction on unity spaced delays 
* 
**************************************************************************/ 
void CalcIntAdaptParms( 
float	AdaptCB[MAX_ABUF_LEN], 
float	pc_imp[SF_LEN], 
int	MinDelayPtr, 
int	MaxDelayPtr, 
float	DelayTable[MAX_NUM_ADAPT], 
float	residual[RES_LEN], 
float	gain[MAX_NUM_ADAPT], 
float	match[MAX_NUM_ADAPT]) 
{ 
int	first = TRUE; 
int	IntDelay; 
float	FracDelay; 
int	i; 
 
 
	for(i=MinDelayPtr;i<=MaxDelayPtr;i++)	{ 
	  IntDelay = (int)(DelayTable[i]); 
	  FracDelay = DelayTable[i] - IntDelay; 
	  if (fabs(FracDelay) < .0001)	{ 
	    CalcACBParms(&AdaptCB[START - IntDelay-1], SF_LEN, pc_imp, 
		first,IntDelay, LEN_TRUNC_H, &residual[0], &match[i], &gain[i]); 
	    first = FALSE; 
	  } 
	  else 
	    match[i] = 0.0; 
	} 
 
} 
/* 
 
************************************************************************* 
*                                                                         * 
* ROUTINE 
*		CalcFracAdaptParms 
* 
* FUNCTION 
*		Calculate gain and match score for fractional adaptive delays 
* SYNOPSIS 
*		CalcFracAdaptParms(AdaptCB, pc_imp, MinDelayPtr, MaxDelayPtr,  
*			DelayTable, residual, gain, match) 
* 
*   formal 
* 
*                       data    I/O 
*       name            type    type    function 
*       ------------------------------------------------------------------- 
*	AdaptCB		float	 i	Adaptive Codebook 
*	pc_imp		float	 i	Impulse response of PCs 
*	MinDelayPtr	int	 i	Minimum delay pointer to search 
*	MaxDelayPtr	int	 i	Maximum delay pointer to search 
*	DelayTable	float	 i	Adaptive delay coding table 
*	residual	float	 i	Residual from LPC analysis 
*	gain		float	 o	Gain array 
*	match		float	 o	Match score array 
* 
************************************************************************** 
* 
*	Uses end-point correction on unity spaced delays 
* 
**************************************************************************/ 
void CalcFracAdaptParms( 
float	AdaptCB[MAX_ABUF_LEN], 
float	pc_imp[SF_LEN], 
int	MinDelayPtr, 
int	MaxDelayPtr, 
float	DelayTable[MAX_NUM_ADAPT], 
float	residual[RES_LEN], 
float	gain[MAX_NUM_ADAPT], 
float	match[MAX_NUM_ADAPT]) 
{ 
int	IntDelay; 
double	FracDelay; 
int	i; 
float	AdaptCBShift[MAX_A_LEN]; 
 
 
	for(i=MinDelayPtr;i<=MaxDelayPtr;i++)	{ 
	  IntDelay = (int)(DelayTable[i]); 
	  FracDelay = DelayTable[i] - IntDelay; 
	  if (fabs(FracDelay) >= .0001)	{ 
	    delay(AdaptCB, B_PTR, START, SF_LEN, FracDelay, IntDelay, -4, 3, 5,  
			AdaptCBShift); 
	    CalcACBParms(AdaptCBShift, SF_LEN, pc_imp, 1, 69, LEN_TRUNC_H,  
			residual, &match[i], &gain[i]); 
	  } 
	} 
 
} 
/* 
 
************************************************************************* 
*                                                                         * 
* ROUTINE 
*		FindAdaptResidual 
* 
* FUNCTION 
*		Find residual after adaptive analysis 
* SYNOPSIS 
*		FindAdaptResidual(speech, AdaptCB, pc, AdaptGain, AdaptDelay,  
*			residual) 
* 
*   formal 
* 
*                       data    I/O 
*       name            type    type    function 
*       ------------------------------------------------------------------- 
*	speech		float	 i	Subframe of input speech 
*	AdaptCB		float	 i	Adaptive Codebook vector 
*	pc		float	 i	Subframe of interpolated predictor 
*					coefficients 
*	AdaptGain	float 	 i	Adaptive codebook gain 
*	AdaptDelay	float	 i	Adaptive codebook delay 
*	residual	float	 o	Adaptive residual 
* 
**************************************************************************/ 
 
void FindAdaptResidual( 
float	speech[SF_LEN], 
float	AdaptCB[MAX_ABUF_LEN], 
float	pc[ORDER+1], 
float	AdaptGain, 
float	AdaptDelay, 
float	residual[RES_LEN]) 
{ 
int	i; 
float	pcexp[ORDER+1]; 
 
/*  Initialize residual */ 
	SetArray(RES_LEN, 0.0, residual); 
 
/*  Adaptive Codebook Synthesis */ 
	ConstructAdaptCW(residual, SF_LEN, AdaptCB, ACB_SIZE, AdaptGain,  
		AdaptDelay, "long"); 
 
/*  LP Filter */ 
	do_pfilt_dynamic(&Adapt_ResP, pc, residual); 
 
/*  Calculate Residual */ 
	for(i=0;i