#include "Click.h" #include "MIDI.h" #include "PCM.h" #include "Timer.h" #include "UI.h" #include "config.h" #include "log.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std::chrono_literals; using namespace std::string_literals; double diff_timespec(const struct timespec *time1, const struct timespec *time0) { return (time1->tv_sec - time0->tv_sec) + (time1->tv_nsec - time0->tv_nsec) / 1000000000.0; } int main(void) { try { //debug_cout.activate(); log_cout.activate(); log_cout.log_lines(log_lines); Config config; std::shared_ptr clock_click = std::make_shared(); std::shared_ptr note_click = std::make_shared(config); std::shared_ptr internal_click = std::make_shared(config); // Active Mode std::shared_ptr click = note_click; MIDI midi; PCM pcm; UI ui; pcm.write(); Timer timer_500ms(500ms, true); timer_500ms.start(); // Main signals boost::signals2::signal signal_count_loops; // // Signal-Slot Connections: // midi.signal_note.connect([&](int channel, int note){note_click->receive_note(channel, note);}); 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();}); midi.flush(); while (true) { debug_cout << "Main loop entered." << std::endl; signal_count_loops(); fd_set read_set; FD_ZERO(&read_set); FD_SET(midi.fd(), &read_set); #if 0 // PCM fd almost always writeable: for single frames at high speed fd_set write_set; FD_ZERO(&write_set); FD_SET(pcm.fd(), &write_set); #endif struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 20000; int result = select(FD_SETSIZE, &read_set, nullptr/*&write_set*/, nullptr, &timeout); if (result < 0) { throw std::runtime_error("select() failed"); } else if (result == 0) { debug_cout << "select() timeout" << std::endl; } while (midi.event_ready()) { //std::cout << "read..." << std::endl; auto event = midi.read(); //std::cout << "process..." << std::endl; midi.process(event); } if (pcm.write_available()) { //std::cout << "DEBUG: WRITE" << std::endl; pcm.write(); } // handle timers, TODO: make updates more efficient at scale timer_500ms.update(); } } catch (const std::exception& ex) { std::cerr << "Error: " << ex.what() << std::endl; } return 0; }