You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
1.8 KiB
C++
95 lines
1.8 KiB
C++
#include "tools/bpmcalculator.h"
|
|
|
|
#include <cmath>
|
|
#include <iostream>
|
|
#include <numeric>
|
|
|
|
BPMCalculator::BPMCalculator()
|
|
{
|
|
reset();
|
|
}
|
|
|
|
void BPMCalculator::reset()
|
|
{
|
|
_calculating = false;
|
|
_deltas.clear();
|
|
_previous_click_offset = 0;
|
|
_first_click_offset = 0;
|
|
_need_recalculate = true;
|
|
}
|
|
|
|
void BPMCalculator::start()
|
|
{
|
|
reset();
|
|
|
|
_calculating = true;
|
|
}
|
|
|
|
void BPMCalculator::stop()
|
|
{
|
|
_calculating = false;
|
|
}
|
|
|
|
bool BPMCalculator::calculating() const
|
|
{
|
|
return _calculating;
|
|
}
|
|
|
|
void BPMCalculator::click(const kku::microsec &offset)
|
|
{
|
|
if (!_calculating)
|
|
return;
|
|
|
|
_need_recalculate = true;
|
|
|
|
if (_previous_click_offset == 0)
|
|
{
|
|
_previous_click_offset = offset;
|
|
_first_click_offset = offset;
|
|
return;
|
|
}
|
|
|
|
const kku::microsec delta = offset - _previous_click_offset;
|
|
_deltas.emplace_back(delta);
|
|
|
|
_previous_click_offset = offset;
|
|
}
|
|
|
|
const beat_utils::BeatInfo &BPMCalculator::fetchApproximatedInfo()
|
|
{
|
|
if (!_need_recalculate)
|
|
return _approximated_info;
|
|
|
|
_need_recalculate = false;
|
|
|
|
bool hasEnoughDeltas = _deltas.size() >= 8;
|
|
|
|
_approximated_info = (!hasEnoughDeltas)
|
|
? beat_utils::BeatInfo{}
|
|
: beat_utils::calculateBeatRateInfo(_deltas);
|
|
|
|
return _approximated_info;
|
|
}
|
|
|
|
kku::microsec BPMCalculator::getStartingOffset() const
|
|
{
|
|
return _first_click_offset;
|
|
}
|
|
|
|
void BPMCalculator::setStartingOffset(kku::microsec offset)
|
|
{
|
|
_first_click_offset = offset;
|
|
}
|
|
|
|
void BPMCalculator::moveStartingOffsetBy(kku::microsec shift)
|
|
{
|
|
_first_click_offset += shift;
|
|
}
|
|
|
|
kku::microsec BPMCalculator::fetchTimeUntilNextBeat(const kku::microsec &offset)
|
|
{
|
|
const kku::microsec actual_offset = offset - getStartingOffset();
|
|
|
|
return actual_offset % fetchApproximatedInfo().interval;
|
|
}
|