blob: bbc5a7db8c5ba8ec40c354bbcf7c1b17c1db3b13 (
plain)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#pragma once
#include "config.h"
#include <chrono>
#include <deque>
#include <utility>
#include <boost/signals2.hpp>
#include "Touchpad.h"
#include "Temperature.h"
using clock_type = std::chrono::high_resolution_clock;
struct IntervalCounter
{
public:
IntervalCounter();
int get_count_per_second();
void count(uint64_t n = 1);
private:
uint64_t m_count{};
uint64_t m_count_checkpoint{};
std::chrono::time_point<clock_type> m_checkpoint_timestamp{};
};
template<typename T>
class AgeOutValue
{
public:
AgeOutValue(std::chrono::milliseconds timeout):
m_timeout(timeout),
m_checkpoint_timestamp(clock_type::now()),
m_value{}
{
}
bool is_current()
{
return clock_type::now() - m_checkpoint_timestamp < m_timeout;
}
// returns value, or 0 if aged-out
T value()
{
T result{};
if (is_current()) {
result = m_value;
}
return result;
}
void update(const T& value)
{
m_value = value;
m_checkpoint_timestamp = clock_type::now();
}
private:
const std::chrono::milliseconds m_timeout;
std::chrono::time_point<clock_type> m_checkpoint_timestamp{};
T m_value;
};
class UI
{
public:
UI(Config& config);
void draw();
void handle_input();
bool key_available();
// signals, from user input
boost::signals2::signal<void(int)> signal_bpm;
boost::signals2::signal<void(int, int)> signal_note_set_from_midi;
boost::signals2::signal<void(int)> signal_mode;
boost::signals2::signal<void(int)> signal_output;
// slots
void count_main_loops();
void count_midi_events(size_t size);
void count_midi_notes();
void slot_active_sensing();
void slot_midi_note(int channel, int note, uint64_t timestamp);
void slot_note_bpm(int bpm);
void slot_clock_bpm(int bpm);
private:
Config& m_config;
IntervalCounter m_main_loops;
IntervalCounter m_midi_events;
IntervalCounter m_midi_bytes;
IntervalCounter m_midi_notes;
std::chrono::time_point<clock_type> m_active_sensing_timestamp;
uint64_t m_midi_timestamp;
std::deque<std::pair<int,int>> m_midi_monitor;
AgeOutValue<int> m_note_bpm;
AgeOutValue<int> m_clock_bpm;
Touchpad m_touchpad;
Temperature m_temperature;
};
|