www.pudn.com > WCDMA.rar > 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; kDesiredDPCHformat;
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; kreal,(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= 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; kreal,(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; jreal,(FilteredSignal+k)->imaginary);
fclose(fp);
/*********************************************************************************/
//Descramble the Filtered Signal
Descramble(FilteredSignal,ScrambleCode);
// fp=fopen("DescrambledSignal.txt","w");
// for (k=0;kreal,(FilteredSignal+k)->imaginary);
// fclose(fp);
//Despread the Descrambled Signal
DespreadSignal = DespreadFrame(Format,FilteredSignal);
free(FilteredSignal);
/*********************************************************************
fp=fopen("DespreadSignal.txt","w");
unsigned SF,fee;
SF = Format.SF;
fee=38400/SF;
for (k=0;kreal,(DespreadSignal+k)->imaginary);
fclose(fp);
/***********************************************************************/
//Obtain Channel Estimates
ChannelEstimates=ChannelEstimator(Format,DespreadSignal);
/*********************************************************************
fp=fopen("ChannelEstimates.txt","w");
for (k=0;k<15;k++)
fprintf(fp,"%g %g\n",(ChannelEstimates+k)->real,(ChannelEstimates+k)->imaginary);
fclose(fp);
/***********************************************************************/
//Apply Channel Estimates to Despread Signal
ApplyChannelEstimates(Format, DespreadSignal, ChannelEstimates);
free (ChannelEstimates);
/**************************************************************************
fp=fopen("ModifiedDespreadSignal.txt","w");
for (k=0;k<150;k++)
fprintf(fp,"%g %g\n",(DespreadSignal+k)->real,(DespreadSignal+k)->imaginary);
fclose(fp);
/***************************************************************************/
return(DespreadSignal);
}
int * ReceiverClass::STTDReceiver(ComplexNumber *IncomingSignal,
unsigned SignalLength)
/**************************************************************************************
* int * ReceiverClass::STTDReceiver(ComplexNumber *IncomingSignal, unsigned SignalLength)
*
* Copyright 2002 The Mobile and Portable Radio Research Group
*
* The function implements a RAKE receiver for an STTD coded signal. 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 soft STTD decoding. The output of each finger
* is then a soft decoded estimate of the transmitted signal. These estimates are then
* summed. 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
//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; kreal,(IncomingSignalComponent+k)->imaginary);
fclose(fp);
/*************************************************************/
//Process one figuer of the RAKE reciever
RakeFingerOutputPtr = STTDRakeFinger(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; jreal,(FilteredSignal+k)->imaginary);
fclose(fp);
/*********************************************************************************/
//Descramble the Filtered Signal
Descramble(FilteredSignal,ScrambleCode);
/******************************************************************
fp=fopen("DescrambledSignal.txt","w");
for (k=0;kreal,(FilteredSignal+k)->imaginary);
fclose(fp);
/*********************************************************************************/
//Despread the Descrambled Signal
DespreadSignal = DespreadFrame(Format,FilteredSignal);
free(FilteredSignal);
/******************************************************************
fp=fopen("DespreadSignal.txt","w");
for (k=0;k<150;k++)
fprintf(fp,"%g %g\n",(DespreadSignal+k)->real,(DespreadSignal+k)->imaginary);
fclose(fp);
/*********************************************************************************/
//Obtain Channel Estimates
ChannelEstimates = STTDChannelEstimator(Format,DespreadSignal);
//Peform STTD Soft Decode
DecodedSignal = STTDSoftDecode(Format,ChannelEstimates,DespreadSignal);
/******************************************************************
fp=fopen("DecodedSignal.txt","w");
for (k=0;k<150;k++)
fprintf(fp,"%g %g\n",(DecodedSignal+k)->real,(DecodedSignal+k)->imaginary);
fclose(fp);
/*********************************************************************************/
//free channel estimate array
free(ChannelEstimates);
//free array containing despreaded signal
free(DespreadSignal);
//free array containing the soft decoded symbols
return(DecodedSignal);
}
ComplexNumber * ReceiverClass::Filter(ComplexNumber *SignalPtr,unsigned IncomingSignalLength,unsigned FilteredSignalSamples)
/*************************************************************************************************
*ComplexNumber * ReceiverClass::Filter(ComplexNumber *SignalPtr,
* unsigned IncomingSignalLength,
* unsigned FilteredSignalSamples)*
*
* Copyright 2002 The Mobile and Portable Radio Research Group
*
*This function filters and decimates the incoming complex-valued signal with the FIR impulse
*reponse stored in PulseShape. The decimation rate is equal to SamplesPerChip. Decimation is simply
*performed by filtering every SamplesPerChip'th output sample. The "delay" and "tail" due to the
*filtering is removed
*This fuction works on matrix of signal data, where each column in the the matrix is a
*different signal
*
*Returns A poiter to an array of type ComplexNumber that contains the values of the filtered
* and decimated signal
*
*Parameters
* Input
* SignalPtr ComplexNumber Pointer to array of length NumSamples that stores the
* signal values
* IncomingSignalLength unsigned Length of incoming signal
*
* Output
* FilteredSignalSamples unsigned legnth of filtered signal
*
**************************************************************************************************/
{
ComplexNumber *FilteredSignalPtr; //Pointer to the array that contains the values fo the
//filtered and ecimated signal
unsigned k1,k2; //Loop counters
unsigned PaddedLength; //Length of signal array, included the necessary zero padding
// double *InphasePaddedPtr,*QuadPaddedPtr;
ComplexNumber *SigPtr; //Temporary pointer to the signal array. Used to determine the
//what elements of the incoming signal are to be included for
//the filtering of a particular value
ComplexNumber *FilterSigPtr; //Temporary pointer to the filtered signal array
ComplexNumber *FilterTmpPtr; //Another temporary pointer to the filtered signal array
ComplexNumber *TmpPtr; //Temporary pointer to the signal array. used to perform the
//Actuall filtering (i.e., multiplication with the pulse shape)
double *PulseTmpPtr; //Temporary pointer to the array that contains the pulse shape
unsigned loopstart; //Looping parameter. Used to determine the start of a given for loop
PaddedLength = IncomingSignalLength + 2 * PulseLength;
//Allocated memory for filtered signal
FilteredSignalPtr = (ComplexNumber *) calloc(FilteredSignalSamples,sizeof(ComplexNumber));
if (FilteredSignalPtr == NULL)
{
printf("Memory Allocation to FilteredSignalPtr failed!--returning\n");
return(NULL);
}
SigPtr = SignalPtr;
FilterSigPtr = FilteredSignalPtr;
//perform filtering and decimation
loopstart=PulseLength-1;
FilterTmpPtr = FilterSigPtr;
SigPtr += loopstart;
for (k1=loopstart;k1> 1);
//Allocated memory for the despread signal array
DespreadSignal = (ComplexNumber *) calloc(SymbolsPerFrame,sizeof(ComplexNumber));
if (DespreadSignal == NULL)
{
printf("\nMemory allocation failed for DespreadSignal--exiting\n");
return(NULL);
}
//Assign temporary pointers
TempDespreadSignal = DespreadSignal;
TempDescrambledSignal = DescrambledSignal;
TempChanCodePtr = ChannelCode;
//Perform despreading operation
for (k=0; k> 1);
PilotPositionInSlot = (Format.BitsPerSlot >> 1) - NumPilotSymbols;
SlotsPerFrame = Format.ActualSlotsPerFrame;
//Get the correct Pilot Symbols
switch (Format.NPilot)
{
case 2:
PilotPtr = (ComplexNumber *) Npilot2;
break;
case 4:
PilotPtr = (ComplexNumber *) Npilot4;
break;
case 8:
PilotPtr = (ComplexNumber *) Npilot8;
break;
case 16:
PilotPtr = (ComplexNumber *) Npilot16;
break;
}
//Initialize the Channel Estimate Vector
ChannelEstimatePtr = (ComplexNumber *) calloc(SlotsPerFrame,sizeof(ComplexNumber));
if (ChannelEstimatePtr == NULL)
{
printf("Memory allocation for ChannelEstimatePtr failed--exiting\n");
return(NULL);
}
//Now Perform the channel Estimates--One estimate per Slot
//The estimates are obtained by dividing the despread symbol by the known pilot symbol
//for that particular location. Then for each slot, these estimates are averaged
TempChannelEstimatePtr = ChannelEstimatePtr;
TempDespreadSignalPtr = DespreadSignal;
TempPilotPtr = PilotPtr;
for (k=0; k> 1;
//Assign temporary pointers
TempChannelEstimate = ChannelEstimate;
TempDespreadSignal = DespreadSignal;
//Apply the channel estimate by multiplying each slot with the conjugate of the channel estimate
//for that slot
for (k=0; k> 1;
//Determine the number of symbols in the data1 field
Data1Symbols = Format.Ndata1 >> 1;
//Determine the number of symbols in the data2 field
Data2Symbols = Format.Ndata2 >> 1;
//Determine the number of databits in a given frame
DataBitsPerFrame = Format.ActualSlotsPerFrame * (Format.Ndata1 + Format.Ndata2);
//Allocate memory for an array that will store the detected data bits
DetectedDataBits = (int *) calloc(DataBitsPerFrame,sizeof(int));
if (DetectedDataBits == NULL)
{
printf("memory Allocation for DetectedDataBits failed--exiting\n");
return(NULL);
}
//Assign temporary pointers
TempDetectedDataBits = DetectedDataBits;
TempDespreadSignal = DespreadSignal;
//Go through the detection process on a slot-by-slot basis
for (k=0; kreal) >= 0.0)
*TempDetectedDataBits++ = 1;
else
*TempDetectedDataBits++ = -1;
if ((TempDespreadSignal->imaginary) >= 0.0)
*TempDetectedDataBits++ = 1;
else
*TempDetectedDataBits++ = -1;
TempDespreadSignal++;
}
TempDespreadSignal += SkipLength;
//Then do symbols in the data2 field
for (j=0; j< Data2Symbols; j++)
{
if ((TempDespreadSignal->real) >= 0.0)
*TempDetectedDataBits++ = 1;
else
*TempDetectedDataBits++ = -1;
if ((TempDespreadSignal->imaginary) >= 0.0)
*TempDetectedDataBits++ = 1;
else
*TempDetectedDataBits++ = -1;
TempDespreadSignal++;
}
TempDespreadSignal += (Format.NPilot >> 1);
}
return(DetectedDataBits);
}
ComplexNumber * ReceiverClass::STTDChannelEstimator(DPCH_FormatStructure Format,ComplexNumber *DespreadSignal)
/********************************************************************************************************************
* ComplexNumber * ReceiverClass::STTDChannelEstimator(DPCH_FormatStructure Format,ComplexNumber *DespreadSignal)
*
* Copyright 2002 The Mobile and Portable Radio Research Group
*
* The function estimates the two complex channel gains associated with a STTD link. In such a link, two transimtter
* antennas and only one receive antenna are employed. Therefore, for each slot, two channel gain estimates are required.
* this function uses the Pilot symbols in each slot to estimate these gains.
*
* It is important to note that specific estimation procedure is a direct funciton of the number of Pilot bits per slot
* used in the transmission. Details of the specific estimation procedure are documented in the code
*
* Returns A ComplexNumber type array of length 30 (assuming the frame contains 15 slots) containing the channel gains
* from the two antennas to the receiver. The even numbered elements (note the elements are numbered 0 to 29)
* contain the channel estimates from transmit antenna 0 to the receiver. The odd numbered elements contain
* the channel estimates from transmit antenna 1 to the receiver.
*
* Parameters
* Format DPCH_FormatStructure Contains the format information of the desired frame
* DespreadSignal ComplexNumber * Contains the despread symbol values
*********************************************************************************************************************/
{
//***************************************************************************************************************
//Declare and define Pilot symbols
const ComplexNumber Npilot2[15]= {{-1,-1},
{1,1},
{1,-1},
{1,1},
{-1,1},
{-1,-1},
{-1,-1},
{-1,1},
{1,-1},
{-1,-1},
{1,-1},
{-1,1},
{-1,1},
{1,1},
{1,1}};
const ComplexNumber Npilot4[30]= {{-1,-1},{-1,-1},
{-1,-1},{1,1},
{-1,-1},{1,-1},
{-1,-1},{1,1},
{-1,-1},{-1,1},
{-1,-1},{-1,-1},
{-1,-1},{-1,-1},
{-1,-1},{-1,1},
{-1,-1},{1,-1},
{-1,-1},{-1,-1},
{-1,-1},{1,-1},
{-1,-1},{-1,1},
{-1,-1},{-1,1},
{-1,-1},{1,1},
{-1,-1},{1,1}};
const ComplexNumber Npilot8[60]= {{-1,-1},{-1,-1},{-1,-1},{-1,1},
{-1,-1},{1,1},{-1,-1},{-1,1},
{-1,-1},{1,-1},{-1,-1},{1,-1},
{-1,-1},{1,1},{-1,-1},{1,1},
{-1,-1},{-1,1},{-1,-1},{1,-1},
{-1,-1},{-1,-1},{-1,-1},{-1,1},
{-1,-1},{-1,-1},{-1,-1},{1,1},
{-1,-1},{-1,1},{-1,-1},{1,1},
{-1,-1},{1,-1},{-1,-1},{-1,1},
{-1,-1},{-1,-1},{-1,-1},{-1,-1},
{-1,-1},{1,-1},{-1,-1},{1,-1},
{-1,-1},{-1,1},{-1,-1},{-1,-1},
{-1,-1},{-1,1},{-1,-1},{1,1},
{-1,-1},{1,1},{-1,-1},{-1,-1},
{-1,-1},{1,1},{-1,-1},{-1,-1}};
const ComplexNumber Npilot16[120]= {{-1,-1},{-1,-1},{-1,-1},{-1,1},{-1,-1},{-1,-1},{-1,-1},{-1,1},
{-1,-1},{1,1},{-1,-1},{-1,1},{-1,-1},{-1,-1},{-1,-1},{1,1},
{-1,-1},{1,-1},{-1,-1},{1,-1},{-1,-1},{-1,1},{-1,-1},{1,1},
{-1,-1},{1,1},{-1,-1},{1,1},{-1,-1},{1,-1},{-1,-1},{-1,1},
{-1,-1},{-1,1},{-1,-1},{1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
{-1,-1},{-1,-1},{-1,-1},{-1,1},{-1,-1},{1,-1},{-1,-1},{1,-1},
{-1,-1},{-1,-1},{-1,-1},{1,1},{-1,-1},{-1,1},{-1,-1},{-1,-1},
{-1,-1},{-1,1},{-1,-1},{1,1},{-1,-1},{-1,1},{-1,-1},{1,1},
{-1,-1},{1,-1},{-1,-1},{-1,1},{-1,-1},{1,1},{-1,-1},{-1,-1},
{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{1,1},{-1,-1},{-1,-1},
{-1,-1},{1,-1},{-1,-1},{1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,1},
{-1,-1},{-1,1},{-1,-1},{-1,-1},{-1,-1},{1,1},{-1,-1},{-1,1},
{-1,-1},{-1,1},{-1,-1},{1,1},{-1,-1},{1,-1},{-1,-1},{1,-1},
{-1,-1},{1,1},{-1,-1},{-1,-1},{-1,-1},{1,1},{-1,-1},{1,1},
{-1,-1},{1,1},{-1,-1},{-1,-1},{-1,-1},{-1,1},{-1,-1},{1,-1}};
//Pilot symbols declared and defined
//***************************************************************************************************************
const ComplexNumber Sdata[4] = {{1,1},{1,-1},{-1,1},{-1,-1}}; //Stores the four possible symbol values
ComplexNumber *PilotPtr,*TempPilotPtr; //Poiter and temporary pointer to the array that contains
//the select pilot symbol
unsigned SF; //Spreading Factor
unsigned NumPilotSymbols; //Number of pilto symbols
ComplexNumber *ChannelEstimatePtr,*TempChannelEstimatePtr; //Poiner and temporary pointer to the array that
//contains the channel estimates
ComplexNumber *TempDespreadSignalPtr; //Temporary poiner to the despread signal
unsigned PilotPositionInSlot; //Location of the first pilot symbol in every slot
unsigned SlotsPerFrame; //Number of slots per frame
ComplexNumber TempEstimate0,TempEstimate1; //Temporary storage for the channel estimates
ComplexNumber s,s0,s1,r0,r1,r2,r3,r4,r5,r6,r7; //Varialbes used in channel estimation procedure
ComplexNumber fee,foo; //Temporary storage (general use)
unsigned j,k; //Loop counters
//Get spreading factor
SF = Format.SF;
//Determine the number of pilot symbols in a given slot
NumPilotSymbols = (Format.NPilot >> 1);
//Determine the postion of th efirst pilot symbol in any given slot
PilotPositionInSlot = (Format.BitsPerSlot >> 1) - NumPilotSymbols;
//Determine the number slots per frame
SlotsPerFrame = Format.ActualSlotsPerFrame;
//Get the correct Pilot Symbols
switch (Format.NPilot)
{
case 2:
PilotPtr = (ComplexNumber *) Npilot2;
// Pilot2Ptr = (ComplexNumber *) N2Pilot2;
break;
case 4:
PilotPtr = (ComplexNumber *) Npilot4;
// Pilot2Ptr = (ComplexNumber *) N4Pilot2;
break;
case 8:
PilotPtr = (ComplexNumber *) Npilot8;
// Pilot2Ptr = (ComplexNumber *) N8Pilot2;
break;
case 16:
PilotPtr = (ComplexNumber *) Npilot16;
// Pilot2Ptr = (ComplexNumber *) N16Pilot2;
break;
}
//Initialize the Channel Estimate Vector
ChannelEstimatePtr = (ComplexNumber *) calloc(2*SlotsPerFrame,sizeof(ComplexNumber));
if (ChannelEstimatePtr == NULL)
{
printf("Memory allocation for ChannelEstimatePtr failed--exiting\n");
return(NULL);
}
//Now Perform the channel Estimates--One estimate per Slot
//The estimates are obtained by dividing the despread symbol by the known pilot symbol
//for that particular location. Then for each slot, these estimates are averaged
TempChannelEstimatePtr = ChannelEstimatePtr;
TempDespreadSignalPtr = DespreadSignal;
TempPilotPtr = PilotPtr;
if (NumPilotSymbols==1)
{
for (k=0; k> 1;
//Get the number of symples for the entire frame
SymbolsPerFrame = SymbolsPerSlot * Format.ActualSlotsPerFrame;
//Get the number of slots for the entire frame
SlotsPerFrame = Format.ActualSlotsPerFrame;
//Compute the number of decoding iterations per slot
IterationsPerSlot = SymbolsPerSlot >> 1;
//Allocate Output Array
DecodedSignalPtr = (ComplexNumber *) calloc(SymbolsPerFrame,sizeof(ComplexNumber));
if (DecodedSignalPtr == NULL)
{
printf("\nMemory allocation for DecodedSignalPtr failed--exiting\n");
return(NULL);
}
//Assign Temporary Pointers
TempChannelEstimates = ChannelEstimates;
TempDespreadSignal = DespreadSignal;
TempDecodedSignalPtr = DecodedSignalPtr;
//Perform the decoding
for (k=0; k