📄 transmitterclass.cpp
字号:
/Parameters
/ SF unsigned Spreading factor
/******************************************************************************************************/
{
unsigned i,j,p; //loop counters
unsigned UnsignedLog2SF; //Base 2 log of the SF in unsigned format
unsigned long N1,N2; //Looping parameters
int *Ptr1; //Pointer used to store the OVSF codes associated with previous spreading factors
//Also used to return the OVSF code for the SF of interest
int *Ptr2; //Pointer used to store the OVSF codes associated with current spreading factors
//in any iteration
int *TmpPtr2; //Temporary Pointer
int *RowPtr,*TempRowPtr; //Row pointer associated with *Ptr1
double log2SF; //Base 2 log of the SF
double IntegerPortion,fraction; //Used in conjunction with modf to make sure SF is a integer power of 2
double fee; //Temporary variable
//initialize Ptr2 to NULL
Ptr2=NULL;
//Compute the base 2 log of SF
fee = (double) SF;
log2SF = log(fee);
fee = log( (double) 2.0000);
log2SF = log2SF/fee;
//Make sure that the base 2 log of SF is an integer
fraction = modf(log2SF,&IntegerPortion);
if (fraction != 0)
{
printf("\nThe spreading factor (SF) must be a power of 2--exiting\n");
return(NULL);
}
//Get the unsigned version of log2SF
UnsignedLog2SF = (unsigned) log2SF;
//If SF = 1, then we have the trivial situation where the OVSF code has only one element,
//which happens to be the number 1
if (SF == 1)
{
Ptr1 = (int *) calloc(1,sizeof(int));
*Ptr1= 1;
return(Ptr1);
}
//For all other cases we have a recursion, where the OVSF code for a given SF is generated from the
//OVSF code from a previous SF. The recursion is initialized by starting with a spreading factor of 1
Ptr1 = (int *) calloc(1,sizeof(int));
*Ptr1 = 1;
N1=1; //Start with a spreading factor of 1
for (i=1; i<=UnsignedLog2SF ;i++)
{
//Compute the next spreading factor 2^i
N2 = (unsigned) pow(2.0,(double) i);
//if Ptr2 is already allocated, then deallocated it
if (Ptr2 != NULL) free(Ptr2);
//Allocate sufficient memory for Ptr2 so that it can store on OVSF code for an SF of N2
Ptr2 = (int *) calloc(N2*N2,sizeof(int));
TmpPtr2=Ptr2;
//Fill Ptr2 with the new code
for (p=0; p<N1; p++)
{
RowPtr = Ptr1 + p*N1;
TempRowPtr=RowPtr;
for (j = 0; j < N1; j++) *TmpPtr2++ = *TempRowPtr++;
TempRowPtr=RowPtr;
for (j = 0; j < N1; j++) *TmpPtr2++ = *TempRowPtr++;
TempRowPtr=RowPtr;
for (j = 0; j < N1; j++) *TmpPtr2++ = *TempRowPtr++;
TempRowPtr=RowPtr;
for (j = 0; j < N1; j++) *TmpPtr2++ = -(*TempRowPtr++);
}
//Free Ptr1. Ptr1 contains the OVSF code for the previous SF
free(Ptr1);
//Have Ptr1 point to the OVSF code just created--we are getting ready to move to the next iterartion
Ptr1=Ptr2;
N1=N2;
//Set Ptr2 to NULL
Ptr2=NULL;
//Go to the next iteration (if necessary)
}
return(Ptr1);
}
ComplexNumber *TransmitterClass::GenDPCH(DPCH_FormatStructure format,
int *ChanCode,
ComplexNumber *ScrambleCode,
unsigned TPCCommand,
bool STTDflag,
bool DesiredFrame,
int *DesiredData)
/*******************************************************************************************
*ComplexNumber *GenDPCH(DPCH_FormatClass format,
* unsigned *ChannelCode,
* ComplexNumber *ScrambleCode,
* unsigned, TPCCommand,
* bool STTDflag,
* bool DesiredFrame,
* *unsigned DesiredData)
*
* Copyright 2002 The Mobile and Portable Radio Research Group
*
* This funciton generates the DPCH frame corresponding to one of the 49 allowable
* frame formats. The funciton places the data in complex number format and then spreads
* the data. The resutlatant data is then scambled via the scamble code and a pointer to the
* spreaded and scrambled frame is then returned. If the frame corresponds to the desired user,
* then the DesiredFrame flag is set to true and the data bits associated with that frame are
* placed in *DesiredData so that BERs can be measured at the Receiver Object
*
* Returns Pointer to the array that stores the spreaded scrambled frame
*
*Parameters
* Input
* format DPCH_FormatStructure Contains the format parameters for the frame
* ChannelCode unsigned * Contains the array that stores the Channel Code
* ScramleCode ComplexNumber * Contains the array that stores the scamble Code
* TPCCommand unsigned Transmit Power Control Command--either a 0 or a 1
* STTDflag bool Flag which determines if STTD is employed
* DesiredFrame bool Flag which determines if this frame is "desired"
* or an interfering frame
* Output
* DesiredData int * Contains the Data bits used to generate the array
*************************************************************************************************/
{
//*********************************************************************************************
//Declare and define Pilot symbols
const int Npilot2[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};
const int Npilot4[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};
const int Npilot8[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};
const int Npilot16[240]= {-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,
-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,
-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,
-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,
-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,
-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,
-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,
-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,
-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,
-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,
-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,
-1,-1,1,1,-1,-1,-1,-1,-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 Defined and Declared
//*********************************************************************************************
int RandInitFlag=1; //Initialization flag for random number generator
unsigned j,k; //Loop Counters
ComplexNumber *FrameBufferPtr,*TempFrameBufferPtr; //Pointer and temporary pointer to the Frame Buffer Array
//The array that contains the data and control symbols for
//the frame
ComplexNumber *ChipSequencePtr,*TempChipSequencePtr;//Pointer and temporary pointer to the Chip Sequence Array,
//the array that contains the chipping sequence for the given
//frame
int *PilotPtr,*TempPilotPtr; //Pointer and temporary pointer to the pilot bits used in the given frame
unsigned Nbits; //The total number of bits (data and control) used in the given frame
int *DataBitsPtr,*TempDataBitsPtr; //Pointer and temporary pointer to the data bits produced for this frame
double RandomNumber; //Uniformly generated Random number
unsigned BitsPerFrame; //Bits per frame
unsigned SymbolsPerFrame; //Symbols per frame
unsigned NDesiredDataBits; //number of data bits per frame (only used when the "Desired DPCH" is generated
int *TempChanCodePtr; //Pointer to the OVSF code assigned to this channel
ComplexNumber *TempScrambleCodePtr; //Pointer to scrambling code assigned to this frame
int result; //Primarily used to store the return variable of some of the functions that are called
unsigned CodeLength; //Dermines length of the chipping sequence for the frame. IF STTD is used, then
//CodeLength=76800 because two chipping sequences are actually retured--one per antenna.
//If STTD is not used, then CodeLength=38400
//*********************
//For debugging purposes
//FILE *fp;
//*********************
//Determine the maximum number of random bits that are required for the given frame format
Nbits = format.MaxSlotsPerFrame*(format.Ndata1 + format.Ndata2 + format.Ntfci);
//create an array to for storing these bits
DataBitsPtr = (int *) calloc(Nbits,sizeof(int));
if (DataBitsPtr == NULL)
{
printf("\nAllocation of memory to DataBitsPtr failed--exiting\n");
return(NULL);
}
//Generate these bits and store in the array
TempDataBitsPtr = DataBitsPtr;
for (k=0; k<Nbits; k++)
{
RandomNumber = UniformRandomNumberGenerator(&RandInitFlag)-0.5;
/******************************
//Debug code for testing
RandomNumber = 1;
/*****************************/
if (RandomNumber <= 0.0) *TempDataBitsPtr++ = -1;
else *TempDataBitsPtr++ = 1;
}
//Assign PilotPtr to the correct pilot sequence
if (format.NPilot == 2) PilotPtr = (int *) Npilot2;
else if (format.NPilot == 4) PilotPtr = (int *) Npilot4;
else if (format.NPilot == 8) PilotPtr = (int *) Npilot8;
else if (format.NPilot == 16) PilotPtr = (int *) Npilot16;
else
{
printf("format.NPilot = %d\nMust be equal to 2, 4, 8, or 16!--exiting\n",format.NPilot);
return(NULL);
}
TempPilotPtr = PilotPtr;
//Create an array for storing the entire frame
BitsPerFrame = format.MaxSlotsPerFrame * format.BitsPerSlot;
SymbolsPerFrame = BitsPerFrame >> 1;
if (STTDflag) //If Space-time Transmit Diveristy is employed
FrameBufferPtr = (ComplexNumber *) calloc(40000,sizeof(ComplexNumber));
else //If Space-time Transmit Diveristy is not employed
FrameBufferPtr = (ComplexNumber *) calloc(20000,sizeof(ComplexNumber));
//Note that the array sized of 20000 (40000 for the STTD case) is an arbitrary upper bound that should cover all cases.
//A more precise size could be determined. However, that approach caused memory faults that
//I could not seem to correct. This approach seems to correct the memory problem
if (FrameBufferPtr == NULL)
{
printf("\nAllocation of memory to FrameBufferPtr failed--exiting\n");
return(NULL);
}
if (DesiredFrame) //Fill the buffer on a slot by slot basis and save the DataBits
{
NDesiredDataBits = FillDesiredFrame(format,PilotPtr,TPCCommand,FrameBufferPtr,DataBitsPtr,DesiredData);
/**********************************************************
//Debug Code
fp = fopen("TransmittedData.txt","w");
for (k=0;k<NDesiredDataBits;k++)
fprintf(fp,"%d\n",*(DesiredData+k));
fclose(fp);
/**********************************************************/
}
else //Just fill the buffer on a slot by slot basis
result = FillUndesiredFrame(format,PilotPtr,TPCCommand,FrameBufferPtr,DataBitsPtr);
//Data Bits are no longer needed--Free the memory
free(DataBitsPtr);
if (STTDflag) //If STTD is employed, then create the frame for the 2nd Antenna
{
result = STTDcodeDPCH(FrameBufferPtr,format,SymbolsPerFrame);
if (result < 0)
{
printf("\nresult = %d, STTDcode() failed--exiting\n",result);
return (NULL);
}
}
/********************************************
//Debuggin Code
fp = fopen("DPCHdata.txt","w");
if(STTDflag) j = 2*SymbolsPerFrame;
else j = SymbolsPerFrame;
TempFrameBufferPtr=FrameBufferPtr;
for (k=0;k<j;k++)
{
fprintf(fp,"%d %d\n",(int) TempFrameBufferPtr->real,(int) TempFrameBufferPtr->imaginary);
TempFrameBufferPtr++;
}
fclose(fp);
/************************************************/
//
// fp = fopen("ChannelCode.txt","w");
// TempChanCodePtr=ChanCode;
// for (k=0; k<format.SF; k++) fprintf(fp,"%d\n",*TempChanCodePtr++);
// fclose(fp);
//
// fp = fopen("ScrambleCode.txt","w");
// TempScrambleCodePtr = ScrambleCode;
// for (k=0; k<38400; k++)
// {
// fprintf(fp,"%d %d\n",(int) TempScrambleCodePtr->real, (int) TempScrambleCodePtr->imaginary);
// TempScrambleCodePtr++;
// }
// fclose(fp);
//
//
//End Debuging Code
//********************************************
//Allocated memory for the unscrambled chipping sequence
if (STTDflag) CodeLength = 2*CHIPS_PER_FRAME;
else CodeLength = CHIPS_PER_FRAME;
ChipSequencePtr = (ComplexNumber *) calloc(CodeLength,sizeof(ComplexNumber));
if (ChipSequencePtr == NULL)
{
printf("\nAllocation of memory to ChipSequencePtr failed--exiting\n");
return(NULL);
}
//Assign temporary pointers
TempChipSequencePtr=ChipSequencePtr;
TempChanCodePtr=ChanCode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -