/* Differential SSS estimation. * Returns m0 and m1 estimates * * Source: "SSS Detection Method for Initial Cell Search in 3GPP LTE FDD/TDD Dual Mode Receiver" * Jung-In Kim, Jung-Su Han, Hee-Jin Roh and Hyung-Jin Choi * */ int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, cf_t *input, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, uint32_t *m1, float *m1_value) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && input != NULL && m0 != NULL && m1 != NULL) { cf_t yprod[SRSLTE_SSS_N]; cf_t y[2][SRSLTE_SSS_N]; extract_pair_sss(q, input, ce, y); srslte_vec_prod_conj_ccc(&y[0][1], y[0], yprod, SRSLTE_SSS_N - 1); corr_all_zs(yprod, q->fc_tables[q->N_id_2].sd, q->corr_output_m0); *m0 = srslte_vec_max_fi(q->corr_output_m0, SRSLTE_SSS_N); if (m0_value) { *m0_value = q->corr_output_m0[*m0]; } srslte_vec_prod_cfc(y[1], q->fc_tables[q->N_id_2].z1[*m0], y[1], SRSLTE_SSS_N); srslte_vec_prod_conj_ccc(&y[1][1], y[1], yprod, SRSLTE_SSS_N - 1); corr_all_zs(yprod, q->fc_tables[q->N_id_2].sd, q->corr_output_m1); *m1 = srslte_vec_max_fi(q->corr_output_m1, SRSLTE_SSS_N); if (m1_value) { *m1_value = q->corr_output_m1[*m1]; } ret = SRSLTE_SUCCESS; } return ret; }
/* Partial correlation SSS estimation. * Returns m0 and m1 estimates * * Source: "SSS Detection Method for Initial Cell Search in 3GPP LTE FDD/TDD Dual Mode Receiver" * Jung-In Kim, Jung-Su Han, Hee-Jin Roh and Hyung-Jin Choi */ int srslte_sss_synch_m0m1_partial(srslte_sss_synch_t *q, cf_t *input, uint32_t M, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, uint32_t *m1, float *m1_value) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && input != NULL && m0 != NULL && m1 != NULL && M <= MAX_M) { cf_t y[2][SRSLTE_SSS_N]; extract_pair_sss(q, input, ce, y); corr_all_sz_partial(y[0], q->fc_tables[q->N_id_2].s, M, q->corr_output_m0); *m0 = srslte_vec_max_fi(q->corr_output_m0, SRSLTE_SSS_N); if (m0_value) { *m0_value = q->corr_output_m0[*m0]; } srslte_vec_prod_cfc(y[1], q->fc_tables[q->N_id_2].z1[*m0], y[1], SRSLTE_SSS_N); corr_all_sz_partial(y[1], q->fc_tables[q->N_id_2].s, M, q->corr_output_m1); *m1 = srslte_vec_max_fi(q->corr_output_m1, SRSLTE_SSS_N); if (m1_value) { *m1_value = q->corr_output_m1[*m1]; } ret = SRSLTE_SUCCESS; } return ret; }
void srslte_interp_linear_offset(srslte_interp_lin_t *q, cf_t *input, cf_t *output, uint32_t off_st, uint32_t off_end) { uint32_t i, j; cf_t diff; i=0; for (j=0;j<off_st;j++) { output[j] = input[i] + (j+1) * (input[i+1]-input[i]) / q->M; } srslte_vec_sub_ccc(&input[1], input, q->diff_vec, (q->vector_len-1)); srslte_vec_sc_prod_cfc(q->diff_vec, (float) 1/q->M, q->diff_vec, q->vector_len-1); for (i=0;i<q->vector_len-1;i++) { for (j=0;j<q->M;j++) { output[i*q->M+j+off_st] = input[i]; q->diff_vec2[i*q->M+j] = q->diff_vec[i]; } srslte_vec_prod_cfc(&q->diff_vec2[i*q->M],q->ramp,&q->diff_vec2[i*q->M],q->M); } srslte_vec_sum_ccc(&output[off_st], q->diff_vec2, &output[off_st], q->M*(q->vector_len-1)); if (q->vector_len > 1) { diff = input[q->vector_len-1]-input[q->vector_len-2]; for (j=0;j<off_end;j++) { output[i*q->M+j+off_st] = input[i] + j * diff / q->M; } } }
static void extract_pair_sss(srslte_sss_synch_t *q, cf_t *input, cf_t *ce, cf_t y[2][SRSLTE_SSS_N]) { cf_t input_fft[SRSLTE_SYMBOL_SZ_MAX]; srslte_dft_run_c(&q->dftp_input, input, input_fft); if (ce) { srslte_vec_prod_conj_ccc(&input_fft[q->fft_size/2-SRSLTE_SSS_N], ce, &input_fft[q->fft_size/2-SRSLTE_SSS_N], 2*SRSLTE_SSS_N); } for (int i = 0; i < SRSLTE_SSS_N; i++) { y[0][i] = input_fft[q->fft_size/2-SRSLTE_SSS_N + 2 * i]; y[1][i] = input_fft[q->fft_size/2-SRSLTE_SSS_N + 2 * i + 1]; } srslte_vec_prod_cfc(y[0], q->fc_tables[q->N_id_2].c[0], y[0], SRSLTE_SSS_N); srslte_vec_prod_cfc(y[1], q->fc_tables[q->N_id_2].c[1], y[1], SRSLTE_SSS_N); }
void srslte_scrambling_c_offset(srslte_sequence_t *s, cf_t *data, int offset, int len) { assert (len + offset <= s->cur_len); srslte_vec_prod_cfc(data, &s->c_float[offset], data, len); }