diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2017-10-17 09:50:35 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2017-10-17 09:50:35 +0200 |
commit | 6dbb86d709c433cafc3583978e1bd6f0d44a2b52 (patch) | |
tree | 18f319cc6b1c6bba072efb4bdf367555ecfd6695 | |
parent | 065c92d1e9e0574452e92f07b797301c987d5ab4 (diff) | |
download | dabmod-6dbb86d709c433cafc3583978e1bd6f0d44a2b52.tar.gz dabmod-6dbb86d709c433cafc3583978e1bd6f0d44a2b52.tar.bz2 dabmod-6dbb86d709c433cafc3583978e1bd6f0d44a2b52.zip |
Improve MER calculation
-rw-r--r-- | src/OfdmGenerator.cpp | 26 | ||||
-rw-r--r-- | src/OfdmGenerator.h | 2 |
2 files changed, 16 insertions, 12 deletions
diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp index 48449c3..bac3db0 100644 --- a/src/OfdmGenerator.cpp +++ b/src/OfdmGenerator.cpp @@ -177,13 +177,14 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) // That's why we copy it to the reference. std::vector<complexf> reference; + // IFFT output before CFR applied, for MER calc std::vector<complexf> before_cfr; size_t num_clip = 0; size_t num_error_clip = 0; - // For performance reasons, do not calculate MER for every symbols. - myLastMERCalc = (myLastMERCalc + 1) % myNbSymbols; + // For performance reasons, do not calculate MER for every symbol. + myMERCalcIndex = (myMERCalcIndex + 1) % myNbSymbols; for (size_t i = 0; i < myNbSymbols; ++i) { myFftIn[0][0] = 0; @@ -203,7 +204,7 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) fftwf_execute(myFftPlan); // IFFT from myFftIn to myFftOut if (myCfr) { - if (myLastMERCalc == i) { + if (myMERCalcIndex == i) { before_cfr.resize(mySpacing); memcpy(before_cfr.data(), myFftOut, mySpacing * sizeof(FFT_TYPE)); } @@ -214,26 +215,29 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) */ const auto stat = cfr_one_iteration(symbol, reference.data()); - if (myLastMERCalc == i) { + // i == 0 always zero power, so the MER ends up being NaN + if (i > 0 and myMERCalcIndex == i) { /* MER definition, ETSI ETR 290, Annex C * - * \sum I^2 Q^2 - * MER[dB] = 10 log_10( -------------- ) - * \sum dI^2 dQ^2 - * Where I and Q are the ideal coordinates, and dI and dQ are the errors - * in the received datapoints. + * \sum I^2 + Q^2 + * MER[dB] = 10 log_10( ---------------- ) + * \sum dI^2 + dQ^2 + * Where I and Q are the ideal coordinates, and dI and dQ are + * the errors in the received datapoints. * * In our case, we consider the constellation points given to the * OfdmGenerator as "ideal", and we compare the CFR output to it. */ - double sum_iq = 0; double sum_delta = 0; for (size_t i = 0; i < mySpacing; i++) { sum_iq += (double)std::norm(before_cfr[i]); sum_delta += (double)std::norm(symbol[i] - before_cfr[i]); } - const double mer = 10.0 * std::log10(sum_iq / sum_delta); + + // Clamp to 90dB, otherwise the MER average is going to be inf + const double mer = sum_delta > 0 ? + 10.0 * std::log10(sum_iq / sum_delta) : 90; myMERs.push_back(mer); } diff --git a/src/OfdmGenerator.h b/src/OfdmGenerator.h index f357fa6..008d84e 100644 --- a/src/OfdmGenerator.h +++ b/src/OfdmGenerator.h @@ -102,7 +102,7 @@ class OfdmGenerator : public ModCodec, public RemoteControllable std::deque<double> myClipRatios; std::deque<double> myErrorClipRatios; - size_t myLastMERCalc = 0; + size_t myMERCalcIndex = 0; std::deque<double> myMERs; }; |