summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ManagementServer.cpp59
-rw-r--r--src/ManagementServer.h13
2 files changed, 34 insertions, 38 deletions
diff --git a/src/ManagementServer.cpp b/src/ManagementServer.cpp
index 10ba396..d299085 100644
--- a/src/ManagementServer.cpp
+++ b/src/ManagementServer.cpp
@@ -34,13 +34,15 @@
#include <stdint.h>
#include <limits>
#include <sstream>
+#include <algorithm>
#include <ctime>
#include <boost/thread.hpp>
#include <boost/version.hpp>
#include "ManagementServer.h"
#include "Log.h"
-static constexpr auto stats_keep_duration = std::chrono::seconds(30);
+static constexpr
+auto stats_keep_duration = std::chrono::seconds(INPUT_NODATA_TIMEOUT);
ManagementServer& get_mgmt_server()
{
@@ -140,7 +142,6 @@ std::string ManagementServer::getValuesJSON()
ss << " \"" << id << "\" : ";
ss << stats->encodeValuesJSON();
- stats->reset();
}
ss << "}\n}\n";
@@ -256,12 +257,12 @@ InputStat::InputStat(const std::string& name)
/* State handling */
time_t now = time(NULL);
m_time_last_event = now;
- m_time_last_buffer_nonempty = 0;
- m_buffer_empty = true;
m_glitch_counter = 0;
m_silence_counter = 0;
- reset();
+ buffer_fill_stats.clear();
+ peaks_left.clear();
+ peaks_right.clear();
}
InputStat::~InputStat()
@@ -274,34 +275,23 @@ void InputStat::registerAtServer()
get_mgmt_server().registerInput(this);
}
-void InputStat::reset()
-{
- min_fill_buffer = MIN_FILL_BUFFER_UNDEF;
- max_fill_buffer = 0;
-
- peaks_left.clear();
- peaks_right.clear();
-}
-
void InputStat::notifyBuffer(long bufsize)
{
boost::mutex::scoped_lock lock(m_mutex);
- // Statistics
- if (bufsize > max_fill_buffer) {
- max_fill_buffer = bufsize;
- }
+ buffer_fill_stats.push_back(bufsize);
- if (bufsize < min_fill_buffer ||
- min_fill_buffer == MIN_FILL_BUFFER_UNDEF) {
- min_fill_buffer = bufsize;
- }
+ using namespace std::chrono;
+ const auto time_now = steady_clock::now();
+ if (buffer_fill_stats.size() > 1) {
+ auto insertion_interval = time_now - time_last_buffer_notify;
+ auto total_length = insertion_interval * buffer_fill_stats.size();
- // State
- m_buffer_empty = (bufsize == 0);
- if (!m_buffer_empty) {
- m_time_last_buffer_nonempty = time(NULL);
+ if (total_length > stats_keep_duration) {
+ buffer_fill_stats.pop_front();
+ }
}
+ time_last_buffer_notify = time_now;
}
void InputStat::notifyPeakLevels(int peak_left, int peak_right)
@@ -403,6 +393,15 @@ std::string InputStat::encodeValuesJSON()
int dB_l = peak_left ? round(20*log10((double)peak_left / int16_max)) : -90;
int dB_r = peak_right ? round(20*log10((double)peak_right / int16_max)) : -90;
+ long min_fill_buffer = MIN_FILL_BUFFER_UNDEF;
+ long max_fill_buffer = 0;
+ if (not buffer_fill_stats.empty()) {
+ auto buffer_min_max_fill = minmax_element(buffer_fill_stats.begin(),
+ buffer_fill_stats.end());
+ min_fill_buffer = *buffer_min_max_fill.first;
+ max_fill_buffer = *buffer_min_max_fill.second;
+ }
+
ss <<
"{ \"inputstat\" : {"
"\"min_fill\": " << min_fill_buffer << ", "
@@ -453,12 +452,14 @@ input_state_t InputStat::determineState()
/* If the buffer has been empty for more than
* INPUT_NODATA_TIMEOUT, we go to the NoData state.
+ *
+ * Consider an empty deque to be NoData too.
*/
- if (m_buffer_empty &&
- now - m_time_last_buffer_nonempty > INPUT_NODATA_TIMEOUT) {
+ if (std::all_of(
+ buffer_fill_stats.begin(), buffer_fill_stats.end(),
+ [](long fill) { return fill == 0; }) ) {
state = NoData;
}
-
/* Otherwise, the state depends on the glitch counter */
else if (m_glitch_counter >= INPUT_UNSTABLE_THRESHOLD) {
state = Unstable;
diff --git a/src/ManagementServer.h b/src/ManagementServer.h
index fcdbc16..1b432d5 100644
--- a/src/ManagementServer.h
+++ b/src/ManagementServer.h
@@ -151,10 +151,6 @@ class InputStat
~InputStat();
void registerAtServer(void);
- // Gets called each time the statistics are transmitted,
- // and resets the counters to zero
- void reset(void);
-
std::string get_name(void) const { return m_name; }
/* This function is called for every frame read by
@@ -170,9 +166,10 @@ class InputStat
std::string m_name;
/************ STATISTICS ***********/
- // minimum and maximum buffer fill since last reset
- long min_fill_buffer;
- long max_fill_buffer;
+ // Calculate minimum and maximum buffer fill from
+ // a FIFO of values from the last few seconds
+ std::deque<long> buffer_fill_stats;
+ std::chrono::time_point<std::chrono::steady_clock> time_last_buffer_notify;
// counter of number of overruns and underruns since startup
uint32_t num_underruns;
@@ -189,8 +186,6 @@ class InputStat
int m_glitch_counter; // saturating counter
int m_silence_counter; // saturating counter
time_t m_time_last_event;
- time_t m_time_last_buffer_nonempty;
- bool m_buffer_empty;
// The mutex that has to be held during all notify and readout
mutable boost::mutex m_mutex;