summaryrefslogtreecommitdiffstats
path: root/src/server/Engine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/Engine.cpp')
-rw-r--r--src/server/Engine.cpp63
1 files changed, 58 insertions, 5 deletions
diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp
index 1a0ab0a0..893f6f92 100644
--- a/src/server/Engine.cpp
+++ b/src/server/Engine.cpp
@@ -83,9 +83,11 @@ Engine::Engine(Ingen::World* world)
, _worker(new Worker(world->log(), event_queue_size()))
, _sync_worker(new Worker(world->log(), event_queue_size(), true))
, _listener(NULL)
+ , _cycle_start_time(0)
, _rand_engine(0)
, _uniform_dist(0.0f, 1.0f)
, _quit_flag(false)
+ , _reset_load_flag(false)
, _direct_driver(true)
, _atomic_bundles(world->conf().option("atomic-bundles").get<int32_t>())
{
@@ -264,8 +266,29 @@ Engine::quit()
bool
Engine::main_iteration()
{
+ const Ingen::URIs& uris = world()->uris();
+
_post_processor->process();
_maid->cleanup();
+
+ if (_event_load.changed) {
+ _broadcaster->set_property(Raul::URI("ingen:/engine"),
+ uris.ingen_maxEventLoad,
+ uris.forge.make(_event_load.max / 100.0f));
+ _event_load.changed = false;
+ }
+
+ if (_run_load.changed) {
+ _broadcaster->put(Raul::URI("ingen:/engine"),
+ { { uris.ingen_meanRunLoad,
+ uris.forge.make(floorf(_run_load.mean) / 100.0f) },
+ { uris.ingen_minRunLoad,
+ uris.forge.make(_run_load.min / 100.0f) },
+ { uris.ingen_maxRunLoad,
+ uris.forge.make(_run_load.max / 100.0f) } });
+ _run_load.changed = false;
+ }
+
return !_quit_flag;
}
@@ -275,6 +298,7 @@ Engine::set_driver(SPtr<Driver> driver)
_driver = driver;
for (RunContext* ctx : _run_contexts) {
ctx->set_priority(driver->real_time_priority());
+ ctx->set_rate(driver->sample_rate());
}
}
@@ -285,14 +309,31 @@ Engine::event_time()
return 0;
}
- const SampleCount start = _direct_driver
+ // FIXME: Jitter with direct driver
+ const SampleCount now = _direct_driver
? run_context().start()
: _driver->frame_time();
- /* Exactly one cycle latency (some could run ASAP if we get lucky, but not
- always, and a slight constant latency is far better than jittery lower
- (average) latency */
- return start + _driver->block_length();
+ return now + _driver->block_length();
+}
+
+uint64_t
+Engine::current_time(const RunContext& context) const
+{
+ struct timespec time;
+#ifdef CLOCK_MONOTONIC_RAW
+ clock_gettime(CLOCK_MONOTONIC_RAW, &time);
+#else
+ clock_gettime(CLOCK_MONOTONIC, &time);
+#endif
+
+ return (uint64_t)time.tv_sec * 1e6 + (uint64_t)time.tv_nsec / 1e3;
+}
+
+void
+Engine::reset_load()
+{
+ _reset_load_flag = true;
}
void
@@ -367,6 +408,7 @@ unsigned
Engine::run(uint32_t sample_count)
{
RunContext& ctx = run_context();
+ _cycle_start_time = current_time(ctx);
// Apply control bindings to input
control_bindings()->pre_process(
@@ -377,6 +419,7 @@ Engine::run(uint32_t sample_count)
// Process events that came in during the last cycle
// (Aiming for jitter-free 1 block event latency, ideally)
const unsigned n_processed_events = process_events();
+ const uint64_t t_events = current_time(ctx);
// Run root graph
if (_root_graph) {
@@ -387,6 +430,16 @@ Engine::run(uint32_t sample_count)
ctx, _root_graph->port_impl(1)->buffer(0).get());
}
+ // Update load for this cycle
+ if (ctx.duration() > 0) {
+ _event_load.update(t_events - _cycle_start_time, ctx.duration());
+ _run_load.update(current_time(ctx) - t_events, ctx.duration());
+ if (_reset_load_flag) {
+ _run_load = Load();
+ _reset_load_flag = false;
+ }
+ }
+
return n_processed_events;
}