summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Mayberry <mojofunk@gmail.com>2015-09-10 11:44:39 +1000
committerTim Mayberry <mojofunk@gmail.com>2015-09-10 12:12:56 +1000
commit8625362cac6fbec43f953e684c54eba46ad213c0 (patch)
treec494d872a6856c8d13fa9c6ee3aeb2b7b35535e9
parent09caf8336f4ec681668a940e7df00ec18b3fd836 (diff)
Add DSPLoadCalculator class to libardour
This is similar to the class in the PortaudioBackend but uses an average of the values if raw load is under 80%
-rw-r--r--libs/ardour/ardour/dsp_load_calculator.h100
-rw-r--r--libs/ardour/dsp_load_calculator.cc80
-rw-r--r--libs/ardour/wscript1
3 files changed, 181 insertions, 0 deletions
diff --git a/libs/ardour/ardour/dsp_load_calculator.h b/libs/ardour/ardour/dsp_load_calculator.h
new file mode 100644
index 0000000000..911f1e3f14
--- /dev/null
+++ b/libs/ardour/ardour/dsp_load_calculator.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2015 Tim Mayberry <mojofunk@gmail.com>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef ARDOUR_DSP_LOAD_CALCULATOR_H
+#define ARDOUR_DSP_LOAD_CALCULATOR_H
+
+#include <stdint.h>
+#include <cassert>
+#include <algorithm>
+
+#include <pbd/ringbuffer.h>
+
+namespace ARDOUR {
+
+class DSPLoadCalculator {
+public:
+ DSPLoadCalculator()
+ : m_max_time_us(0)
+ , m_start_timestamp_us(0)
+ , m_stop_timestamp_us(0)
+ , m_dsp_load(0)
+ , m_value_history (max_value_history())
+ , m_num_values(0)
+ {
+
+ }
+
+ void set_max_time_us(uint64_t max_time_us) {
+ assert(m_max_time_us != 0);
+ m_max_time_us = max_time_us;
+
+ // Use average of last 1/4 second of values so responsiveness
+ // remains consistent independent of max time
+ uint32_t max_dsp_samples_per_qtr_second = (250000 / m_max_time_us);
+ m_num_values =
+ std::min(max_value_history() - 1, max_dsp_samples_per_qtr_second);
+
+ m_value_history.reset();
+ }
+
+
+ uint64_t get_max_time_us() const { return m_max_time_us; }
+
+ void set_start_timestamp_us(uint64_t start_timestamp_us)
+ {
+ m_start_timestamp_us = start_timestamp_us;
+ }
+
+ void set_stop_timestamp_us(uint64_t stop_timestamp_us);
+
+ uint64_t elapsed_time_us()
+ {
+ return m_stop_timestamp_us - m_start_timestamp_us;
+ }
+
+ /**
+ * @return a decimal value between 0.0 and 1.0 representing the percentage
+ * of time spent between start and stop in proportion to the max expected time
+ * in microseconds(us).
+ */
+ float get_dsp_load() const
+ {
+ if (m_dsp_load > m_max_time_us) {
+ return 1.0f;
+ }
+ if (m_dsp_load < 0.0f) {
+ return 0.0f;
+ }
+ return m_dsp_load;
+ }
+private: // methods
+ static uint32_t max_value_history () { return 16; }
+
+private: // data
+ uint64_t m_max_time_us;
+ uint64_t m_start_timestamp_us;
+ uint64_t m_stop_timestamp_us;
+ float m_dsp_load;
+ RingBuffer<float> m_value_history;
+ uint32_t m_num_values;
+};
+
+} // namespace ARDOUR
+
+#endif // ARDOUR_DSP_LOAD_CALCULATOR_H
diff --git a/libs/ardour/dsp_load_calculator.cc b/libs/ardour/dsp_load_calculator.cc
new file mode 100644
index 0000000000..d30b417ad5
--- /dev/null
+++ b/libs/ardour/dsp_load_calculator.cc
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 Tim Mayberry <mojofunk@gmail.com>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "ardour/dsp_load_calculator.h"
+
+namespace ARDOUR {
+
+void
+DSPLoadCalculator::set_stop_timestamp_us(uint64_t stop_timestamp_us)
+{
+ // We could only bother with calculations if a certain amount of time
+ // has passed, or the Raw DSP value is > X% different than last calc
+ // which would mean consistent overhead for small values of m_max_time_us
+
+ m_stop_timestamp_us = stop_timestamp_us;
+ float load = 0;
+
+ if (elapsed_time_us() > m_max_time_us) {
+ load = 1.0f;
+ } else {
+ load = elapsed_time_us() / (float)m_max_time_us;
+ }
+
+ assert(m_value_history.write_space() >= 1);
+
+ // push raw load value onto history
+ m_value_history.write(&load, 1);
+
+ // if load is under 80% use an average of past values
+ if (elapsed_time_us() < ((m_max_time_us * 80) / 100)) {
+
+ RingBuffer<float>::rw_vector vec;
+ m_value_history.get_read_vector(&vec);
+ uint32_t values_read = 0;
+ float dsp_accumulator = 0.0f;
+
+ // iterate through the read vectors accumulating the dsp load
+ for (unsigned int i = 0; i < vec.len[0]; ++i) {
+ dsp_accumulator += vec.buf[0][i];
+ values_read++;
+ }
+
+ for (unsigned int i = 0; i < vec.len[1]; ++i) {
+ dsp_accumulator += vec.buf[1][i];
+ values_read++;
+ }
+
+ load = dsp_accumulator / (float)values_read;
+
+ const float alpha = 0.2f * (m_max_time_us * 1e-6f);
+ m_dsp_load = m_dsp_load + alpha * (load - m_dsp_load) + 1e-12;
+
+ } else {
+ // Use raw load value otherwise 100% may never be indicated because of
+ // averaging/LPF etc
+ m_dsp_load = load;
+ }
+
+ if (m_value_history.read_space() >= m_num_values) {
+ // "remove" the oldest value
+ m_value_history.increment_read_idx(1);
+ }
+}
+
+} // namespace ARDOUR
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index c0049b55fe..becb2e117d 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -65,6 +65,7 @@ libardour_sources = [
'delivery.cc',
'directory_names.cc',
'diskstream.cc',
+ 'dsp_load_calculator.cc',
'element_import_handler.cc',
'element_importer.cc',
'engine_slave.cc',