Browse Source

Add Engine::getFrameTime() and getStepDuration().

tags/v2.0.0
Andrew Belt 5 years ago
parent
commit
abde7d983f
2 changed files with 41 additions and 10 deletions
  1. +8
    -0
      include/engine/Engine.hpp
  2. +33
    -10
      src/engine/Engine.cpp

+ 8
- 0
include/engine/Engine.hpp View File

@@ -47,6 +47,10 @@ struct Engine {
/** Returns the number of audio samples since the Engine's first sample.
*/
int64_t getFrame();
/** Returns the estimated timestamp corresponding to the current frame, based on the timestamp of when step() was last called.
Calculated by `stepTime + framesSinceStep / sampleRate`.
*/
int64_t getFrameTime();
/** Returns the frame when step() was last called.
*/
int64_t getStepFrame();
@@ -56,6 +60,10 @@ struct Engine {
/** Returns the total number of frames in the current step() call.
*/
int getStepFrames();
/** Returns the total time that step() is advancing, in nanoseconds.
Calculated by `stepFrames / sampleRate`.
*/
int64_t getStepDuration();

// Modules
size_t getNumModules();


+ 33
- 10
src/engine/Engine.cpp View File

@@ -210,7 +210,15 @@ struct Engine::Internal {
int smoothParamId = 0;
float smoothValue = 0.f;

/** Engine mutex
Writers lock when mutating the engine's Modules, Cables, etc.
Readers lock when using the engine's Modules, Cables, etc.
*/
SharedMutex mutex;
/** Step mutex
step() locks to guarantee its exclusivity.
*/
std::mutex stepMutex;

int threadCount = 0;
std::vector<EngineWorker> workers;
@@ -380,27 +388,29 @@ static void Cable_step(Cable* that) {
}


static void Engine_stepModules(Engine* that) {
/** Steps a single frame
*/
static void Engine_stepFrame(Engine* that) {
Engine::Internal* internal = that->internal;

// Param smoothing
Module* smoothModule = internal->smoothModule;
int smoothParamId = internal->smoothParamId;
float smoothValue = internal->smoothValue;
if (smoothModule) {
Param* param = &smoothModule->params[smoothParamId];
float value = param->value;
// Decay rate is 1 graphics frame
int smoothParamId = internal->smoothParamId;
float smoothValue = internal->smoothValue;
Param* smoothParam = &smoothModule->params[smoothParamId];
float value = smoothParam->value;
// Use decay rate of roughly 1 graphics frame
const float smoothLambda = 60.f;
float newValue = value + (smoothValue - value) * smoothLambda * internal->sampleTime;
if (value == newValue) {
// Snap to actual smooth value if the value doesn't change enough (due to the granularity of floats)
param->setValue(smoothValue);
smoothParam->setValue(smoothValue);
internal->smoothModule = NULL;
internal->smoothParamId = 0;
}
else {
param->value = newValue;
smoothParam->setValue(newValue);
}
}

@@ -543,6 +553,7 @@ void Engine::clear() {


void Engine::step(int frames) {
std::lock_guard<std::mutex> stepLock(internal->stepMutex);
SharedLock lock(internal->mutex);
// Configure thread
initMXCSR();
@@ -573,9 +584,9 @@ void Engine::step(int frames) {
// Launch workers
Engine_relaunchWorkers(this, settings::threadCount);

// Step modules
// Step individual frames
for (int i = 0; i < frames; i++) {
Engine_stepModules(this);
Engine_stepFrame(this);
}

yieldWorkers();
@@ -620,6 +631,12 @@ int64_t Engine::getFrame() {
}


int64_t Engine::getFrameTime() {
double timeSinceStep = (internal->frame - internal->stepFrame) * internal->sampleTime;
return internal->stepTime + int64_t(timeSinceStep * 1e9);
}


int64_t Engine::getStepFrame() {
return internal->stepFrame;
}
@@ -635,6 +652,12 @@ int Engine::getStepFrames() {
}


int64_t Engine::getStepDuration() {
double duration = internal->stepFrames * internal->sampleTime;
return int64_t(duration * 1e9);
}


size_t Engine::getNumModules() {
return internal->modules.size();
}


Loading…
Cancel
Save