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


#include  
#include  
#include  
#include  
#include  
#include "C:\MATLABR11\extern\include\mex.h" 
#include "MAI_Mpath_Channel.cpp" 
#include "ScrambleLong1.cpp" 
#include "GenUplinkSignal.cpp" 
 
 
#define CHIPS_PER_FRAME	38400 
#define CONTROL_BITS	150 
 
extern void scramble_long(unsigned long, short int *, short int *); 
extern void GenWCDMAUplinkSignal(double *,double *,double *,double *, 
	  					         double *,double *,unsigned ,double *,unsigned , 
						         unsigned ,double *,double *,unsigned ); 
extern void MAI_Mpath_Channel(double * ,double *,unsigned long, 
						      unsigned long * ,unsigned long ,double *,double ,unsigned long , 
						      double *,double *); 
 
void MAI_Processor(double *, double *, unsigned long, double *, double *, 
				   unsigned long, const mxArray *, unsigned, unsigned long *, 
				   unsigned long, double *, double *, unsigned, double,  
				   unsigned, unsigned, unsigned, double *, double *,  
				   unsigned long, double *, double *, unsigned long,bool); 
 
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 MAI_Processor.  Supports the passing of seven or nine input  
* parameters and two output parameters.  If nine input parameters are passed, then the  
* funciton assumes that the parameters for describing a a multipath channel are passed.   
* In this case the multipath channel is applied to the MAI.  If only seven parameters are  
* passed, then the function assumes that the parameters for describing a multipath  
* channel are not passed.  In this case the multipath channel is not applied to the MAI 
* The inpup parameters are 
*		CurrentSignal		Matrix containing the interfering signals associated with  
*							the current frame 
*		LastSignal			Matrix containing the interfering signals associated wit 
*							the previous frame 
*		ChanCode			The Channel Code Matrix 
*		SamplesPerChip		Contains the oversampling factor 
*		PulseShape			Vector containing the imulse response transmitter filter 
*		MaxOffset			The maximum allowable offset for each interferer in ters 
*		MPathDelay			Vector containing the delay (in terms of sample durations) 
*							for each of the multipath components.  This is only needed 
*							to determine the maximum delay, which is necessary to ensure 
*							that the array is of the correct size 
* (Optional Parameters) 
*		MPathAmp			Vector containing the energ in each multipath component 
*		fDoppler			Contains the Doppler rate associated with all multipath  
*							components 
*							of Chips 
* 
* The two output parameters are 
*		MAI_Signal			Matrix containing the MAI signal from each interferer 
*		NextSignal			Matrix containign the interferering signals associated  
*							with the next frame 
***************************************************************************************/ 
{ 
	const mxArray *tprhs,*tplhs; 
	double *mexRealCurrentSigPtr,*mexImagCurrentSigPtr; 
	double *mexRealLastSigPtr,*mexImagLastSigPtr; 
	unsigned long mexNSig; 
	const mxArray *mexChanCodePtr; 
	unsigned mexNumInterferers,mexSF; 
	double *mexDblDelayPtr,*TempDbleDelayPtr; 
	unsigned long *mexDelayPtr,*TempDelayPtr,mexNumDelays; 
	double *mexMPathAmpPtr,mexfDoppler; 
	unsigned mexSamplesPerChip; 
	double *mexPulseShapePtr; 
	unsigned mexPulseLength,mexMaxOffset; 
	double *mexRealNextSigPtr,*mexImagNextSigPtr; 
	double *mexRealMAISigPtr,*mexImagMAISigPtr; 
	unsigned mexMaxDelay; 
	unsigned long mexN_MAISignal; 
	unsigned mrows,ncols,mrowsA,ncolsB; 
	unsigned i; 
	double dbl_value, fraction, integer_portion; 
	bool M_PATH_FLAG; 
 
		//Check for the proper number of input and output arguments 
	if ((nrhs != 9) && (nrhs != 7)) mexErrMsgTxt("\nEither NINE or SEVEN input arguemnts are required!!\n"); 
	else if (nlhs != 2 ) mexErrMsgTxt("\nExactly TWO output arguements arerequired!!\n"); 
 
	//CurrentSignal 
	//Must be a double, complex and a vector or Matrix 
	tprhs = *prhs; 
	mrows = (unsigned) mxGetM(tprhs); 
	ncols = (unsigned) mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || !mxIsComplex(tprhs) || (mrows ==1 && ncols ==1) ) 
		mexErrMsgTxt("\nCurrentSignal must be a complex vector or matrix\n"); 
	mexNumInterferers = mrows; 
	mexNSig = ncols; 
	mexRealCurrentSigPtr = mxGetPr(tprhs); 
	mexImagCurrentSigPtr = mxGetPi(tprhs); 
 
	//LastSignal 
	//Must be a double, complex and a vector or Matrix 
	tprhs = *(prhs+1); 
	mrows = (unsigned) mxGetM(tprhs); 
	ncols = (unsigned) mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || !mxIsComplex(tprhs) || (mrows ==1 && ncols ==1) ) 
		mexErrMsgTxt("\nLastSignal must be a complex vector or matrix\n"); 
	if ( (mrows != mexNumInterferers) || (ncols != mexNSig)) 
		mexErrMsgTxt("\nLastSignal and Current Signal Must have the same dimensions\n"); 
	mexRealLastSigPtr = mxGetPr(tprhs); 
	mexImagLastSigPtr = mxGetPi(tprhs); 
	 
	//ChanCode 
	//Must be a real valued, square matrix 
	tprhs = *(prhs+2); 
	mrows = (unsigned) mxGetM(tprhs); 
	ncols = (unsigned) mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || (mrows ==1 && ncols ==1) || (mrows != ncols)) 
		mexErrMsgTxt("\nChanCode must be a real-valued, square matrix\n"); 
	mexChanCodePtr = tprhs; 
	mexSF = mrows; 
 
	//SamplesPerChip 
	//Must be a dobule, real valued scalar 
	tprhs = *(prhs+3); 
	mrows = (unsigned) mxGetM(tprhs); 
	ncols = (unsigned) mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || (mrows !=1) || (ncols !=1) ) 
		mexErrMsgTxt("\nSampelsPerChip must be a real-valued, scalar\n"); 
	dbl_value=mxGetScalar(tprhs); 
	fraction=modf(dbl_value,&integer_portion); 
	mexSamplesPerChip = (unsigned ) integer_portion; 
	if (fraction != 0) mexErrMsgTxt("\nSamplesPerChip must be an integer\n"); 
 
	//PulseShape 
	//Must be a dobule, real valued vector 
	tprhs = *(prhs+4); 
	mrows = (unsigned) mxGetM(tprhs); 
	ncols = (unsigned) mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || (mrows ==1 && ncols ==1) || ((mrows > 1) && (ncols > 1))) 
		mexErrMsgTxt("\nPulseShape must be a real-valued, vector\n"); 
	if (mrows >= ncols) mexPulseLength = mrows; 
	else mexPulseLength = ncols; 
	mexPulseShapePtr = mxGetPr(tprhs); 
	 
	//MaxOffset 
	//Must be a dobule, real valued scalar 
	tprhs = *(prhs+5); 
	mrows = (unsigned) mxGetM(tprhs); 
	ncols = (unsigned) mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || (mrows !=1) || (ncols !=1) ) 
		mexErrMsgTxt("\nMaxOffset must be a real-valued, scalar\n"); 
	dbl_value=mxGetScalar(tprhs); 
	fraction=modf(dbl_value,&integer_portion); 
	mexMaxOffset = (unsigned) integer_portion; 
	if (fraction != 0) mexErrMsgTxt("\nMaxOffset must be an integer\n"); 
 
	//MPathDelay 
	//Must be a dobule, real valued vector or scalar 
	tprhs = *(prhs+6); 
	mrows = (unsigned) mxGetM(tprhs); 
	ncols = (unsigned) mxGetN(tprhs); 
	if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || ((mrows > 1) && (ncols > 1))) 
		mexErrMsgTxt("\nMPathDelay must be a real-valued, vector or scalar\n"); 
	if (mrows >= ncols) mexNumDelays = mrows; 
	else mexNumDelays = ncols; 
	mexDblDelayPtr = mxGetPr(tprhs); 
 
	mexDelayPtr = (unsigned long *) mxCalloc(mexNumDelays,sizeof(unsigned long)); 
	if (mexDelayPtr == NULL) 
		mexErrMsgTxt("\nAllocation of mexDelay ptr array failed--exiting\n"); 
 
	TempDbleDelayPtr = mexDblDelayPtr; 
	TempDelayPtr = mexDelayPtr; 
	for (i = 0; i < mexNumDelays; i++) *TempDelayPtr++ = (unsigned long) *TempDbleDelayPtr++; 
 
	mexMaxDelay = 0; 
	TempDelayPtr = mexDelayPtr; 
	for (i=0; i mexMaxDelay) mexMaxDelay = *TempDelayPtr++; 
		else TempDelayPtr++; 
	} 
 
	if (nrhs == 9) 
	{ 
		//MPathAmp 
		//Must be a dobule, real valued vector 
		tprhs = *(prhs+7); 
		mrowsA = (unsigned) mxGetM(tprhs); 
		ncolsB = (unsigned) mxGetN(tprhs); 
		if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || (mrows ==1 && ncols ==1) || ((mrows > 1) && (ncols > 1))) 
			mexErrMsgTxt("\nMPathAmp must be a real-valued, vector\n"); 
		if ( (mrowsA != mrows) || (ncolsB != ncols)) 
			mexErrMsgTxt("\nMPathDelay and MPathAmp Must have the same dimensions\n"); 
		mexMPathAmpPtr = mxGetPr(tprhs); 
 
		//fDoppler 
		//Must be a dobule, real valued scalar 
		tprhs = *(prhs+8); 
		mrows = (unsigned) mxGetM(tprhs); 
		ncols = (unsigned) mxGetN(tprhs); 
		if ( !mxIsDouble(tprhs) || mxIsComplex(tprhs) || (mrows !=1) || (ncols !=1) ) 
		mexErrMsgTxt("\nfDoppler must be a real-valued, scalar\n"); 
		mexfDoppler = mxGetScalar(tprhs); 
		M_PATH_FLAG = true; 
	} 
	else 
	{ 
		mexMPathAmpPtr = NULL; 
		mexfDoppler = NULL; 
		M_PATH_FLAG = false; 
	} 
	 
 
	mexN_MAISignal = mexNSig + mexMaxDelay; 
 
	 
	*plhs = mxCreateDoubleMatrix(1,mexN_MAISignal,mxCOMPLEX); 
	tplhs = *plhs; 
	if ( tplhs == NULL) 
		mexErrMsgTxt("\n MAI_Signal Matrix Could Not be Created!!--Exiting\n"); 
	mexRealMAISigPtr = mxGetPr(tplhs); 
	mexImagMAISigPtr = mxGetPi(tplhs); 
 
	 
	*(plhs+1) = mxCreateDoubleMatrix(mexNumInterferers,mexNSig,mxCOMPLEX); 
	tplhs = *(plhs+1); 
	if ( tplhs == NULL) 
		mexErrMsgTxt("\n NextSignal Matrix Could Not be Created!!--Exiting\n"); 
	mexRealNextSigPtr = mxGetPr(tplhs); 
	mexImagNextSigPtr = mxGetPi(tplhs); 
 
	MAI_Processor(mexRealCurrentSigPtr,mexImagCurrentSigPtr,mexNSig, 
				   mexRealLastSigPtr,mexImagLastSigPtr,mexNSig, 
				   mexChanCodePtr,mexSF,mexDelayPtr,mexNumDelays, 
				   mexMPathAmpPtr, 
				   mexPulseShapePtr,mexPulseLength,mexfDoppler,mexSamplesPerChip, 
				   mexMaxOffset,mexNumInterferers, 
				   mexRealNextSigPtr,mexImagNextSigPtr,mexNSig, 
				   mexRealMAISigPtr, mexImagMAISigPtr, mexN_MAISignal, 
				   M_PATH_FLAG); 
	mxFree(mexDelayPtr); 
} 
 
 
 
void MAI_Processor(double *RealCurrentSignalPtr,double *ImagCurrentSignalPtr,unsigned long NCurrentSignal, 
				   double *RealLastSignalPtr,double *ImagLastSignalPtr,unsigned long NLastSignal, 
				   const mxArray *mxChanCodePtr,unsigned SF,unsigned long *DelayPtr,unsigned long NumDelays, 
				   double *MPathAmpPtr, 
				   double *PulseShapePtr,unsigned PulseLength,double fDoppler,unsigned SamplesPerChip, 
				   unsigned MaxOffset,unsigned NumInterferers, 
				   double *RealNextSignalPtr,double *ImagNextSignalPtr,unsigned long NNextSignal, 
				   double *RealMAISignalPtr, double *ImagMAISignalPtr, unsigned long N_MAISignal, 
				   bool M_PATH_FLAG) 
/*********************************************************************************************************** 
/void MAI_Processor(double *RealCurrentSignalPtr,double *ImagCurrentSignalPtr,unsigned long NCurrentSignal, 
/				   double *RealLastSignalPtr,double *ImagLastSignalPtr,unsigned long NLastSignal, 
/				   mxArray *mxChanCodePtr,double *DelayPtr,double *MPathAmpPtr,double *PulseShapePtr, 
/				   double fDoppler,unsigned SamplesPerChip,unsigned MaxOffset,unsigned NumInterferers, 
/				   double *RealNextSignalPtr,double *ImagNextSignalPtr,unsigned long NNextSignal, 
/				   double *RealMAISignalPtr, double *ImagMAISignalPtr, unsigned long N_MAISignal, 
/                  bool M_PATH_FLAG) 
/ 
/ Copyright 2002 The Mobile and Portable Radio Research Group 
/ 
/The funciton generates the Mutual Access Interference signals for each frame,  Each intererer has an  
/offset, which is defined in units of chips.  For each interferer, the datat and control bits are  
/generated at random, spread with the channel code and then scrambled with a different code per  
/interferer.  The resulting froma is then filtered ad processed throug the channel defined by *DelayPtr 
/and *MPathAmpPtr.  Once this is done for each interferer, the signals are then added to create  
/the MAI signal 
/ 
/Parameters 
/	Input 
/		RealCurrentSignalPtr	*double		Pointer to the matrix storing the real part of the  
/											MAI signals associated with the current frame.  Note that 
/											this and all other signal arrays contain the signals for all 
/											"NumInterferers" Interferers.  Hence this array and all other 
/											arrays are of length "NumInterferers*NCurrentSignal" 
/		ImagCurrentSignalPtr	*double		Pointer to array string the imaginary part of the MAI  
/											signals associated with the current frame. 
/		NCurrentSignal		unsigned long	Contains the length of an MAI signal for  one interferer 
/		RealLastSignalPtr	*double			Pointer to the matrix storing the real part of the  
/											MAI signals associated with the previous frame.   
/		ImagLastSignalPtr	*double			Pointer to array string the imaginary part of the MAI  
/											signals associated with the previous frame. 
/		NLastSignal			unsigned long	Contains the length of an MAI signal for  one interferer 
/		mxChanCodePtr		*mxArray		Pointer to a SF*SF array the contains the  
/											channelization code for the interferers. 
/		SF					unsigned		Spreading Factor 
/		DelayPtr			*unsigned long	Pointer to the array that contains the delay of each  
/											multipath component 
/		NumDelays			unsigned long	Contains the number of multipath delay componenets 
/		MPathAmpPtr			*double			Pointer to the array that contains the average energy  
/											for each multipath componnent 
/		PulseShapePtr		*double			Pointer to the transmitter pulse shape. 
/		PulseLength			unsigned		Length of transmiter pulse shape 
/		fDoppler			double			Stores the Doppler Rate 
/		SamplesPerChip		unsigned		Stores the number of signal samples per chip 
/		MaxOffset			unsigned		The maximum allowable offset for each interferer in  
/											terms of chips 
/		NumInterferers		unsigned		The number of interferers 
/		N_MAISignal			unsinged long	Length of the combined MAI signal/ 
/		NNextSignal			unsigned long	Contains the length of an MAI signal for  one interferer 
/	Output 
/		RealNextSignalPtr	*double			Pointer to the matrix storing the real part of the  
/											MAI signals associated with the next frame.   
/		ImagNextSignalPtr	*double			Pointer to array string the imaginary part of the MAI  
/											signals associated with the next frame. 
/		RealMAISignal		*double			Pointer to the matrix storing the real part  
/											of the combined MAI signal 
/		ImagMAISignal		*double			Pointer to the matrix storing the imaginary part of the  
/											combined MAI signal 
/***********************************************************************************************************/ 
{ 
	double *TempRealCurrentPtr,*TempImagCurrentPtr; 
	double *TempRealLastPtr,*TempImagLastPtr; 
	double *TempRealNextPtr,*TempImagNextPtr; 
	unsigned long *TempDelayPtr; 
	double *TempRealMAIPtr,*TempImagMAIPtr; 
	unsigned MaxDelay; 
	double *ControlBitsPtr,*TempControlBitsPtr; 
	unsigned long ScrambleCodeNumber; 
	double *RealScrambleCodePtr, *ImagScrambleCodePtr, *TmpRealScrambleCodePtr, *TmpImagScrambleCodePtr; 
	short int  *RealCodePtr, *ImagCodePtr, *TmpRealCodePtr, *TmpImagCodePtr; 
	mxArray *mxScrambleCodePtr,*mxNumChanPtr; 
	mxArray *mxLeftHandSide[5],*mxRightHandSide[10]; 
	int N_lhs,N_rhs; 
	int ErrCode; 
	double *NumChanPtr; 
	unsigned i,j; 
	unsigned SamplesPerInterferer; 
	double fee; 
	int Offset; 
	double OffsetDouble; 
	double *RealUplinkSignalPtr,*TempRealUplinkSignalPtr; 
	double *ImagUplinkSignalPtr,*TempImagUplinkSignalPtr; 
	unsigned N_UplinkSignal; 
	unsigned Stop; 
	double *RealMpathSignalPtr,*TempRealMpathPtr; 
	double *ImagMpathSignalPtr,*TempImagMpathPtr; 
	mxArray *mxControlBitsPtr; 
	double *InphaseUplinkChipsPtr,*QuadUplinkChipsPtr; 
	mxArray *mxBetaCPtr,*mxBetaDPtr; 
	double *BetaCPtr,*BetaDPtr; 
//	FILE *fp; 
//	float sam; 
 
	srand( (unsigned)time( NULL ) ); 
 
	SamplesPerInterferer = PulseLength + SamplesPerChip*(CHIPS_PER_FRAME-1); 
 
	//Find the Maximum Delay 
	MaxDelay=0; 
	TempDelayPtr=DelayPtr; 
	for (i = 0; i  MaxDelay) MaxDelay = *TempDelayPtr++; 
		else TempDelayPtr++; 
	} 
 
	RealUplinkSignalPtr = (double *) mxCalloc(NCurrentSignal+MaxDelay,sizeof(double)); 
	if (RealUplinkSignalPtr == NULL) 
		mexErrMsgTxt("\n RealUplinkSignalPtr Array Not Allocated!--exiting \n"); 
	ImagUplinkSignalPtr = (double *) mxCalloc(NCurrentSignal+MaxDelay,sizeof(double)); 
	if (ImagUplinkSignalPtr == NULL) 
		mexErrMsgTxt("\n ImagUplinkSignalPtr Array Not Allocated!--exiting \n"); 
 
	RealMpathSignalPtr = (double *) mxCalloc(NCurrentSignal+MaxDelay,sizeof(double)); 
	if (RealMpathSignalPtr == NULL) 
		mexErrMsgTxt("\n RealMpathSignalPtr Array Not Allocated!--exiting \n"); 
	ImagMpathSignalPtr = (double *) mxCalloc(NCurrentSignal+MaxDelay,sizeof(double)); 
	if (ImagMpathSignalPtr == NULL) 
		mexErrMsgTxt("\n ImagMpathSignalPtr Array Not Allocated!--exiting \n"); 
 
	//Generate Array for Control Bits 
 
	mxNumChanPtr = mxCreateDoubleMatrix(1,1,mxREAL); 
	if (mxNumChanPtr == NULL) 
		mexErrMsgTxt("\n mxNumChanPtr Matrix Not Allocated!--exiting \n"); 
	NumChanPtr = mxGetPr(mxNumChanPtr); 
	*NumChanPtr = (double) 1.0; 
 
	mxControlBitsPtr = mxCreateDoubleMatrix(1,CONTROL_BITS,mxREAL); 
	if (mxControlBitsPtr == NULL) 
		mexErrMsgTxt("\n mxControlBitsPtr Matrix Not Allocated!--exiting \n"); 
	ControlBitsPtr = mxGetPr(mxControlBitsPtr); 
 
	RealCodePtr = (short int *) mxCalloc(CHIPS_PER_FRAME,sizeof(short int)); 
	if (RealCodePtr == NULL) 
		mexErrMsgTxt("\n RealCodePtr Array Not Allocated!--exiting \n"); 
 
	ImagCodePtr = (short int *) mxCalloc(CHIPS_PER_FRAME,sizeof(short int)); 
	if (ImagCodePtr == NULL) 
		mexErrMsgTxt("\n ImagCodePtr Array Not Allocated!--exiting \n"); 
 
	mxScrambleCodePtr = mxCreateDoubleMatrix(1,CHIPS_PER_FRAME,mxCOMPLEX); 
	if (mxScrambleCodePtr == NULL) 
		mexErrMsgTxt("\n mxScrambleCodePtr Matrix Not Allocated!--exiting \n"); 
	RealScrambleCodePtr = mxGetPr(mxScrambleCodePtr); 
	ImagScrambleCodePtr = mxGetPi(mxScrambleCodePtr); 
 
	mxBetaCPtr = mxCreateDoubleMatrix(1,1,mxREAL); 
	if (mxBetaCPtr == NULL) 
		mexErrMsgTxt("\n mxBetaCPtr Matrix Not Allocated!--exiting \n"); 
	BetaCPtr = mxGetPr(mxBetaCPtr); 
	*BetaCPtr = (double) 1.0; 
 
	mxBetaDPtr = mxCreateDoubleMatrix(1,1,mxREAL); 
	if (mxBetaDPtr == NULL) 
		mexErrMsgTxt("\n mxBetaDPtr Matrix Not Allocated!--exiting \n"); 
	BetaDPtr = mxGetPr(mxBetaDPtr); 
	*BetaDPtr = (double) 1.0; 
 
	for (i = 0;i < NumInterferers; i++) 
	{ 
		//Generate Control Frame 
		TempControlBitsPtr=ControlBitsPtr; 
		for (j = 0; j < CONTROL_BITS; j++) 
		{ 
			fee = ((double) rand() / (double) RAND_MAX) - 0.5; 
			if (fee <= 0.0)	*TempControlBitsPtr++ = (double) -1.0; 
			else *TempControlBitsPtr++ = (double) 1.0; 
		} 
/****************************************************************** 
		//DEBUG CODE 
		TempControlBitsPtr=ControlBitsPtr; 
		fp = fopen("C:/MATLABR11/work/LGICtest/testdata.txt","r"); 
		for (j = 0; j < CONTROL_BITS; j++) 
		{ 
			fscanf(fp, "%e\n", &sam); 
			*TempControlBitsPtr++ = (double) sam; 
		}  
		fscanf(fp, "%e\n", &sam); 
		ScrambleCodeNumber = (unsigned long) sam; 
		fclose (fp); 
 
 
//DEBUG CODE 
/***************************************************************************/ 
 
		//Generate Scramble code for each interferer 
 
 
		ScrambleCodeNumber =unsigned long (((double) rand() / (double) RAND_MAX)* (pow( (double) 2.0, (double) 24.0) - (double) 1)); 
 
		scramble_long(ScrambleCodeNumber, RealCodePtr, ImagCodePtr); 
 
		//Store Scramble Code in an mxArray 
		TmpRealCodePtr = RealCodePtr; 
		TmpImagCodePtr = ImagCodePtr; 
		TmpRealScrambleCodePtr = RealScrambleCodePtr; 
		TmpImagScrambleCodePtr = ImagScrambleCodePtr; 
 
		for (j = 0; j < CHIPS_PER_FRAME; j++) 
		{ 
			*TmpRealScrambleCodePtr++ = (double) *TmpRealCodePtr++; 
			*TmpImagScrambleCodePtr++ = (double) *TmpImagCodePtr++; 
		} 
 
		*mxRightHandSide = mxNumChanPtr; 
		*(mxRightHandSide+1) = mxScrambleCodePtr; 
		*(mxRightHandSide+2) = (mxArray *) mxChanCodePtr; 
		*(mxRightHandSide+3) = mxControlBitsPtr; 
		*(mxRightHandSide+4) = mxBetaCPtr; 
		*(mxRightHandSide+5) = mxBetaDPtr; 
		N_rhs = 6; 
		N_lhs = 2; 
 
		ErrCode = mexCallMATLAB(N_lhs,mxLeftHandSide,N_rhs,mxRightHandSide,"gen_uplink_wcdma_frame"); 
		if(ErrCode != 0) 
			mexErrMsgTxt("\nError Calling gen_uplink_wcdma_frame from MAI_Processr\n"); 
 
		//Prepare Parameters for caling GenWCDMAUplinkSignal 
//		InphaseUplinkChipsPtr = mxGetPr(mxUplinkFramePtr); 
//		QuadUplinkChipsPtr = mxGetPi(mxUplinkFramePtr); 
		InphaseUplinkChipsPtr = mxGetPr(mxLeftHandSide[0]); 
		QuadUplinkChipsPtr = mxGetPi(mxLeftHandSide[0]); 
 
		TempRealNextPtr = RealNextSignalPtr + i*SamplesPerInterferer; 
		TempImagNextPtr = ImagNextSignalPtr + i*SamplesPerInterferer; 
 
		GenWCDMAUplinkSignal(InphaseUplinkChipsPtr,QuadUplinkChipsPtr, 
							InphaseUplinkChipsPtr,QuadUplinkChipsPtr, 
							InphaseUplinkChipsPtr,QuadUplinkChipsPtr, 
							CHIPS_PER_FRAME,PulseShapePtr,PulseLength,SamplesPerChip, 
							TempRealNextPtr,TempImagNextPtr,SamplesPerInterferer); 
 
		//Generate Offset 
 
		OffsetDouble = (double) rand() / (double) RAND_MAX -  0.5; 
		OffsetDouble *= 2 * MaxOffset * SamplesPerChip; 
		if ((OffsetDouble - floor(OffsetDouble)) < 0.5) 
			Offset = (int) OffsetDouble; 
		else 
			Offset = (int) OffsetDouble + 1; 
 
		//************************ 
		//DEBUG CODE 
		//Offset = 10; 
		//DEBUG CODE 
		//************************ 
 
		TempRealUplinkSignalPtr = RealUplinkSignalPtr; 
		TempImagUplinkSignalPtr = ImagUplinkSignalPtr; 
 
		if (Offset > (int) MaxDelay) 
		{ 
			TempRealLastPtr = RealLastSignalPtr + (i+1)*NLastSignal - Offset; 
			TempImagLastPtr = ImagLastSignalPtr + (i+1)*NLastSignal - Offset; 
			TempRealCurrentPtr = RealCurrentSignalPtr + i*NCurrentSignal; 
			TempImagCurrentPtr = ImagCurrentSignalPtr + i*NCurrentSignal; 
 
			for (j = 0; j < (unsigned) Offset; j++) 
			{ 
				*TempRealUplinkSignalPtr++ = *TempRealLastPtr++; 
				*TempImagUplinkSignalPtr++ = *TempImagLastPtr++; 
			} 
			 
			Stop = NCurrentSignal + MaxDelay - Offset; 
			for (j = 0; j < Stop; j++) 
			{ 
				*TempRealUplinkSignalPtr++ = *TempRealCurrentPtr++; 
				*TempImagUplinkSignalPtr++ = *TempImagCurrentPtr++; 
			} 
		} 
		else if (Offset >= 1) 
		{ 
			TempRealLastPtr = RealLastSignalPtr + (i+1)*NLastSignal - Offset; 
			TempImagLastPtr = ImagLastSignalPtr + (i+1)*NLastSignal - Offset; 
			TempRealCurrentPtr = RealCurrentSignalPtr + i*NCurrentSignal; 
			TempImagCurrentPtr = ImagCurrentSignalPtr + i*NCurrentSignal; 
			TempRealNextPtr = RealNextSignalPtr + i*NNextSignal; 
			TempImagNextPtr = ImagNextSignalPtr + i*NNextSignal; 
 
			for (j = 0; j < (unsigned) Offset; j++) 
			{ 
				*TempRealUplinkSignalPtr++ = *TempRealLastPtr++; 
				*TempImagUplinkSignalPtr++ = *TempImagLastPtr++; 
			} 
			 
			for (j = 0; j < NCurrentSignal; j++) 
			{ 
				*TempRealUplinkSignalPtr++ = *TempRealCurrentPtr++; 
				*TempImagUplinkSignalPtr++ = *TempImagCurrentPtr++; 
			} 
 
			Stop = MaxDelay - Offset; 
			for (j = 0; j < Stop; j++) 
			{ 
				*TempRealUplinkSignalPtr++ = *TempRealNextPtr++; 
				*TempImagUplinkSignalPtr++ = *TempImagNextPtr++; 
			} 
		} 
		else if (Offset < 0) 
		{ 
			TempRealCurrentPtr = RealCurrentSignalPtr + i*NCurrentSignal - Offset; 
			TempImagCurrentPtr = ImagCurrentSignalPtr + i*NCurrentSignal - Offset; 
			TempRealNextPtr = RealNextSignalPtr + i*NNextSignal; 
			TempImagNextPtr = ImagNextSignalPtr + i*NNextSignal; 
 
			Stop = NCurrentSignal + Offset; 
			for (j = 0; j < Stop; j++) 
			{ 
				*TempRealUplinkSignalPtr++ = *TempRealCurrentPtr++; 
				*TempImagUplinkSignalPtr++ = *TempImagCurrentPtr++; 
			} 
 
			Stop = MaxDelay - Offset; 
			for (j = 0; j < Stop; j++) 
			{ 
				*TempRealUplinkSignalPtr++ = *TempRealNextPtr++; 
				*TempImagUplinkSignalPtr++ = *TempImagNextPtr++; 
			} 
		} 
 
		else  //Offset = 0 
		{ 
			TempRealCurrentPtr = RealCurrentSignalPtr + i*NCurrentSignal; 
			TempImagCurrentPtr = ImagCurrentSignalPtr + i*NCurrentSignal; 
			TempRealNextPtr = RealNextSignalPtr + i*NNextSignal; 
			TempImagNextPtr = RealNextSignalPtr + i*NNextSignal; 
 
			for (j = 0; j < NCurrentSignal; j++) 
			{ 
				*TempRealUplinkSignalPtr++ = *TempRealCurrentPtr++; 
				*TempImagUplinkSignalPtr++ = *TempImagCurrentPtr++; 
			} 
 
			for (j = 0; j < MaxDelay; j++) 
			{ 
				*TempRealUplinkSignalPtr++ = *TempRealNextPtr++; 
				*TempImagUplinkSignalPtr++ = *TempImagNextPtr++; 
			} 
		} 
 
		if (M_PATH_FLAG) 
		{ 
			//ApplyMultipathChannel 
 
			//First Initialize output vector 
 
			TempRealMpathPtr = RealMpathSignalPtr; 
			TempImagMpathPtr = ImagMpathSignalPtr; 
			N_UplinkSignal = NCurrentSignal + MaxDelay; 
			for (j = 0; j < N_UplinkSignal; j++) 
			{ 
				*TempRealMpathPtr++ = (double) 0.0; 
				*TempImagMpathPtr++ = (double) 0.0; 
			} 
 
			MAI_Mpath_Channel(RealUplinkSignalPtr,ImagUplinkSignalPtr,N_UplinkSignal, 
							  DelayPtr,NumDelays,MPathAmpPtr,fDoppler,SamplesPerChip, 
							  RealMpathSignalPtr,ImagMpathSignalPtr); 
		} 
		else	//Do Not apply Multipath  
		{ 
			TempRealMpathPtr = RealMpathSignalPtr; 
			TempImagMpathPtr = ImagMpathSignalPtr; 
			TempRealUplinkSignalPtr = RealUplinkSignalPtr; 
			TempImagUplinkSignalPtr = ImagUplinkSignalPtr; 
 
			N_UplinkSignal = NCurrentSignal + MaxDelay; 
			for (j = 0; j < N_UplinkSignal; j++) 
			{ 
				*TempRealMpathPtr++ = *TempRealUplinkSignalPtr++; 
				*TempImagMpathPtr++ = *TempImagUplinkSignalPtr++; 
			} 
		} 
			 
		TempRealMAIPtr = RealMAISignalPtr; 
		TempImagMAIPtr = ImagMAISignalPtr; 
		TempRealMpathPtr = RealMpathSignalPtr; 
		TempImagMpathPtr = ImagMpathSignalPtr; 
 
		for (j = 0; j < N_UplinkSignal; j++) 
		{ 
			*TempRealMAIPtr++ += *TempRealMpathPtr++; 
			*TempImagMAIPtr++ += *TempImagMpathPtr++; 
		} 
 
	} 
	mxFree(RealUplinkSignalPtr); 
	mxFree(ImagUplinkSignalPtr); 
	mxFree(RealMpathSignalPtr); 
	mxFree(ImagMpathSignalPtr); 
	mxDestroyArray(mxNumChanPtr); 
	mxDestroyArray(mxControlBitsPtr); 
	mxFree(RealCodePtr); 
	mxFree(ImagCodePtr); 
	mxDestroyArray(mxScrambleCodePtr); 
	mxDestroyArray(mxBetaCPtr); 
	mxDestroyArray(mxBetaDPtr); 
 
}