⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 receiverclass.cpp

📁 用matlab程序实现WCDMA系统的仿真
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// ReceiverClass.cpp: implementation of the ReceiverClass class.
//
// Copyright 2002 The Mobile and Portable Radio Research Group
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "ReceiverClass.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

ReceiverClass::ReceiverClass(SimConfigClass SimConfig,TransmitterConfigClass *TxConfig)
/************************************************************************************************
/ReceiverClass::ReceiverClass(SimConfigClass SimConfig,TransmitterConfigClass *TxConfig)
/
/ Copyright 2002 The Mobile and Portable Radio Research Group
/
/This is the constructor for an object of type receiver class.  The constructor performs the 
/following actions
/	1.  Generates the pusle shape wavefirn
/	2.  Stores the desired channel's channelization code and scrambling code
/	3.  Stores the multipath delays and their associated average amplitudes
/
/Parameters
/	SimConfig	SimConfigClass				Structure that contains the simulation 
/											configuration parameters
/	TxConfig	TransmitterConfigClass *	Structure that contains the configuation of the 
/											Transmitter
*************************************************************************************************/
{
	unsigned *DelayPtr;		//Stores the multipath delays in chip duration
	double *UIDelayPtr;		//Stores the multipath delays in seconds
	double *AmplitudePtr;	//Stores the average amplitude in linear terms
	double *UIAmplitudePtr;	//Stores the average amplitude in decibels
	unsigned k;				//Loop counter
	double TempDelay;		//Contains the delay of the "current" multipath component
	double fsample;			//sampling frequence
	double IntegerPortion;	//Used for rounding the multipath delay (when expressed as an integer
							//number of chips
		
	//Get parameters needed to generate pulse shape
	UpperBoundT = SimConfig.PulseLength >> 1;
	LowerBoundT = - (int) SimConfig.PulseLength >> 1;
	SamplesPerChip = SimConfig.SamplesPerChip;
	SamplesPerFrame = CHIPS_PER_FRAME * SamplesPerChip;
	Rolloff = 0.22;
	PulseLength = (UpperBoundT-LowerBoundT)*SamplesPerChip+1;
	//Generate Pulse shape
	PulseShape = GeneratePulseShape();

	/****************************************
	//Debug Code
	FILE *fp;
	fp = fopen("Pulse.txt","w");
	for (k=0; k<PulseLength; k++) fprintf(fp,"%g\n",*(PulseShape+k));
	fclose(fp);
	/****************************************/

	//Get configuration and coding information of the desired channel
	DPCH_Format = TxConfig->DesiredDPCHformat;
	ChannelCode = TxConfig->DesiredChannelCode;
	ScrambleCode = TxConfig->DesiredScrambleCode;
	//Determine if STTD is used
	STTDflag = TxConfig->STTDflag;
	//Compute the length of the transmitted signal for a given frame
	TransmittedSignalLength = PulseLength + (SamplesPerChip*(CHIPS_PER_FRAME-1));

	//****************************************
	//Debug Code
//	fp = fopen("ChannelCode.txt","w");
//	for (k=0; k<DPCH_Format.SF; k++) fprintf(fp,"%d\n",*(ChannelCode+k));
//	fclose(fp);
//	fp = fopen("ScrambleCode.txt","w");
//	for (k=0; k<CHIPS_PER_FRAME; k++)
//		fprintf(fp,"%g %g\n",(ScrambleCode+k)->real,(ScrambleCode+k)->imaginary);
//	fclose(fp);
	//****************************************

		//Allocated arrays for the multipath delays and amplitudes
	MultiPathComponents = SimConfig.MPathComponents;
	Delays = (unsigned *) calloc(MultiPathComponents,sizeof(unsigned));
	if (Delays == NULL)
	{
		printf("Memory allocation for Delays failed--exiting\n");
		return;
	}

	Amplitudes= (double *) calloc(MultiPathComponents,sizeof(double));
	if (Delays == NULL)
	{
		printf("Memory allocation for Delays failed--exiting\n");
		return;
	}

	//Compute the delay of each component in terms of signal samples
	//Compute the "linear" amplitude of each component
	//Generate a fading signal for each component
	fsample = SamplesPerChip*CHIPS_PER_FRAME/FRAME_DURATION;
	DelayPtr = Delays;
	UIDelayPtr = SimConfig.Delays;
	AmplitudePtr = Amplitudes;
	UIAmplitudePtr = SimConfig.Amplitudes;
	for (k=0; k<MultiPathComponents; k++)
	{
		//Compute the delay for the k_th multipath component in terms of samples
		TempDelay = *UIDelayPtr++ * fsample;
		if (modf(TempDelay,&IntegerPortion) >= 0.5) *DelayPtr++ = (unsigned) IntegerPortion + 1.00;
		else *DelayPtr++ = (unsigned) IntegerPortion;

		//Compute the amplitude of each multipath component
		*AmplitudePtr++ = pow(10.000, *UIAmplitudePtr++ / 20.00);
	}


}

ReceiverClass::~ReceiverClass()
{
	//These pointers "point" to arrays that were allocated elsewhere.  
	//Just set to NULL and deallocate later
	Amplitudes = NULL;
	Delays = NULL;
	ChannelCode = NULL;
	ScrambleCode = NULL;

	if (DataBits != NULL)
	{
		free(DataBits);
		DataBits = NULL;
	}

	if (PulseShape != NULL)
	{
		free(PulseShape);
		PulseShape = NULL;
	}



}


int * ReceiverClass::Receiver(ComplexNumber *IncomingSignal, unsigned SignalLength)
/**************************************************************************************
* int * ReceiverClass::Receiver(ComplexNumber *IncomingSignal, unsigned SignalLength)
*
* Copyright 2002 The Mobile and Portable Radio Research Group
*
* Function that determines which receiver is to be used.  If STTD coding is employed, 
* then the STTDReceiver (a RAKE receiver with an STTD decoder) is used.  Otherise, a
* Simple RAKE reciever is employed
*
* Returns	An array that contains the decoded bits in the "data fields". 
*			Note that TFCI, TCP, and Pilot bits are not returned
*
* Parameters
*	IncomingSignal	ComplexNumber *		Array that contains the receiver input 
*										(channel output) for the given radio frame
*	SignalLength	unsigned			Length of the signal sample
***************************************************************************************/
{
	if (STTDflag) DataBits = STTDReceiver(IncomingSignal, SignalLength);
	else DataBits = SimpleReceiver(IncomingSignal, SignalLength);

	return (DataBits);
}



int * ReceiverClass::SimpleReceiver(ComplexNumber *IncomingSignal,
										 unsigned SignalLength)
/**************************************************************************************
* int * ReceiverClass::SimpleReceiver(ComplexNumber *IncomingSignal, unsigned SignalLength)
*
* Copyright 2002 The Mobile and Portable Radio Research Group
*
* The function implements a "simple" RAKE receiver.  The number of fingers on the receiver
* equals the number of multipath components in the channel, and each finger is exactly 
* tuned to the delay of the multipath components (i.e., the receiver has perfect knowledge
* of the multipath delays.  Each finger performs the following operations:  matched filter,
* descramble, despread, channel estimate, and weighting by the complex conjugate of the 
* channel estimate. Then the output of each finger is then summed, thereby implementing
* maximum ratio diveristy combiner.  The resultant combined signal is then sent to a detector
* to extract the transmitted symbols
*
* Returns	An array that contains the decoded bits in the "data fields". 
*			Note that TFCI, TCP, and Pilot bits are not returned
*
* Parameters
*	IncomingSignal	ComplexNumber *		Array that contains the receiver input 
*										(channel output) for the given radio frame
*	SignalLength	unsigned			Length of the signal sample
***************************************************************************************/
{
	unsigned k,j;	//Loop counters
	ComplexNumber *IncomingSignalComponent;	//That portion of the incoming signal that contains
											//the complete transmitted signal record for a givn
											//multipath component
	ComplexNumber *RakeFingerOutputPtr,*TempRakeFingerOutputPtr;	//Pointer and temporary pointer
																	//to the output of one finger
																	//of the RAKE receiver
	ComplexNumber *CombinedOutputPtr,*TempCombinedOutputPtr;		//Pointer and temporary pointer
																	//to the resultant signal when	
																	//the outputs of each RAKE figner 
																	//is linearly combined
	unsigned SymbolsPerFrame;		//Number of symbols in a given frame
	unsigned *DelayPtr;				//Temporary Pointer to the array that contains the multipath delays in chips
//	FILE *fp;			

	//Determine the number of symbols in a frame
	SymbolsPerFrame = DPCH_Format.ActualSlotsPerFrame * (DPCH_Format.BitsPerSlot >> 1);
	//Allocate array for the receiver output
	CombinedOutputPtr = (ComplexNumber *) calloc(SymbolsPerFrame,sizeof(ComplexNumber));
	if (CombinedOutputPtr == NULL)
	{
		printf("\nMemory allocation to CombinedOutputPtr failed--exiting\n");
		return(NULL);
	}

	DelayPtr = Delays;
	//Process each figner of the RAKE receiver
	for (k=0; k<MultiPathComponents; k++)
	{
		//Extract that portion of the incoming signal that contains the complete transmitted signal
		//record for the given multipath component
		IncomingSignalComponent = IncomingSignal + *DelayPtr++;

/**********************************************************
	//Debug Code
		fp=fopen("IncomingSignal.txt","w");
		for (j=0;j<SignalLength;k++) 
			fprintf(fp,"%g %g\n",(IncomingSignalComponent+j)->real,(IncomingSignalComponent+j)->imaginary);
		fclose(fp);
/**********************************************************/

		//Process one figuer of the RAKE reciever
		RakeFingerOutputPtr = SimpleRakeFinger(DPCH_Format,IncomingSignalComponent,TransmittedSignalLength);

		//Combine RAKE finger output with the output of all the other RAKE fingers that have been proceed to date
		TempRakeFingerOutputPtr = RakeFingerOutputPtr;
		TempCombinedOutputPtr = CombinedOutputPtr;
		for (j=0; j<SymbolsPerFrame; j++) 
			*TempCombinedOutputPtr++ = ComplexAdd(*TempCombinedOutputPtr,*TempRakeFingerOutputPtr++);
		free(RakeFingerOutputPtr);
	}
	//Detect data bits
	DataBits = DetectBits(DPCH_Format, CombinedOutputPtr);

	free(CombinedOutputPtr);
/**********************************************************
	//Debug Code
	fp = fopen("ReceivedData.txt","w");
	for (k=0;k<((DPCH_Format.Ndata1+DPCH_Format.Ndata2)*15);k++)
		fprintf(fp,"%d\n",*(DataBits+k));
	fclose(fp);
/**********************************************************/

	return(DataBits);
}

ComplexNumber * ReceiverClass::SimpleRakeFinger(DPCH_FormatStructure Format,ComplexNumber *IncomingSignal,unsigned SignalLength)
/********************************************************************************************************
* ComplexNumber * ReceiverClass::SimpleRakeFinger(DPCH_FormatStructure Format,ComplexNumber *IncomingSignal,unsigned SignalLength)
*
* Copyright 2002 The Mobile and Portable Radio Research Group
*
* This funciton implements one finger of a "simple" RAKE receiver.  Specifically, the function performs
* the following oeprations
*		Matched Filters and decimates the incoming singal
*		Descrambles the signal
*		Despreads the signal
*		Estimates the channels using the Pilot symbols.  These estimates are performed on a 
*			slot-by-slot basis
*		Multiply the despread signal by the conjugate of the channel estimate on a slot-by-slot basis
*		Returns the resultant signal
* Note that this prepares the signal for maximal ratio combining in the calling funciton
*
* Returns	An array of type ComplexNumber that contains the weighted, despread signal
*
* Parameters
*	Input
*		Format			DPCH_FormatStructure	Contains the formatting information for the desired channel
*		IncomingSignal	ComplexNumber *			Array that contains the incoming signal for the finger
*		SignalLength	unsigned				Length of the incoming signal
*********************************************************************************************************/
{
	ComplexNumber *FilteredSignal;	//Pointer to the array that contains the output of the 
									//receiver matched fitler

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -