📄 receiverclass.cpp
字号:
// 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 + -