int srslte_conv_fft_cc_init(srslte_conv_fft_cc_t *q, uint32_t input_len, uint32_t filter_len) { q->input_len = input_len; q->filter_len = filter_len; q->output_len = input_len+filter_len; q->input_fft = srslte_vec_malloc(sizeof(cf_t)*q->output_len); q->filter_fft = srslte_vec_malloc(sizeof(cf_t)*q->output_len); q->output_fft = srslte_vec_malloc(sizeof(cf_t)*q->output_len); if (!q->input_fft || !q->filter_fft || !q->output_fft) { return SRSLTE_ERROR; } if (srslte_dft_plan(&q->input_plan,q->output_len,SRSLTE_DFT_FORWARD,SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error initiating input plan\n"); return SRSLTE_ERROR; } if (srslte_dft_plan(&q->filter_plan,q->output_len,SRSLTE_DFT_FORWARD,SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error initiating filter plan\n"); return SRSLTE_ERROR; } if (srslte_dft_plan(&q->output_plan,q->output_len,SRSLTE_DFT_BACKWARD,SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error initiating output plan\n"); return SRSLTE_ERROR; } srslte_dft_plan_set_norm(&q->input_plan, true); srslte_dft_plan_set_norm(&q->filter_plan, true); srslte_dft_plan_set_norm(&q->output_plan, false); return SRSLTE_SUCCESS; }
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_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; }
/* 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; }
int srslte_prach_init(srslte_prach_t *p, uint32_t N_ifft_ul, uint32_t preamble_format, uint32_t root_seq_index, bool high_speed_flag, uint32_t zero_corr_zone_config) { int ret = SRSLTE_ERROR; if(p != NULL && N_ifft_ul < 2049 && preamble_format < 4 && // Currently supporting formats 0-3 root_seq_index < MAX_ROOTS && zero_corr_zone_config < 16) { p->f = preamble_format; p->rsi = root_seq_index; p->hs = high_speed_flag; p->zczc = zero_corr_zone_config; // Determine N_zc and N_cs if(4 == preamble_format){ p->N_zc = 139; p->N_cs = prach_Ncs_format4[p->zczc]; }else{ p->N_zc = 839; if(p->hs){ p->N_cs = prach_Ncs_restricted[p->zczc]; }else{ p->N_cs = prach_Ncs_unrestricted[p->zczc]; } } // Set up containers p->prach_bins = srslte_vec_malloc(sizeof(cf_t)*p->N_zc); p->corr_spec = srslte_vec_malloc(sizeof(cf_t)*p->N_zc); p->corr = srslte_vec_malloc(sizeof(float)*p->N_zc); // Set up ZC FFTS p->zc_fft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t)); if(srslte_dft_plan(p->zc_fft, p->N_zc, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){ return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(p->zc_fft, false); srslte_dft_plan_set_norm(p->zc_fft, true); p->zc_ifft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t)); if(srslte_dft_plan(p->zc_ifft, p->N_zc, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)){ return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(p->zc_ifft, false); srslte_dft_plan_set_norm(p->zc_ifft, true); // Generate our 64 sequences p->N_roots = 0; srslte_prach_gen_seqs(p); // Generate sequence FFTs for(int i=0;i<N_SEQS;i++){ srslte_dft_run(p->zc_fft, p->seqs[i], p->dft_seqs[i]); } // Create our FFT objects and buffers p->N_ifft_ul = N_ifft_ul; if(4 == preamble_format){ p->N_ifft_prach = p->N_ifft_ul * DELTA_F/DELTA_F_RA_4; }else{ p->N_ifft_prach = p->N_ifft_ul * DELTA_F/DELTA_F_RA; } p->ifft_in = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t)); p->ifft_out = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t)); p->ifft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t)); if(srslte_dft_plan(p->ifft, p->N_ifft_prach, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error creating DFT plan\n"); return -1; } srslte_dft_plan_set_mirror(p->ifft, true); srslte_dft_plan_set_norm(p->ifft, true); p->fft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t)); if(srslte_dft_plan(p->fft, p->N_ifft_prach, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){ fprintf(stderr, "Error creating DFT plan\n"); return -1; } srslte_dft_plan_set_mirror(p->fft, true); srslte_dft_plan_set_norm(p->fft, true); p->N_seq = prach_Tseq[p->f]*p->N_ifft_ul/2048; p->N_cp = prach_Tcp[p->f]*p->N_ifft_ul/2048; ret = SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid parameters\n"); } return ret; }
int srslte_prach_init(srslte_prach_t *p, uint32_t N_ifft_ul, uint32_t config_idx, uint32_t root_seq_index, bool high_speed_flag, uint32_t zero_corr_zone_config) { int ret = SRSLTE_ERROR; if(p != NULL && N_ifft_ul < 2049 && config_idx < 16 && root_seq_index < MAX_ROOTS) { uint32_t preamble_format = srslte_prach_get_preamble_format(config_idx); p->config_idx = config_idx; p->f = preamble_format; p->rsi = root_seq_index; p->hs = high_speed_flag; p->zczc = zero_corr_zone_config; p->detect_factor = PRACH_DETECT_FACTOR; // Determine N_zc and N_cs if(4 == preamble_format){ if (p->zczc < 7) { p->N_zc = 139; p->N_cs = prach_Ncs_format4[p->zczc]; } else { fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d for format4\n", p->zczc); return SRSLTE_ERROR; } }else{ p->N_zc = 839; if(p->hs){ if (p->zczc < 15) { p->N_cs = prach_Ncs_restricted[p->zczc]; } else { fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d for restricted set\n", p->zczc); return SRSLTE_ERROR; } }else{ if (p->zczc < 16) { p->N_cs = prach_Ncs_unrestricted[p->zczc]; } else { fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d\n", p->zczc); return SRSLTE_ERROR; } } } // Set up containers p->prach_bins = srslte_vec_malloc(sizeof(cf_t)*p->N_zc); p->corr_spec = srslte_vec_malloc(sizeof(cf_t)*p->N_zc); p->corr = srslte_vec_malloc(sizeof(float)*p->N_zc); // Set up ZC FFTS p->zc_fft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t)); if(srslte_dft_plan(p->zc_fft, p->N_zc, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){ return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(p->zc_fft, false); srslte_dft_plan_set_norm(p->zc_fft, true); p->zc_ifft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t)); if(srslte_dft_plan(p->zc_ifft, p->N_zc, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)){ return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(p->zc_ifft, false); srslte_dft_plan_set_norm(p->zc_ifft, false); // Generate our 64 sequences p->N_roots = 0; srslte_prach_gen_seqs(p); // Generate sequence FFTs for(int i=0;i<N_SEQS;i++){ srslte_dft_run(p->zc_fft, p->seqs[i], p->dft_seqs[i]); } // Create our FFT objects and buffers p->N_ifft_ul = N_ifft_ul; if(4 == preamble_format){ p->N_ifft_prach = p->N_ifft_ul * DELTA_F/DELTA_F_RA_4; }else{ p->N_ifft_prach = p->N_ifft_ul * DELTA_F/DELTA_F_RA; } /* The deadzone specifies the number of samples at the end of the correlation window * that will be considered as belonging to the next preamble */ p->deadzone = 0; /* if(p->N_cs != 0) { float samp_rate=15000*p->N_ifft_ul; p->deadzone = (uint32_t) ceil((float) samp_rate/((float) p->N_zc*subcarrier_spacing)); }*/ p->ifft_in = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t)); p->ifft_out = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t)); p->ifft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t)); if(srslte_dft_plan(p->ifft, p->N_ifft_prach, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error creating DFT plan\n"); return -1; } srslte_dft_plan_set_mirror(p->ifft, true); srslte_dft_plan_set_norm(p->ifft, true); p->fft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t)); if(srslte_dft_plan(p->fft, p->N_ifft_prach, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){ fprintf(stderr, "Error creating DFT plan\n"); return -1; } p->signal_fft = srslte_vec_malloc(sizeof(cf_t)*p->N_ifft_prach); if (!p->signal_fft) { fprintf(stderr, "Error allocating memory\n"); return -1; } srslte_dft_plan_set_mirror(p->fft, true); srslte_dft_plan_set_norm(p->fft, false); p->N_seq = prach_Tseq[p->f]*p->N_ifft_ul/2048; p->N_cp = prach_Tcp[p->f]*p->N_ifft_ul/2048; p->T_seq = prach_Tseq[p->f]*SRSLTE_LTE_TS; ret = SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid parameters\n"); } return ret; }