// // Created by david on 14.06.2026. // #include "TempoController.h" TempoController::TempoController(std::atomic *have_stretch_factor, std::atomic *stretch_factor) : have_stretch_factor(have_stretch_factor), stretch_factor(stretch_factor), lastBeatT(0.0), lastStepT(0.0) { this->have_stretch_factor->store(false); this->stretch_factor->store(1.0); } void TempoController::reset(std::vector beatTimes) { std::lock_guard lock(mMutex); beatTimesSec.assign(beatTimes.begin(), beatTimes.end()); lastBeatT = (0.0); lastStepT = (0.0); } void TempoController::resume() {} void TempoController::pause() {} void TempoController::seekTo(double oldMarkerPosSec, double newMarkerPosSec) { std::lock_guard lock(mMutex); double dt = newMarkerPosSec - oldMarkerPosSec; lastBeatT += dt; lastStepT += dt; } /** * must be thread-safe since these are called from different threads * @param t marker position in sec of original music time */ void TempoController::onBeat(double t) { std::lock_guard lock(mMutex); if(lastBeatT != 0.0) dtBeat = t - lastBeatT; lastBeatT = t; setStretchFactor(); } /** * must be thread-safe since these are called from different threads * @param t time in sec of accelerometer timebase */ void TempoController::onStep(double t) { std::lock_guard lock(mMutex); if(lastStepT != 0.0) dtStep = t - lastStepT; lastStepT = t; setStretchFactor(); } void TempoController::setStretchFactor() { if(dtBeat == 0.0 || dtStep == 0.0) return; double ratio = dtStep / dtBeat; ratio = std::min(3.3, ratio); ratio = std::max(0.3, ratio); this->have_stretch_factor->store(true); this->stretch_factor->store(ratio); }