void srslte_pdsch_free(srslte_pdsch_t *q) { int i; if (q->e) { free(q->e); } if (q->d) { free(q->d); } for (i = 0; i < q->cell.nof_ports; i++) { if (q->ce[i]) { free(q->ce[i]); } if (q->x[i]) { free(q->x[i]); } if (q->symbols[i]) { free(q->symbols[i]); } } for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { srslte_sequence_free(&q->seq[i]); } for (i = 0; i < 4; i++) { srslte_modem_table_free(&q->mod[i]); } srslte_precoding_free(&q->precoding); srslte_sch_free(&q->dl_sch); bzero(q, sizeof(srslte_pdsch_t)); }
void srslte_pcfich_free(srslte_pcfich_t *q) { for (int ns = 0; ns < SRSLTE_NSUBFRAMES_X_FRAME; ns++) { srslte_sequence_free(&q->seq[ns]); } srslte_modem_table_free(&q->mod); srslte_precoding_free(&q->precoding); bzero(q, sizeof(srslte_pcfich_t)); }
int main(int argc, char **argv) { int i, j; float mse; cf_t *x[SRSLTE_MAX_LAYERS], *r[SRSLTE_MAX_PORTS], *y[SRSLTE_MAX_PORTS], *h[SRSLTE_MAX_PORTS], *xr[SRSLTE_MAX_LAYERS]; srslte_mimo_type_t type; srslte_precoding_t precoding; parse_args(argc, argv); if (nof_ports > SRSLTE_MAX_PORTS || nof_layers > SRSLTE_MAX_LAYERS) { fprintf(stderr, "Invalid number of layers or ports\n"); exit(-1); } if (srslte_str2mimotype(mimo_type_name, &type)) { fprintf(stderr, "Invalid MIMO type %s\n", mimo_type_name); exit(-1); } for (i = 0; i < nof_layers; i++) { x[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols); if (!x[i]) { perror("srslte_vec_malloc"); exit(-1); } xr[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols); if (!xr[i]) { perror("srslte_vec_malloc"); exit(-1); } } for (i = 0; i < nof_ports; i++) { y[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols * nof_layers); // TODO: The number of symbols per port is different in spatial multiplexing. if (!y[i]) { perror("srslte_vec_malloc"); exit(-1); } h[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols * nof_layers); if (!h[i]) { perror("srslte_vec_malloc"); exit(-1); } } /* only 1 receiver antenna supported now */ r[0] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols * nof_layers); if (!r[0]) { perror("srslte_vec_malloc"); exit(-1); } /* generate random data */ for (i = 0; i < nof_layers; i++) { for (j = 0; j < nof_symbols; j++) { x[i][j] = (2*(rand()%2)-1+(2*(rand()%2)-1)*_Complex_I)/sqrt(2); } } if (srslte_precoding_init(&precoding, nof_symbols * nof_layers)) { fprintf(stderr, "Error initializing precoding\n"); exit(-1); } /* precoding */ if (srslte_precoding_type(&precoding, x, y, nof_layers, nof_ports, nof_symbols, type) < 0) { fprintf(stderr, "Error layer mapper encoder\n"); exit(-1); } /* generate channel */ for (i = 0; i < nof_ports; i++) { for (j = 0; j < nof_symbols; j++) { h[i][nof_layers*j] = (float) rand()/RAND_MAX+((float) rand()/RAND_MAX)*_Complex_I; // assume the channel is time-invariant in nlayer consecutive symbols for (int k=0;k<nof_layers;k++) { h[i][nof_layers*j+k] = h[i][nof_layers*j]; } } } /* pass signal through channel (we are in the frequency domain so it's a multiplication) */ /* there's only one receiver antenna, signals from different transmitter * ports are simply combined at the receiver */ for (j = 0; j < nof_symbols * nof_layers; j++) { r[0][j] = 0; for (i = 0; i < nof_ports; i++) { r[0][j] += y[i][j] * h[i][j]; } } /* predecoding / equalization */ struct timeval t[3]; gettimeofday(&t[1], NULL); if (srslte_predecoding_type(&precoding, r[0], h, xr, nof_ports, nof_layers, nof_symbols * nof_layers, type, 0) < 0) { fprintf(stderr, "Error layer mapper encoder\n"); exit(-1); } gettimeofday(&t[2], NULL); get_time_interval(t); printf("Execution Time: %d us\n", t[0].tv_usec); /* check errors */ mse = 0; for (i = 0; i < nof_layers; i++) { for (j = 0; j < nof_symbols; j++) { mse += cabsf(xr[i][j] - x[i][j]); } } printf("MSE: %f\n", mse/ nof_layers / nof_symbols ); if (mse / nof_layers / nof_symbols > MSE_THRESHOLD) { exit(-1); } for (i = 0; i < nof_layers; i++) { free(x[i]); free(xr[i]); } for (i = 0; i < nof_ports; i++) { free(y[i]); free(h[i]); } free(r[0]); srslte_precoding_free(&precoding); printf("Ok\n"); exit(0); }
/* the gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i; srslte_cell_t cell; srslte_chest_dl_t chest; srslte_precoding_t cheq; cf_t *input_signal = NULL, *output_signal[SRSLTE_MAX_LAYERS]; cf_t *output_signal2 = NULL; cf_t *ce[SRSLTE_MAX_PORTS]; double *outr0=NULL, *outi0=NULL; double *outr1=NULL, *outi1=NULL; double *outr2=NULL, *outi2=NULL; if (!mxIsDouble(CELLID) && mxGetN(CELLID) != 1 && !mxIsDouble(PORTS) && mxGetN(PORTS) != 1 && mxGetM(CELLID) != 1) { help(); return; } cell.id = (uint32_t) *((double*) mxGetPr(CELLID)); cell.nof_prb = mxGetM(INPUT)/SRSLTE_NRE; cell.nof_ports = (uint32_t) *((double*) mxGetPr(PORTS)); if ((mxGetN(INPUT)%14) == 0) { cell.cp = SRSLTE_CP_NORM; } else if ((mxGetN(INPUT)%12)!=0) { cell.cp = SRSLTE_CP_EXT; } else { mexErrMsgTxt("Invalid number of symbols\n"); help(); return; } if (srslte_chest_dl_init(&chest, cell)) { mexErrMsgTxt("Error initiating channel estimator\n"); return; } int nsubframes; if (cell.cp == SRSLTE_CP_NORM) { nsubframes = mxGetN(INPUT)/14; } else { nsubframes = mxGetN(INPUT)/12; } uint32_t sf_idx=0; if (nsubframes == 1) { if (nrhs != NOF_INPUTS+1) { mexErrMsgTxt("Received 1 subframe. Need to provide subframe index.\n"); help(); return; } sf_idx = (uint32_t) *((double*) mxGetPr(SFIDX)); } if (nrhs > 5) { uint32_t filter_len = 0; float *filter; double *f; filter_len = mxGetNumberOfElements(FREQ_FILTER); filter = malloc(sizeof(float) * filter_len); f = (double*) mxGetPr(FREQ_FILTER); for (i=0;i<filter_len;i++) { filter[i] = (float) f[i]; } srslte_chest_dl_set_filter_freq(&chest, filter, filter_len); filter_len = mxGetNumberOfElements(TIME_FILTER); filter = malloc(sizeof(float) * filter_len); f = (double*) mxGetPr(TIME_FILTER); for (i=0;i<filter_len;i++) { filter[i] = (float) f[i]; } srslte_chest_dl_set_filter_time(&chest, filter, filter_len); } double *inr=(double *)mxGetPr(INPUT); double *ini=(double *)mxGetPi(INPUT); /** Allocate input buffers */ int nof_re = 2*SRSLTE_CP_NSYMB(cell.cp)*cell.nof_prb*SRSLTE_NRE; for (i=0;i<SRSLTE_MAX_PORTS;i++) { ce[i] = srslte_vec_malloc(nof_re * sizeof(cf_t)); } input_signal = srslte_vec_malloc(nof_re * sizeof(cf_t)); for (i=0;i<SRSLTE_MAX_PORTS;i++) { output_signal[i] = srslte_vec_malloc(nof_re * sizeof(cf_t)); } output_signal2 = srslte_vec_malloc(nof_re * sizeof(cf_t)); srslte_precoding_init(&cheq, nof_re); /* Create output values */ if (nlhs >= 1) { plhs[0] = mxCreateDoubleMatrix(nof_re * nsubframes, cell.nof_ports, mxCOMPLEX); outr0 = mxGetPr(plhs[0]); outi0 = mxGetPi(plhs[0]); } if (nlhs >= 2) { plhs[1] = mxCreateDoubleMatrix(SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb)*nsubframes, cell.nof_ports, mxCOMPLEX); outr1 = mxGetPr(plhs[1]); outi1 = mxGetPi(plhs[1]); } if (nlhs >= 3) { plhs[2] = mxCreateDoubleMatrix(nof_re * nsubframes, 1, mxCOMPLEX); outr2 = mxGetPr(plhs[2]); outi2 = mxGetPi(plhs[2]); } for (int sf=0;sf<nsubframes;sf++) { /* Convert input to C complex type */ for (i=0;i<nof_re;i++) { __real__ input_signal[i] = (float) *inr; if (ini) { __imag__ input_signal[i] = (float) *ini; } inr++; ini++; } if (nsubframes != 1) { sf_idx = sf%10; } if (srslte_chest_dl_estimate(&chest, input_signal, ce, sf_idx)) { mexErrMsgTxt("Error running channel estimator\n"); return; } if (cell.nof_ports == 1) { srslte_predecoding_single(input_signal, ce[0], output_signal2, nof_re, srslte_chest_dl_get_noise_estimate(&chest)); } else { srslte_predecoding_diversity(&cheq, input_signal, ce, output_signal, cell.nof_ports, nof_re, srslte_chest_dl_get_noise_estimate(&chest)); srslte_layerdemap_diversity(output_signal, output_signal2, cell.nof_ports, nof_re/cell.nof_ports); } if (nlhs >= 1) { for (int j=0;j<cell.nof_ports;j++) { for (i=0;i<nof_re;i++) { *outr0 = (double) crealf(ce[j][i]); if (outi0) { *outi0 = (double) cimagf(ce[j][i]); } outr0++; outi0++; } } } if (nlhs >= 2) { for (int j=0;j<cell.nof_ports;j++) { for (i=0;i<SRSLTE_REFSIGNAL_NUM_SF(cell.nof_prb,j);i++) { *outr1 = (double) crealf(chest.pilot_estimates_average[j][i]); if (outi1) { *outi1 = (double) cimagf(chest.pilot_estimates_average[j][i]); } outr1++; outi1++; } } } if (nlhs >= 3) { for (i=0;i<nof_re;i++) { *outr2 = (double) crealf(output_signal2[i]); if (outi2) { *outi2 = (double) cimagf(output_signal2[i]); } outr2++; outi2++; } } } if (nlhs >= 4) { plhs[3] = mxCreateDoubleScalar(srslte_chest_dl_get_noise_estimate(&chest)); } if (nlhs >= 5) { plhs[4] = mxCreateDoubleScalar(srslte_chest_dl_get_rsrp(&chest)); } srslte_chest_dl_free(&chest); srslte_precoding_free(&cheq); return; }