From a2129601dfb9fd7064e85056c9f01459930eeb1b Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 15 Feb 2018 03:16:07 +0100 Subject: [PATCH] Noise level in MIMO is not divided by number of antennas --- lib/examples/pdsch_enodeb.c | 17 ++++++++++++++-- lib/src/phy/ch_estimation/chest_dl.c | 30 +++++++++++++++++----------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index c780e02ea..158d672ea 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -84,6 +84,8 @@ int mbsfn_area_id = -1; char *rf_args = ""; float rf_amp = 0.8, rf_gain = 70.0, rf_freq = 2400000000; +float output_file_snr = +INFINITY; + bool null_file_sink=false; srslte_filesink_t fsink; srslte_ofdm_t ifft[SRSLTE_MAX_PORTS]; @@ -145,13 +147,14 @@ void usage(char *prog) { printf("\t-w Number of codewords/layers (multiplex mode only)* [Default %d]\n", multiplex_nof_layers); printf("\t-u listen TCP port for input data (-1 is random) [Default %d]\n", net_port); printf("\t-v [set srslte_verbose to debug, default none]\n"); + printf("\t-s output file SNR [Default %f]\n", output_file_snr); printf("\n"); printf("\t*: See 3GPP 36.212 Table 5.3.3.1.5-4 for more information\n"); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "aglfmoncpvutxbwM")) != -1) { + while ((opt = getopt(argc, argv, "aglfmoncpvutxbwMs")) != -1) { switch (opt) { case 'a': @@ -200,6 +203,9 @@ void parse_args(int argc, char **argv) { case 'v': srslte_verbose++; break; + case 's': + output_file_snr = atof(argv[optind]); + break; default: usage(argv[0]); exit(-1); @@ -989,7 +995,14 @@ int main(int argc, char **argv) { /* send to file or usrp */ if (output_file_name) { if (!null_file_sink) { - srslte_filesink_write_multi(&fsink, (void**) output_buffer, sf_n_samples, cell.nof_ports); + /* Apply AWGN */ + if (output_file_snr != +INFINITY) { + float var = powf(10.0f, -(output_file_snr + 3.0f) / 20.0f); + for (int k = 0; k < cell.nof_ports; k++) { + srslte_ch_awgn_c(output_buffer[k], output_buffer[k], var, sf_n_samples); + } + } + srslte_filesink_write_multi(&fsink, (void**) output_buffer, sf_n_samples, cell.nof_ports); } usleep(1000); } else { diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index ba9ae40e6..5249696af 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -291,7 +291,7 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id, srslt norm /= norm3; } } - float power = norm*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref); + float power = norm*srslte_vec_avg_power_cf(q->tmp_noise, nref); return power; } @@ -543,7 +543,7 @@ void chest_interpolate_noise_est(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, ui /* Compute RSRP for the channel estimates in this port */ uint32_t npilots = SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); - q->rsrp[rxant_id][port_id] = __real__ srslte_vec_dot_prod_conj_ccc(q->pilot_estimates, q->pilot_estimates, npilots) / npilots; + q->rsrp[rxant_id][port_id] = srslte_vec_avg_power_cf(q->pilot_estimates, npilots); q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id); } @@ -639,7 +639,10 @@ float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q) { for (int i=0;ilast_nof_antennas;i++) { n += srslte_vec_acc_ff(q->noise_estimate[i], q->cell.nof_ports)/q->cell.nof_ports; } - return n/q->last_nof_antennas; + if (q->last_nof_antennas) { + n /= q->last_nof_antennas; + } + return n; } float srslte_chest_dl_get_snr(srslte_chest_dl_t *q) { @@ -691,20 +694,23 @@ float srslte_chest_dl_get_rsrp_ant_port(srslte_chest_dl_t *q, uint32_t ant_idx, } float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q, uint32_t port) { - float max = -INFINITY; - for (int i = 0; i < q->last_nof_antennas; i++) { - if (q->rsrp[i][port] > max) { - max = q->rsrp[i][port]; - } + float sum = 0.0f; + for (int j = 0; j < q->cell.nof_ports; ++j) { + sum +=q->rsrp[port][j]; } - return max; + + if (q->cell.nof_ports) { + sum /= q->cell.nof_ports; + } + + return sum; } float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { - float max = -INFINITY; - for (int i = 0; i < q->cell.nof_ports; ++i) { + float max = -0.0f; + for (int i = 0; i < q->last_nof_antennas; ++i) { float v = srslte_chest_dl_get_rsrp_port(q, i); - if (max < v) { + if (v > max) { max = v; } }