diff options
author | Roland Reichwein <mail@reichwein.it> | 2025-01-04 09:22:17 +0100 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2025-01-04 09:22:17 +0100 |
commit | 9351c6d9812523b0b8027f2b2e0de54c27004bc2 (patch) | |
tree | 6cbf97a8a699630f83bdc1bc93a51736874e82bb | |
parent | 0399f008b22482c46d37fa15e6be205b85681011 (diff) |
Fix config
-rw-r--r-- | Click.h | 6 | ||||
-rw-r--r-- | MIDI.h | 23 | ||||
-rw-r--r-- | PCM.h | 3 | ||||
-rw-r--r-- | UI.cpp | 2 | ||||
-rw-r--r-- | UI.h | 8 | ||||
-rw-r--r-- | config.cpp | 12 | ||||
-rw-r--r-- | config.h | 3 | ||||
-rw-r--r-- | main.cpp | 20 |
8 files changed, 62 insertions, 15 deletions
@@ -38,10 +38,14 @@ public: virtual ~NoteClick(){} + // signals boost::signals2::signal<void()> signal_click; - void receive_note(int channel, int note) + // slots + void receive_note(int channel, int note, uint64_t timestamp) { + (void) timestamp; + if (true || (channel == m_channel && note == m_note)) { signal_click(); } @@ -32,7 +32,7 @@ public: throw std::runtime_error("MIDI port couldn't be opened"); } - log_cout << "in_port: " << std::to_string(in_port) << std::endl; + debug_cout << "in_port: " << std::to_string(in_port) << std::endl; #if 1 snd_seq_addr_t sender, dest; @@ -80,7 +80,7 @@ public: free(pfd); } - boost::signals2::signal<void(int, int)> signal_note; + boost::signals2::signal<void(int, int, uint64_t)> signal_note; boost::signals2::signal<void()> signal_active_sensing; boost::signals2::signal<void()> signal_clock; @@ -121,40 +121,45 @@ public: return ev; } + uint64_t timestamp_from_event(const snd_seq_event_t *ev) + { + return ((ev->flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_REAL) ? ev->time.time.tv_sec : ev->time.tick; + } + // returns if click starts void process(const snd_seq_event_t *ev) { if ((ev->type == SND_SEQ_EVENT_NOTEON) ||(ev->type == SND_SEQ_EVENT_NOTEOFF)) { + uint64_t timestamp = timestamp_from_event(ev); const char *type = (ev->type == SND_SEQ_EVENT_NOTEON) ? "on " : "off"; - debug_cout << fmt::format("[{}] Note {}: {:2x} vel({:2x}), ch {:2x}\n", ((ev->flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_REAL) ? ev->time.time.tv_sec : ev->time.tick, + debug_cout << fmt::format("[{}] Note {}: {:2x} vel({:2x}), ch {:2x}\n", timestamp, type, ev->data.note.note, ev->data.note.velocity, ev->data.control.channel); if (ev->type == SND_SEQ_EVENT_NOTEON) { - signal_note(ev->data.control.channel, ev->data.note.note); + signal_note(ev->data.control.channel, ev->data.note.note, timestamp); } } else if (ev->type == SND_SEQ_EVENT_CONTROLLER) { - debug_cout << fmt::format("[{}] Control: {:2x} val({:2x})\n", - ((ev->flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_REAL) ? ev->time.time.tv_sec : ev->time.tick, + debug_cout << fmt::format("[{}] Control: {:2x} val({:2x})\n", timestamp_from_event(ev), ev->data.control.param, ev->data.control.value); } else if (ev->type == SND_SEQ_EVENT_SENSING) { signal_active_sensing(); - debug_cout << fmt::format("[{}] Active Sensing\n", ((ev->flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_REAL) ? ev->time.time.tv_sec : ev->time.tick) << std::endl; + debug_cout << fmt::format("[{}] Active Sensing\n", timestamp_from_event(ev)) << std::endl; } else if (ev->type == SND_SEQ_EVENT_CLOCK) { signal_clock(); - debug_cout << fmt::format("[{}] Clock\n", ((ev->flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_REAL) ? ev->time.time.tv_sec : ev->time.tick) << std::endl; + debug_cout << fmt::format("[{}] Clock\n", timestamp_from_event(ev)) << std::endl; } else { - log_cout << fmt::format("[{}] Unknown MIDI event: {}\n", ev->time.tick, ev->type) << std::endl; + log_cout << fmt::format("[{}] Unknown MIDI event: {}\n", timestamp_from_event(ev), ev->type) << std::endl; } } @@ -1,6 +1,7 @@ #pragma once #include "config.h" +#include "debug.h" #include "log.h" #include <libreichwein/file.h> @@ -132,7 +133,7 @@ public: if (0 > snd_pcm_avail_delay(handle, &avail, &delay)) { log_cout << "Error detecting avail and delay" << std::endl; } else { - log_cout << fmt::format("Delay: {}, avail. buffer; {} frames", delay, avail) << std::endl; + debug_cout << fmt::format("Delay: {}, avail. buffer; {} frames", delay, avail) << std::endl; } generate(); @@ -54,7 +54,7 @@ void UI::draw() std::cout << fmt::format(", max. {:2}%", max) << std::endl; std::cout << " Notes/Channels: -- -- -- ... (Choose)" << std::endl; - std::cout << " Timestamp: ------" << std::endl; + std::cout << " 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; @@ -2,6 +2,8 @@ #include <chrono> +#include <boost/signals2.hpp> + class UI { public: @@ -11,6 +13,12 @@ public: void draw(); + // signals + boost::signals2::signal<void()> bpm_plus; + boost::signals2::signal<void()> bpm_minus; + boost::signals2::signal<void()> note_set_from_midi; + boost::signals2::signal<void()> mode; + // slots void count_main_loops(); void slot_active_sensing(); @@ -15,6 +15,16 @@ std::string config_filename = "click.cfg"; Config::Config() { + recover(); +} + +Config::~Config() +{ + persist(); +} + +void Config::recover() +{ try { // presets / defaults m_midi_channel = CLICK_CHANNEL; @@ -41,7 +51,7 @@ Config::Config() } } -Config::~Config() +void Config::persist() { std::string config = fmt::format("midi_channel={}\n", m_midi_channel) + fmt::format("midi_note={}\n", m_midi_note) + @@ -28,6 +28,9 @@ public: int get_bpm(); void set_bpm(int bpm); + void recover(); + void persist(); + private: int m_midi_channel; int m_midi_note; @@ -19,6 +19,7 @@ #include <sys/types.h> #include <sys/time.h> #include <time.h> +#include <signal.h> #include <boost/signals2.hpp> @@ -30,8 +31,18 @@ double diff_timespec(const struct timespec *time1, const struct timespec *time0) + (time1->tv_nsec - time0->tv_nsec) / 1000000000.0; } +bool run_flag = true; + +void signal_handler(int) { + run_flag = false; + std::cout << "Signal received. Terminating." << std::endl; +} + int main(void) { + signal(SIGTERM, signal_handler); + signal(SIGINT, signal_handler); + try { //debug_cout.activate(); log_cout.activate(); @@ -55,21 +66,25 @@ int main(void) Timer timer_500ms(500ms, true); timer_500ms.start(); + Timer timer_10min(10min, true); + timer_10min.start(); + // Main signals boost::signals2::signal<void()> signal_count_loops; // // Signal-Slot Connections: // - midi.signal_note.connect([&](int channel, int note){note_click->receive_note(channel, note);}); + midi.signal_note.connect([&](int channel, int note, uint64_t timestamp){note_click->receive_note(channel, note, timestamp);}); note_click->signal_click.connect([&](){pcm.click();}); midi.signal_active_sensing.connect([&](){ui.slot_active_sensing();}); timer_500ms.elapsed.connect([&](){ui.draw();}); signal_count_loops.connect([&](){ui.count_main_loops();}); + timer_10min.elapsed.connect([&](){config.persist();}); midi.flush(); - while (true) { + while (run_flag) { debug_cout << "Main loop entered." << std::endl; signal_count_loops(); @@ -110,6 +125,7 @@ int main(void) // handle timers, TODO: make updates more efficient at scale timer_500ms.update(); + timer_10min.update(); } } catch (const std::exception& ex) { std::cerr << "Error: " << ex.what() << std::endl; |