📄 downlinksimulator.cpp
字号:
// DownlinkSimulator.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "TransmitterClass.h"
//#include "Sim.h"
#include "mex.h"
#include "matrix.h"
ErrorRunClass DownLinkSimulator(SimConfigClass Config);
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 the down simulator. Supports the passing of one arguement,
* which happens to be a structure, and returns one parameters.
*
* The members of the input structure are
* S_CCPCHformatID Integer Format ID for S_CCPCH
* PDSCHformatID Integer Format ID for PDSCH
* DesiredDPCHformatID Integer Format ID for Desired DPCH
* Num_DPCH Integer Number of remaining DPCHs
* NumDPCCHforCPCH Integer Number of DPCCHs for CPCH
* NumS_CPICH Integer Number of S_CPICH
* STTD boolean STTD flag
* OtherDPCHformatID Int array Format ID for remaining DPCHs
* PulseUpperBound Integer Upper bould of pulse length
* SamplesPerChip Integer Oversampling rate
* EbNo_dB double EbNo in dB
* Velocity double Velocity in km/hr
* Delays dbl array Delay of each multipath component
* Amplitudes dbl array Amplitude of each multipath component
*
* The output parameter is
* Error Run Length int array Error run lenght for simulation
***************************************************************************************/
{
int NumFields;
int Ncolumns,Mrows;
char *s1=" ";
mxArray *tmpPtr;
SimConfigClass SimConfig;
double *fee;
ErrorRunClass ErrorRun;
unsigned k;
/**********************************************/
//Error Checking
if (nrhs != 1)
mexErrMsgTxt("Exactly one input argument is required\n");
else if (nlhs > 1)
mexErrMsgTxt("At least one output argument is required\n");
else if (!mxIsStruct(prhs[0]))
mexErrMsgTxt("Input argument must be a structure\n");
//Get the number of fields--There should be 15
NumFields = mxGetNumberOfFields(prhs[0]);
if (NumFields != 15)
{
sprintf(s1,"NumFields = %d: It should equal 15!! exiting\n",NumFields);
mexErrMsgTxt(s1);
}
/***************************************************/
//Extract Fields
//S_CCPCH format ID field 1
tmpPtr = mxGetField(prhs[0],0,"S_CCPCHformatID");
if (tmpPtr == NULL)
mexErrMsgTxt("Field S_CCPCHformatID could not be found. Verify validity of field name\n");
SimConfig.S_CCPCHformatID = (unsigned) mxGetScalar(tmpPtr);
//PDSCH format ID field 2
tmpPtr = mxGetField(prhs[0],0,"PDSCHformatID");
if (tmpPtr == NULL)
mexErrMsgTxt("Field PDSCHformatID could not be found. Verify validity of field name\n");
SimConfig.PDSCHformatID = (unsigned) mxGetScalar(tmpPtr);
//Desired DPCH format ID field 3
tmpPtr = mxGetField(prhs[0],0,"DesiredDPCHformatID");
if (tmpPtr == NULL)
mexErrMsgTxt("Field DesiredDPCHformatID could not be found. Verify validity of field name\n");
SimConfig.DesiredDPCHformatID = (unsigned) mxGetScalar(tmpPtr);
//Number of Remaining DPCHs field 4
tmpPtr = mxGetField(prhs[0],0,"Num_DPCH");
if (tmpPtr == NULL)
mexErrMsgTxt("Field Num_DPCH could not be found. Verify validity of field name\n");
SimConfig.Num_DPCH = (unsigned) mxGetScalar(tmpPtr);
//Number of DPCCH for CPCH field 5
tmpPtr = mxGetField(prhs[0],0,"NumDPCCHforCPCH");
if (tmpPtr == NULL)
mexErrMsgTxt("Field NumDPCCHforCPCH could not be found. Verify validity of field name\n");
SimConfig.NumDPCCHforCPCH = (unsigned) mxGetScalar(tmpPtr);
//Number of S_CPICH field 6
tmpPtr = mxGetField(prhs[0],0,"NumS_CPICH");
if (tmpPtr == NULL)
mexErrMsgTxt("Field NumS_CPICH could not be found. Verify validity of field name\n");
SimConfig.NumS_CPICH = (unsigned) mxGetScalar(tmpPtr);
//STTDflag field 7
tmpPtr = mxGetField(prhs[0],0,"STTD");
if (tmpPtr == NULL)
mexErrMsgTxt("Field STTD could not be found. Verify validity of field name\n");
SimConfig.STTDflag = (bool) mxGetScalar(tmpPtr);
//Pulse Upper Bound field 8
tmpPtr = mxGetField(prhs[0],0,"PulseLength");
if (tmpPtr == NULL)
mexErrMsgTxt("Field PulseUpperBound could not be found. Verify validity of field name\n");
SimConfig.PulseLength = (unsigned) mxGetScalar(tmpPtr);
//Samples Per Chip field 9
tmpPtr = mxGetField(prhs[0],0,"SamplesPerChip");
if (tmpPtr == NULL)
mexErrMsgTxt("Field SamplesPerChip could not be found. Verify validity of field name\n");
SimConfig.SamplesPerChip = (unsigned) mxGetScalar(tmpPtr);
//EbNo_dB field 10
tmpPtr = mxGetField(prhs[0],0,"EbNo_dB");
if (tmpPtr == NULL)
mexErrMsgTxt("Field EbNo_dB could not be found. Verify validity of field name\n");
SimConfig.EbNo_dB = mxGetScalar(tmpPtr);
//Velocity field 11
tmpPtr = mxGetField(prhs[0],0,"Velocity");
if (tmpPtr == NULL)
mexErrMsgTxt("Field Velocity could not be found. Verify validity of field name\n");
SimConfig.Velocity = mxGetScalar(tmpPtr);
//Other DPCH Format ID field 12
tmpPtr = mxGetField(prhs[0],0,"OtherDPCHformatID");
if (tmpPtr == NULL)
mexErrMsgTxt("Field OtherDPCHformatID could not be found. Verify validity of field name\n");
fee = mxGetPr(tmpPtr);
SimConfig.OtherDPCHformatID = (unsigned *) calloc(SimConfig.Num_DPCH,sizeof(unsigned));
for (k=0; k<SimConfig.Num_DPCH; k++) *((SimConfig.OtherDPCHformatID) + k) = (unsigned) *(fee + k);
//Delays field 13
tmpPtr = mxGetField(prhs[0],0,"Delays");
if (tmpPtr == NULL)
mexErrMsgTxt("Field Delays could not be found. Verify validity of field name\n");
SimConfig.Delays = mxGetPr(tmpPtr);
Ncolumns = mxGetN(tmpPtr);
Mrows = mxGetM(tmpPtr);
if (Ncolumns == 1) SimConfig.MPathComponents = Mrows;
else if (Mrows == 1) SimConfig.MPathComponents = Ncolumns;
else mexErrMsgTxt("The Delays field must either be a scalar or a vector, not a matrix\n");
//Amplitudes field 14
tmpPtr = mxGetField(prhs[0],0,"Amplitudes");
if (tmpPtr == NULL)
mexErrMsgTxt("Field Amplitudes could not be found. Verify validity of field name\n");
SimConfig.Amplitudes = mxGetPr(tmpPtr);
//Iterations Field 15
tmpPtr = mxGetField(prhs[0],0,"Iterations");
if (tmpPtr == NULL)
mexErrMsgTxt("Field Iterations could not be found. Verify validity of field name\n");
SimConfig.Iterations = (unsigned) mxGetScalar(tmpPtr);
ErrorRun = DownLinkSimulator(SimConfig);
plhs[0] = mxCreateDoubleMatrix(1,ErrorRun.Length,mxREAL);
fee = (double *) mxCalloc(ErrorRun.Length,sizeof(double));
if (fee == NULL)
mexErrMsgTxt("Array allocation for Error Run vector (fee) failed!--exiting\n");
for (k=0; k<ErrorRun.Length; k++) *(fee+k) = (double) *(ErrorRun.Array+k);
free(ErrorRun.Array);
ErrorRun.Array = NULL;
mxSetPr(plhs[0],fee);
}
ErrorRunClass DownLinkSimulator(SimConfigClass Config)
/****************************************************************************************************
/ErrorRunClass DownLinkSimulator(SimConfigClass Config)
/
/ Copyright 2002 The Mobile and Portable Radio Research Group
/
/
/Executive function that runs the simulator
*****************************************************************************************************/
{
ErrorRunClass ErrorRun;
unsigned RunCount,*TempErrorArray;
unsigned ErrorRunBlockSize,ErrorRunBlockIncrement = 1000,ErrorRunOffset;
bool ErrorState;
unsigned formatid[2] = {11,14};
unsigned k,Iterations=10;
ChannelClass *Channel2;
int *DataBits,*ReceivedDataBits,*SentDataBits;
unsigned DataBitLength;
// FILE *fp;
unsigned j;
mxArray *plhs[1],*prhs[2];
int nlhs=1,nrhs=2,mexStatus;
double *ZeroPtr,FigureHandle,*FigureHandlePtr;
//Initialize Objects
TransmitterClass Tx(Config); //Transmitter object
ModulatorClass Modulator(Config); //Modulator Object
ChannelClass Channel1(Config, &Modulator, &Tx); //Channel Object for 1st Tx antenna
//Channel object for 2nd Tx antenna (if STTD is used)
if (Tx.TxConfiguration.STTDflag) Channel2 = new ChannelClass (Config, &Modulator, &Tx);
//Receier Object
ReceiverClass Rx(Config,&(Tx.TxConfiguration));
//Set up Wait Bar--Matlab function
prhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
ZeroPtr = (double *) mxCalloc(1,sizeof(double));
FigureHandlePtr = (double *) mxCalloc(1,sizeof(double));
mxSetPr(prhs[0],ZeroPtr);
prhs[1] = mxCreateString("Simulation in Progress");
mexStatus = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"waitbar");
if (mexStatus != 0)
mexErrMsgTxt("Call to mexCallMATLAB failed!--exiting\n");
FigureHandle = mxGetScalar(plhs[0]);
*FigureHandlePtr = FigureHandle;
mxDestroyArray(prhs[1]);
//Stores handle to wait bar
prhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
mxSetPr(prhs[1],FigureHandlePtr);
//Allocate fist block of data for the error run array
ErrorRun.Array = (unsigned *) calloc(ErrorRunBlockIncrement,sizeof(unsigned));
ErrorRunBlockSize = ErrorRunBlockIncrement;
TempErrorArray = ErrorRun.Array;
ErrorState = false;
RunCount = 1; //Assume that the first bit was correctly received
ErrorRun.Length = 0;
//Generate the three frames
Tx.PreviousFrame = Tx.GenerateInitialFrame();
Tx.CurrentFrame = Tx.GenerateFrame();
Tx.NextFrame = Tx.GenerateFrame();
//Generate "previous" signal
Modulator.PrevSignal1= Modulator.GenerateDownlinkSignal(Tx.CurrentFrame.Chips,Tx.PreviousFrame.Chips,Tx.NextFrame.Chips);
if (Tx.TxConfiguration.STTDflag)
Modulator.PrevSignal2 = Modulator.GenerateDownlinkSignal(Tx.CurrentFrame.Chips + CHIPS_PER_FRAME,
Tx.PreviousFrame.Chips + CHIPS_PER_FRAME,
Tx.NextFrame.Chips + CHIPS_PER_FRAME);
//Delete the "Previous" frame
free(Tx.PreviousFrame.Chips);
Tx.PreviousFrame.Chips = NULL;
free(Tx.PreviousFrame.DataBits);
Tx.PreviousFrame.DataBits = NULL;
//Update the frames
//The "current" frame is now the "previous" frame
//The "next" frame is now the "current frame
Tx.PreviousFrame = Tx.CurrentFrame;
Tx.CurrentFrame = Tx.NextFrame;
//Generate a new frame for the "next" frame
Tx.NextFrame = Tx.GenerateFrame();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -