-
Notifications
You must be signed in to change notification settings - Fork 0
/
BPMAnalyzer.h
66 lines (52 loc) · 2 KB
/
BPMAnalyzer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#pragma once
#include "Config.h"
#include "Note.h"
#include <math.h>
#include <vector>
namespace RhythmTranscriber
{
const float minBeatDuration = 60.f / maxBpm;
const float maxBeatDuration = 60.f / minBpm;
class BPMAnalyzer
{
public:
BaseNote *notes = nullptr;
unsigned int notesLen = 0;
std::vector<std::vector<float>> scoreData;
float beatDurationStep = 0.0025;
void get_score_data();
private:
float calc_beat_score(float duration, unsigned int noteIndex);
float calc_avg_beat_score(float duration);
float calc_full_beat_score_at(unsigned int durationIndex);
/// @brief Given the index of a beat duration score, gets the score of that beat duration
/// times `multiplier`.
/// @param durationIndex
/// @param multiplier
/// @return
inline float get_beat_score_mult(unsigned int durationIndex, float multiplier,
unsigned int noteIndex)
{
float index = (minBeatDuration * (multiplier - 1)) / beatDurationStep +
multiplier * durationIndex;
int floorIndex = index;
/// Exclude last index since we don't have enough data to get it
/// TODO: If outside range, manually calculate it..?
if (index > scoreData.size() - 1 || index < 0.f)
{
return calc_beat_score(
(minBeatDuration + beatDurationStep * durationIndex) * multiplier, noteIndex);
/* return 0.f; */
}
if (floorIndex != index)
{
/// Interp value
return (scoreData.at(floorIndex + 1).at(noteIndex) -
scoreData.at(floorIndex).at(noteIndex)) *
(index - floorIndex) +
scoreData.at(floorIndex).at(noteIndex);
}
return scoreData.at(std::round(index)).at(noteIndex);
}
};
}