int srslte_pss_synch_init_N_id_2(cf_t *pss_signal_freq, cf_t *pss_signal_time, uint32_t N_id_2, uint32_t fft_size, int cfo_i) { srslte_dft_plan_t plan; cf_t pss_signal_pad[2048]; int ret = SRSLTE_ERROR_INVALID_INPUTS; if (srslte_N_id_2_isvalid(N_id_2) && fft_size <= 2048) { srslte_pss_generate(pss_signal_freq, N_id_2); bzero(pss_signal_pad, fft_size * sizeof(cf_t)); bzero(pss_signal_time, fft_size * sizeof(cf_t)); memcpy(&pss_signal_pad[(fft_size-SRSLTE_PSS_LEN)/2+cfo_i], pss_signal_freq, SRSLTE_PSS_LEN * sizeof(cf_t)); /* Convert signal into the time domain */ if (srslte_dft_plan(&plan, fft_size, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(&plan, true); srslte_dft_plan_set_dc(&plan, true); srslte_dft_plan_set_norm(&plan, true); srslte_dft_run_c(&plan, pss_signal_pad, pss_signal_time); srslte_vec_conj_cc(pss_signal_time, pss_signal_time, fft_size); srslte_vec_sc_prod_cfc(pss_signal_time, 1.0/SRSLTE_PSS_LEN, pss_signal_time, fft_size); srslte_dft_plan_free(&plan); ret = SRSLTE_SUCCESS; } return ret; }
int srslte_sss_synch_init(srslte_sss_synch_t *q, uint32_t fft_size) { if (q != NULL && fft_size <= 2048) { uint32_t N_id_2; srslte_sss_tables_t sss_tables; bzero(q, sizeof(srslte_sss_synch_t)); if (srslte_dft_plan(&q->dftp_input, fft_size, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { srslte_sss_synch_free(q); return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(&q->dftp_input, true); srslte_dft_plan_set_dc(&q->dftp_input, true); q->fft_size = fft_size; generate_N_id_1_table(q->N_id_1_table); for (N_id_2=0;N_id_2<3;N_id_2++) { generate_sss_all_tables(&sss_tables, N_id_2); convert_tables(&q->fc_tables[N_id_2], &sss_tables); } q->N_id_2 = 0; return SRSLTE_SUCCESS; } return SRSLTE_ERROR_INVALID_INPUTS; }
int srslte_ofdm_init_(srslte_ofdm_t *q, srslte_cp_t cp, int symbol_sz, int nof_prb, srslte_dft_dir_t dir) { if (srslte_dft_plan_c(&q->fft_plan, symbol_sz, dir)) { fprintf(stderr, "Error: Creating DFT plan\n"); return -1; } q->tmp = srslte_vec_malloc((uint32_t) symbol_sz * sizeof(cf_t)); if (!q->tmp) { perror("malloc"); return -1; } srslte_dft_plan_set_mirror(&q->fft_plan, true); srslte_dft_plan_set_dc(&q->fft_plan, true); q->symbol_sz = (uint32_t) symbol_sz; q->nof_symbols = SRSLTE_CP_NSYMB(cp); q->cp = cp; q->freq_shift = false; q->shift_buffer = NULL; q->nof_re = nof_prb * SRSLTE_NRE; q->nof_guards = ((symbol_sz - q->nof_re) / 2); q->slot_sz = SRSLTE_SLOT_LEN(symbol_sz); DEBUG("Init %s symbol_sz=%d, nof_symbols=%d, cp=%s, nof_re=%d, nof_guards=%d\n", dir==SRSLTE_DFT_FORWARD?"FFT":"iFFT", q->symbol_sz, q->nof_symbols, q->cp==SRSLTE_CP_NORM?"Normal":"Extended", q->nof_re, q->nof_guards); return SRSLTE_SUCCESS; }
int srslte_sss_synch_realloc(srslte_sss_synch_t *q, uint32_t fft_size) { if (q != NULL && fft_size <= 2048) { srslte_dft_plan_free(&q->dftp_input); if (srslte_dft_plan(&q->dftp_input, fft_size, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { srslte_sss_synch_free(q); return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(&q->dftp_input, true); srslte_dft_plan_set_norm(&q->dftp_input, true); srslte_dft_plan_set_dc(&q->dftp_input, true); q->fft_size = fft_size; return SRSLTE_SUCCESS; } return SRSLTE_ERROR_INVALID_INPUTS; }
/* Shifts the signal after the iFFT or before the FFT. * Freq_shift is relative to inter-carrier spacing. * Caution: This function shall not be called during run-time */ int srslte_ofdm_set_freq_shift(srslte_ofdm_t *q, float freq_shift) { q->shift_buffer = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN(q->symbol_sz)); if (!q->shift_buffer) { perror("malloc"); return -1; } cf_t *ptr = q->shift_buffer; for (uint32_t n=0;n<2;n++) { for (uint32_t i=0;i<q->nof_symbols;i++) { uint32_t cplen = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(i, q->symbol_sz):SRSLTE_CP_LEN_EXT(q->symbol_sz); for (uint32_t t=0;t<q->symbol_sz+cplen;t++) { ptr[t] = cexpf(I*2*M_PI*((float) t-(float)cplen)*freq_shift/q->symbol_sz); } ptr += q->symbol_sz+cplen; } } /* Disable DC carrier addition */ srslte_dft_plan_set_dc(&q->fft_plan, false); q->freq_shift = true; return SRSLTE_SUCCESS; }
/* 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 srslte_pss_synch_init_fft_offset(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t fft_size, int offset) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { uint32_t N_id_2; uint32_t buffer_size; bzero(q, sizeof(srslte_pss_synch_t)); q->N_id_2 = 10; q->fft_size = fft_size; q->frame_size = frame_size; q->ema_alpha = 0.1; buffer_size = fft_size + frame_size + 1; if (srslte_dft_plan(&q->dftp_input, fft_size, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error creating DFT plan \n"); goto clean_and_exit; } srslte_dft_plan_set_mirror(&q->dftp_input, true); srslte_dft_plan_set_dc(&q->dftp_input, true); srslte_dft_plan_set_norm(&q->dftp_input, true); q->tmp_input = srslte_vec_malloc(buffer_size * sizeof(cf_t)); if (!q->tmp_input) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } bzero(&q->tmp_input[q->frame_size], q->fft_size * sizeof(cf_t)); q->conv_output = srslte_vec_malloc(buffer_size * sizeof(cf_t)); if (!q->conv_output) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output, sizeof(cf_t) * buffer_size); q->conv_output_avg = srslte_vec_malloc(buffer_size * sizeof(float)); if (!q->conv_output_avg) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output_avg, sizeof(float) * buffer_size); #ifdef SRSLTE_PSS_ACCUMULATE_ABS q->conv_output_abs = srslte_vec_malloc(buffer_size * sizeof(float)); if (!q->conv_output_abs) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output_abs, sizeof(float) * buffer_size); #endif for (N_id_2=0;N_id_2<3;N_id_2++) { q->pss_signal_time[N_id_2] = srslte_vec_malloc(buffer_size * sizeof(cf_t)); if (!q->pss_signal_time[N_id_2]) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } /* The PSS is translated into the time domain for each N_id_2 */ if (srslte_pss_synch_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { fprintf(stderr, "Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); goto clean_and_exit; } bzero(&q->pss_signal_time[N_id_2][q->fft_size], q->frame_size * sizeof(cf_t)); } #ifdef CONVOLUTION_FFT if (srslte_conv_fft_cc_init(&q->conv_fft, frame_size, fft_size)) { fprintf(stderr, "Error initiating convolution FFT\n"); goto clean_and_exit; } #endif srslte_pss_synch_reset(q); ret = SRSLTE_SUCCESS; } clean_and_exit: if (ret == SRSLTE_ERROR) { srslte_pss_synch_free(q); } return ret; }
/* 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 srslte_pss_init_fft_offset_decim(srslte_pss_t *q, uint32_t max_frame_size, uint32_t max_fft_size, int offset, int decimate) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { ret = SRSLTE_ERROR; uint32_t N_id_2; uint32_t buffer_size; bzero(q, sizeof(srslte_pss_t)); q->N_id_2 = 10; q->ema_alpha = 0.2; q->max_fft_size = max_fft_size; q->max_frame_size = max_frame_size; q->decimate = decimate; uint32_t fft_size = max_fft_size/q->decimate; uint32_t frame_size = max_frame_size/q->decimate; q->fft_size = fft_size; q->frame_size = frame_size; buffer_size = fft_size + frame_size + 1; q->filter_pss_enable = false; q->chest_on_filter = false; if(q->decimate > 1) { int filter_order = 3; srslte_filt_decim_cc_init(&q->filter,q->decimate,filter_order); q->filter.filter_output = srslte_vec_malloc((buffer_size) * sizeof(cf_t)); q->filter.downsampled_input = srslte_vec_malloc((buffer_size + filter_order) * sizeof(cf_t)); printf("decimation for the PSS search is %d \n",q->decimate); } if (srslte_dft_plan(&q->dftp_input, fft_size, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { ERROR("Error creating DFT plan \n"); goto clean_and_exit; } srslte_dft_plan_set_mirror(&q->dftp_input, true); srslte_dft_plan_set_dc(&q->dftp_input, true); srslte_dft_plan_set_norm(&q->dftp_input, false); if (srslte_dft_plan(&q->idftp_input, fft_size, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { ERROR("Error creating DFT plan \n"); goto clean_and_exit; } srslte_dft_plan_set_mirror(&q->idftp_input, true); srslte_dft_plan_set_dc(&q->idftp_input, true); srslte_dft_plan_set_norm(&q->idftp_input, false); bzero(q->tmp_fft2, sizeof(cf_t)*SRSLTE_SYMBOL_SZ_MAX); q->tmp_input = srslte_vec_malloc((buffer_size + frame_size*(q->decimate - 1)) * sizeof(cf_t)); if (!q->tmp_input) { ERROR("Error allocating memory\n"); goto clean_and_exit; } bzero(&q->tmp_input[q->frame_size], q->fft_size * sizeof(cf_t)); q->conv_output = srslte_vec_malloc(buffer_size * sizeof(cf_t)); if (!q->conv_output) { ERROR("Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output, sizeof(cf_t) * buffer_size); q->conv_output_avg = srslte_vec_malloc(buffer_size * sizeof(float)); if (!q->conv_output_avg) { ERROR("Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output_avg, sizeof(float) * buffer_size); #ifdef SRSLTE_PSS_ACCUMULATE_ABS q->conv_output_abs = srslte_vec_malloc(buffer_size * sizeof(float)); if (!q->conv_output_abs) { ERROR("Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output_abs, sizeof(float) * buffer_size); #endif for (N_id_2=0;N_id_2<3;N_id_2++) { q->pss_signal_time[N_id_2] = srslte_vec_malloc(buffer_size * sizeof(cf_t)); if (!q->pss_signal_time[N_id_2]) { ERROR("Error allocating memory\n"); goto clean_and_exit; } /* The PSS is translated into the time domain for each N_id_2 */ if (srslte_pss_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { ERROR("Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); goto clean_and_exit; } bzero(&q->pss_signal_time[N_id_2][q->fft_size], q->frame_size * sizeof(cf_t)); } #ifdef CONVOLUTION_FFT if (srslte_conv_fft_cc_init(&q->conv_fft, frame_size, fft_size)) { ERROR("Error initiating convolution FFT\n"); goto clean_and_exit; } for(N_id_2=0; N_id_2<3; N_id_2++) { q->pss_signal_freq_full[N_id_2] = srslte_vec_malloc(buffer_size * sizeof(cf_t)); srslte_dft_run_c(&q->conv_fft.filter_plan, q->pss_signal_time[N_id_2], q->pss_signal_freq_full[N_id_2]); } #endif srslte_pss_reset(q); ret = SRSLTE_SUCCESS; } clean_and_exit: if (ret == SRSLTE_ERROR) { srslte_pss_free(q); } return ret; }