|
|
|
@ -141,6 +141,11 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, uint32_t max_prb)
|
|
|
|
|
goto clean_exit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srslte_interp_linear_init(&q->srslte_interp_lin_3, 4*max_prb, SRSLTE_NRE/4)) {
|
|
|
|
|
fprintf(stderr, "Error initializing interpolator\n");
|
|
|
|
|
goto clean_exit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srslte_interp_linear_init(&q->srslte_interp_lin_mbsfn, 6*max_prb, SRSLTE_NRE/6)) {
|
|
|
|
|
fprintf(stderr, "Error initializing interpolator\n");
|
|
|
|
|
goto clean_exit;
|
|
|
|
@ -185,6 +190,7 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q)
|
|
|
|
|
}
|
|
|
|
|
srslte_interp_linear_vector_free(&q->srslte_interp_linvec);
|
|
|
|
|
srslte_interp_linear_free(&q->srslte_interp_lin);
|
|
|
|
|
srslte_interp_linear_free(&q->srslte_interp_lin_3);
|
|
|
|
|
srslte_interp_linear_free(&q->srslte_interp_lin_mbsfn);
|
|
|
|
|
if (q->pilot_estimates) {
|
|
|
|
|
free(q->pilot_estimates);
|
|
|
|
@ -238,6 +244,11 @@ int srslte_chest_dl_set_cell(srslte_chest_dl_t *q, srslte_cell_t cell)
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srslte_interp_linear_resize(&q->srslte_interp_lin_3, 4 * q->cell.nof_prb, SRSLTE_NRE / 4)) {
|
|
|
|
|
fprintf(stderr, "Error initializing interpolator\n");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
ret = SRSLTE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
@ -338,9 +349,15 @@ static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
fidx_offset = srslte_refsignal_cs_fidx(q->cell, l, port_id, 0);
|
|
|
|
|
if (q->average_subframe) {
|
|
|
|
|
srslte_interp_linear_offset(&q->srslte_interp_lin_3, &pilot_estimates[q->cell.nof_prb * l],
|
|
|
|
|
&ce[srslte_refsignal_cs_nsymbol(l, q->cell.cp, port_id) * q->cell.nof_prb
|
|
|
|
|
* SRSLTE_NRE], fidx_offset, SRSLTE_NRE / 2 - fidx_offset);
|
|
|
|
|
} else {
|
|
|
|
|
srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2 * q->cell.nof_prb * l],
|
|
|
|
|
&ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE],
|
|
|
|
|
fidx_offset, SRSLTE_NRE/2-fidx_offset);
|
|
|
|
|
&ce[srslte_refsignal_cs_nsymbol(l, q->cell.cp, port_id) * q->cell.nof_prb
|
|
|
|
|
* SRSLTE_NRE], fidx_offset, SRSLTE_NRE / 2 - fidx_offset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -417,11 +434,26 @@ static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint
|
|
|
|
|
|
|
|
|
|
// Average in the time domain if enabled
|
|
|
|
|
if (q->average_subframe) {
|
|
|
|
|
if (ch_mode == SRSLTE_SF_MBSFN) {
|
|
|
|
|
for (int l = 1; l < nsymbols; l++) {
|
|
|
|
|
srslte_vec_sum_ccc(&input[l * nref], input, input, nref);
|
|
|
|
|
}
|
|
|
|
|
srslte_vec_sc_prod_cfc(input, 1.0/((float) nsymbols), input, nref);
|
|
|
|
|
srslte_vec_sc_prod_cfc(input, 1.0f / ((float) nsymbols), input, nref);
|
|
|
|
|
nsymbols = 1;
|
|
|
|
|
} else {
|
|
|
|
|
cf_t *temp = &output[nref * 2];
|
|
|
|
|
bzero(temp, sizeof(cf_t) * nref * 2);
|
|
|
|
|
|
|
|
|
|
srslte_vec_interleave(input, &input[nref], temp, nref);
|
|
|
|
|
for (int l = 2; l < nsymbols - 1; l += 2) {
|
|
|
|
|
srslte_vec_interleave_add(&input[l * nref], &input[(l + 1) * nref], temp, nref);
|
|
|
|
|
}
|
|
|
|
|
srslte_vec_sc_prod_cfc(temp, 2.0f / (float) nsymbols, temp, 2 * nref);
|
|
|
|
|
srslte_conv_same_cf(temp, q->smooth_filter, output, 2 * nref, q->smooth_filter_len);
|
|
|
|
|
|
|
|
|
|
nsymbols = 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Average in the frequency domain
|
|
|
|
|