Commit b9ddfe65 authored by Florian Kaltenberger's avatar Florian Kaltenberger

moving Matlab to extras


git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7223 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 7fe41b08
include $(OPENAIR_HOME)/common/utils/Makefile.inc
#include $(OPENAIR1_DIR)/SIMULATION/LTE_PHY/Makefile
COMMON_UTILS_DIR = $(OPENAIR_HOME)/common/utils
TOP_DIR = $(OPENAIR1_DIR)
OPENAIR1_TOP = $(OPENAIR1_DIR)
OPENAIR2_TOP = $(OPENAIR2_DIR)
OPENAIR3 = $(OPENAIR3_DIR)
CFLAGS += -DMAX_NUM_CCs=1 -Wall -DPHYSIM -DNODE_RG -DUSER_MODE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DPHY_CONTEXT=1 -DMALLOC_CHECK_=1 -DENABLE_VCD_FIFO
CFLAGS += -DOPENAIR_LTE -DNO_RRM -DOPENAIR1 #-DPHY_ABSTRACTION #-DOPENAIR2
CFLAGS += -I/usr/include/X11 -I/usr/X11R6/include
include $(COMMON_UTILS_DIR)/Makefile.inc
include $(TOP_DIR)/PHY/Makefile.inc
include $(TOP_DIR)/SCHED/Makefile.inc
SCHED_OBJS = $(TOP_DIR)/SCHED/phy_procedures_lte_common.o #$(TOP_DIR)/SCHED/phy_procedures_lte_eNb.o $(TOP_DIR)/SCHED/phy_procedures_lte_ue.o
include $(TOP_DIR)/SIMULATION/Makefile.inc
include $(OPENAIR2_DIR)/LAYER2/Makefile.inc
include $(OPENAIR2_DIR)/UTIL/Makefile.inc
include $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc
ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES
CFLAGS += $(L2_incl) -I$(ASN1_MSG_INC) -I$(TOP_DIR) -I$(OPENAIR2_DIR) -I$(OPENAIR3) $(UTIL_incl) $(UTILS_incl)
CFLAGS += -DMEX -fPIC
CFLAGS += -I/opt/MATLAB/R2014a/extern/include/
# Set mex extension, can be determined with mexext function in Matlab
MEXEXT = mexglx
# Just compile all the PHY objects
OBJ = $(PHY_OBJS) $(TOP_DIR)/SIMULATION/TOOLS/taus.o $(LOG_DIR)/log.o $(LOG_DIR)/vcd_signal_dumper.o
# List of all mex-files to compile
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/get_tbs.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_encoding.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_decoding.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_decoding_init.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_channel_level_prec.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_channel_compensation_prec.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_dual_stream_correlation.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_detection_mrc.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_mu_mimo_llr.$(MEXEXT)
MEX_FILES += ./PHY/TOOLS/mexfiles/log2_approx.$(MEXEXT)
MEX_FILES += ./SIMULATION/TOOLS/mexfiles/taus.$(MEXEXT)
MEX_FILES += ./SIMULATION/TOOLS/mexfiles/set_taus_seed.$(MEXEXT)
# ===========================================================================================
# Commands to compile the static and shared lib for mex-files
# Libpath
LIBDIR := ./lib
LIBNAME := oai
sharedlib : $(OBJ)
@$(CC) -shared -Wl,-soname,lib$(LIBNAME).so.1 -o $(LIBDIR)/lib$(LIBNAME).so.1.0.1 $(OBJ) -lc
staticlib : $(OBJ)
@ar ruv $(LIBDIR)/lib$(LIBNAME).a $(OBJ)
libs : $(OBJ)
@$(CC) -shared -Wl,-soname,lib$(LIBNAME).so.1 -o $(LIBDIR)/lib$(LIBNAME).so.1.0.1 $(OBJ) -lc
@ar ruv $(LIBDIR)/lib$(LIBNAME).a $(OBJ)
$(MEX_FILES) : %.$(MEXEXT) : %.c
@echo
@echo Compiling $< ...
@mex CFLAGS="$(CFLAGS)" -l$(LIBNAME) -L$(LIBDIR) -output $@ $<
mex : $(MEX_FILES)
cleanlibs :
rm -f $(LIBDIR)/lib$(LIBNAME).*
cleanmex :
rm -f $(MEX_FILES)
clean:
rm -f $(OBJ)
cleanall: clean cleanlibs cleanmex
show :
echo $(ASN1_MSG_INC)
#include "../../../defs.h"
/*==============================================================================
* dlsch_channel_compensation_prec.c
*
* Returns the matched filter channel and the scaled channel magnitude.
*
* example: [ymf heff hmag hmagb] = dlsch_channel_compensation_prec(y,H,pmi,struct1,struct2,slot)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
// #define DEBUG_CHANNEL_COMP
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
int *H,*y,*dl_ch_estimates_ext[NB_ANTENNAS_RX*NB_ANTENNAS_TX],*rxdataF_ext[NB_ANTENNAS_RX*NB_ANTENNAS_TX],*ymf, *hmag, *hmagb,*dl_ch_mag[NB_ANTENNAS_RX*NB_ANTENNAS_TX],
*dl_ch_magb[NB_ANTENNAS_RX*NB_ANTENNAS_TX];
int *rxdataF_comp[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *ymf_out, *hmag_out, *hmagb_out, *heff_out, *heff;
unsigned int nb_re_per_symbol, nb_re, nb_re_per_frame;
unsigned char *pmi_ext, mod_order, output_shift,dl_power_off;
unsigned char symbol;
int eNB_id = 0,i; // dummy
mxArray *tmp;
LTE_DL_FRAME_PARMS *frame_parms;
PHY_MEASUREMENTS *phy_measurements;
/* Check proper input and output. */
if(nrhs!=6)
mexErrMsgTxt("5 inputs required.");
else if(nlhs > 4)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[3]))
mexErrMsgTxt("Fourth input must be a structure.");
else if(!mxIsStruct(prhs[4]))
mexErrMsgTxt("Fifth input must be a structure.");
if(!mxIsInt16(prhs[0]))
mexErrMsgTxt("First argument must belong to Int16 class.");
if(!mxIsInt16(prhs[1]))
mexErrMsgTxt("Second argument must belong to Int16 class.");
if(!mxIsUint8(prhs[2]))
mexErrMsgTxt("Third argument must belong to Uint8 class.");
/* Allocate input */
y = (int*) mxGetData(prhs[0]);
H = (int*) mxGetData(prhs[1]);
pmi_ext = (unsigned char*) mxGetData(prhs[2]);
symbol = (unsigned char) mxGetScalar(prhs[5]);
tmp = mxGetField(prhs[4],0,"mod_order");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'mod_order' in input argument 5.");
} else {
mod_order = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"log2_maxh");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'log2_maxh' in input argument 4.");
} else {
output_shift = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"dl_power_offset");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'dl_power_offset' in input argument 4.");
} else {
dl_power_off = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"nb_re");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_re' in input argument 4.");
} else {
nb_re = (unsigned int) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"nb_re_per_frame");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_re_per_frame' in input argument 4.");
} else {
nb_re_per_frame = (unsigned int) mxGetScalar(tmp);
}
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
tmp = mxGetField(prhs[3],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 4.");
} else {
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"nb_antennas_rx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 4.");
} else {
frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"nb_antennas_tx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_tx' in input argument 4.");
} else {
frame_parms->nb_antennas_tx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ncp' in input argument 4.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"ofdm_symbol_size");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'ofdm_symbol_size' in input argument 4.");
} else {
frame_parms->ofdm_symbol_size = (unsigned short) mxGetScalar(tmp);
}
// Create PHY_MEASUREMENTS structure and assign required params
phy_measurements = calloc(1,sizeof(PHY_MEASUREMENTS));
phy_measurements->n0_power[0] = 1; // dummy values
phy_measurements->n0_power[1] = 1;
phy_measurements->n0_power_tot = 1;
// Adapt the channel estimates and receive signal
nb_re_per_symbol = frame_parms->N_RB_DL*12;
// Assign pointers
rxdataF_ext[0] = y;
rxdataF_ext[1] = &y[nb_re_per_frame];
rxdataF_ext[2] = &y[2*nb_re_per_frame];
rxdataF_ext[3] = &y[3*nb_re_per_frame];
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
ymf_out = (int*) mxGetPr(plhs[0]);
plhs[1] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
heff_out = (int*) mxGetPr(plhs[1]);
plhs[2] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
hmag_out = (int*) mxGetPr(plhs[2]);
plhs[3] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
hmagb_out = (int*) mxGetPr(plhs[3]);
ymf = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
heff = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
hmag = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
hmagb = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
// copy input since it gets modified in function "dlsch_channel_compensation_prec"
memcpy(heff,H,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame)<<2);
rxdataF_comp[0] = ymf;
rxdataF_comp[1] = &ymf[nb_re_per_frame];
rxdataF_comp[2] = &ymf[2*nb_re_per_frame];
rxdataF_comp[3] = &ymf[3*nb_re_per_frame];
dl_ch_estimates_ext[0] = heff;
dl_ch_estimates_ext[1] = &heff[nb_re_per_frame];
dl_ch_estimates_ext[2] = &heff[2*nb_re_per_frame];
dl_ch_estimates_ext[3] = &heff[3*nb_re_per_frame];
dl_ch_mag[0] = hmag;
dl_ch_mag[1] = &hmag[nb_re_per_frame];
dl_ch_mag[2] = &hmag[2*nb_re_per_frame];
dl_ch_mag[3] = &hmag[3*nb_re_per_frame];
dl_ch_magb[0] = hmagb;
dl_ch_magb[1] = &hmagb[nb_re_per_frame];
dl_ch_magb[2] = &hmagb[2*nb_re_per_frame];
dl_ch_magb[3] = &hmagb[3*nb_re_per_frame];
#ifdef DEBUG_CHANNEL_COMP
mexPrintf("symbol = %d\n", symbol);
mexPrintf("nb_re_per_symbol = %d\n", nb_re_per_symbol);
mexPrintf("nb_re_per_frame = %d\n", nb_re_per_frame);
for(i=0; i<25; i++)
mexPrintf("pmi_ext = %d\n", pmi_ext[i]);
#endif
/* Algo */
dlsch_channel_compensation_prec(rxdataF_ext,
dl_ch_estimates_ext,
dl_ch_mag,
dl_ch_magb,
rxdataF_comp,
pmi_ext,
frame_parms,
phy_measurements,
eNB_id,
symbol,
mod_order,
frame_parms->N_RB_DL,
output_shift,
dl_power_off);
// memcpy copies bytes!
memcpy(ymf_out,&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf_out[nb_re_per_symbol],&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf_out[2*nb_re_per_symbol],&rxdataF_comp[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf_out[3*nb_re_per_symbol],&rxdataF_comp[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(hmag_out,&dl_ch_mag[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmag_out[nb_re_per_symbol],&dl_ch_mag[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmag_out[2*nb_re_per_symbol],&dl_ch_mag[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmag_out[3*nb_re_per_symbol],&dl_ch_mag[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(hmagb_out, &dl_ch_magb[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmagb_out[nb_re_per_symbol],&dl_ch_magb[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmagb_out[2*nb_re_per_symbol],&dl_ch_magb[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmagb_out[3*nb_re_per_symbol],&dl_ch_magb[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(heff_out,&dl_ch_estimates_ext[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&heff_out[nb_re_per_symbol],&dl_ch_estimates_ext[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&heff_out[2*nb_re_per_symbol],&dl_ch_estimates_ext[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&heff_out[3*nb_re_per_symbol],&dl_ch_estimates_ext[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
/* free */
free(frame_parms);
free(phy_measurements);
mxFree(ymf);
mxFree(heff);
mxFree(hmag);
mxFree(hmagb);
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_channel_level_prec.c
*
* Returns average squared channel magnitude of effective channel.
*
* example: avg = dlsch_channel_level_prec(H,pmi,simparms);
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
int *H,*dl_ch_estimates_ext[4];
unsigned int nb_re_per_frame;
unsigned char *pmi_ext;
unsigned char symbol_mod = 3;
int *avg;
mxArray *tmp;
LTE_DL_FRAME_PARMS *frame_parms;
/* Check proper input and output. */
if(nrhs!=3)
mexErrMsgTxt("Three inputs required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[2]))
mexErrMsgTxt("Third input must be a structure.");
if(!mxIsInt16(prhs[0]))
mexErrMsgTxt("First argument must belong to Int16 class.");
if(!mxIsUint8(prhs[1]))
mexErrMsgTxt("Second argument must belong to Uint8 class.");
/* Allocate input */
H = (int*) mxGetData(prhs[0]);
pmi_ext = (unsigned char*) mxGetData(prhs[1]);
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
tmp = mxGetField(prhs[2],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 3.");
} else {
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"nb_antennas_rx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 3.");
} else {
frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"mode1_flag");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'mode1_flag' in input argument 3.");
} else {
frame_parms->mode1_flag = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ncp' in input argument 3.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
// Adapt the channel estimates
tmp = mxGetField(prhs[2],0,"nb_re_per_frame");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_re_per_frame' in input argument 3.");
} else {
nb_re_per_frame = (unsigned int) mxGetScalar(tmp);
}
dl_ch_estimates_ext[0] = (int*) H;
dl_ch_estimates_ext[1] = (int*) &H[nb_re_per_frame];
dl_ch_estimates_ext[2] = (int*) &H[2*nb_re_per_frame];
dl_ch_estimates_ext[3] = (int*) &H[3*nb_re_per_frame];
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
avg = (int*) mxGetPr(plhs[0]);
/* Algo */
dlsch_channel_level_prec(dl_ch_estimates_ext, frame_parms, pmi_ext, avg, symbol_mod, frame_parms->N_RB_DL);
/* free */
free(frame_parms);
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_encoding.c
*
* Returns the decoded bit sequence.
*
* example: e = dlsch_encoding(llrs,struct1,struct2)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
#define DEBUG_DLSCH_DECODING
void mexFunction( int mlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
short *dlsch_llr;
unsigned char mcs;
unsigned int *ret;
unsigned char mod_order;
unsigned char num_pdcch_symbols;
unsigned char harq_pid;
unsigned char subframe;
unsigned char Kmimo;
unsigned char Mdlharq;
unsigned char abstraction_flag;
LTE_UE_DLSCH_t* dlsch;
LTE_DL_FRAME_PARMS *frame_parms;
PHY_VARS_UE *phy_vars_ue;
extern int *pi2tab16[188],*pi5tab16[188],*pi4tab16[188],*pi6tab16[188];
unsigned long *ptr_td; //hack for 64bit
int *tmp[1];
/* Allocate input */
dlsch_llr = (short*) mxGetData(prhs[0]);
/* Create new dlsch */
Kmimo = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"Kmimo"));
Mdlharq = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"Mdlharq"));
abstraction_flag = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"abstraction_flag"));
mcs = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"mcs"));
#ifdef DEBUG_DLSCH_DECODING
mexPrintf("Kmimo %d\n",Kmimo);
mexPrintf("Mdlharq %d\n",Mdlharq);
mexPrintf("abstraction_flag %d\n",abstraction_flag);
mexPrintf("mcs %d\n",mcs);
#endif
/* Create new dlsch */
dlsch = new_ue_dlsch(Kmimo,Mdlharq,8,25,abstraction_flag);
// Init CRC tables
crcTableInit();
// init_td();
// copy the pointers to memory allocated in dlsch_decoding_init
ptr_td = (unsigned int*) mxGetData(mxGetField(prhs[1],0,"ptr_td"));
#ifdef DEBUG_DLSCH_DECODING
mexPrintf("ptr_td0 %p\n",ptr_td[0]);
mexPrintf("ptr_td1 %p\n",ptr_td[1]);
mexPrintf("ptr_td2 %p\n",ptr_td[2]);
mexPrintf("ptr_td3 %p\n",ptr_td[3]);
#endif
memcpy(&tmp[0], &ptr_td[0], sizeof(ptr_td[0]));
memcpy(&pi2tab16[0], tmp[0], 188*sizeof(pi2tab16[0]));
memcpy(&tmp[0], &ptr_td[1], sizeof(ptr_td[1]));
memcpy(&pi4tab16[0], tmp[0], 188*sizeof(pi4tab16[0]));
memcpy(&tmp[0], &ptr_td[2], sizeof(ptr_td[2]));
memcpy(&pi5tab16[0], tmp[0], 188*sizeof(pi5tab16[0]));
memcpy(&tmp[0], &ptr_td[3], sizeof(ptr_td[3]));
memcpy(&pi6tab16[0], tmp[0], 188*sizeof(pi6tab16[0]));
harq_pid = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"harq_pid"));
dlsch->current_harq_pid = harq_pid;
dlsch->harq_processes[harq_pid]->rvidx = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"rvidx"));
dlsch->harq_processes[harq_pid]->Nl = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"Nl"));
//dlsch->harq_processes[harq_pid]->Ndi = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"Ndi"));
dlsch->harq_processes[harq_pid]->mcs = mcs;
dlsch->harq_processes[harq_pid]->rb_alloc[0] = (unsigned int) mxGetScalar(mxGetField(prhs[1],0,"rb_alloc"));
dlsch->harq_processes[harq_pid]->nb_rb = (unsigned short) mxGetScalar(mxGetField(prhs[1],0,"nb_rb"));
dlsch->harq_processes[harq_pid]->TBS = dlsch_tbs25[get_I_TBS(mcs)][dlsch->harq_processes[harq_pid]->nb_rb-1];
num_pdcch_symbols = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"num_pdcch_symbols"));
subframe = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"subframe"));
phy_vars_ue = calloc(1,sizeof(PHY_VARS_UE));
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"nb_rb"));
frame_parms->frame_type = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"frame_type"));
frame_parms->mode1_flag = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"mode1_flag"));
frame_parms->Ncp = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"Ncp"));
mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs);
dlsch->harq_processes[harq_pid]->G = get_G(frame_parms,dlsch->harq_processes[harq_pid]->nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,
0,subframe);
#ifdef DEBUG_DLSCH_DECODING
mexPrintf("TBS %d\n",dlsch->harq_processes[harq_pid]->TBS);
mexPrintf("nb_rb %d\n",dlsch->harq_processes[harq_pid]->nb_rb);
mexPrintf("ncs %d\n",dlsch->harq_processes[harq_pid]->mcs);
mexPrintf("num_pdcch_symbols %d\n",num_pdcch_symbols);
mexPrintf("subframe %d\n",subframe);
mexPrintf("G %d\n",dlsch->harq_processes[harq_pid]->G);
#endif
if (dlsch->harq_processes[harq_pid]->G != mxGetM(prhs[0])) {
free_ue_dlsch(dlsch);
free(frame_parms);
free(phy_vars_ue);
mexErrMsgTxt("Length of the LLR vector is incorrect.");
}
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
ret = (unsigned int*) mxGetPr(plhs[0]);
/* Algo */
*ret = dlsch_decoding(phy_vars_ue, dlsch_llr, frame_parms, dlsch, dlsch->harq_processes[harq_pid], subframe, dlsch->current_harq_pid, 1,0);
/* free dlsch */
free_ue_dlsch(dlsch);
free(frame_parms);
free(phy_vars_ue);
// free_td();
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_encoding_init.c
*
* Returns the decoded bit sequence.
*
* example: dlsch_decoding_init(struct1)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
#define DEBUG_DLSCH_DECODING_INIT
void mexFunction( int mlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
extern int *pi2tab16[188],*pi5tab16[188],*pi4tab16[188],*pi6tab16[188];
int i;
unsigned long *ptr; //hack for 64bit
int **tmp[1];
// Init CRC tables
// crcTableInit();
init_td16();
// assign output
plhs[0] = mxCreateNumericMatrix(4,1, mxUINT64_CLASS, mxREAL);
ptr = (unsigned int*) mxGetData(plhs[0]);
tmp[0] = &pi2tab16[0];
memcpy(&ptr[0], tmp, sizeof(tmp[0]));
tmp[0] = &pi4tab16[0];
memcpy(&ptr[1], tmp, sizeof(tmp[0]));
tmp[0] = &pi5tab16[0];
memcpy(&ptr[2], tmp, sizeof(tmp[0]));
tmp[0] = &pi6tab16[0];
memcpy(&ptr[3], tmp, sizeof(tmp[0]));
#ifdef DEBUG_DLSCH_DECODING_INIT
mexPrintf("pi2tab %p\n",&pi2tab16[0]);
mexPrintf("pi4tab %p\n",&pi4tab16[0]);
mexPrintf("pi5tab %p\n",&pi5tab16[0]);
mexPrintf("pi6tab %p\n",&pi6tab16[0]);
mexPrintf("ptr0 %p\n",ptr[0]);
mexPrintf("ptr1 %p\n",ptr[1]);
mexPrintf("ptr2 %p\n",ptr[2]);
mexPrintf("ptr3 %p\n",ptr[3]);
#endif
// The memory here is never explictly freed via mxFree. It is implicitly taken
// care of by clear functions at the beginning of the simulation.
for (i=0; i<188; i++) {
mexMakeMemoryPersistent((void *) pi2tab16[i]);
mexMakeMemoryPersistent((void *) pi5tab16[i]);
mexMakeMemoryPersistent((void *) pi4tab16[i]);
mexMakeMemoryPersistent((void *) pi6tab16[i]);
}
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_detection_mrc.c
*
* Combines the parameters of both receive antennas.
*
* example: [ymf heff hmag hmagb] = dlsch_detection_mrc(ymf0,ymf1,hmag0,hmag1,hamgb0,hmagb1,rho10,struct,slot)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
//#define DEBUG_DETECTION_MRC
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
int *ymf0, *ymf1, *Hmag0, *Hmag1, *Hmag0b, *Hmag1b, *rho10;
int *ymf0_out, *ymf1_out, *Hmag0_out, *Hmag1_out, *Hmag0b_out, *Hmag1b_out, *rho10_out;
int *ymf0_cpy, *ymf1_cpy, *Hmag0_cpy, *Hmag1_cpy, *Hmag0b_cpy, *Hmag1b_cpy, *rho10_cpy;
int *rxdataF_comp[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *rxdataF_comp_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *rho_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX];
int *dl_ch_mag[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *dl_ch_mag_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *dl_ch_magb[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *dl_ch_magb_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX];
int i;
mxArray *tmp;
unsigned int nb_re_per_symbol, nb_re_per_frame;
unsigned char symbol, dual_stream_UE;
LTE_DL_FRAME_PARMS *frame_parms;
/* Check proper input and output. */
if(nrhs!=9)
mexErrMsgTxt("9 inputs required.");
else if(nlhs > 7)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[7]))
mexErrMsgTxt("8th input must be a structure.");
if(!mxIsInt16(prhs[0]))
mexErrMsgTxt("First argument must belong to Int16 class.");
if(!mxIsInt16(prhs[1]))
mexErrMsgTxt("Second argument must belong to Int16 class.");
if(!mxIsInt16(prhs[2]))
mexErrMsgTxt("Third argument must belong to Int16 class.");
if(!mxIsInt16(prhs[3]))
mexErrMsgTxt("Fourth argument must belong to Int16 class.");
if(!mxIsInt16(prhs[4]))
mexErrMsgTxt("Fifth argument must belong to Int16 class.");
if(!mxIsInt16(prhs[5]))
mexErrMsgTxt("Sixth argument must belong to Int16 class.");
if(!mxIsInt16(prhs[6]))
mexErrMsgTxt("Seventh argument must belong to Int16 class.");
/* Allocate input */
ymf0 = (int*) mxGetData(prhs[0]);
ymf1 = (int*) mxGetData(prhs[1]);
Hmag0 = (int*) mxGetData(prhs[2]);
Hmag1 = (int*) mxGetData(prhs[3]);
Hmag0b = (int*) mxGetData(prhs[4]);
Hmag1b = (int*) mxGetData(prhs[5]);
rho10 = (int*) mxGetData(prhs[6]);
symbol = (unsigned char) mxGetScalar(prhs[8]);
tmp = mxGetField(prhs[7],0,"nb_re_per_frame");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_re_per_frame' in input argument 8.");
} else {
nb_re_per_frame = (unsigned int) mxGetScalar(tmp);
}
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
tmp = mxGetField(prhs[7],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 8.");
} else {
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[7],0,"nb_antennas_rx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 8.");
} else {
frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[7],0,"nb_antennas_tx_eNB");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_tx_eNB' in input argument 8.");
} else {
frame_parms->nb_antennas_tx_eNB = (unsigned char) mxGetScalar(tmp);
}
nb_re_per_symbol = frame_parms->N_RB_DL*12;
if (frame_parms->nb_antennas_rx>1)
dual_stream_UE = 1;
// Make copies of inputs to avoid override
ymf0_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
ymf1_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
Hmag0_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
Hmag1_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
Hmag0b_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
Hmag1b_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
rho10_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
memcpy(ymf0_cpy,ymf0,NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2);
memcpy(ymf1_cpy,ymf1,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
memcpy(Hmag0_cpy,Hmag0,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
memcpy(Hmag1_cpy,Hmag1,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
memcpy(Hmag0b_cpy,Hmag0b,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
memcpy(Hmag1b_cpy,Hmag1b,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
memcpy(rho10_cpy,rho10,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
// Assign correct inputs to algo
rxdataF_comp[0] = ymf0_cpy;
rxdataF_comp[1] = &ymf0_cpy[nb_re_per_frame];
rxdataF_comp[2] = &ymf0_cpy[2*nb_re_per_frame];
rxdataF_comp[3] = &ymf0_cpy[3*nb_re_per_frame];
rxdataF_comp_i[0] = ymf1_cpy;
rxdataF_comp_i[1] = &ymf1_cpy[nb_re_per_frame];
rxdataF_comp_i[2] = &ymf1_cpy[2*nb_re_per_frame];
rxdataF_comp_i[3] = &ymf1_cpy[3*nb_re_per_frame];
rho_i[0] = rho10_cpy;
rho_i[1] = &rho10_cpy[nb_re_per_frame];
rho_i[2] = &rho10_cpy[2*nb_re_per_frame];
rho_i[3] = &rho10_cpy[3*nb_re_per_frame];
dl_ch_mag[0] = Hmag0_cpy;
dl_ch_mag[1] = &Hmag0_cpy[nb_re_per_frame];
dl_ch_mag[2] = &Hmag0_cpy[2*nb_re_per_frame];
dl_ch_mag[3] = &Hmag0_cpy[3*nb_re_per_frame];
dl_ch_magb[0] = Hmag0b_cpy;
dl_ch_magb[1] = &Hmag0b_cpy[nb_re_per_frame];
dl_ch_magb[2] = &Hmag0b_cpy[2*nb_re_per_frame];
dl_ch_magb[3] = &Hmag0b_cpy[3*nb_re_per_frame];
dl_ch_mag_i[0] = Hmag1_cpy;
dl_ch_mag_i[1] = &Hmag1_cpy[nb_re_per_frame];
dl_ch_mag_i[2] = &Hmag1_cpy[2*nb_re_per_frame];
dl_ch_mag_i[3] = &Hmag1_cpy[3*nb_re_per_frame];
dl_ch_magb_i[0] = Hmag1b_cpy;
dl_ch_magb_i[1] = &Hmag1b_cpy[nb_re_per_frame];
dl_ch_magb_i[2] = &Hmag1b_cpy[2*nb_re_per_frame];
dl_ch_magb_i[3] = &Hmag1b_cpy[3*nb_re_per_frame];
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
ymf0_out = (int*) mxGetPr(plhs[0]);
plhs[1] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
ymf1_out = (int*) mxGetPr(plhs[1]);
plhs[2] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
Hmag0_out = (int*) mxGetPr(plhs[2]);
plhs[3] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
Hmag0b_out = (int*) mxGetPr(plhs[3]);
plhs[4] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
Hmag1_out = (int*) mxGetPr(plhs[4]);
plhs[5] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
Hmag1b_out = (int*) mxGetPr(plhs[5]);
plhs[6] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
rho10_out = (int*) mxGetPr(plhs[6]);
#ifdef DEBUG_DETECTION_MRC
mexPrintf("Got until here\n");
#endif
/* Algo */
dlsch_detection_mrc(frame_parms,
rxdataF_comp,
rxdataF_comp_i,
NULL,
rho_i,
dl_ch_mag,
dl_ch_magb,
dl_ch_mag_i,
dl_ch_magb_i,
symbol,
frame_parms->N_RB_DL,
dual_stream_UE);
#ifdef DEBUG_DETECTION_MRC
mexPrintf("Got until here too\n");
#endif
// memcpy copies bytes!
memcpy(ymf0_out,&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf0_out[nb_re_per_symbol],&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf0_out[2*nb_re_per_symbol],&rxdataF_comp[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf0_out[3*nb_re_per_symbol],&rxdataF_comp[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(ymf1_out,&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf1_out[nb_re_per_symbol],&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf1_out[2*nb_re_per_symbol],&rxdataF_comp_i[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf1_out[3*nb_re_per_symbol],&rxdataF_comp_i[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(Hmag0_out,&dl_ch_mag[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&Hmag0_out[nb_re_per_symbol],&dl_ch_mag[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&Hmag0_out[2*nb_re_per_symbol],&dl_ch_mag[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&Hmag0_out[3*nb_re_per_symbol],&dl_ch_mag[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(Hmag0b_out, &dl_ch_magb[0][symbol*frame_parms->N_RB_DL*12], nb_re_per_symbol<<2);
memcpy(&Hmag0b_out[nb_re_per_symbol],&dl_ch_magb[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&Hmag0b_out[2*nb_re_per_symbol],&dl_ch_magb[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&Hmag0b_out[3*nb_re_per_symbol],&dl_ch_magb[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(Hmag1_out,&dl_ch_mag_i[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&Hmag1_out[nb_re_per_symbol],&dl_ch_mag_i[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&Hmag1_out[2*nb_re_per_symbol],&dl_ch_mag_i[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&Hmag1_out[3*nb_re_per_symbol],&dl_ch_mag_i[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(Hmag1b_out, &dl_ch_magb_i[0][symbol*frame_parms->N_RB_DL*12], nb_re_per_symbol<<2);
memcpy(&Hmag1b_out[nb_re_per_symbol],&dl_ch_magb_i[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&Hmag1b_out[2*nb_re_per_symbol],&dl_ch_magb_i[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&Hmag1b_out[3*nb_re_per_symbol],&dl_ch_magb_i[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(rho10_out, &rho_i[0][symbol*frame_parms->N_RB_DL*12], nb_re_per_symbol<<2);
memcpy(&rho10_out[nb_re_per_symbol],&rho_i[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&rho10_out[2*nb_re_per_symbol],&rho_i[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&rho10_out[3*nb_re_per_symbol],&rho_i[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
/* free */
free(frame_parms);
mxFree(ymf0_cpy);
mxFree(ymf1_cpy);
mxFree(Hmag0_cpy);
mxFree(Hmag1_cpy);
mxFree(Hmag0b_cpy);
mxFree(Hmag1b_cpy);
mxFree(rho10_cpy);
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_dual_stream_correlation.c
*
* Returns the correlation coefficient Heff1'Heff0.
*
* example: rho = dlsch_dual_stream_correlation(Heff0,Heff1,simparms,slot);
*
* Author: Sebastian Wagner
* Date: 24-07-2012
*
===============================================================================*/
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
int *dl_ch_estimates_ext[NB_ANTENNAS_RX*NB_ANTENNAS_TX],*dl_ch_estimates_ext_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX],*Heff0,*Heff1,*rho10,*rho10_out,*dl_ch_rho_ext[NB_ANTENNAS_RX*NB_ANTENNAS_TX];
unsigned int nb_re_per_symbol, nb_re_per_frame;
unsigned char output_shift, symbol;
LTE_DL_FRAME_PARMS *frame_parms;
mxArray *tmp;
/* Check proper input and output. */
if(nrhs!=4)
mexErrMsgTxt("4 inputs required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[2]))
mexErrMsgTxt("Third input must be a structure.");
if(!mxIsInt16(prhs[0]))
mexErrMsgTxt("First argument must belong to Int16 class.");
if(!mxIsInt16(prhs[1]))
mexErrMsgTxt("Second argument must belong to Int16 class.");
/* Allocate input */
Heff0 = (int*) mxGetData(prhs[0]);
Heff1 = (int*) mxGetData(prhs[1]);
symbol = (unsigned char) mxGetScalar(prhs[3]);
tmp = mxGetField(prhs[2],0,"log2_maxh");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'log2_maxh' in input argument 3.");
} else {
output_shift = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"nb_re_per_frame");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_re_per_frame' in input argument 3.");
} else {
nb_re_per_frame = (unsigned int) mxGetScalar(tmp);
}
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
tmp = mxGetField(prhs[2],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 3.");
} else {
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"nb_antennas_rx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 3.");
} else {
frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ncp' in input argument 3.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
nb_re_per_symbol = frame_parms->N_RB_DL*12;
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
rho10_out = (int*) mxGetPr(plhs[0]);
rho10 = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
dl_ch_rho_ext[0] = rho10;
dl_ch_rho_ext[1] = &rho10[nb_re_per_frame];
dl_ch_rho_ext[2] = &rho10[2*nb_re_per_frame];
dl_ch_rho_ext[3] = &rho10[3*nb_re_per_frame];
dl_ch_estimates_ext[0] = Heff0;
dl_ch_estimates_ext[1] = &Heff0[nb_re_per_frame];
dl_ch_estimates_ext[2] = &Heff0[2*nb_re_per_frame];
dl_ch_estimates_ext[3] = &Heff0[3*nb_re_per_frame];
dl_ch_estimates_ext_i[0] = Heff1;
dl_ch_estimates_ext_i[1] = &Heff1[nb_re_per_frame];
dl_ch_estimates_ext_i[2] = &Heff1[2*nb_re_per_frame];
dl_ch_estimates_ext_i[3] = &Heff1[3*nb_re_per_frame];
/* Algo */
dlsch_dual_stream_correlation(frame_parms,
symbol,
frame_parms->N_RB_DL,
dl_ch_estimates_ext,
dl_ch_estimates_ext_i,
dl_ch_rho_ext,
output_shift);
memcpy(rho10_out,&dl_ch_rho_ext[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&rho10_out[nb_re_per_symbol],&dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&rho10_out[2*nb_re_per_symbol],&dl_ch_rho_ext[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&rho10_out[3*nb_re_per_symbol],&dl_ch_rho_ext[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
/* free */
free(frame_parms);
mxFree(rho10);
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_encoding.c
*
* Returns the encoded bit sequence.
*
* example: e = dlsch_encoding(bits,struct1,struct2)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
// #define DEBUG_DLSCH_ENCODING
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned char *input_buffer;
unsigned char *e; // encoded bits = output
unsigned char mcs=0;
unsigned char mod_order=2;
unsigned char num_pdcch_symbols=1;
unsigned char harq_pid=0;
unsigned char subframe=0;
unsigned char Kmimo=1;
unsigned char Mdlharq=8;
unsigned char abstraction_flag;
int ret, input_buffer_length;
unsigned int G;
mxArray *tmp;
LTE_eNB_DLSCH_t* dlsch;
LTE_DL_FRAME_PARMS *frame_parms;
time_stats_t dlsch_rate_matching_stats, dlsch_turbo_encoding_stats, dlsch_interleaving_stats;
/* Check proper input and output. */
if(nrhs!=3)
mexErrMsgTxt("Three inputs required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[1]))
mexErrMsgTxt("Second input must be a structure.");
else if(!mxIsStruct(prhs[2]))
mexErrMsgTxt("Third input must be a structure.");
// Init CRC tables
crcTableInit();
/* Create new dlsch */
tmp = mxGetField(prhs[2],0,"Kmimo");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Kmimo' in input argument 3.");
} else {
Kmimo = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Mdlharq");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Mdlharq' in input argument 3.");
} else {
Mdlharq = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"abstraction_flag");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'abstraction_flag' in input argument 2.");
} else {
abstraction_flag = (unsigned char) mxGetScalar(tmp);
}
dlsch = new_eNB_dlsch(Kmimo,Mdlharq,25,abstraction_flag);
/* Allocate input */
input_buffer = (unsigned char*) mxGetData(prhs[0]);
(mxGetM(prhs[0]) > 1) ? (input_buffer_length = mxGetM(prhs[0])) : (input_buffer_length = mxGetN(prhs[0]));
tmp = mxGetField(prhs[2],0,"mcs");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'mcs' in input argument 3.");
} else {
mcs = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"harq_pid");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'harq_pid' in input argument 3.");
} else {
harq_pid = (unsigned char) mxGetScalar(tmp);
}
dlsch->current_harq_pid = harq_pid;
dlsch->harq_processes[harq_pid]->mcs = mcs;
tmp = mxGetField(prhs[2],0,"rvidx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'rvidx' in input argument 3.");
} else {
dlsch->harq_processes[harq_pid]->rvidx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Nl");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Nl' in input argument 3.");
} else {
dlsch->harq_processes[harq_pid]->Nl = (unsigned char) mxGetScalar(tmp);
}
/*
tmp = mxGetField(prhs[2],0,"Ndi");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ndi' in input argument 3.");
} else {
dlsch->harq_processes[harq_pid]->Ndi = (unsigned char) mxGetScalar(tmp);
}
*/
tmp = mxGetField(prhs[1],0,"rb_alloc");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'rb_alloc' in input argument 2.");
} else {
dlsch->rb_alloc[0] = (unsigned int) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 2.");
} else {
dlsch->nb_rb = (unsigned short) mxGetScalar(tmp);
}
dlsch->harq_processes[harq_pid]->TBS = dlsch_tbs25[get_I_TBS(mcs)][dlsch->nb_rb-1];
// Check if input buffer length is correct
if ((input_buffer_length) != (dlsch->harq_processes[harq_pid]->TBS/8+4)) {
free_eNB_dlsch(dlsch);
mexErrMsgTxt("Length of the input buffer is incorrect.");
}
tmp = mxGetField(prhs[1],0,"num_pdcch_symbols");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'num_pdcch_symbols' in input argument 2.");
} else {
num_pdcch_symbols = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"subframe");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'subframe' in input argument 2.");
} else {
subframe = (unsigned char) mxGetScalar(tmp);
}
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
frame_parms->N_RB_DL = (unsigned char) dlsch->nb_rb;
tmp = mxGetField(prhs[1],0,"frame_type");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'frame_type' in input argument 2.");
} else {
frame_parms->frame_type = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"mode1_flag");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'frame_type' in input argument 2.");
} else {
frame_parms->mode1_flag = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'frame_type' in input argument 2.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs);
G = get_G(frame_parms,dlsch->nb_rb,dlsch->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,0,subframe);
#ifdef DEBUG_DLSCH_ENCODING
mexPrintf("dlsch->current_harq_pid = %d\n", dlsch->current_harq_pid);
mexPrintf("dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
mexPrintf("dlsch->harq_processes[harq_pid]->Nl = %d\n", dlsch->harq_processes[harq_pid]->Nl);
mexPrintf("dlsch->harq_processes[harq_pid]->Ndi = %d\n", dlsch->harq_processes[harq_pid]->Ndi);
mexPrintf("mod_order = %d\n",mod_order);
mexPrintf("G = %d\n",G);
mexPrintf("frame_parms->N_RB_DL = %d\n", frame_parms->N_RB_DL);
mexPrintf("frame_parms->frame_type = %d\n", frame_parms->frame_type);
mexPrintf("frame_parms->mode1_flag = %d\n", frame_parms->mode1_flag);
mexPrintf("frame_parms->Ncp = %d\n", frame_parms->Ncp);
#endif
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(G, 1, mxUINT8_CLASS, mxREAL);
e = (unsigned char*) mxGetPr(plhs[0]);
/* Algo */
ret = dlsch_encoding(input_buffer, frame_parms, num_pdcch_symbols, dlsch, 0, subframe,&dlsch_rate_matching_stats, &dlsch_turbo_encoding_stats, &dlsch_interleaving_stats);
/* Assign output */
memcpy((void*) e, (void*) dlsch->e,G);
/* free */
free_eNB_dlsch(dlsch);
free(frame_parms);
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_mu_mimo_llr.c
*
* Returns the LLRs for interference aware receiver.
*
* example: llr = dlsch_mu_mimo_llr(ymf0,ymf1,Hmag0,Hmag1,rho10,simparms,slot);
*
* Author: Sebastian Wagner
* Date: 24-07-2012
*
===============================================================================*/
// #define DEBUG_MU_MIMO_LLR
#define LLR_GUARD 48
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
short *ymf0, *ymf1,*hmag0, *hmag1, *rho10, *llr;
short *llr_16 __attribute__ ((aligned(16)));
unsigned char mod_order;
unsigned char symbol, symbol_mod;
int nb_re_per_symbol,i;
mxArray *tmp;
LTE_DL_FRAME_PARMS *frame_parms;
/* Check proper input and output. */
if(nrhs!=7)
mexErrMsgTxt("7 inputs required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[5]))
mexErrMsgTxt("6. input must be a structure.");
if(!mxIsInt16(prhs[0]))
mexErrMsgTxt("First argument must belong to Int16 class.");
if(!mxIsInt16(prhs[1]))
mexErrMsgTxt("Second argument must belong to Int16 class.");
if(!mxIsInt16(prhs[2]))
mexErrMsgTxt("Third argument must belong to Int16 class.");
if(!mxIsInt16(prhs[3]))
mexErrMsgTxt("4. argument must belong to Int16 class.");
if(!mxIsInt16(prhs[4]))
mexErrMsgTxt("5. argument must belong to Int16 class.");
/* Allocate input */
ymf0 = (short*) mxGetData(prhs[0]);
ymf1 = (short*) mxGetData(prhs[1]);
hmag0 = (short*) mxGetData(prhs[2]);
hmag1 = (short*) mxGetData(prhs[3]);
rho10 = (short*) mxGetData(prhs[4]);
symbol = (unsigned char) mxGetScalar(prhs[6]);
tmp = mxGetField(prhs[5],0,"codeword");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'codeword' in input argument 6.");
} else {
tmp = mxGetField(mxGetField(prhs[5],0,"codeword"),0,"mod_order");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'mod_order' in input argument '6.codeword(1)'.");
} else {
mod_order = (unsigned char) mxGetScalar(tmp);
}
}
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = (LTE_DL_FRAME_PARMS*) mxCalloc(1,sizeof(LTE_DL_FRAME_PARMS));
tmp = mxGetField(prhs[5],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 6.");
} else {
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[5],0,"nb_antennas_rx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 6.");
} else {
frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[5],0,"nb_antennas_tx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_tx' in input argument 6.");
} else {
frame_parms->nb_antennas_tx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[5],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ncp' in input argument 6.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
// Adapt the channel estimates and receive signal
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))
nb_re_per_symbol = frame_parms->N_RB_DL*8; // pilots
else
nb_re_per_symbol = frame_parms->N_RB_DL*12;
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(mod_order*nb_re_per_symbol,1, mxINT16_CLASS, mxREAL);
llr = (short*) mxGetPr(plhs[0]);
#ifdef DEBUG_MU_MIMO_LLR
mexPrintf("mod_order: %d\n", mod_order);
mexPrintf("frame_parms->N_RB_DL %d\n", frame_parms->N_RB_DL);
mexPrintf("frame_parms->nb_antennas_rx %d\n", frame_parms->nb_antennas_rx);
mexPrintf("frame_parms->nb_antennas_tx %d\n", frame_parms->nb_antennas_tx);
mexPrintf("frame_parms->Ncp %d\n", frame_parms->Ncp);
mexPrintf("nb_re_per_symbol %d\n", nb_re_per_symbol);
mexPrintf("frame_parms %p\n", frame_parms);
// mexPrintf("ymf0 %p\n",ymf0);
// mexPrintf("ymf1 %p\n",ymf1);
// mexPrintf("llr %p\n",llr);
// mexPrintf("hmag0 %p\n",hmag0);
// mexPrintf("hmag1 %p\n",hmag1);
// mexPrintf("rho10 %p\n",rho10);
// for(i=0;i<(nb_re_per_symbol*2);i++) {
for(i=0; i<(8*2); i++) {
mexPrintf("i=%d\n",i);
mexPrintf("ymf0 = %d\n",ymf0[i]);
mexPrintf("ymf1 = %d\n",ymf1[i]);
mexPrintf("hmag0 = %d\n",hmag0[i]);
mexPrintf("hmag1 = %d\n",hmag1[i]);
mexPrintf("rho10 = %d\n",rho10[i]);
}
#endif
// 16 bit aligned memory allocation with guard samples
llr_16 = (short *) malloc16((mod_order*nb_re_per_symbol+LLR_GUARD)*sizeof(short));
/* Algo */
switch (mod_order) {
case 2 :
qpsk_qpsk(ymf0, ymf1, llr_16, rho10, nb_re_per_symbol);
break;
case 4 :
qam16_qam16(ymf0, ymf1, hmag0, hmag1, llr_16, rho10, nb_re_per_symbol);
break;
case 6 :
qam64_qam64(ymf0, ymf1, hmag0, hmag1, llr_16, rho10, nb_re_per_symbol);
break;
default :
mexErrMsgTxt("Unknown mod_order.");
break;
}
// copy just valid LLRs to output
memcpy((void*) llr, (void *) llr_16, mod_order*nb_re_per_symbol*sizeof(short));
/* free */
mxFree(frame_parms);
free(llr_16);
}
#include "../../../defs.h"
/*==============================================================================
* get_tbs.c
*
* Returns the transport block size (TBS) given the MCS and the number of RBs.
*
* example: tbs = get_tbs(16,25)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
unsigned char get_I_TBS(unsigned char I_MCS);
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned char mcs, nb_rb;
unsigned int *tbs;
/* Check correct I/O number */
if(nrhs!=2) {
mexErrMsgTxt("Two inputs required.");
} else if(nlhs>1) {
mexErrMsgTxt("Too many output arguments.");
}
/* Allocate input */
mcs = (unsigned char) mxGetScalar(prhs[0]);
nb_rb = (unsigned char) mxGetScalar(prhs[1]);
/* Check input */
if((mcs < 0) || (mcs > 28)) {
mexErrMsgTxt("Wrong MCS index.");
} else if((nb_rb<=0) || (nb_rb>25)) {
mexErrMsgTxt("Unsupported number of RBs.");
};
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
tbs = (unsigned int*) mxGetPr(plhs[0]);
/* Algo */
*tbs = dlsch_tbs25[get_I_TBS(mcs)][nb_rb-1];
}
%% Testfile for dlsch_encoding mex-function
clear all;
addpath('../mexfiles');
%% Input
simparms.nb_rb = 25; % fixed number of RB per OFDM symbol
simparms.rb_alloc = hex2dec('1FFFFFF'); % 25 ones
simparms.num_pdcch_symbols = 3;
simparms.subframe = 7;
simparms.abstraction_flag = 0;
simparms.frame_type = 1; % TDD frame
simparms.mode1_flag = 0; % is TM1 active?
simparms.Ncp = 0; % Normal CP
codeword.mcs = 13;
codeword.TBS = get_tbs(codeword.mcs,simparms.nb_rb);
codeword.Kmimo = 1;
codeword.harq_pid = 0; % First HARQ round
codeword.Mdlharq = 1; % Number of HARQ rounds
codeword.rvidx = 0;
codeword.Nl = 1;
codeword.Ndi = 1;
data0 = uint8(randi([0,255],codeword.TBS/8+4,1));
%% mex
edata0 = dlsch_encoding(data0,simparms,codeword);
llr = int16((double(edata0)-0.5)*128);
ret0 = dlsch_decoding(llr,simparms,codeword);
%% Print
disp(ret0);
\ No newline at end of file
#include "../../../defs.h"
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned int x;
unsigned char *l2;
/* Allocate input */
x = (unsigned int) mxGetScalar(prhs[0]);
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(1, 1, mxUINT8_CLASS, mxREAL);
l2 = (unsigned char*) mxGetPr(plhs[0]);
/* Algo */
*l2 = log2_approx(x);
}
\ No newline at end of file
function [ simparms ] = InitSimparms( mcs, n_frames, SNRdB )
%INITSIMPARMS initialize simparms struct for TM5
% There are always 2 user schedules for transmission
% INPUT:
% nb_antennas_tx = Number of transmit antennas, max = 2
% nb_antennas_rx = Number of receive antennas per UE, max = 2
% MCS(2) = Modulation and Coding Scheme [1,...,27]
% n_frames = Number of frames to simulate
% SNRdB = SNR in dB
addpath('../../../PHY/LTE_TRANSPORT/mexfiles');
j = sqrt(-1);
%% Custom parameters
simparms.nb_antennas_tx = 2;
simparms.nb_antennas_tx_eNB = simparms.nb_antennas_tx;
simparms.nb_antennas_rx = 2;
simparms.n_frames = n_frames;
simparms.snr_db = SNRdB;
%% Constant parameters
simparms.NB_ANTENNAS_TX = 2; % max number of TX antennas
simparms.NB_ANTENNAS_RX = 2; % max number of RX antennas
simparms.snr = 10.^(SNRdB/10);
simparms.num_pdcch_symbols = 3;
simparms.subframe = 7;
simparms.abstraction_flag = 0;
simparms.nb_rb = 25; % fixed number of RB per OFDM symbol
simparms.rb_alloc = hex2dec('1FFF'); % 25 RBs
simparms.MAX_TURBO_ITERATIONS = 5;
simparms.nb_re = 3000; % there are 3000 REs in subframe 7
simparms.frame_type = 1; % TDD frame
simparms.mode1_flag = 0; % no is TM1 active
simparms.Ncp = 0; % Normal CP
simparms.ofdm_symbol_size = 512;
simparms.log2_maxh = 16;
simparms.dl_power_offset= 1; % no 3dB power offset
simparms.nb_slots = 14;
simparms.nb_re_per_symbol = simparms.nb_rb*12;
simparms.nb_re_per_frame = simparms.nb_slots*simparms.nb_re_per_symbol;
simparms.frame_errors = zeros(length(simparms.snr),simparms.NB_ANTENNAS_RX);
simparms.CB = [[1;1],[1;-1],[1;j],[1;-j]]/sqrt(2); % codebook
simparms.tseeds = set_taus_seed(1); % taus seeds
% Turbo decoder: set the pointer to the td tables allocated by init_td()
simparms.ptr_td = dlsch_decoding_init();
% Init codewords
% simparms.codeword(1) = InitCodeword(simparms,mcs(1));
% simparms.codeword(2) = InitCodeword(simparms,mcs(2));
simparms.codeword(1) = InitCodeword(simparms,mcs(1));
simparms.codeword(2) = InitCodeword(simparms,mcs(2));
% simparms.codeword(3) = InitCodeword(simparms,mcs(1));
% simparms.codeword(4) = InitCodeword(simparms,mcs(1));
end
function codeword = InitCodeword(simparms,mcs)
% Constellation
j = sqrt(-1);
amp = 1/32;
Q4 = amp*[ 1+j, 1- j, -1+j, -1-j]./sqrt(2);
Q16 = amp*[ 1+j, 1+3*j, 3+j, 3+3*j, 1-j, 1-3*j, 3-j, 3-3*j,...
-1+j, -1+3*j, -3+j, -3+3*j, -1-j, -1-3*j, -3-j, -3-3*j]./sqrt(10);
Q64 = amp*[ 3+3*j, 3+j, 1+3*j, 1+ j, 3+5*j, 3+7*j, 1+5*j, 1+7*j,...
5+3*j, 5+j, 7+ j, 7+3*j, 5+5*j, 5+7*j, 7+5*j, 7+7*j,...
3-3*j, 3-j, 1-3*j, 1- j, 3-5*j, 3-7*j, 1-5*j, 1-7*j,...
5-3*j, 5-j, 7-3*j, 7- j, 5-5*j, 5-7*j, 7-5*j, 7-7*j,...
-3+3*j,-3+j,-1+3*j,-1+ j,-3+5*j,-3+7*j,-1+5*j,-1+7*j,...
-5+3*j,-5+j,-7+3*j,-7+ j,-5+5*j,-5+7*j,-7+5*j,-7+7*j,...
-3-3*j,-3-j,-1-3*j,-1- j,-3-5*j,-3-7*j,-1-5*j,-1-7*j,...
-5-3*j,-5-j,-7-3*j,-7- j,-5-5*j,-5-7*j,-7-5*j,-7-7*j]./sqrt(42);
if (mcs <= 9)
codeword.mod_order = 2;
codeword.base2 = [2 1];
codeword.const = Q4;
elseif (mcs <= 16)
codeword.mod_order = 4;
codeword.base2 = [8 4 2 1];
codeword.const = Q16;
elseif (mcs <= 27)
codeword.mod_order = 6;
codeword.base2 = [32 16 8 4 2 1];
codeword.const = Q64;
else
error('invalid MCS: %d\n', mcs);
end
codeword.mcs = mcs;
codeword.G = simparms.nb_re*codeword.mod_order; % Number of softbits
codeword.TBS = get_tbs(mcs,simparms.nb_rb);
codeword.Kmimo = 2;
codeword.harq_pid = 0; % First HARQ round
codeword.Mdlharq = 1; % Number of HARQ rounds
codeword.rvidx = 0;
codeword.Nl = 1;
codeword.Ndi = 1;
end
%% Header
%==========================================================================
% This testbench simulates transmission mode 4 on subframe 7.
% Results can be compared to "./dlsim -x5 -S7 -R1 -u1" with perfect chest
% No OFDM Modulation and Demodulation is applied!
% Only 5 MHz bandwidth simulated. The Channel is Rayleigh block-fading.
%
% The matrices ymf0, ymf1, etc are in the form samples x antennas.
% More precisely:
% row dimension = [Re Im Re Im ...]
% col dimension: Heffx: [tx1->rx1 tx1->rx2 tx2->rx1 tx2->rx2]
% ymfx, Hmagx, Hmagbx, rho10 : [rx1 rx2 rx3 rx4]
%
% The same random data is generate as in dlsim.c by setting the right
% seed value simparms.tseeds.
%
%
% Author: Sebastian Wagner
% Date: 10-04-2013
%
%==========================================================================
clear all;
close all;
clear mex;
addpath('../../../PHY/LTE_TRANSPORT/mexfiles');
addpath('../../../PHY/TOOLS/mexfiles');
addpath('../../../SIMULATION/TOOLS/mexfiles');
% profile on;
%% System parameters
nt = 2; % number of transmit antennas
nr = 2; % number of receive antennas
N = 100; % number of frames (or subframes, codewords)
nSNR = 1; % number of SNR points
SNRdB = 5; % SNR per receive antenna in dB
% nSNR = 13;
% SNRdB = linspace(8,20,nSNR);
MCS = [16 16]; % MCS for the 2 users
j = sqrt(-1);
amp = 1/32; % amplitude scaling for FXP conversion
XFORMS = 0; % flag to activate graphics
% LLRs are computed for 8 RE make sure enough valid memory is allocated
LLR_GUARD_SAMPLES = 8*6; % max mod_order 6 for 8 REs
%% Initialize simparms
simparms = InitSimparms(MCS, N, SNRdB);
%% Random data, same seed as in dlsim.c
[tmp simparms.tseeds] = taus(1,simparms.tseeds);
%% Index of REs carrying data
data_idx = [901:1400 1501:2300 2401:3500 3601:4200];
data_idx_int = [1801:2800 3001:4600 4801:7000 7201:8400]; % [Re Im] format
data_idx_int_r = data_idx_int(1:2:length(data_idx_int));
data_idx_int_i = data_idx_int(2:2:length(data_idx_int));
%% Allocate memory
% The LLRs of subframe
llr0 = zeros(simparms.codeword(1).G, 1,'int16');
llr1 = zeros(simparms.codeword(2).G, 1,'int16');
% received signal transformed to FXP
y_fxp = zeros(simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,simparms.nb_re_per_frame,'int16');
% FXP received signal with transformed dimensions
y_fxp_t = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
% MF output of desired user
ymf0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
% Effective channel will contain the channel estimate at pilot positions
Heff0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmag0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmagb0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
ymf1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Heff1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmag1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmagb1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
rho10 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
rho01 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
H = zeros(simparms.NB_ANTENNAS_RX,simparms.NB_ANTENNAS_TX);
noise = zeros(simparms.NB_ANTENNAS_RX,simparms.nb_re);
%% XFORMS
if (XFORMS)
scrsz = get(0,'ScreenSize');mu_mimo
figure('Position',[1 scrsz(4)/2 scrsz(3)/2 scrsz(4)/2])
subplot(1,2,1);
xlim([1 simparms.codeword(1).G]);
title('LLRs of UE 0');
fig_llr0 = scatter(1:simparms.codeword(1).G,llr0,'.','YDataSource','llr0');
subplot(1,2,2);
title('MF output of UE 0');
fig_ymf = scatter(ymf0(data_idx_int_r),ymf0(data_idx_int_i),'.','XDataSource','ymf0(data_idx_int_r)','YDataSource','ymf0(data_idx_int_i)');
end
%% Encode and modulate transmit signal
% The same data is used throughout the simulation -> saves time
[data0 simparms.tseeds] = taus(simparms.codeword(1).TBS/8,simparms.tseeds);
[data1 simparms.tseeds] = taus(simparms.codeword(2).TBS/8,simparms.tseeds);
% Add 4 bytes CRC
data0 = [data0; zeros(4,1,'uint8')];
data1 = [data1; zeros(4,1,'uint8')];
% Turbo encoding of 2 streams for 2 users
edata0 = dlsch_encoding(data0,simparms,simparms.codeword(1)); % user 1
edata1 = dlsch_encoding(data1,simparms,simparms.codeword(2)); % user 2
% Symbol mapping and modulation
edata_enc(:,1) = simparms.codeword(1).base2*double(reshape(edata0,simparms.codeword(1).mod_order,simparms.nb_re));
edata_enc(:,2) = simparms.codeword(2).base2*double(reshape(edata1,simparms.codeword(2).mod_order,simparms.nb_re));
s(:,1) = simparms.codeword(1).const(edata_enc(:,1)+1);
s(:,2) = simparms.codeword(2).const(edata_enc(:,2)+1);
%% Loop over SNRs
for iSNR=1:length(simparms.snr)
cSNR = simparms.snr(iSNR); % current SNR
%% Loop over Frames
for n=1:simparms.n_frames
%% Channel
% Rayleigh channel, constant for whole codeblock/frame
H(1:nr,1:nt) = (randn(nr,nt) + j*randn(nr,nt))/sqrt(2);
%% PMI computation
pmi = 1;
r = H(:,2)'*H(:,1); % correlation
rr = real(r);
ri = imag(r);
if (rr>ri && rr>-ri)
pmi = 1;
elseif (rr<ri && rr>-ri)
pmi = 3;
elseif (rr<ri && rr<-ri)
pmi = 2;
elseif (rr>ri && rr<-ri)
pmi = 4;
end
% opposite pmi
if(pmi<3)
pmi_o = mod(pmi,2) + 1;
else
pmi_o = mod(pmi,2) + 3;
end
pmi_ext = uint8(repmat(pmi-1,1,simparms.nb_rb));
pmi_ext_o = uint8(repmat(pmi_o-1,1,simparms.nb_rb));
% normelized precoding vectors
g0 = simparms.CB(:,pmi);
g1 = simparms.CB(:,pmi_o);
%% Transmit signal (frequency domain)
x = [g0,g1]*conj(s'); % E[|x|^2] = amp^2
Ptx = sum(diag(x'*x))/simparms.nb_re; % average transmit power per RE
%% Noise
sigma2 = (Ptx/cSNR);
% E[|noise|^2] = amp^2/sqrt(SNR) -> SNR=1/sigma^2
noise(1:nr,:) = sqrt(sigma2)*(randn(nr,simparms.nb_re) + j*randn(nr,simparms.nb_re))/sqrt(2);
% real SNR per receive antenna
SNR_real = 10*log10(Ptx / ((noise(1,:)*noise(1,:)')/simparms.nb_re));
%% Received signal
y = H*x + noise; % flat-fading channel model
% Quantization
y_fxp_data = int16(floor(y*pow2(15)));
H_fxp = int16(fix(H*floor(amp*pow2(15)))); % Perfect Chest
% insert dummy pilots
y_fxp(1:2,data_idx) = y_fxp_data;
% reorder for processing
H_fxp_t = repmat([real(H_fxp(:)) imag(H_fxp(:))]',simparms.nb_re_per_frame,1);
y_fxp_t(:,1) = reshape([real(y_fxp(1,:)); imag(y_fxp(1,:))],2*simparms.nb_re_per_frame,1);
y_fxp_t(:,2) = reshape([real(y_fxp(2,:)); imag(y_fxp(2,:))],2*simparms.nb_re_per_frame,1);
%% Compute Scaling
avg = dlsch_channel_level_prec(H_fxp_t,pmi_ext,simparms);
simparms.log2_maxh = max(double(log2_approx(avg))-13,0);
%% Inner receiver loop
llr0p = 1; % LLR pointer for codeword 0
llr1p = 1; % LLR pointer for codeword 1
for symbol = 4:14
idxs = 2*(symbol-1)*simparms.nb_re_per_symbol + 1;
idxe = 2*(symbol-1)*simparms.nb_re_per_symbol + 2*simparms.nb_re_per_symbol;
%% Preprocessing
[ymf0(idxs:idxe,:)...
Heff0(idxs:idxe,:)...
Hmag0(idxs:idxe,:)...
Hmagb0(idxs:idxe,:)]...
= dlsch_channel_compensation_prec(y_fxp_t,H_fxp_t,pmi_ext,simparms,simparms.codeword(1),symbol-1);
% Interfering stream
[ymf1(idxs:idxe,:)...
Heff1(idxs:idxe,:)...
Hmag1(idxs:idxe,:)...
Hmagb1(idxs:idxe,:)]...
= dlsch_channel_compensation_prec(y_fxp_t,H_fxp_t,pmi_ext_o,simparms,simparms.codeword(2),symbol-1);
%% Correlation coefficient
rho10(idxs:idxe,:) = dlsch_dual_stream_correlation(Heff0,Heff1,simparms,symbol-1);
%% Combining
[ymf0(idxs:idxe,:)...
ymf1(idxs:idxe,:)...
Hmag0(idxs:idxe,:)...
Hmagb0(idxs:idxe,:)...
Hmag1(idxs:idxe,:)...
Hmagb1(idxs:idxe,:)...
rho10(idxs:idxe,:)]...
= dlsch_detection_mrc(ymf0,ymf1,Hmag0,Hmag1,Hmagb0,Hmagb1,rho10,simparms,symbol-1);
%% LLR computation
% first stream
llr0_t = dlsch_mu_mimo_llr([ymf0(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[ymf1(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[Hmag0(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[Hmag1(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[rho10(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
simparms,...
symbol-1);
llr0(llr0p:llr0p+length(llr0_t)-1,:) = llr0_t;
llr0p = llr0p + length(llr0_t);
% second stream
% compute conj. correlation term
tmp = rho10(idxs:idxe,:);
tmp(2:2:end) = -tmp(2:2:end);
rho01(idxs:idxe,:) = tmp;
llr1_t = dlsch_mu_mimo_llr([ymf1(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[ymf0(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[Hmag1(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[Hmag0(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[rho01(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
simparms,...
symbol-1);
llr1(llr1p:llr1p+length(llr1_t)-1,:) = llr1_t;
llr1p = llr1p + length(llr1_t);
end
if (XFORMS)
refreshdata(fig_llr0,'caller');
drawnow;
refreshdata(fig_ymf,'caller');
drawnow; pause(0.1);
end
%% Channel decoding
llr0 = -llr0; % invert (since no scrambling applied)
llr1 = -llr1; % invert (since no scrambling applied)
ret0 = dlsch_decoding(llr0,simparms,simparms.codeword(1));
ret1 = dlsch_decoding(llr1,simparms,simparms.codeword(2));
% Check if decoded correctly
if (ret0 >= simparms.MAX_TURBO_ITERATIONS)
simparms.frame_errors(iSNR,1) = simparms.frame_errors(iSNR,1) + 1;
end
if (ret1 >= simparms.MAX_TURBO_ITERATIONS)
simparms.frame_errors(iSNR,2) = simparms.frame_errors(iSNR,2) + 1;
end
end
fprintf('********************SNR = %3.1f dB processed on %s********************\n',real(simparms.snr_db(iSNR)),datestr(now));
fprintf('Errors: %d/%d\n',simparms.frame_errors(iSNR,1),N);
fprintf('Errors: %d/%d\n',simparms.frame_errors(iSNR,2),N);
end
%% Post Processing
% total_frame_errors = sum(frame_errors,2);
% fer = total_frame_errors/N;
% figure; semilogy(SNRdB,fer); grid;
%
% disp(fer);
% profile viewer
function [ simparms ] = InitSimparms( nb_antennas_tx, nb_antennas_rx, mcs, n_frames, SNRdB )
%INITSIMPARMS initialize simparms struct for TM5
% There are always 2 user schedules for transmission
% INPUT:
% nb_antennas_tx = Number of transmit antennas, max = 2
% nb_antennas_rx = Number of receive antennas per UE, max = 2
% MCS(2) = Modulation and Coding Scheme [1,...,27]
% n_frames = Number of frames to simulate
% SNRdB = SNR in dB
addpath('../../../PHY/LTE_TRANSPORT/mexfiles');
if (nb_antennas_tx ~= 2)
error('unsupported number of tx antennas, only 2 is valid');
elseif (nb_antennas_rx > 2 || nb_antennas_rx < 1)
error('unsupported number of rx antennas, only 1,2 is valid');
end
j = sqrt(-1);
%% Custom parameters
simparms.nb_antennas_tx = nb_antennas_tx;
simparms.nb_antennas_tx_eNB = simparms.nb_antennas_tx;
simparms.nb_antennas_rx = nb_antennas_rx;
simparms.n_frames = n_frames;
simparms.snr_db = SNRdB;
%% Constant parameters
simparms.NB_ANTENNAS_TX = 2; % max number of TX antennas
simparms.NB_ANTENNAS_RX = 2; % max number of RX antennas
simparms.snr = 10.^(SNRdB/10);
simparms.num_pdcch_symbols = 3;
simparms.subframe = 7;
simparms.abstraction_flag = 0;
simparms.nb_rb = 25; % fixed number of RB per OFDM symbol
simparms.rb_alloc = hex2dec('1FFF'); % 25 RBs
simparms.MAX_TURBO_ITERATIONS = 5;
simparms.nb_re = 3000; % there are 3000 REs in subframe 7
simparms.frame_type = 1; % TDD frame
simparms.mode1_flag = 0; % is TM1 active?
simparms.Ncp = 0; % Normal CP
simparms.ofdm_symbol_size = 512;
simparms.log2_maxh = 16;
simparms.dl_power_offset= 0; % 0 = 3dB power offset
simparms.nb_slots = 14;
simparms.nb_re_per_symbol = simparms.nb_rb*12;
simparms.nb_re_per_frame = simparms.nb_slots*simparms.nb_re_per_symbol;
simparms.frame_errors = zeros(length(simparms.snr),1);
simparms.CB = [[1;1],[1;-1],[1;j],[1;-j]]; % codebook
simparms.tseeds = set_taus_seed(1); % taus seeds
% Turbo decoder: set the pointer to the td tables allocated by init_td()
simparms.ptr_td = dlsch_decoding_init();
% Init codewords
simparms.codeword(1) = InitCodeword(simparms,mcs(1));
simparms.codeword(2) = InitCodeword(simparms,mcs(2));
end
function codeword = InitCodeword(simparms,mcs)
% Constellation
j = sqrt(-1);
amp = 1/32;
Q4 = amp*[ 1+j, 1- j, -1+j, -1-j]./sqrt(2);
Q16 = amp*[ 1+j, 1+3*j, 3+j, 3+3*j, 1-j, 1-3*j, 3-j, 3-3*j,...
-1+j, -1+3*j, -3+j, -3+3*j, -1-j, -1-3*j, -3-j, -3-3*j]./sqrt(10);
Q64 = amp*[ 3+3*j, 3+j, 1+3*j, 1+ j, 3+5*j, 3+7*j, 1+5*j, 1+7*j,...
5+3*j, 5+j, 7+ j, 7+3*j, 5+5*j, 5+7*j, 7+5*j, 7+7*j,...
3-3*j, 3-j, 1-3*j, 1- j, 3-5*j, 3-7*j, 1-5*j, 1-7*j,...
5-3*j, 5-j, 7-3*j, 7- j, 5-5*j, 5-7*j, 7-5*j, 7-7*j,...
-3+3*j,-3+j,-1+3*j,-1+ j,-3+5*j,-3+7*j,-1+5*j,-1+7*j,...
-5+3*j,-5+j,-7+3*j,-7+ j,-5+5*j,-5+7*j,-7+5*j,-7+7*j,...
-3-3*j,-3-j,-1-3*j,-1- j,-3-5*j,-3-7*j,-1-5*j,-1-7*j,...
-5-3*j,-5-j,-7-3*j,-7- j,-5-5*j,-5-7*j,-7-5*j,-7-7*j]./sqrt(42);
if (mcs <= 9)
codeword.mod_order = 2;
codeword.base2 = [2 1];
codeword.const = Q4;
elseif (mcs <= 16)
codeword.mod_order = 4;
codeword.base2 = [8 4 2 1];
codeword.const = Q16;
elseif (mcs <= 27)
codeword.mod_order = 6;
codeword.base2 = [32 16 8 4 2 1];
codeword.const = Q64;
else
error('invalid MCS: %d\n', mcs);
end
codeword.mcs = mcs;
codeword.G = simparms.nb_re*codeword.mod_order; % Number of softbits
codeword.TBS = get_tbs(mcs,simparms.nb_rb);
codeword.Kmimo = 1;
codeword.harq_pid = 0; % First HARQ round
codeword.Mdlharq = 1; % Number of HARQ rounds
codeword.rvidx = 0;
codeword.Nl = 1;
codeword.Ndi = 1;
end
%% Header
%==========================================================================
% This testbench simulations transmission mode 5 on subframe 7.
% Results can be compared to "./dlsim -x5 -S7 -R1 -u1" with perfect chest
% No OFDM Modulation and Demodulation is applied!
%
% Author: Sebastian Wagner
% Date: 24-07-2012
%
%==========================================================================
clear all;
close all;
clear mex;
addpath('../../../PHY/LTE_TRANSPORT/mexfiles');
addpath('../../../PHY/TOOLS/mexfiles');
addpath('../../../SIMULATION/TOOLS/mexfiles');
% profile on;
tic
%% System parameters
nt = 2;
nr = 2;
N = 1000; % number of frames (codewords)
nSNR = 1;
%SNRdB = [1:20];
SNRdB = 10;
% nSNR = 13;
%SNRdB = linspace(1,20,nSNR);
MCS = [9 9]; % MCS for the 2 users, currently it is assumed that mcs(2)=mcs(1)
j = sqrt(-1);
amp = 1/32;
XFORMS = 0;
% LLRs are computed for 8RE make sure enough valid memory is allocated
LLR_GUARD_SAMPLES = 8*6; % max mod_order 6 for 8 REs
%% Initialize simparms
simparms = InitSimparms( nt, nr, MCS, N, SNRdB);
%% Random data, same seed as in dlsim.c
[tmp simparms.tseeds] = taus(1,simparms.tseeds);
%% Index of REs carrying data
data_idx = [901:1400 1501:2300 2401:3500 3601:4200];
data_idx_int = [1801:2800 3001:4600 4801:7000 7201:8400]; % [Re Im] format
data_idx_int_r = data_idx_int(1:2:length(data_idx_int));
data_idx_int_i = data_idx_int(2:2:length(data_idx_int));
%% Allocate memory
llr0 = zeros(simparms.codeword(1).G, 1,'int16');
y_fxp = zeros(simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,simparms.nb_re_per_frame,'int16');
y_fxp_t = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
ymf0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
% Effective channel will contain the channel estimate at pilot positions
Heff0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmag0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmagb0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
ymf1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Heff1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmag1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmagb1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
rho10 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
H = zeros(simparms.NB_ANTENNAS_RX,simparms.NB_ANTENNAS_TX);
noise = zeros(simparms.NB_ANTENNAS_RX,simparms.nb_re);
%% XFORMS
if (XFORMS)
scrsz = get(0,'ScreenSize');
figure('Position',[1 scrsz(4)/2 scrsz(3)/2 scrsz(4)/2])
subplot(1,2,1);
xlim([1 simparms.codeword(1).G]);
title('LLRs of UE 0');
fig_llr0 = scatter(1:simparms.codeword(1).G,llr0,'.','YDataSource','llr0');
subplot(1,2,2);
title('MF output of UE 0');
fig_ymf = scatter(ymf0(data_idx_int_r),ymf0(data_idx_int_i),'.','XDataSource','ymf0(data_idx_int_r)','YDataSource','ymf0(data_idx_int_i)');
end
%% Encode and modulate transmit signal
% The same data is used throughout the simulation -> saves time
[data0 simparms.tseeds] = taus(simparms.codeword(1).TBS/8,simparms.tseeds);
[data1 simparms.tseeds] = taus(simparms.codeword(2).TBS/8,simparms.tseeds);
% Add 4 bytes CRC
data0 = [data0; zeros(4,1,'uint8')];
data1 = [data1; zeros(4,1,'uint8')];
edata0 = dlsch_encoding(data0,simparms,simparms.codeword(1)); % user 1
edata1 = dlsch_encoding(data1,simparms,simparms.codeword(2)); % user 2
% Modulation
edata_enc(:,1) = simparms.codeword(1).base2*double(reshape(edata0,simparms.codeword(1).mod_order,simparms.nb_re));
edata_enc(:,2) = simparms.codeword(2).base2*double(reshape(edata1,simparms.codeword(2).mod_order,simparms.nb_re));
s(:,1) = simparms.codeword(1).const(edata_enc(:,1)+1);
s(:,2) = simparms.codeword(2).const(edata_enc(:,2)+1);
Ptx = sum(diag(s'*s))/simparms.nb_re; % average transmit power per RE
%% Loop over SNRs
for iSNR=1:length(simparms.snr)
cSNR = simparms.snr(iSNR); % current SNR
%% Loop over Frames
for n=1:simparms.n_frames
%% Channel
% Rayleigh channel, constant for whole codeblock/frame, always 2x2
H(1:nr,1:nt) = (randn(nr,nt) + j*randn(nr,nt))/sqrt(2);
%% PMI computation
pmi = 1;
r = H(:,2)'*H(:,1);
rr = real(r);
ri = imag(r);
if (rr>ri && rr>-ri)
pmi = 1;
elseif (rr<ri && rr>-ri)
pmi = 3;
elseif (rr<ri && rr<-ri)
pmi = 2;
elseif (rr>ri && rr<-ri)
pmi = 4;
end
% opposite pmi
if(pmi<3)
pmi_o = mod(pmi,2) + 1;
else
pmi_o = mod(pmi,2) + 3;
end
pmi_ext = uint8(repmat(pmi-1,1,simparms.nb_rb));
pmi_ext_o = uint8(repmat(pmi_o-1,1,simparms.nb_rb));
% precoding vectors
g0 = simparms.CB(:,pmi);
g1 = simparms.CB(:,pmi_o);
%% Transmit signal (frequency domain)
x = [g0,g1]*conj(s')/sqrt(2); % E[|x|^2] = 2*amp^2
%% Noise
sigma2 = (Ptx/cSNR);
% E[|noise|^2] = 2*amp^2/sqrt(SNR) -> SNR=1/sigma^2
noise(1:nr,:) = sqrt(sigma2)*(randn(nr,simparms.nb_re) + j*randn(nr,simparms.nb_re))/sqrt(2);
%% Received signal
y = H*x + noise;
% Quantization
y_fxp_data = int16(floor(y*pow2(15)));
H_fxp = int16(fix(H*floor(amp/sqrt(2)*pow2(15)))); % Perfect Chest
% insert dummy pilots
y_fxp(1:2,data_idx) = y_fxp_data;
% reorder for processing
H_fxp_t = repmat([real(H_fxp(:)) imag(H_fxp(:))]',simparms.nb_re_per_frame,1);
y_fxp_t(:,1) = reshape([real(y_fxp(1,:)); imag(y_fxp(1,:))],2*simparms.nb_re_per_frame,1);
y_fxp_t(:,2) = reshape([real(y_fxp(2,:)); imag(y_fxp(2,:))],2*simparms.nb_re_per_frame,1);
%% Compute Scaling
avg = dlsch_channel_level_prec(H_fxp_t,pmi_ext,simparms);
simparms.log2_maxh = max(double(log2_approx(avg))-13,0);
%% Inner receiver loop
llrp = 1; % LLR pointer
for symbol = 4:14
idxs = 2*(symbol-1)*simparms.nb_re_per_symbol + 1;
idxe = 2*(symbol-1)*simparms.nb_re_per_symbol + 2*simparms.nb_re_per_symbol;
%% Preprocessing
[ymf0(idxs:idxe,:)...
Heff0(idxs:idxe,:)...
Hmag0(idxs:idxe,:)...
Hmagb0(idxs:idxe,:)]...
= dlsch_channel_compensation_prec(y_fxp_t,H_fxp_t,pmi_ext,simparms,simparms.codeword(1),symbol-1);
% Interfering user
[ymf1(idxs:idxe,:)...
Heff1(idxs:idxe,:)...
Hmag1(idxs:idxe,:)...
Hmagb1(idxs:idxe,:)]...
= dlsch_channel_compensation_prec(y_fxp_t,H_fxp_t,pmi_ext_o,simparms,simparms.codeword(2),symbol-1);
%% Correlation coefficient
rho10(idxs:idxe,:) = dlsch_dual_stream_correlation(Heff0,Heff1,simparms,symbol-1);
%% Combining
if (nr>1)
[ymf0(idxs:idxe,:)...
ymf1(idxs:idxe,:)...
Hmag0(idxs:idxe,:)...
Hmagb0(idxs:idxe,:)...
Hmag1(idxs:idxe,:)...
Hmagb1(idxs:idxe,:)...
rho10(idxs:idxe,:)]...
= dlsch_detection_mrc(ymf0,ymf1,Hmag0,Hmag1,Hmagb0,Hmagb1,rho10,simparms,symbol-1);
end
%% LLR computation
llr = dlsch_mu_mimo_llr([ymf0(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[ymf1(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[Hmag0(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[Hmag1(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[rho10(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
simparms,...
symbol-1);
llr0(llrp:llrp+length(llr)-1,:) = llr;
llrp = llrp + length(llr);
end
if (XFORMS)
refreshdata(fig_llr0,'caller');
drawnow;
refreshdata(fig_ymf,'caller');
drawnow; pause(0.1);
end
%% Channel decoding
llr0 = -llr0; % invert (since no scrambling applied)
ret0 = dlsch_decoding(llr0,simparms,simparms.codeword(1));
% Check if decoded correctly
if (ret0 >= simparms.MAX_TURBO_ITERATIONS)
simparms.frame_errors(iSNR,1) = simparms.frame_errors(iSNR,1) + 1;
end
end
fprintf('********************SNR = %3.1f dB processed on %s********************\n',real(simparms.snr_db(iSNR)),datestr(now));
fprintf('Errors: %d/%d\nPe = %1.5f\n',simparms.frame_errors(iSNR,1),N,simparms.frame_errors(iSNR,1)/N);
end
%% Post Processing
% total_frame_erros = sum(simparms.frame_errors,2);
% fer = total_frame_erros/N;
% figure; semilogy(SNRdB,fer); grid;
%
% disp(fer);
%
% profile viewer
toc
#include "../../../defs.h"
/*==============================================================================
* set_taus_seed.c
*
* Returns seeds which are the input to taus.c.
*
* example: seeds = set_taus_seed(0)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned int seed_init;
unsigned int s0, s1, s2, *ret;
if(nrhs!=1)
mexErrMsgTxt("Single input required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
/* Allocate input */
seed_init = (unsigned int) mxGetScalar(prhs[0]);
/* Algo */
#ifdef USER_MODE
struct drand48_data buffer;
unsigned int result = 0;
#endif
if (seed_init == 0) {
s0 = (unsigned int)time(NULL);
s1 = (unsigned int)time(NULL);
s2 = (unsigned int)time(NULL);
} else {
#ifndef USER_MODE
s0 = (unsigned int)0x1e23d852;
s1 = (unsigned int)0x81f38a1c;
s2 = (unsigned int)0xfe1a133e;
#else
/* Use reentrant version of rand48 to ensure that no conflicts with other generators occur */
srand48_r((long int)seed_init, &buffer);
mrand48_r(&buffer, (long int *)&result);
s0 = result;
mrand48_r(&buffer, (long int *)&result);
s1 = result;
mrand48_r(&buffer, (long int *)&result);
s2 = result;
#endif
}
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(3, 1, mxUINT32_CLASS, mxREAL);
ret = (unsigned int*) mxGetPr(plhs[0]);
ret[0] = s0;
ret[1] = s1;
ret[2] = s2;
}
\ No newline at end of file
#include "../../../defs.h"
/*==============================================================================
* taus.c
*
* Returns random unsigned chars as well as the new seeds.
*
* example: [rchar seeds] = taus(len, seeds)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
unsigned int s0, s1, s2, b;
inline unsigned int mtaus()
{
b = (((s0 << 13) ^ s0) >> 19);
s0 = (((s0 & 0xFFFFFFFE) << 12)^ b);
b = (((s1 << 2) ^ s1) >> 25);
s1 = (((s1 & 0xFFFFFFF8) << 4)^ b);
b = (((s2 << 3) ^ s2) >> 11);
s2 = (((s2 & 0xFFFFFFF0) << 17)^ b);
return s0 ^ s1 ^ s2;
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned int len, *tseeds, *tseeds_out;
unsigned char *out;
int i;
if(nrhs!=2)
mexErrMsgTxt("Two inputs required.");
else if(nlhs > 2)
mexErrMsgTxt("Too many output arguments.");
/* Allocate input */
len = (unsigned int) mxGetScalar(prhs[0]);
tseeds = (unsigned int*) mxGetData(prhs[1]);
if (mxGetM(prhs[1])!=3 && mxGetN(prhs[1])!=3)
mexErrMsgTxt("Three seeds are required.");
s0 = tseeds[0];
s1 = tseeds[1];
s2 = tseeds[2];
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(len, 1, mxUINT8_CLASS, mxREAL);
out = (unsigned char*) mxGetPr(plhs[0]);
plhs[1] = mxCreateNumericMatrix(3, 1, mxUINT32_CLASS, mxREAL);
tseeds_out = (unsigned int*) mxGetPr(plhs[1]);
/* Algo */
for(i=0; i<len; i++)
out[i] = (unsigned char)(mtaus()&0xff);
tseeds_out[0] = s0;
tseeds_out[1] = s1;
tseeds_out[2] = s2;
}
\ No newline at end of file
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
#include "mex.h"
#include "../../SIMULATION/TOOLS/defs.h"
#include "../../PHY/types.h"
#include "../../PHY/TOOLS/defs.h"
#include "../../PHY/defs.h"
#include "../../PHY/vars.h"
#include "../../MAC_INTERFACE/vars.h"
/*
* @(#)mex.h generated by: makeheader 5.1.5 Mon Jun 29 15:54:48 2009
*
* built from: ../../src/include/copyright.h
* ../../src/include/pragma_interface.h
* mex_typedefs.h
* mexfunction.hpp
* fmexapi.cpp
* fmexapi_stdcall.cpp
* globals.cpp
* mexapi.cpp
* mexcbk.cpp
* mexdispatch.cpp
* mexintrf.cpp
* mexdbg.h
*/
#if defined(_MSC_VER)
# pragma once
#endif
#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3))
# pragma once
#endif
#ifndef mex_h
#define mex_h
/*
* Copyright 1984-2003 The MathWorks, Inc.
* All Rights Reserved.
*/
/* Copyright 2003-2006 The MathWorks, Inc. */
/* Only define EXTERN_C if it hasn't been defined already. This allows
* individual modules to have more control over managing their exports.
*/
#ifndef EXTERN_C
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C extern
#endif
#endif
/* Copyright 1999-2007 The MathWorks, Inc. */
/* $Revision: 1.7.4.4 $ */
#ifndef mex_typedefs_h
#define mex_typedefs_h
typedef struct impl_info_tag *MEX_impl_info;
#include "matrix.h"
#ifdef __cplusplus
extern "C"
{
#endif
typedef void (*mex_exit_fn)(void);
#ifdef __cplusplus
}
#endif
typedef struct mexGlobalTableEntry_Tag {
const char *name; /* The name of the global */
mxArray **variable; /* A pointer to the variable */
} mexGlobalTableEntry, *mexGlobalTable;
#ifdef _WIN32
#define cicompare(s1,s2) utStrcmpi((s1),(s2))
#else
#define cicompare(s1,s2) strcmp((s1),(s2))
#endif
#define cscompare(s1,s2) strcmp((s1),(s2))
typedef struct mexFunctionTableEntry_tag {
const char * name;
mxFunctionPtr f;
int nargin;
int nargout;
struct _mexLocalFunctionTable *local_function_table;
} mexFunctionTableEntry, *mexFunctionTable;
typedef struct _mexLocalFunctionTable {
size_t length;
mexFunctionTable entries;
} _mexLocalFunctionTable, *mexLocalFunctionTable;
typedef struct {
void (*initialize)(void);
void (*terminate)(void);
} _mexInitTermTableEntry, *mexInitTermTableEntry;
#define MEX_INFORMATION_VERSION 1
typedef struct {
int version;
int file_function_table_length;
mexFunctionTable file_function_table;
int global_variable_table_length;
mexGlobalTable global_variable_table;
int npaths;
const char ** paths;
int init_term_table_length;
mexInitTermTableEntry init_term_table;
} _mex_information, *mex_information;
typedef mex_information(*fn_mex_file)(void);
typedef void (*fn_clean_up_after_error)(void);
typedef const char *(*fn_simple_function_to_string)(mxFunctionPtr f);
typedef void (*fn_mex_enter_mex_library)(mex_information x);
typedef fn_mex_enter_mex_library fn_mex_exit_mex_library;
typedef mexLocalFunctionTable (*fn_mex_get_local_function_table)(void);
typedef mexLocalFunctionTable (*fn_mex_set_local_function_table)(mexLocalFunctionTable);
#endif
#ifdef EXPORT_EXTERN_C
# define MEXFUNCTION_LINKAGE EXPORT_EXTERN_C
#else
# ifdef MW_NEEDS_VERSION_H
# include "version.h"
# define MEXFUNCTION_LINKAGE EXPORT_EXTERN_C
# else
# define MEXFUNCTION_LINKAGE EXTERN_C
# endif
#endif
MEXFUNCTION_LINKAGE
/*
* mexFunction is the user-defined C routine that is called upon invocation
* of a MEX-function.
*/
void mexFunction(
int nlhs, /* number of expected outputs */
mxArray *plhs[], /* array of pointers to output arguments */
int nrhs, /* number of inputs */
const mxArray *prhs[] /* array of pointers to input arguments */
);
/*
* This header file "mex.h" declares all the types, macros and
* functions necessary to interface mex files with the current
* version of MATLAB. See the release notes for information on
* supporting syntax from earlier versions.
*/
#include "matrix.h"
#include <stdio.h>
/*
* Issue error message and return to MATLAB prompt
*/
EXTERN_C void mexErrMsgTxt(
const char *error_msg /* string with error message */
);
/*
* Issue formatted error message with corresponding error identifier and return to MATLAB
* prompt.
*/
EXTERN_C void mexErrMsgIdAndTxt(
const char * identifier, /* string with error message identifier */
const char * err_msg, /* string with error message printf-style format */
... /* any additional arguments */
);
/*
* Invoke an unidentified warning. Such warnings can only be affected by the M-code
* 'warning * all', since they have no specific identifier. See also mexWarnMsgIdAndTxt.
*/
EXTERN_C void mexWarnMsgTxt(
const char *warn_msg /* string with warning message */
);
/*
* Invoke a warning with message identifier 'identifier' and message derived from 'fmt' and
* subsequent arguments. The warning may either get printed as is (if it is set to 'on'), or
* not actually get printed (if set to 'off'). See 'help warning' in MATLAB for more
* details.
*/
EXTERN_C void mexWarnMsgIdAndTxt(
const char * identifier, /* string with warning message identifer */
const char * warn_msg, /* string with warning message printf-style format */
... /* any additional arguments */
);
/*
* mex equivalent to MATLAB's "disp" function
*/
EXTERN_C int mexPrintf(
const char *fmt, /* printf style format */
... /* any additional arguments */
);
#define printf mexPrintf
/*
* Remove all components of an array plus the array header itself
* from MATLAB's memory allocation list. The array will now
* persist between calls to the mex function. To destroy this
* array, you will need to explicitly call mxDestroyArray().
*/
EXTERN_C void mexMakeArrayPersistent(
mxArray *pa /* pointer to array */
);
/*
* Remove memory previously allocated via mxCalloc from MATLAB's
* memory allocation list. To free this memory, you will need to
* explicitly call mxFree().
*/
EXTERN_C void mexMakeMemoryPersistent(void *ptr);
/*
* mex equivalent to MATLAB's "set" function
*/
EXTERN_C int mexSet(double handle, const char *property, mxArray *value);
/* API interface which mimics the "get" function */
EXTERN_C const mxArray *mexGet(double handle, const char *property);
/*
* call MATLAB function
*/
EXTERN_C int mexCallMATLAB(
int nlhs, /* number of expected outputs */
mxArray *plhs[], /* pointer array to outputs */
int nrhs, /* number of inputs */
mxArray *prhs[], /* pointer array to inputs */
const char *fcn_name /* name of function to execute */
);
/*
* call MATLAB function with Trap
*/
EXTERN_C mxArray *mexCallMATLABWithTrap(
int nlhs, /* number of expected outputs */
mxArray *plhs[], /* pointer array to outputs */
int nrhs, /* number of inputs */
mxArray *prhs[], /* pointer array to inputs */
const char *fcn_name /* name of function to execute */
);
/*
* set or clear mexCallMATLAB trap flag (if set then an error in
* mexCallMATLAB is caught and mexCallMATLAB will return a status value,
* if not set an error will cause control to revert to MATLAB)
*/
EXTERN_C void mexSetTrapFlag(int flag);
/*
* Print an assertion-style error message and return control to the
* MATLAB command line.
*/
EXTERN_C void mexPrintAssertion(
const char *test,
const char *fname,
int linenum,
const char *message);
/*
* Tell whether or not a mxArray is in MATLAB's global workspace.
*/
EXTERN_C bool mexIsGlobal(const mxArray *pA);
/*
* Place a copy of the array value into the specified workspace with the
* specified name
*/
EXTERN_C int mexPutVariable(
const char *workspace,
const char *name,
const mxArray *parray /* matrix to copy */
);
/*
* return a pointer to the array value with the specified variable
* name in the specified workspace
*/
EXTERN_C const mxArray *mexGetVariablePtr(
const char *workspace,
const char *name /* name of symbol */
);
/*
* return a copy of the array value with the specified variable
* name in the specified workspace
*/
EXTERN_C mxArray *mexGetVariable(
const char *workspace,
const char *name /* name of variable in question */
);
/*
* Lock a MEX-function so that it cannot be cleared from memory.
*/
EXTERN_C void mexLock(void);
/*
* Unlock a locked MEX-function so that it can be cleared from memory.
*/
EXTERN_C void mexUnlock(void);
/*
* Return true if the MEX-function is currently locked, false otherwise.
*/
EXTERN_C bool mexIsLocked(void);
/*
* Return the name of a the MEXfunction currently executing.
*/
EXTERN_C const char *mexFunctionName(void);
/*
* Parse and execute MATLAB syntax in string. Returns zero if successful,
* and a non zero value if an error occurs.
*/
EXTERN_C int mexEvalString(
const char *str /* matlab command string */
);
/*
* Parse and execute MATLAB syntax in string. Returns NULL if successful,
* and an MException if an error occurs.
*/
EXTERN_C mxArray* mexEvalStringWithTrap(
const char *str /* matlab command string */
);
/*
* Register Mex-file's At-Exit function (accessed via MEX callback)
*/
EXTERN_C int mexAtExit(mex_exit_fn exit_fcn );
/* Copyright 1996-2006 The MathWorks, Inc. */
/* $Revision: 1.9.4.3 $ */
/*
* Revisit. Conflicts with 32-bit compatibility API. XXX
*/
#if 0
#ifdef ARGCHECK
#include "mwdebug.h" /* Prototype _d versions of API functions */
#define mexAtExit(exitfcn) mexAtExit_d(exitfcn, __FILE__, __LINE__)
#define mexCallMATLAB(nlhs, plhs, nrhs, prhs, fcn) mexCallMATLAB_d(nlhs, plhs, nrhs, prhs, fcn, __FILE__, __LINE__)
#define mexErrMsgTxt(errmsg) mexErrMsgTxt_d(errmsg, __FILE__, __LINE__)
#define mexEvalString(str) mexEvalString_d(str, __FILE__, __LINE__)
#define mexGet(handle, property) mexGet_d(handle, property, __FILE__, __LINE__)
#define mexGetVariable(workspace, name) mexGetVariable_d(workspace, name, __FILE__, __LINE__)
#define mexGetVariablePtr(workspace, name) mexGetVariablePtr_d(workspace, name, __FILE__, __LINE__)
#define mexIsGlobal(pa) mexIsGlobal_d(pa, __FILE__, __LINE__)
#define mexMakeArrayPersistent(pa) mexMakeArrayPersistent_d(pa, __FILE__, __LINE__)
#define mexMakeMemoryPersistent(ptr) mexMakeMemoryPersistent_d(ptr, __FILE__, __LINE__)
#define mexPutVariable(workspace, name, pa) mexPutVariable_d(workspace, name, pa, __FILE__, __LINE__)
#define mexSet(handle, property, value) mexSet_d(handle, property, value, __FILE__, __LINE__)
#define mexSetTrapFlag(value) mexSetTrapFlag_d(value, __FILE__, __LINE__)
#define mexSubsAssign(plhs, sub, nsubs, rhs) mexSubsAssign_d(plhs, sub, nsubs, rhs, __FILE__, __LINE__)
#define mexSubsReference(prhs, sub, nsubs) mexSubsReference_d(prhs, sub, nsubs, __FILE__, __LINE__)
#define mexWarnMsgTxt(str) mexWarnMsgTxt_d(str, __FILE__, __LINE__)
#endif
#endif
#endif /* mex_h */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment