2 * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <gtkmm/button.h>
21 #include <gtkmm/table.h>
23 #ifdef PLATFORM_WINDOWS
24 #include <pbd/windows_timer_utils.h>
27 #include "temporal/time.h"
29 #include "idleometer.h"
32 static int64_t _x_get_monotonic_usec() {
33 #ifdef PLATFORM_WINDOWS
34 return PBD::get_microseconds();
36 return g_get_monotonic_time();
41 IdleOMeter::IdleOMeter ()
42 : ArdourDialog (_("Idle O Meter"))
44 get_vbox()->set_spacing (8);
45 Label* l = manage (new Label (_("<b>GUI Idle Timing Statistics</b>"), ALIGN_CENTER));
48 HBox* hbox = manage (new HBox ());
49 Table* t = manage (new Table ());
50 hbox->pack_start (*t, true, false);
52 Button* b = manage (new Button (_("Reset")));
53 b->signal_clicked().connect (sigc::mem_fun(*this, &IdleOMeter::reset));
55 get_vbox()->pack_start (*l, false, false);
56 get_vbox()->pack_start (*hbox, false, false);
57 get_vbox()->pack_start (*b, false, false);
59 _label_cur.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
60 _label_min.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
61 _label_max.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
62 _label_avg.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
63 _label_dev.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
64 _label_acq.set_alignment (ALIGN_CENTER, ALIGN_CENTER);
67 t->attach (*manage (new Label (_("Current:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
68 t->attach (_label_cur, 1, 2, row, row + 1, FILL, SHRINK);
70 t->attach (*manage (new Label (_("Min:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
71 t->attach (_label_min, 1, 2, row, row + 1, FILL, SHRINK);
73 t->attach (*manage (new Label (_("Max:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
74 t->attach (_label_max, 1, 2, row, row + 1, FILL, SHRINK);
76 t->attach (*manage (new Label (_("Mean:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
77 t->attach (_label_avg, 1, 2, row, row + 1, FILL, SHRINK);
79 t->attach (*manage (new Label (_("\u03c3:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
80 t->attach (_label_dev, 1, 2, row, row + 1, FILL, SHRINK);
82 t->attach (*manage (new Label (_("Elapsed:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
83 t->attach (_label_acq, 1, 2, row, row + 1, FILL, SHRINK);
86 IdleOMeter::~IdleOMeter ()
88 _idle_connection.disconnect ();
94 const int64_t now = _x_get_monotonic_usec ();
95 const int64_t elapsed = now - _last;
97 _max = std::max (_max, elapsed);
98 _min = std::min (_min, elapsed);
103 const double cnt = _cnt;
105 /* running variance */
110 const double var_m1 = _var_m;
111 const double t = elapsed;
112 _var_m += (t - _var_m) / cnt;
113 _var_s += (t - _var_m) * (t - var_m1);
116 if (now - _last_display < 100000 || _cnt < 2) {
120 const double avg = _total / cnt;
121 const double stddev = sqrt (_var_s / (_cnt - 1.0));
126 snprintf (buf, sizeof(buf), "%8.2f ms", elapsed / 1000.0);
127 _label_cur.set_text (buf);
128 snprintf (buf, sizeof(buf), "%8.2f ms", _min / 1000.0);
129 _label_min.set_text (buf);
130 snprintf (buf, sizeof(buf), "%8.2f ms", _max / 1000.0);
131 _label_max.set_text (buf);
132 snprintf (buf, sizeof(buf), "%8.3f ms", avg / 1000.0);
133 _label_avg.set_text (buf);
134 snprintf (buf, sizeof(buf), "%8.3f ms", stddev / 1000.0);
135 _label_dev.set_text (buf);
136 _label_acq.set_text (Timecode::timecode_format_sampletime (now - _start, 1000000, 100, false));
144 _last = _x_get_monotonic_usec ();
145 _last_display = _last;
150 _total = _var_m = _var_s = 0;
152 _label_cur.set_text ("-");
153 _label_min.set_text ("-");
154 _label_max.set_text ("-");
155 _label_avg.set_text ("-");
156 _label_dev.set_text ("-");
157 _label_acq.set_text ("-");
161 IdleOMeter::on_show ()
163 ArdourDialog::on_show ();
165 _idle_connection = Glib::signal_idle().connect (sigc::mem_fun (*this, &IdleOMeter::idle));
169 IdleOMeter::on_hide ()
171 _idle_connection.disconnect ();
172 ArdourDialog::on_hide ();