Ardour  9.0-pre0-582-g084a23a80d
dsp_load_calculator.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org>
3  * Copyright (C) 2015 Tim Mayberry <mojofunk@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef ARDOUR_DSP_LOAD_CALCULATOR_H
21 #define ARDOUR_DSP_LOAD_CALCULATOR_H
22 
23 #include <glib.h>
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <cassert>
27 #include <algorithm>
28 
29 namespace ARDOUR {
30 
32 public:
34  : m_max_time_us(0)
37  , m_alpha(0)
38  , m_dsp_load(0)
39  {
40  m_calc_avg_load = NULL != g_getenv("ARDOUR_AVG_DSP_LOAD");
41  }
42 
43  void reset () {
44  m_dsp_load = 0;
47  }
48 
49  void set_max_time(double samplerate, uint32_t period_size) {
50  m_max_time_us = period_size * 1e6 / samplerate;
51  m_alpha = 0.2f * (m_max_time_us * 1e-6f);
52  }
53 
54  void set_max_time_us(uint64_t max_time_us) {
55  assert(max_time_us != 0);
56  m_max_time_us = max_time_us;
57  m_alpha = 0.2f * (m_max_time_us * 1e-6f);
58  }
59 
60  int64_t get_max_time_us() const { return m_max_time_us; }
61 
62  void set_start_timestamp_us(int64_t start_timestamp_us) {
63  m_start_timestamp_us = start_timestamp_us;
64  }
65 
66  void set_stop_timestamp_us(int64_t stop_timestamp_us)
67  {
68  m_stop_timestamp_us = stop_timestamp_us;
69 
70  /* querying the performance counter can fail occasionally (-1).
71  * Also on some multi-core systems, timers are CPU specific and not
72  * synchronized. We assume they differ more than a few milliseconds
73  * (4 * nominal cycle time) and simply ignore cases where the
74  * execution switches cores.
75  */
79  return;
80  }
81  assert (m_max_time_us > 0);
82 
83  const float load = (float) elapsed_time_us() / (float)m_max_time_us;
84  if ((m_calc_avg_load && load > .95f) || (!m_calc_avg_load && (load > m_dsp_load || load > 1.f))) {
85  m_dsp_load = load;
86  } else {
87  m_dsp_load = std::min (1.f, m_dsp_load);
88  m_dsp_load += m_alpha * (load - m_dsp_load) + 1e-12;
89  }
90  }
91 
92  int64_t elapsed_time_us()
93  {
95  }
96 
102  float get_dsp_load() const
103  {
104  assert (m_dsp_load >= 0.f); // since stop > start is assured this cannot happen.
105  return std::min (1.f, m_dsp_load);
106  }
107 
113  float get_dsp_load_unbound() const
114  {
115  assert (m_dsp_load >= 0.f);
116  return m_dsp_load;
117  }
118 
123  int64_t max_timer_error_us() { return 4 * m_max_time_us; }
124 
125 private: // data
127  int64_t m_max_time_us;
130  float m_alpha;
131  float m_dsp_load;
132 };
133 
134 } // namespace ARDOUR
135 
136 #endif // ARDOUR_DSP_LOAD_CALCULATOR_H
void set_stop_timestamp_us(int64_t stop_timestamp_us)
void set_max_time_us(uint64_t max_time_us)
void set_max_time(double samplerate, uint32_t period_size)
void set_start_timestamp_us(int64_t start_timestamp_us)
void load(const std::string &filename)