void srslte_sync_free(srslte_sync_t *q) { if (q) { srslte_pss_free(&q->pss); srslte_sss_free(&q->sss); srslte_cfo_free(&q->cfo_corr_frame); srslte_cfo_free(&q->cfo_corr_symbol); srslte_cp_synch_free(&q->cp_synch); for (int i = 0; i < 2; i++) { if (q->cfo_i_corr[i]) { free(q->cfo_i_corr[i]); } srslte_pss_free(&q->pss_i[i]); } if (q->temp) { free(q->temp); } } }
/* 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; }