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


/* Copyright 2001,2002,2003 NAH6 
 * All Rights Reserved 
 * 
 * Parts Copyright DoD, Parts Copyright Starium 
 * 
 */ 
#include  
#include "main.h" 
#include "acb_parm.h" 
 
static void CalcAdaptConv( 
float	pc_imp[], 
int	len_trunc, 
float	Exc[], 
int	Exc_len, 
float	conv[]); 
 
static void EndCorrectAdapt( 
float	conv[], 
float	Exc[], 
int	Exc_len, 
float	pc_imp[], 
int	len_trunc); 
 
static void ReplicateShortToFull( 
int	Exc_len, 
int	delay, 
float	Conv[], 
float	FullConv[]); 
 
static void CalcCorEngAdapt( 
float	y2[MAX_A_LEN], 
float	residual[RES_LEN], 
int	ex_len, 
float	*cor, 
float	*eng); 
 
static void CompGainErrAdapt( 
float	correlation, 
float	energy, 
float	*gain, 
float	*match); 
 
/* 
 
************************************************************************* 
* 
* ROUTINE 
*		CalcACBParms 
* 
* FUNCTION 
*		Find ACB gain and error (match score) 
* 
* SYNOPSIS 
*               CalcACBParms(Exc, Exc_len, pc_imp, first, delay, trunc_len,  
*			residual, gain, match) 
* 
*   formal  
* 
*                       data    I/O 
*       name            type    type    function 
*       ------------------------------------------------------------------- 
*       Exc		float	i	excitation vector 
*       Exc_len		int	i	size of ex 
*	pc_imp		float	i	impulse response of PCs 
*       first		int	i	first call flag 
*	delay		int	i	pitch lag 
*	trunc_len	int	i	length to truncate impulse response 
*	residual	float	i	residual from LPC analysis 
*       match		float	o	negative partial squared error 
*	gain		float	o	optimal gain for excitation vector 
* 
*========================================================================== 
*	 
* DESCRIPTION 
* 
* (The calculations below may be valid for version 3.2, but may not be  
*  correct for version 3.3). 
* 
*	For each delay: 
*	   a.  Filter excitation vector through truncated 
*	       impulse response of perceptual weighting filter 
*	       (LPC filter with bandwidth broadening). 
*	   b.  Correlate filtered result with residual 
*	   c.  Compute first order pitch filter coefficient (gain) 
*	       and error (match) for each lag. 
* 
*	Note:  Proper selection of the convolution length depends on 
*	       the perceptual weighting filter's expansion factor (gamma) 
*	       which controls the damping of the impulse response. 
* 
*	        This is one of CELP's most computationally intensive 
*	        routines.  Neglecting overhead, the approximate number of 
*		DSP instructions (add, multiply, multiply accumulate, or 
*		compare) per second (IPS) is: 
* 
*	        C:  convolution (recursive truncated end-point correction) 
*               C': convolution (recursive truncated end-point correction) 
*               R = E:  full correlation & energy 
*               R'= E': delta correlation & energy 
*               G:      gain quantization 
*               G':     delta gain quantization 
* 
*	        IPS = 2.34 M (for integer delays) 
* 
*	ACB search complexity for integer delays: 
*	implicit undefined(a-z) 
* 
*	DSP chip instructions/operation: 
*	integer MUL, ADD, SUB, MAC, MAD, CMP 
*	parameter (MUL=1)	!multiply 
*	parameter (ADD=1)	!add 
*	parameter (SUB=1)	!subtract 
*	parameter (MAC=1)	!multiply & accumulate 
*	parameter (MAD=2)	!multiply & add 
*	parameter (CMP=1)	!compare 
* 
*	CELP algorithm parameters: 
*	integer L, len, K, Kp, Np, dmin 
*	real F 
*	parameter (L=60)	!subframe length 
*	parameter (len=30)	!length to truncate calculations (<= L) 
*	parameter (K=2)		!number of full search subframes 
*	parameter (Kp=2)	!number of delta search subframes 
*	parameter (F=30.e-3)	!time (seconds)/frame 
*	parameter (Np=32)	!number of delta subframe delays 
*	parameter (dmin=20)	!minimum delay 
* 
*	integer j 
*	parameter (j=4) 
*	integer N(j), i 
*	real C, R, E, G, Cp, Rp, Ep, Gp, IPS 
*	data N/32, 64, 128, 256/ 
*	print 1 
*1	format(10x,'N',10x,'C',13x,'R',12x,'E',15x,'G',13x,'MIPS') 
*	do i = 1, j 
*	   C = (len*(len+1)/2 + len*len)*MAC + (N(i)-1)*len*MAD 
C     &	     + min(L-dmin,N(i))*(L-dmin)*ADD + (L/2-dmin)*(L-2*dmin)*ADD 
C	   Cp= (len*(len+1)/2 + len*len)*MAC + (Np-1)*len*MAD 
C     &	     + min(L-dmin,Np)*(L-dmin)*ADD + (L/2-dmin)*(L-2*dmin)*ADD 
C	   R = N(i)*L*MAC 
C	   Rp= Np*L*MAC 
C	   E = R 
C	   Ep= Rp 
C	   G = N(i)*(1*CMP+1*MUL + 1*MUL) 
C	   Gp= Np*(1*CMP+1*MUL + 1*MUL) 
C	   IPS = ((C+R+E+G)*K + (Cp+Rp+Ep+Gp)*Kp)/F 
C	   print *,N(i),C*K/1.e6/F,R*K/1.e6/F,E*K/1.e6/F,G*K/1.e6/F,IPS/1.e6 
C	   print *,Np,Cp*Kp/1.e6/F,Rp*Kp/1.e6/F,Ep*Kp/1.e6/F,Gp*Kp/1.e6/F 
C	end do 
C	end 
C 
C  N          C             R            E               G             MIPS 
C  32  0.3136667      0.1280000      0.1280000      6.4000003E-03   1.152133     
C  32  0.3136667      0.1280000      0.1280000      6.4000003E-03 
C  64  0.4630000      0.2560000      0.2560000      1.2800001E-02   1.563867     
C  32  0.3136667      0.1280000      0.1280000      6.4000003E-03 
C 128  0.7190000      0.5120000      0.5120000      2.5600001E-02   2.344667     
C  32  0.3136667      0.1280000      0.1280000      6.4000003E-03 
C 256   1.231000       1.024000       1.024000      5.1200002E-02   3.906267     
C  32  0.3136667      0.1280000      0.1280000      6.4000003E-03 
C 
************************************************************************** 
* 
*	Compute gain and error: 
*	  NOTE: Actual MSPE = e0.e0 - gain(2*correlation-gain*energy) 
*		since e0.e0 is independent of the code word, 
*		minimizing MSPE is equivalent to maximizing: 
*		     match = gain(2*correlation-gain*energy)   (1) 
*		If unquantized gain is used, this simplifies: 
*		     match = correlation*gain 
* 
*	  NOTE: Inferior results were obtained when quantized 
*		gain was used in equation (1)??? 
* 
*	  NOTE: When the delay is less than the frame length, "match" 
*	        is only an approximation to the actual error. 
* 
*	Independent (open-loop) quantization of gain and match (index): 
 
***************************************************************************/ 
 
void CalcACBParms( 
float 	Exc[], 
int	Exc_len, 
float	pc_imp[], 
int	first, 
int	delay, 
int	trunc_len, 
float	residual[RES_LEN], 
float	*match, 
float	*gain) 
{ 
static	float	Conv1[MAX_A_LEN]; 
	float 	FullConv[MAX_A_LEN]; 
	float	correlation, energy; 
 
	if (first)	{ 
 
/*  Calculate and save convolution of truncated impulse response 
	for first delay  */ 
	  CalcAdaptConv(pc_imp, trunc_len, Exc, Exc_len, Conv1); 
 
	} 
	else	{ 
 
/*  End correct the convulution sum on subsequent delays */ 
	  EndCorrectAdapt(Conv1, Exc, Exc_len, pc_imp, trunc_len); 
	} 
 
/*  For lags shorter than frame size, replicate the short adaptive codeword  
	to the full codeword length */ 
	ReplicateShortToFull(Exc_len, delay, Conv1, FullConv); 
 
/*  Calculate Correlation and Energy */ 
	CalcCorEngAdapt(FullConv, residual, Exc_len, &correlation, &energy); 
 
/*  Compute gain and match score */ 
	CompGainErrAdapt(correlation, energy, gain, match); 
 
 
 
} 
/* 
 
************************************************************************* 
*                                                                          
* ROUTINE 
*		CalcAdaptConv 
* 
* FUNCTION 
*		Calculate and save convolution of truncated impulse  
*		response. 
* SYNOPSIS 
*		CalcAdaptConv(pc_imp, len_trunc, Exc, Exc_len, conv); 
* 
*   formal 
* 
*                       data    I/O 
*       name            type    type    function 
*       ------------------------------------------------------------------- 
*	pc_imp		float	 i	Impulse response of PCs 
*	len_trunc	int	 i	Length to truncate impulse response 
*       Exc		float	 i	Excitation vector 
*	Exc_len		int	 i	Lenght of excitation vector 
*	conv		float	 o	Truncated convolved impulse response 
* 
************************************************************************** 
	   Calculate and save convolution of truncated (to len) 
	   impulse response for first lag of t (=mmin) samples: 
 
	        min(i, len) 
	   y     =  SUM  h * ex       , where i = 1, ..., L points 
	    i, t    j=1   j    i-j+1 
 
	              h |1 2...len x x| 
	   ex |L . . . 2 1|             = y(1) 
	     ex |L . . . 2 1|           = y(2) 
	                   :              : 
	             ex |L  . . .  2 1| = y(L) 
**************************************************************************/ 
 
void CalcAdaptConv( 
float	pc_imp[], 
int	len_trunc, 
float	Exc[], 
int	Exc_len, 
float	conv[]) 
{ 
int	i, j; 
 
/*  Calculate convolution */ 
	for(i=0;i=1;i--)	{ 
	  conv[i-1] += Exc[0] * pc_imp[i]; 
	} 
	 
	for(i=Exc_len;i>=1;i--)	{ 
	  conv[i] = conv[i-1]; 
	} 
 
	conv[0] = Exc[0] * pc_imp[0]; 
} 
/* 
 
************************************************************************* 
*                                                                         * 
* ROUTINE 
*		ReplicateShortToFull 
* FUNCTION 
*		Replicate the short adaptive codeword to the full codeword  
*		length  
* SYNOPSIS 
*		ReplicateShortToFull(Exc_len, delay, Conv, FullConv) 
* 
*   formal 
* 
*                       data    I/O 
*       name            type    type    function 
*       ------------------------------------------------------------------- 
*	Exc_len		int	 i	Length of excitation vector 
*	delay		int	 i	Pitch lag 
*	Conv		float	 i	Truncated convolved impulse response 
*	FullConv	float	 o	Replicated convolved impulse response 
* 
**************************************************************************/ 
 
void ReplicateShortToFull( 
int	Exc_len, 
int	delay, 
float	Conv[], 
float	FullConv[]) 
{ 
int 	i; 
 
	for(i=0;i