/* 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; }
/* Assumes input points to the beginning of the SSS symbol. The SSS symbol start is * given by SSS_SYMBOL_ST() macro in sss.h. * Estimates the m0 and m1 values and saves in m0_value and m1_value * the resulted correlation (higher is more likely) * * * 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 * */ void sss_synch_m0m1(sss_synch_t *q, cf_t *input, int *m0, float *m0_value, int *m1, float *m1_value) { /* This is aprox 3-4 kbytes of stack. Consider moving to sss_synch_t?? */ cf_t zdelay[N_SSS+1],zconj[N_SSS+1],zprod[N_SSS+1]; cf_t y[2][N_SSS+1], z[N_SSS+1], tmp[N_SSS+1]; float tmp_real[N_SSS+1]; cf_t input_fft[SSS_DFT_LEN]; int i; dft_run_c2c(&q->dftp_input, input, input_fft); for (i = 0; i < N_SSS; i++) { y[0][i] = input_fft[SSS_POS_SYMBOL + 2 * i]; y[1][i] = input_fft[SSS_POS_SYMBOL + 2 * i + 1]; } vec_prod_ccc(y[0], q->fc_tables.c[0], z, N_SSS); memcpy(zdelay, &z[1], (N_SSS - 1) * sizeof(cf_t)); vec_conj_cc(z, zconj, N_SSS - 1); vec_prod_ccc(zdelay, zconj, zprod, N_SSS - 1); corr_all_zs(zprod, q->fc_tables.s, tmp); vec_abs_cf(tmp, tmp_real, N_SSS); *m0 = vec_max_fi(tmp_real, N_SSS); if (m0_value) { *m0_value = tmp_real[*m0]; } vec_prod_ccc(y[1], q->fc_tables.c[1], tmp, N_SSS); vec_prod_ccc(tmp, q->fc_tables.z1[*m0], z, N_SSS); memcpy(zdelay, &z[1], (N_SSS - 1) * sizeof(cf_t)); vec_conj_cc(z, zconj, N_SSS - 1); vec_prod_ccc(zdelay, zconj, zprod, N_SSS - 1); corr_all_zs(zprod, q->fc_tables.s, tmp); vec_abs_cf(tmp, tmp_real, N_SSS); *m1 = vec_max_fi(tmp_real, N_SSS); if (m1_value) { *m1_value = tmp_real[*m1]; } }