Report a rolling minimum and maximum instead

Over the last 2048 processing cycles. Should give a better idea of the
spread.
This commit is contained in:
Robbert van der Helm
2021-06-11 16:02:42 +02:00
parent 4ff01cce6c
commit a1c9d0fbf5
2 changed files with 53 additions and 25 deletions
+36 -12
View File
@@ -237,20 +237,42 @@ Vst3PluginProxyImpl::process(Steinberg::Vst::ProcessData& data) {
.count()) + .count()) +
" us"); " us");
// As mentioned below, we'll only record the maximum after the first if (process_time_ring_buffer_wrapped_around) {
// report // We only report these values every few seconds, so we don't need
// to be clever with keeping rolling minima and maxima and we can
// just linearly iterate over everything every now and then
std::chrono::high_resolution_clock::duration min_process_time =
process_time_ring_buffer[0];
std::chrono::high_resolution_clock::duration max_process_time =
process_time_ring_buffer[0];
for (size_t i = 1; i < process_time_ring_buffer.size(); i++) {
if (process_time_ring_buffer[i] < min_process_time) {
min_process_time = process_time_ring_buffer[i];
} else if (process_time_ring_buffer[i] > max_process_time) {
max_process_time = process_time_ring_buffer[i];
}
}
bridge.logger.log(
"Min processing time: " +
std::to_string(std::chrono::duration_cast<
std::chrono::duration<float, std::micro>>(
min_process_time)
.count()) +
" us");
bridge.logger.log( bridge.logger.log(
"Max processing time: " + "Max processing time: " +
(have_reported std::to_string(std::chrono::duration_cast<
? std::to_string(std::chrono::duration_cast<
std::chrono::duration<float, std::micro>>( std::chrono::duration<float, std::micro>>(
max_process_time) max_process_time)
.count()) + .count()) +
" us" " us");
: "<still warming up>")); } else {
bridge.logger.log("Min processing time: <still warming up>");
bridge.logger.log("Max processing time: <still warming up>");
}
last_report = now; last_report = now;
have_reported = true;
} }
// Doing this twice is a bit of a waste, but we don't want to measure IO // Doing this twice is a bit of a waste, but we don't want to measure IO
@@ -306,11 +328,13 @@ Vst3PluginProxyImpl::process(Steinberg::Vst::ProcessData& data) {
std::chrono::high_resolution_clock::duration>( std::chrono::high_resolution_clock::duration>(
(process_time * 0.05) + (mean_process_time * 0.95)); (process_time * 0.05) + (mean_process_time * 0.95));
// With the current implementation we may need to resize our buffers in the // For the minma and maxima we keep the last `process_time_ring_buffer_size`
// first call, so we'll give ourselves a bit of a grace period to allow the // timings around so we can compute these during the report
// buffers to warm up process_time_ring_buffer[process_time_ring_buffer_pos] = process_time;
if (have_reported) { process_time_ring_buffer_pos += 1;
max_process_time = std::max(process_time, max_process_time); if (process_time_ring_buffer_pos >= process_time_ring_buffer.size()) {
process_time_ring_buffer_pos = 0;
process_time_ring_buffer_wrapped_around = true;
} }
return process_response.result; return process_response.result;
+12 -8
View File
@@ -19,6 +19,8 @@
#include "../vst3.h" #include "../vst3.h"
#include "plug-view-proxy.h" #include "plug-view-proxy.h"
constexpr size_t process_time_ring_buffer_size = 2048;
/** /**
* Here we pass though all function calls made by the host to the Windows VST3 * Here we pass though all function calls made by the host to the Windows VST3
* plugin. We had to deviate from yabridge's 'one-to-one passthrough' philosphy * plugin. We had to deviate from yabridge's 'one-to-one passthrough' philosphy
@@ -555,19 +557,21 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy {
*/ */
std::chrono::high_resolution_clock::duration mean_process_time = std::chrono::high_resolution_clock::duration mean_process_time =
std::chrono::high_resolution_clock::duration::zero(); std::chrono::high_resolution_clock::duration::zero();
/** /**
* The maximum time it took to handle `YaAudioProcessor::process()`. * A ring buffer for calculating the rolling minimum and maximum for the
* time it takes to handle `YaAudioProcessor::process()`. Since we only
* report the maximum every five seconds, we don't need to be clever with
* rolling maxima and can just iterate over it every five seconds.
*/ */
std::chrono::high_resolution_clock::duration max_process_time = std::array<std::chrono::high_resolution_clock::duration,
std::chrono::high_resolution_clock::duration::zero(); process_time_ring_buffer_size>
process_time_ring_buffer;
size_t process_time_ring_buffer_pos = 0;
bool process_time_ring_buffer_wrapped_around = false;
/** /**
* The last time we reported the mean processing time. * The last time we reported the mean processing time.
*/ */
std::chrono::high_resolution_clock::time_point last_report; std::chrono::high_resolution_clock::time_point last_report;
/**
* We'll wait with reporting the maximum processing time until the first
* report to allow buffers to warm up.
*/
bool have_reported = false;
}; };