www.pudn.com > WCDMA.rar > GenRxRootRaisedCosine.cpp


#include  
#include  
#include  
#include  
#include "mex.h" 
 
#define PI 3.14159265358979 
 
void GenRootRaisedCosine(int , int ,unsigned ,double ,double ,double * ,double * ,unsigned ); 
 
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
/*************************************************************************************** 
* void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
* 
* Copyright 2002 The Mobile and Portable Radio Research Group 
* 
* Gateway function for GenRxRootRaisedCosine.  Supports that passing of five input parameters 
* and two output parameters.  The five input parameters are 
*		Lower Bound			Determines the minimum limit of the truncated  
*							impulse response normalized by symbol period 
*		Upper Bound			Determines the maximum limit of the truncated  
*							impulse response normalized by symbol period 
*		SampleRate			The number of samples per symbol duration 
*		RollOff				Rolloff of the Filter.  Must not exceed 1 
*		SymbolPeriod		Symbol Duration (in seconds) 
* 
* The two output parameters are 
*		Pulse					Impulse response 
*		t_index					Time index 
***************************************************************************************/ 
{ 
	int MexLBound,MexUBound,PLength; 
	unsigned MexSamplesPerSymbol; 
	double MexRollOff,MexSymbolPeriod; 
	int mrows,ncols; 
	double dbleScale,fraction,integer_portion; 
	double *pulse,*TimeIndex; 
	const mxArray *tprhs; 
	 
	 
	//Check for the proper number of input and output arguments 
	if (nrhs != 5) mexErrMsgTxt("\nExactly FIVE input arguemnts are required!!\n"); 
	else if (nlhs != 2 ) mexErrMsgTxt("\nExactly TWO output arguements are required!!\n"); 
 
	//All Inputs must be scalars 
	//Lower Bound 
	tprhs = *prhs; 
	mrows = mxGetM(tprhs); 
	ncols = mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || !(mrows ==1 && ncols ==1)) 
		mexErrMsgTxt("\nLowerBoundT must be a noncomplex scalar\n"); 
	MexLBound = (int) mxGetScalar(tprhs); 
 
 
	//Upper Bound 
	tprhs = *(prhs+1); 
	mrows = mxGetM(tprhs); 
	ncols = mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || !(mrows ==1 && ncols ==1)) 
		mexErrMsgTxt("\nUpperBoundT must be a noncomplex scalar\n"); 
	MexUBound = (int) mxGetScalar(tprhs); 
 
	//SampleRate 
	tprhs = *(prhs+2); 
	mrows = mxGetM(tprhs); 
	ncols = mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || !(mrows ==1 && ncols ==1)) 
		mexErrMsgTxt("\nSamples Per Symbol must be a noncomplex scalar\n"); 
	dbleScale=mxGetScalar(tprhs); 
	fraction=modf(dbleScale,&integer_portion); 
	if (integer_portion <= 0.0) mexErrMsgTxt("\nMexSamplesPerSymbol must be positive\n"); 
	MexSamplesPerSymbol = (unsigned) integer_portion; 
	if (fraction != 0) mexErrMsgTxt("\nMexSamplesPerSymbol must be an integer\n"); 
 
	//RollOff 
	tprhs = *(prhs+3); 
	mrows = mxGetM(tprhs); 
	ncols = mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || !(mrows ==1 && ncols ==1)) 
		mexErrMsgTxt("\nSamples Per Symbol must be a noncomplex scalar\n"); 
	MexRollOff=mxGetScalar(tprhs); 
	if ((MexRollOff <= 0.0) || (MexRollOff > 1.0)) mexErrMsgTxt("\nMexRollOff must be between 0 and 1\n"); 
 
	//Symbol Period 
	tprhs = *(prhs+4); 
	mrows = mxGetM(tprhs); 
	ncols = mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || !(mrows ==1 && ncols ==1)) 
		mexErrMsgTxt("\nSamples Per Symbol must be a noncomplex scalar\n"); 
	MexSymbolPeriod=mxGetScalar(tprhs); 
	if (MexRollOff <= 0.0)  mexErrMsgTxt("\nSample Period must be positive\n"); 
 
	PLength = (MexUBound - MexLBound) * (int) MexSamplesPerSymbol + 1; 
	*plhs = mxCreateDoubleMatrix( PLength,1,mxREAL); 
	*(plhs+1) = mxCreateDoubleMatrix( PLength,1,mxREAL); 
	pulse = mxGetPr(*plhs); 
	TimeIndex = mxGetPr(*(plhs+1)); 
	//Call Root Raised Cosine function 
	GenRootRaisedCosine(MexLBound, MexUBound,MexSamplesPerSymbol,MexRollOff, MexSymbolPeriod,pulse,TimeIndex,PLength); 
	 
 
} 
 
 
 
 
 
void GenRootRaisedCosine(int LowerBoundT, int UpperBoundT,unsigned SamplesPerSymbol,double RollOff,double SymbolPeriod,double *filter,double *t_index,unsigned NumSamples) 
/****************************************************************************************** 
/ void GenRootRaisedCosine(int LowerBoundT, int UpperBoundT,unsigned SamplesPerSymbol, 
/      double RollOff,double SymbolPeriod,double *filter,double *t_index,unsigned NumSamples) 
/ 
/ Copyright 2002 The Mobile and Portable Radio Research Group 
/ 
/ GenRootRaisedCosine produces the impulse response of a root raised cosine filter and 
/ stores it in an array.  Note that the impulse of a root raised cosine filter ranges 
/ from -infinity to infinity.  It is therefore necessary to truncated from LowerBoundT to 
/ UperBountT. 
/ 
/ Parameters 
/   Input 
/      LowerBoundT        Determines the minimum limit of the truncated imulse response 
/                         normalized by symbol period 
/      UpperBoundT        Determines the maximum limit of the truncated imulse response 
/                         normalized by symbol period 
/      SamplesPerSymbol   The number of samples per symbol duration 
/      RollOff            Rolloff of the Filter.  Must not exceed 1 
/      SymbolPeriod       Symbol Duration (in seconds) 
/  
/   Output 
/      *filter            Pointer ot an array that contains the filter impulse response 
/      *t_index           Pointer ot an array that contains the associated time. 
/      NumSamples         Length of the output array 
/ 
/******************************************************************************************/ 
{ 
	double *filter_temp,*t_temp;	//Temporary pointers for *filter and *t_index 
	double cos_arg;					//Stores arguement to cosine funciton 
	double bottom_arg;				//Stores non-trivial term in the denominator 
	double coeff;					//Stores the normalizing coefficient 
	double SampleDuration;			//Stores the sample period 
	int k; 
	//Determine Array length 
	NumSamples = (UpperBoundT-LowerBoundT)*SamplesPerSymbol+1; 
 
	 
	//Compute impulse response 
	SampleDuration = SymbolPeriod/SamplesPerSymbol; 
	coeff = (4.0 * RollOff * sqrt(SampleDuration)) / (PI * sqrt(SymbolPeriod)); 
 
    t_temp=t_index; 
	filter_temp=filter; 
	for (k=0; k< (int) NumSamples;k++) 
	{ 
		//Compute time index 
		*t_temp=(LowerBoundT * SymbolPeriod) + (k * SampleDuration); 
		if (*t_temp == double (0.0)) *t_temp = 1e-20; 
		cos_arg = (1 + RollOff) * (PI * *t_temp / SymbolPeriod); 
//		sin_arg = (1 - RollOff) * (PI * *t_temp / SymbolPeriod); 
		bottom_arg = (double) 4.0 * RollOff * *t_temp / SymbolPeriod; 
		t_temp++; 
		*filter_temp++ = coeff * (cos(cos_arg) ) / (1 - (bottom_arg * bottom_arg)); 
	} 
}