#include "UI.h" #include "cpuload.h" #include "debug.h" #include "log.h" #include #include #include #include #include const int midi_monitor_max_size = 3; using namespace std::chrono_literals; static std::vector mode_names{{ "NoteClick", "Clock", "Internal" }}; UI::UI(Config& config): m_config(config), m_main_loops{}, m_main_loops_checkpoint{}, m_main_loops_timestamp{}, m_active_sensing_timestamp{}, m_midi_timestamp{} { } int UI::get_main_loops_per_second() { // calculate result std::chrono::time_point now = clock_type::now(); uint64_t diff_ms = std::chrono::duration_cast(now - m_main_loops_timestamp).count(); uint64_t loops_per_second = (diff_ms == 0 || m_main_loops_checkpoint == 0) ? 0 : ((m_main_loops - m_main_loops_checkpoint) * 1000 / diff_ms); // update state m_main_loops_timestamp = now; m_main_loops_checkpoint = m_main_loops; return loops_per_second; } void UI::draw() { std::vector cpuloads = get_cpu_loads(); int main_loops_per_second = get_main_loops_per_second(); int mode = m_config.get_mode(); int channel = m_config.get_midi_channel(); int note = m_config.get_midi_note(); int bpm = m_config.get_bpm(); bool active_sensing_detected = (clock_type::now() - m_active_sensing_timestamp) < 2s; // clear screen std::cout << "\x1B[2J\x1B[H"; //std::cout << std::endl; std::cout << fmt::format("- {:3} BPM +", bpm) << std::endl; std::cout << "Mode: "; for (int i = 0; i < mode_names.size(); ++i) { if (i == mode) { std::cout << fmt::format(fg(fmt::color::crimson) | fmt::emphasis::bold, " {}", mode_names[i]); } else { std::cout << fmt::format(" {}", mode_names[i]); } } std::cout << std::endl; std::cout << fmt::format("MIDI Note: {}/{}", channel, note); std::cout << std::endl; std::cout << std::endl; std::cout << "Status:" << std::endl; std::cout << " CPU:"; for (auto& i: cpuloads) { std::cout << fmt::format(" {:2}%", i); } int max = *std::max_element(cpuloads.begin(), cpuloads.end()); std::cout << fmt::format(", max. {:2}%", max) << std::endl; std::cout << " MIDI Activity: "; if (m_midi_monitor.empty()) { std::cout << "--"; } else { int count{}; for (const auto& i: m_midi_monitor) { if (count == 0) { std::cout << fmt::format(fg(fmt::color::crimson) | fmt::emphasis::bold, " {}/{}", i.first, i.second); } else { std::cout << fmt::format(" {}/{}", i.first, i.second); } ++count; } if (count >= midi_monitor_max_size) { std::cout << " ..."; } } std::cout << std::endl; std::cout << fmt::format(" MIDI Timestamp: {}", m_midi_timestamp) << std::endl; std::cout << fmt::format(" Active sensing: {}", active_sensing_detected) << std::endl; std::cout << " Clock: ____ BPM" << std::endl; std::cout << " Click: ____ BPM" << std::endl; std::cout << fmt::format(" Internal: {:3} BPM", bpm) << std::endl; std::cout << fmt::format(" Main loops/s: {}", main_loops_per_second) << std::endl; std::cout << "Log:" << std::endl; std::cout << log_cout.get_log() << std::endl; } void UI::count_main_loops() { ++m_main_loops; debug_cout << "DEBUG:" << m_main_loops << std::endl; } void UI::slot_active_sensing() { m_active_sensing_timestamp = clock_type::now(); } void UI::slot_midi_note(int channel, int note, uint64_t timestamp) { m_midi_timestamp = timestamp; m_midi_monitor.emplace_front(channel, note); while (m_midi_monitor.size() > midi_monitor_max_size) { m_midi_monitor.pop_back(); } }