|
|
|
@ -3,18 +3,27 @@
|
|
|
|
|
#include <numeric>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
constexpr microsec MICROSECONDS_IN_MINUTE = 60000000;
|
|
|
|
|
constexpr float MICROSECONDS_IN_MINUTE_f = 60000000.;
|
|
|
|
|
|
|
|
|
|
BPMCalculator::BPMCalculator(const std::shared_ptr<Music>& music) :
|
|
|
|
|
_music(music),
|
|
|
|
|
_previous_click_offset(0)
|
|
|
|
|
{}
|
|
|
|
|
_music(music)
|
|
|
|
|
{
|
|
|
|
|
reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BPMCalculator::setMusic(const std::shared_ptr<Music>& music)
|
|
|
|
|
void BPMCalculator::reset()
|
|
|
|
|
{
|
|
|
|
|
_calculating = false;
|
|
|
|
|
_deltas.clear();
|
|
|
|
|
_previous_click_offset = 0;
|
|
|
|
|
_approximated_bpm = 0;
|
|
|
|
|
_need_recalculate = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BPMCalculator::setMusic(const std::shared_ptr<Music>& music)
|
|
|
|
|
{
|
|
|
|
|
_music = music;
|
|
|
|
|
reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<Music> BPMCalculator::music() const
|
|
|
|
@ -24,15 +33,23 @@ std::shared_ptr<Music> BPMCalculator::music() const
|
|
|
|
|
|
|
|
|
|
void BPMCalculator::start()
|
|
|
|
|
{
|
|
|
|
|
_deltas.clear();
|
|
|
|
|
_previous_click_offset = 0;
|
|
|
|
|
reset();
|
|
|
|
|
|
|
|
|
|
_calculating = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BPMCalculator::stop()
|
|
|
|
|
{
|
|
|
|
|
_calculating = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BPMCalculator::click()
|
|
|
|
|
{
|
|
|
|
|
const microsec click_offset = _music->fetchOffset();
|
|
|
|
|
if (!_calculating)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
std::cout << click_offset << "\n\n\n\n";
|
|
|
|
|
const microsec click_offset = _music->fetchOffset();
|
|
|
|
|
_need_recalculate = true;
|
|
|
|
|
|
|
|
|
|
if (_previous_click_offset == 0)
|
|
|
|
|
{
|
|
|
|
@ -46,14 +63,57 @@ void BPMCalculator::click()
|
|
|
|
|
_previous_click_offset = click_offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BPMCalculator::getCurrentApproximation() const
|
|
|
|
|
float BPMCalculator::fetchCurrentBPMApproximation()
|
|
|
|
|
{
|
|
|
|
|
const microsec sum = std::accumulate(_deltas.begin(), _deltas.end(), 0);
|
|
|
|
|
if (!_need_recalculate)
|
|
|
|
|
return _approximated_bpm;
|
|
|
|
|
|
|
|
|
|
_need_recalculate = false;
|
|
|
|
|
|
|
|
|
|
std::cout << "S: " << sum << " _deltas.size(): " << _deltas.size();
|
|
|
|
|
std::cout << "\n " << (static_cast<float>(sum) / static_cast<float>(_deltas.size())) << '\n';
|
|
|
|
|
const microsec sum = std::accumulate(_deltas.begin(), _deltas.end(), 0);
|
|
|
|
|
bool hasEnoughDeltas = _deltas.size() >= 8;
|
|
|
|
|
|
|
|
|
|
return (sum == 0 || _deltas.size() < 8)
|
|
|
|
|
_approximated_bpm = (!hasEnoughDeltas)
|
|
|
|
|
? 0.
|
|
|
|
|
: static_cast<int>(static_cast<float>(MICROSECONDS_IN_MINUTE) / (static_cast<float>(sum) / static_cast<float>(_deltas.size())));
|
|
|
|
|
: calculateBPM(sum, _deltas.size());
|
|
|
|
|
|
|
|
|
|
return _approximated_bpm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float BPMCalculator::calculateBPM(microsec all_microseconds, std::size_t beats_amount) const
|
|
|
|
|
{
|
|
|
|
|
if (beats_amount == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
float relation = static_cast<float>(all_microseconds)
|
|
|
|
|
/ static_cast<float>(beats_amount);
|
|
|
|
|
|
|
|
|
|
return static_cast<float>(1. / relation);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
microsec BPMCalculator::getStartingOffset() const
|
|
|
|
|
{
|
|
|
|
|
return _first_click_offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BPMCalculator::setStartingOffset(microsec offset)
|
|
|
|
|
{
|
|
|
|
|
_first_click_offset = offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BPMCalculator::moveStartingOffsetBy(microsec shift)
|
|
|
|
|
{
|
|
|
|
|
_first_click_offset += shift;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
microsec BPMCalculator::fetchTimeUntilNextBeat()
|
|
|
|
|
{
|
|
|
|
|
const microsec actual_offset = _music->fetchOffset() - _first_click_offset;
|
|
|
|
|
|
|
|
|
|
return fetchBeatInterval() % actual_offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
microsec BPMCalculator::fetchBeatInterval()
|
|
|
|
|
{
|
|
|
|
|
return static_cast<microsec>(1. / fetchCurrentBPMApproximation());
|
|
|
|
|
}
|
|
|
|
|