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
|
#pragma once
|
||||||
|
|
||||||
#include <SFML/System/Clock.hpp>
|
#include <SFML/System/Clock.hpp>
|
||||||
|
|
||||||
using microsec = sf::Int64;
|
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