diff options
| -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;  };  | 
