aboutsummaryrefslogtreecommitdiffstats
path: root/repetitionrate.cpp
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2016-01-22 14:08:58 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2016-01-22 14:08:58 +0100
commit74e2beb5b80470a26054c8c51665996b10303f68 (patch)
tree55032f4b62aea432d03c8a49adfab51740b4640b /repetitionrate.cpp
parente05c1b5903709651aac348fd5144de3ccbbd77a3 (diff)
downloadetisnoop-74e2beb5b80470a26054c8c51665996b10303f68.tar.gz
etisnoop-74e2beb5b80470a26054c8c51665996b10303f68.tar.bz2
etisnoop-74e2beb5b80470a26054c8c51665996b10303f68.zip
Add repetition rate analyser
Diffstat (limited to 'repetitionrate.cpp')
-rw-r--r--repetitionrate.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/repetitionrate.cpp b/repetitionrate.cpp
new file mode 100644
index 0000000..45dd495
--- /dev/null
+++ b/repetitionrate.cpp
@@ -0,0 +1,147 @@
+/*
+ Copyright (C) 2016 Matthias P. Braendli (http://www.opendigitalradio.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ Authors:
+ Matthias P. Braendli <matthias@mpb.li>
+
+*/
+
+#include "repetitionrate.hpp"
+#include <vector>
+#include <map>
+#include <unordered_set>
+
+using namespace std;
+
+const double frame_duration = 24e-3;
+
+struct FIGTypeExt {
+ int figtype;
+ int figextension;
+
+ bool operator<(const FIGTypeExt& other) const {
+ if (this->figtype == other.figtype) {
+ return this->figextension < other.figextension;
+ }
+ else {
+ return this->figtype < other.figtype ;
+ }
+ }
+};
+
+struct FIGRateInfo {
+ // List of frame numbers in which the FIG is present
+ vector<int> frames_present;
+
+ // List of frame numbers in which a complete DB for that FIG has been sent
+ vector<int> frames_complete;
+
+ // Which FIBs this FIG was seen in
+ unordered_set<int> in_fib;
+};
+
+
+static map<FIGTypeExt, FIGRateInfo> fig_rates;
+
+static int current_frame_number = 0;
+static int current_fib = 0;
+
+void rate_announce_fig(int figtype, int figextension, bool complete)
+{
+ FIGTypeExt f = {.figtype = figtype, .figextension = figextension};
+
+ if (fig_rates.count(f) == 0) {
+ FIGRateInfo rate;
+ fig_rates[f] = rate;
+ }
+
+ FIGRateInfo& rate = fig_rates[f];
+
+ rate.frames_present.push_back(current_frame_number);
+ if (complete) {
+ rate.frames_complete.push_back(current_frame_number);
+ }
+ rate.in_fib.insert(current_fib);
+}
+
+void rate_disply_analysis()
+{
+ printf("FIG carousel analysis. Format:\n"
+ " average FIGs per second (total count, delta variance in frames)\n"
+ " average complete FIGs per second (total count, delta variance in frames)\n");
+ for (auto& fig_rate : fig_rates) {
+ auto& frames_present = fig_rate.second.frames_present;
+ auto& frames_complete = fig_rate.second.frames_complete;
+
+ const size_t n_present = frames_present.size();
+ const size_t n_complete = frames_complete.size();
+
+ if (n_present and n_complete) {
+ double average_present_interval =
+ (double)(frames_present.back() - frames_present.front()) /
+ (double)(frames_present.size() - 1);
+
+ double average_complete_interval =
+ (double)(frames_complete.back() - frames_complete.front()) /
+ (double)(frames_complete.size() - 1);
+
+ double variance_of_delta_present = 0;
+ for (size_t i = 1; i < frames_present.size(); i++) {
+ double s =
+ (double)(frames_present[i] - frames_present[i-1]) -
+ average_present_interval;
+
+ variance_of_delta_present += s * s;
+ }
+ variance_of_delta_present /= frames_present.size();
+
+ double variance_of_delta_complete = 0;
+ for (size_t i = 1; i < frames_complete.size(); i++) {
+ double s =
+ (double)(frames_complete[i] - frames_complete[i-1]) -
+ average_complete_interval;
+
+ variance_of_delta_complete += s * s;
+ }
+ variance_of_delta_complete /= frames_complete.size();
+
+ const double n_present_per_second =
+ (double)n_present / (double)current_frame_number / frame_duration;
+
+ const double n_complete_per_second =
+ (double)n_complete / (double)current_frame_number / frame_duration;
+
+ printf("FIG%2d/%2d %2.2f (%6zu %2.2f) %2.2f (%6zu %2.2f)\n",
+ fig_rate.first.figtype, fig_rate.first.figextension,
+ n_present_per_second, n_present, variance_of_delta_present,
+ n_complete_per_second, n_complete, variance_of_delta_complete);
+ }
+ else {
+ printf("FIG%2d/%2d 0\n",
+ fig_rate.first.figtype, fig_rate.first.figextension);
+ }
+ }
+}
+
+void rate_new_fib(int fib)
+{
+ if (fib == 0) {
+ current_frame_number++;
+ }
+
+ current_fib = fib;
+}
+