/* Initializes the PSS synchronization object. * * It correlates a signal of frame_size samples with the PSS sequence in the frequency * domain. The PSS sequence is transformed using fft_size samples. */ int pss_synch_init_fft(pss_synch_t *q, uint32_t frame_size, uint32_t fft_size) { int ret = LIBLTE_ERROR_INVALID_INPUTS; if (q != NULL) { uint32_t N_id_2; uint32_t buffer_size; bzero(q, sizeof(pss_synch_t)); q->N_id_2 = 10; q->fft_size = fft_size; q->frame_size = frame_size; buffer_size = fft_size + frame_size + 1; q->tmp_input = vec_malloc(buffer_size * sizeof(cf_t)); if (!q->tmp_input) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } q->conv_output = vec_malloc(buffer_size * sizeof(cf_t)); if (!q->conv_output) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } for (N_id_2=0;N_id_2<3;N_id_2++) { q->pss_signal_freq[N_id_2] = vec_malloc(buffer_size * sizeof(cf_t)); if (!q->pss_signal_freq[N_id_2]) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } /* The PSS is translated into the frequency domain for each N_id_2 */ if (pss_synch_init_N_id_2(q->pss_signal_freq[N_id_2], N_id_2, fft_size)) { fprintf(stderr, "Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); goto clean_and_exit; } } #ifdef CONVOLUTION_FFT if (conv_fft_cc_init(&q->conv_fft, frame_size, fft_size)) { fprintf(stderr, "Error initiating convolution FFT\n"); goto clean_and_exit; } #endif ret = LIBLTE_SUCCESS; } clean_and_exit: if (ret == LIBLTE_ERROR) { pss_synch_free(q); } return ret; }
int filter2d_init(filter2d_t* q, float **taps, int ntime, int nfreq, int sztime, int szfreq) { int ret = -1; bzero(q, sizeof(filter2d_t)); if (matrix_init((void***)&q->taps, ntime, nfreq, sizeof(float))) { goto free_and_exit; } matrix_copy((void**) q->taps, (void**) taps, ntime, nfreq, sizeof(float)); q->output = vec_malloc((ntime+sztime)*(szfreq)*sizeof(cf_t)); if (!q->output) { goto free_and_exit; } bzero(q->output, (ntime+sztime)*(szfreq)*sizeof(cf_t)); q->nfreq = nfreq; q->ntime = ntime; q->szfreq = szfreq; q->sztime = sztime; ret = 0; free_and_exit: if (ret == -1) { filter2d_free(q); } return ret; }
void init (unsigned cap) { buf = vec_malloc (cap); buf_last = buf; buf_end = buf + cap; }
/*** Default Allocation/Deallocation Function ***/ static ILvoid* ILAPIENTRY DefaultAllocFunc(ILuint Size) { #ifdef VECTORMEM return (ILvoid*)vec_malloc(Size); #else return malloc(Size); #endif }
ILvoid *ivec_align_buffer( ILvoid *buffer, ILuint size ) { if( (size_t)buffer % 16 != 0 ) { void *aligned_buffer = vec_malloc( size ); memcpy( aligned_buffer, buffer, size ); ifree( buffer ); return aligned_buffer; } return buffer; }
void *ivec_align_buffer(void *buffer, const ILsizei size) { if( (ILsizei)buffer % 16 != 0 ) { void *aligned_buffer = vec_malloc( size ); memcpy( aligned_buffer, buffer, size ); ifree( buffer ); return aligned_buffer; } return buffer; }
int conv_fft_cc_init(conv_fft_cc_t *state, int input_len, int filter_len) { state->input_len = input_len; state->filter_len = filter_len; state->output_len = input_len+filter_len-1; state->input_fft = vec_malloc(sizeof(_Complex float)*state->output_len); state->filter_fft = vec_malloc(sizeof(_Complex float)*state->output_len); state->output_fft = vec_malloc(sizeof(_Complex float)*state->output_len); if (!state->input_fft || !state->filter_fft || !state->output_fft) { return -1; } if (dft_plan(state->output_len,COMPLEX_2_COMPLEX,FORWARD,&state->input_plan)) { return -2; } if (dft_plan(state->output_len,COMPLEX_2_COMPLEX,FORWARD,&state->filter_plan)) { return -3; } if (dft_plan(state->output_len,COMPLEX_2_COMPLEX,BACKWARD,&state->output_plan)) { return -4; } return 0; }
int cfo_init(cfo_t *h, uint32_t nsamples) { int ret = LIBLTE_ERROR; bzero(h, sizeof(cfo_t)); if (cexptab_init(&h->tab, CFO_CEXPTAB_SIZE)) { goto clean; } h->cur_cexp = vec_malloc(sizeof(cf_t) * nsamples); if (!h->cur_cexp) { goto clean; } h->tol = CFO_TOLERANCE; h->last_freq = 0; h->nsamples = nsamples; cexptab_gen(&h->tab, h->cur_cexp, h->last_freq, h->nsamples); ret = LIBLTE_SUCCESS; clean: if (ret == LIBLTE_ERROR) { cfo_free(h); } return ret; }
int main(int argc, char **argv) { int n; void *uhd; ue_celldetect_t s; ue_celldetect_result_t found_cells[3]; cf_t *buffer; int nof_freqs; lte_earfcn_t channels[MAX_EARFCN]; uint32_t freq; pbch_mib_t mib; parse_args(argc, argv); printf("Opening UHD device...\n"); if (cuhd_open(uhd_args, &uhd)) { fprintf(stderr, "Error opening uhd\n"); exit(-1); } cuhd_set_rx_gain(uhd, uhd_gain); nof_freqs = lte_band_get_fd_band(band, channels, earfcn_start, earfcn_end, MAX_EARFCN); if (nof_freqs < 0) { fprintf(stderr, "Error getting EARFCN list\n"); exit(-1); } buffer = vec_malloc(sizeof(cf_t) * 96000); if (!buffer) { perror("malloc"); return LIBLTE_ERROR; } if (ue_celldetect_init(&s)) { fprintf(stderr, "Error initiating UE sync module\n"); exit(-1); } if (threshold > 0) { ue_celldetect_set_threshold(&s, threshold); } if (nof_frames_total > 0) { ue_celldetect_set_nof_frames_total(&s, nof_frames_total); } if (nof_frames_detected > 0) { ue_celldetect_set_nof_frames_detected(&s, nof_frames_detected); } for (freq=0;freq<nof_freqs;freq+=10) { /* set uhd_freq */ cuhd_set_rx_freq(uhd, (double) channels[freq].fd * MHZ); cuhd_rx_wait_lo_locked(uhd); usleep(10000); INFO("Set uhd_freq to %.3f MHz\n", (double) channels[freq].fd * MHZ/1000000); printf("[%3d/%d]: EARFCN %d Freq. %.2f MHz looking for PSS. \r", freq, nof_freqs, channels[freq].id, channels[freq].fd);fflush(stdout); if (VERBOSE_ISINFO()) { printf("\n"); } n = find_cell(uhd, &s, buffer, found_cells); if (n < 0) { fprintf(stderr, "Error searching cell\n"); exit(-1); } if (n == CS_CELL_DETECTED) { for (int i=0;i<3;i++) { if (found_cells[i].peak > threshold/2) { if (decode_pbch(uhd, buffer, &found_cells[i], nof_frames_total, &mib)) { fprintf(stderr, "Error decoding PBCH\n"); exit(-1); } } } } } ue_celldetect_free(&s); cuhd_close(uhd); exit(0); }
int main(int argc, char **argv) { cf_t *input_buffer, *sf_symbols = NULL; int frame_cnt; ue_sync_t s; int pos; pss_synch_t pss; float peak; struct timeval t[3]; float mean_ce_time=0; bool signal_detected; lte_fft_t fft; lte_cell_t cell; bzero(&cell, sizeof(lte_cell_t)); parse_args(argc, argv); #ifndef DISABLE_GRAPHICS if (!disable_plots) { init_plots(); } #endif input_init(); if (ue_sync_init(&s, cuhd_set_rx_srate, cuhd_recv_wrapper, uhd)) { fprintf(stderr, "Error initiating UE sync module\n"); exit(-1); } ue_sync_pbch_enable(&s, true); signal_detected = true; frame_cnt = 0; mean_ce_time=0; uint32_t valid_frames=0; //uint32_t unaligned = 0; while (frame_cnt < nof_frames || nof_frames == -1) { int n = ue_sync_get_buffer(&s, &input_buffer); if (n < 0) { fprintf(stderr, "Error calling sync work()\n"); exit(-1); } if (n == 1 && ue_sync_get_sfidx(&s) == 0) { if (signal_detected) { cell = ue_sync_get_cell(&s); pss_synch_init_fft(&pss, SF_LEN(lte_symbol_sz(cell.nof_prb), cell.cp), lte_symbol_sz(cell.nof_prb)); pss_synch_set_N_id_2(&pss, cell.id%3); sf_symbols = vec_malloc(SLOT_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); if (!sf_symbols) { perror("malloc"); exit(-1); } lte_fft_init(&fft, cell.cp, cell.nof_prb); signal_detected = false; } mean_ce_time = (float) (mean_ce_time + (float) t[0].tv_usec * valid_frames) / (valid_frames+1); valid_frames++; #ifndef DISABLE_GRAPHICS if (!disable_plots && !(valid_frames % 5) && sf_symbols) { /* Run FFT for the second slot */ lte_fft_run_slot(&fft, input_buffer, sf_symbols); int i; int nof_re = SLOT_LEN_RE(cell.nof_prb, cell.cp); for (i = 0; i < nof_re; i++) { tmp_plot[i] = 10 * log10f(cabsf(sf_symbols[i])); if (isinf(tmp_plot[i])) { tmp_plot[i] = -80; } } plot_real_setNewData(&poutfft, tmp_plot, nof_re); } #endif pos = pss_synch_find_pss(&pss, input_buffer, &peak, NULL); /*if (pos > 962 || pos < 958) { unaligned++; } */ printf("CELL_ID: %3d CFO: %+.4f KHz, SFO: %+.4f Khz, TimeOffset: %4d, Exec: %3.2f\r", cell.id, ue_sync_get_cfo(&s)/1000, ue_sync_get_sfo(&s)/1000, pos, s.mean_exec_time); fflush(stdout); if (VERBOSE_ISINFO()) { printf("\n"); } } frame_cnt++; } printf("\nBye\n"); exit(0); }
/* the gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i; lte_cell_t cell; chest_dl_t chest; precoding_t cheq; cf_t *input_signal = NULL, *output_signal[MAX_LAYERS]; cf_t *output_signal2 = NULL; cf_t *ce[MAX_PORTS]; double *outr0=NULL, *outi0=NULL; double *outr1=NULL, *outi1=NULL; double *outr2=NULL, *outi2=NULL; if (nrhs < NOF_INPUTS) { help(); return; } 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)/RE_X_RB; cell.nof_ports = (uint32_t) *((double*) mxGetPr(PORTS)); if ((mxGetN(INPUT)%14) == 0) { cell.cp = CPNORM; } else if ((mxGetN(INPUT)%12)!=0) { cell.cp = CPEXT; } else { mexErrMsgTxt("Invalid number of symbols\n"); help(); return; } if (chest_dl_init(&chest, cell)) { mexErrMsgTxt("Error initiating channel estimator\n"); return; } int nsubframes; if (cell.cp == CPNORM) { 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)); } else { if (nrhs != NOF_INPUTS) { help(); return; } } 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]; } 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]; } 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*CP_NSYMB(cell.cp)*cell.nof_prb*RE_X_RB; for (i=0;i<MAX_PORTS;i++) { ce[i] = vec_malloc(nof_re * sizeof(cf_t)); } input_signal = vec_malloc(nof_re * sizeof(cf_t)); for (i=0;i<MAX_PORTS;i++) { output_signal[i] = vec_malloc(nof_re * sizeof(cf_t)); } output_signal2 = vec_malloc(nof_re * sizeof(cf_t)); 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(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 (chest_dl_estimate(&chest, input_signal, ce, sf_idx)) { mexErrMsgTxt("Error running channel estimator\n"); return; } if (cell.nof_ports == 1) { predecoding_single(&cheq, input_signal, ce[0], output_signal2, nof_re, chest_dl_get_noise_estimate(&chest)); } else { predecoding_diversity(&cheq, input_signal, ce, output_signal, cell.nof_ports, nof_re, chest_dl_get_noise_estimate(&chest)); 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<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(chest_dl_get_snr(&chest)); } if (nlhs >= 5) { plhs[4] = mxCreateDoubleScalar(chest_dl_get_noise_estimate(&chest)); } if (nlhs >= 6) { plhs[5] = mxCreateDoubleScalar(chest_dl_get_rsrp(&chest)); } chest_dl_free(&chest); precoding_free(&cheq); return; }
/* the gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i; lte_cell_t cell; pcfich_t pcfich; chest_dl_t chest; lte_fft_t fft; regs_t regs; uint32_t sf_idx; cf_t *input_fft, *input_signal; if (nrhs != NOF_INPUTS) { help(); return; } if (mexutils_read_cell(ENBCFG, &cell)) { help(); return; } if (mexutils_read_uint32_struct(ENBCFG, "NSubframe", &sf_idx)) { help(); return; } if (chest_dl_init(&chest, cell)) { mexErrMsgTxt("Error initializing equalizer\n"); return; } if (lte_fft_init(&fft, cell.cp, cell.nof_prb)) { mexErrMsgTxt("Error initializing FFT\n"); return; } if (regs_init(®s, cell)) { mexErrMsgTxt("Error initiating regs\n"); return; } if (pcfich_init(&pcfich, ®s, cell)) { mexErrMsgTxt("Error creating PBCH object\n"); return; } /** Allocate input buffers */ if (mexutils_read_cf(INPUT, &input_signal) < 0) { mexErrMsgTxt("Error reading input signal\n"); return; } input_fft = vec_malloc(SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); // Set Channel estimates to 1.0 (ignore fading) cf_t *ce[MAX_PORTS]; for (i=0;i<cell.nof_ports;i++) { ce[i] = vec_malloc(SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); } lte_fft_run_sf(&fft, input_signal, input_fft); if (nrhs > NOF_INPUTS) { cf_t *cearray; mexutils_read_cf(prhs[NOF_INPUTS], &cearray); for (i=0;i<cell.nof_ports;i++) { for (int j=0;j<SF_LEN_RE(cell.nof_prb, cell.cp);j++) { ce[i][j] = *cearray; cearray++; } } } else { chest_dl_estimate(&chest, input_fft, ce, sf_idx); } float noise_power; if (nrhs > NOF_INPUTS + 1) { noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); } else { noise_power = chest_dl_get_noise_estimate(&chest); } uint32_t cfi; float corr_res; int n = pcfich_decode(&pcfich, input_fft, ce, noise_power, sf_idx, &cfi, &corr_res); if (nlhs >= 1) { if (n < 0) { plhs[0] = mxCreateDoubleScalar(-1); } else { plhs[0] = mxCreateDoubleScalar(cfi); } } if (nlhs >= 2) { mexutils_write_cf(pcfich.pcfich_d, &plhs[1], 16, 1); } if (nlhs >= 3) { mexutils_write_cf(pcfich.pcfich_symbols[0], &plhs[2], 16, 1); } chest_dl_free(&chest); lte_fft_free(&fft); pcfich_free(&pcfich); regs_free(®s); for (i=0;i<cell.nof_ports;i++) { free(ce[i]); } free(input_signal); free(input_fft); return; }
/* Setup USRP or input file */ int iodev_init(iodev_t *q, iodev_cfg_t *config, lte_cell_t *cell, pbch_mib_t *mib) { if (config->input_file_name) { mib->phich_resources = R_1; mib->phich_length = PHICH_NORM; cell->id = config->cell_id_file; cell->cp = CPNORM; cell->nof_ports = config->nof_ports_file; cell->nof_prb = config->nof_prb_file; if (filesource_init(&q->fsrc, config->input_file_name, COMPLEX_FLOAT_BIN)) { return LIBLTE_ERROR; } q->mode = FILESOURCE; int symbol_sz = lte_symbol_sz(cell->nof_prb); if (symbol_sz > 0) { q->sf_len = SF_LEN(symbol_sz); } else { fprintf(stderr, "Invalid number of PRB %d\n", cell->nof_prb); return LIBLTE_ERROR; } q->input_buffer_file = vec_malloc(q->sf_len * sizeof(cf_t)); if (!q->input_buffer_file) { perror("malloc"); return LIBLTE_ERROR; } q->sf_idx = 9; } else { #ifndef DISABLE_UHD printf("Opening UHD device...\n"); if (cuhd_open(config->uhd_args, &q->uhd)) { fprintf(stderr, "Error opening uhd\n"); return LIBLTE_ERROR; } cuhd_set_rx_gain(q->uhd, config->uhd_gain); /* set receiver frequency */ cuhd_set_rx_freq(q->uhd, (double) config->uhd_freq); cuhd_rx_wait_lo_locked(q->uhd); DEBUG("Set uhd_freq to %.3f MHz\n", (double ) config->uhd_freq); int n; ue_celldetect_t cd; ue_celldetect_result_t found_cells[3]; cf_t *buffer = vec_malloc(sizeof(cf_t) * 96000); if (!buffer) { perror("malloc"); return LIBLTE_ERROR; } if (ue_celldetect_init(&cd)) { fprintf(stderr, "Error initiating UE cell detect\n"); exit(-1); } n = find_cell(q->uhd, &cd, buffer, found_cells); if (n < 0) { fprintf(stderr, "Error searching cell\n"); exit(-1); } int max_peak_cell = 0; float max_peak_value = -1.0; if (n > 0) { for (int i=0;i<3;i++) { if (found_cells[i].peak > max_peak_value) { max_peak_value = found_cells[i].peak; max_peak_cell = i; } } if (decode_pbch(q->uhd, buffer, &found_cells[max_peak_cell], 400, mib)) { fprintf(stderr, "Could not decode PBCH from CELL ID %d\n", found_cells[max_peak_cell].cell_id); return LIBLTE_ERROR; } } else { fprintf(stderr, "Could not find any cell in this frequency\n"); return LIBLTE_ERROR; } free(buffer); cell->cp = found_cells[max_peak_cell].cp; cell->id = found_cells[max_peak_cell].cell_id; cell->nof_prb = mib->nof_prb; cell->nof_ports = mib->nof_ports; /* set sampling frequency */ int srate = lte_sampling_freq_hz(cell->nof_prb); if (srate != -1) { cuhd_set_rx_srate(q->uhd, (double) srate); } else { fprintf(stderr, "Invalid number of PRB %d\n", cell->nof_prb); return LIBLTE_ERROR; } DEBUG("Starting receiver...\n", 0); cuhd_start_rx_stream(q->uhd); if (ue_sync_init(&q->sframe, *cell, cuhd_recv_wrapper, q->uhd)) { fprintf(stderr, "Error initiating ue_sync\n"); return LIBLTE_ERROR; } /* Decodes the SSS signal during the tracking phase. Extra overhead, but makes sure we are in the correct subframe */ ue_sync_decode_sss_on_track(&q->sframe, true); // Here, the subframe length and input buffer is managed by ue_sync q->mode = UHD; #else printf("Error UHD not available. Select an input file\n"); return LIBLTE_ERROR; #endif } memcpy(&q->config, config, sizeof(iodev_cfg_t)); return LIBLTE_SUCCESS; }