From 9d68d0adb42f5fa71ea955b4c9b7e10343ada7b9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 29 Aug 2016 17:42:46 +0200 Subject: [PATCH] Revert "chest_dl: subframe averaging with previous" This reverts commit 82cfa014684d452e71e29936d84a7869a282bc10. --- .../include/srslte/ch_estimation/chest_dl.h | 10 -- srslte/lib/ch_estimation/chest_dl.c | 166 +++++++++--------- 2 files changed, 80 insertions(+), 96 deletions(-) diff --git a/srslte/include/srslte/ch_estimation/chest_dl.h b/srslte/include/srslte/ch_estimation/chest_dl.h index 3aabd2595..a4afa1d84 100644 --- a/srslte/include/srslte/ch_estimation/chest_dl.h +++ b/srslte/include/srslte/ch_estimation/chest_dl.h @@ -63,7 +63,6 @@ typedef struct { srslte_refsignal_cs_t csr_signal; cf_t *pilot_estimates; cf_t *pilot_estimates_average; - cf_t *pilot_average_last; cf_t *pilot_recv_signal; cf_t *tmp_noise; @@ -74,9 +73,6 @@ typedef struct { uint32_t smooth_filter_len; float smooth_filter[SRSLTE_CHEST_MAX_SMOOTH_FIL_LEN]; - float time_ema_coeff; - bool average_subframe; - srslte_interp_linsrslte_vec_t srslte_interp_linvec; srslte_interp_lin_t srslte_interp_lin; @@ -106,12 +102,6 @@ SRSLTE_API void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, SRSLTE_API void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w); -SRSLTE_API void srslte_chest_dl_set_time_ema_coeff(srslte_chest_dl_t *q, - float t); - -SRSLTE_API void srslte_chest_dl_set_average_subframe(srslte_chest_dl_t *q, - bool enable); - SRSLTE_API void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q, srslte_chest_dl_noise_alg_t noise_estimation_alg); diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index e550a5305..7ac4444a0 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -39,8 +39,32 @@ #include "srslte/utils/vector.h" #include "srslte/utils/convolution.h" -#define DEFAULT_FILTER_LEN 3 -#define DEFAULT_TIME_EMA_COEFF 0.9 +#define AVERAGE_SUBFRAME + +//#define DEFAULT_FILTER_LEN 3 + +#ifdef DEFAULT_FILTER_LEN +static void set_default_filter(srslte_chest_dl_t *q, int filter_len) { + + float fil[SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN]; + + for (int i=0;ipilot_average_last = srslte_vec_malloc(sizeof(cf_t) * 2 * cell.nof_prb); - if (!q->pilot_average_last) { - perror("malloc"); - goto clean_exit; - } q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb)); if (!q->pilot_recv_signal) { perror("malloc"); @@ -108,14 +127,7 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, srslte_cell_t cell) q->noise_alg = SRSLTE_NOISE_ALG_REFS; - q->time_ema_coeff = 1.0; -#ifdef DEFAULT_TIME_EMA_COEFF - q->time_ema_coeff = DEFAULT_TIME_EMA_COEFF; -#endif - - q->average_subframe = true; - - q->smooth_filter_len = DEFAULT_FILTER_LEN; + q->smooth_filter_len = 3; srslte_chest_dl_set_smooth_filter3_coeff(q, 0.1); q->cell = cell; @@ -146,9 +158,6 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q) if (q->pilot_estimates_average) { free(q->pilot_estimates_average); } - if (q->pilot_average_last) { - free(q->pilot_average_last); - } if (q->pilot_recv_signal) { free(q->pilot_recv_signal); } @@ -224,52 +233,52 @@ static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) { static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *ce, uint32_t port_id) { - if (q->average_subframe) { - // Interpolate symbol 0 in the frequency domain - uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0); - srslte_interp_linear_offset(&q->srslte_interp_lin, pilot_estimates, - &ce[srslte_refsignal_cs_nsymbol(0,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], - fidx_offset, SRSLTE_NRE/2-fidx_offset); - // All channel estimates in the subframe are the same - for (int l=1;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) { - memcpy(&ce[l*q->cell.nof_prb*SRSLTE_NRE], ce, q->cell.nof_prb*SRSLTE_NRE*sizeof(cf_t)); - } - } else { - uint32_t l=0; - uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); - - // Interpolate in the frequency domain - for (l=0;lcell, l, port_id, 0); - 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); - } - // Interpolate in the time domain between symbols - if (SRSLTE_CP_ISNORM(q->cell.cp)) { - if (nsymbols == 4) { - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(4), &cesymb(7), &cesymb(5), 3, 2); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(8), 4, 3); - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(11), &cesymb(12), 4, 2); - } else { - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(8), &cesymb(1), &cesymb(1), &cesymb(0), 7, 1); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(2), 7, 6); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(9), 7, 5); - } - } else { - if (nsymbols == 4) { - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(3), &cesymb(1), 3, 2); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(3), &cesymb(6), &cesymb(4), 3, 2); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(7), 3, 2); - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(9), &cesymb(10), 3, 2); - } else { - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(1), &cesymb(1), &cesymb(0), 6, 1); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(2), 6, 5); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4); - } - } +#ifdef AVERAGE_SUBFRAME + // Interpolate symbol 0 in the frequency domain + uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0); + srslte_interp_linear_offset(&q->srslte_interp_lin, pilot_estimates, + &ce[srslte_refsignal_cs_nsymbol(0,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], + fidx_offset, SRSLTE_NRE/2-fidx_offset); + // All channel estimates in the subframe are the same + for (int l=1;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) { + memcpy(&ce[l*q->cell.nof_prb*SRSLTE_NRE], ce, q->cell.nof_prb*SRSLTE_NRE*sizeof(cf_t)); } +#else + uint32_t l=0; + uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); + + // Interpolate in the frequency domain + for (l=0;lcell, l, port_id, 0); + 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); + } + // Interpolate in the time domain between symbols + if (SRSLTE_CP_ISNORM(q->cell.cp)) { + if (nsymbols == 4) { + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(4), &cesymb(7), &cesymb(5), 3, 2); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(8), 4, 3); + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(11), &cesymb(12), 4, 2); + } else { + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(8), &cesymb(1), &cesymb(1), &cesymb(0), 7, 1); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(2), 7, 6); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(9), 7, 5); + } + } else { + if (nsymbols == 4) { + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(3), &cesymb(1), 3, 2); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(3), &cesymb(6), &cesymb(4), 3, 2); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(7), 3, 2); + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(9), &cesymb(10), 3, 2); + } else { + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(1), &cesymb(1), &cesymb(0), 6, 1); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(2), 6, 5); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4); + } + } +#endif } void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) { @@ -298,36 +307,21 @@ void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w) q->smooth_filter[1] = 1-2*w; } -void srslte_chest_dl_set_time_ema_coeff(srslte_chest_dl_t *q, float t) { - if (t > 0.0 && t <= 1.0) { - q->time_ema_coeff = t; - } -} - -void srslte_chest_dl_set_average_subframe(srslte_chest_dl_t *q, bool enable) { - q->average_subframe = enable; -} - static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id) { uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); uint32_t nref = 2*q->cell.nof_prb; memcpy(output, input, nref*sizeof(cf_t)); for (int l=1;laverage_subframe) { - srslte_vec_sum_ccc(output, &input[l*nref], output, nref); - } else { - srslte_conv_same_cf(&input[l*nref], q->smooth_filter, &output[l*nref], nref, q->smooth_filter_len); - } - } - if (q->average_subframe) { - srslte_vec_sc_prod_cfc(output, (float) q->time_ema_coeff/nsymbols, output, nref); - if (q->time_ema_coeff < 1.0) { - srslte_vec_sc_prod_cfc(q->pilot_average_last, 1-q->time_ema_coeff, q->pilot_average_last, nref); - srslte_vec_sum_ccc(q->pilot_average_last, output, output, nref); - memcpy(q->pilot_average_last, output, nref*sizeof(cf_t)); - } +#ifdef AVERAGE_SUBFRAME + srslte_vec_sum_ccc(output, &input[l*nref], output, nref); +#else + srslte_conv_same_cf(&input[l*nref], q->smooth_filter, &output[l*nref], nref, q->smooth_filter_len); +#endif } +#ifdef AVERAGE_SUBFRAME + srslte_vec_sc_prod_cfc(output, (float) 1.0/nsymbols, output, nref); +#endif } float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id) {