diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2017-09-28 13:34:53 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2017-09-28 13:36:48 +0200 |
commit | 0cfca99b6f0a9b03f148e30c7c44e1f32b82baa1 (patch) | |
tree | 64a34cf248ad7d525873e08c5f4446e87f748e6b /src | |
parent | 4574756f50fd34355aa9d6bfc8a5662f87e88661 (diff) | |
download | dabmod-0cfca99b6f0a9b03f148e30c7c44e1f32b82baa1.tar.gz dabmod-0cfca99b6f0a9b03f148e30c7c44e1f32b82baa1.tar.bz2 dabmod-0cfca99b6f0a9b03f148e30c7c44e1f32b82baa1.zip |
CFR: add some sort of MER calculation that is not correct yet
Diffstat (limited to 'src')
-rw-r--r-- | src/OfdmGenerator.cpp | 50 | ||||
-rw-r--r-- | src/OfdmGenerator.h | 3 |
2 files changed, 51 insertions, 2 deletions
diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp index 4d76dbc..6a5044e 100644 --- a/src/OfdmGenerator.cpp +++ b/src/OfdmGenerator.cpp @@ -177,9 +177,14 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) // That's why we copy it to the reference. std::vector<complexf> reference; + 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 (size_t i = 0; i < myNbSymbols; ++i) { myFftIn[0][0] = 0; myFftIn[0][1] = 0; @@ -198,8 +203,40 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) fftwf_execute(myFftPlan); // IFFT from myFftIn to myFftOut if (myCfr) { + if (myLastMERCalc == i) { + before_cfr.resize(mySpacing); + memcpy(before_cfr.data(), myFftOut, mySpacing * sizeof(FFT_TYPE)); + } + complexf *symbol = reinterpret_cast<complexf*>(myFftOut); + /* cfr_one_iteration runs the myFftPlan again at the end, and + * therefore writes the output data to myFftOut. + */ const auto stat = cfr_one_iteration(symbol, reference.data()); + + if (myLastMERCalc == 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. + * + * 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 += std::norm(before_cfr[i]); + sum_delta += std::norm(symbol[i] - before_cfr[i]); + } + const double mer = 10.0 * std::log10(sum_iq / sum_delta); + myMERs.push_back(mer); + } + num_clip += stat.clip_count; num_error_clip += stat.errclip_count; } @@ -226,6 +263,10 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) while (myErrorClipRatios.size() > MAX_CLIP_STATS) { myErrorClipRatios.pop_front(); } + + while (myMERs.size() > MAX_CLIP_STATS) { + myMERs.pop_front(); + } } return sizeOut; @@ -339,7 +380,7 @@ const std::string OfdmGenerator::get_parameter(const std::string& parameter) con } else if (parameter == "clip_stats") { std::lock_guard<std::mutex> lock(myCfrRcMutex); - if (myClipRatios.empty() or myErrorClipRatios.empty()) { + if (myClipRatios.empty() or myErrorClipRatios.empty() or myMERs.empty()) { ss << "No stats available"; } else { @@ -351,9 +392,14 @@ const std::string OfdmGenerator::get_parameter(const std::string& parameter) con std::accumulate(myErrorClipRatios.begin(), myErrorClipRatios.end(), 0.0) / myErrorClipRatios.size(); + const double avg_mer = + std::accumulate(myMERs.begin(), myMERs.end(), 0.0) / + myMERs.size(); + ss << "Statistics : " << std::fixed << avg_clip_ratio * 100 << "%"" samples clipped, " << - avg_errclip_ratio * 100 << "%"" errors clipped"; + avg_errclip_ratio * 100 << "%"" errors clipped. " << + "MER after CFR: " << avg_mer << " dB"; } } else { diff --git a/src/OfdmGenerator.h b/src/OfdmGenerator.h index 9ac0387..f357fa6 100644 --- a/src/OfdmGenerator.h +++ b/src/OfdmGenerator.h @@ -101,6 +101,9 @@ class OfdmGenerator : public ModCodec, public RemoteControllable // Statistics for CFR std::deque<double> myClipRatios; std::deque<double> myErrorClipRatios; + + size_t myLastMERCalc = 0; + std::deque<double> myMERs; }; |