summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2017-10-17 09:50:35 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2017-10-17 09:50:35 +0200
commit6dbb86d709c433cafc3583978e1bd6f0d44a2b52 (patch)
tree18f319cc6b1c6bba072efb4bdf367555ecfd6695
parent065c92d1e9e0574452e92f07b797301c987d5ab4 (diff)
downloaddabmod-6dbb86d709c433cafc3583978e1bd6f0d44a2b52.tar.gz
dabmod-6dbb86d709c433cafc3583978e1bd6f0d44a2b52.tar.bz2
dabmod-6dbb86d709c433cafc3583978e1bd6f0d44a2b52.zip
Improve MER calculation
-rw-r--r--src/OfdmGenerator.cpp26
-rw-r--r--src/OfdmGenerator.h2
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;
};