forked from NaiJi/project-kyoku
Implement BPMCalculator for internal bpm calculation in level editor
This commit is contained in:
parent
8c3f2a112f
commit
befd7e5cf9
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include "tools/music.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class BPMCalculator
|
||||
{
|
||||
public:
|
||||
explicit BPMCalculator(const std::shared_ptr<Music>& music);
|
||||
void setMusic(const std::shared_ptr<Music>& music);
|
||||
|
||||
void startListening(const microsec& offset);
|
||||
void stopListening();
|
||||
|
||||
void click();
|
||||
int getCurrentApproximation() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Music> _music;
|
||||
std::vector<microsec> _deltas;
|
||||
microsec _previous_click_offset;
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <SFML/System/Clock.hpp>
|
||||
|
||||
using microsec = sf::Int64;
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
#include "tools/bpmcalculator.h"
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
#include <iostream>
|
||||
|
||||
constexpr microsec MICROSECONDS_IN_MINUTE = 60000000;
|
||||
|
||||
BPMCalculator::BPMCalculator(const std::shared_ptr<Music>& music) :
|
||||
_music(music),
|
||||
_previous_click_offset(0)
|
||||
{}
|
||||
|
||||
void BPMCalculator::setMusic(const std::shared_ptr<Music>& music)
|
||||
{
|
||||
_music = music;
|
||||
}
|
||||
|
||||
void BPMCalculator::startListening(const microsec &offset)
|
||||
{
|
||||
_deltas.clear();
|
||||
_previous_click_offset = 0;
|
||||
_music->setOffset(offset);
|
||||
_music->play();
|
||||
}
|
||||
|
||||
void BPMCalculator::stopListening()
|
||||
{
|
||||
_music->stop();
|
||||
}
|
||||
|
||||
void BPMCalculator::click()
|
||||
{
|
||||
const microsec click_offset = _music->fetchOffset();
|
||||
|
||||
if (_previous_click_offset == 0)
|
||||
{
|
||||
_previous_click_offset = click_offset;
|
||||
return;
|
||||
}
|
||||
|
||||
const microsec delta = click_offset - _previous_click_offset;
|
||||
_deltas.emplace_back(delta);
|
||||
|
||||
_previous_click_offset = click_offset;
|
||||
}
|
||||
|
||||
int BPMCalculator::getCurrentApproximation() const
|
||||
{
|
||||
const microsec sum = std::accumulate(_deltas.begin(), _deltas.end(), 0);
|
||||
|
||||
return (sum == 0)
|
||||
? 0.
|
||||
: static_cast<int>(static_cast<float>(MICROSECONDS_IN_MINUTE) / (static_cast<float>(sum) / static_cast<float>(_deltas.size())));
|
||||
}
|
Loading…
Reference in New Issue