diff --git a/Metronome.cpp b/Metronome.cpp index a2ed32f..641bf26 100644 --- a/Metronome.cpp +++ b/Metronome.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -59,6 +58,13 @@ namespace ableton return sessionState.beatAtTime(now(), mQuantum); } + std::chrono::microseconds timeNextBeat() const + { + auto sessionState = mLink.captureAppSessionState(); + double beat = ceil(sessionState.beatAtTime(now(), mQuantum)); + return sessionState.timeAtBeat(beat, mQuantum); + } + double phaseTime() const { auto sessionState = mLink.captureAppSessionState(); @@ -99,12 +105,12 @@ namespace ableton mLink.enableStartStopSync(enabled); } - private: std::chrono::microseconds now() const { return mLink.clock().micros(); } + private: Link& mLink; double mQuantum; }; @@ -146,7 +152,6 @@ void Metronome::terminate() link_.enable(false); } - double Metronome::beats() const { return engine_.beatTime(); @@ -181,6 +186,11 @@ double Metronome::tempo() const return engine_.tempo(); } +std::chrono::microseconds Metronome::timeToBeat() +{ + return engine_.timeNextBeat() - engine_.now(); +} + size_t Metronome::peers() const { return link_.numPeers(); diff --git a/Metronome.h b/Metronome.h index 8fa2831..862a214 100644 --- a/Metronome.h +++ b/Metronome.h @@ -1,7 +1,7 @@ #ifndef METRONOME_H #define METRONOME_H -#include +#include class Metronome { @@ -20,18 +20,20 @@ public: } bool init (); - void terminate(); + void terminate (); - double beats() const; - double phase() const; + double beats () const; + double phase () const; - void setTempo(double t); - double tempo() const; + void setTempo (double t); + double tempo () const; - void setQuantum(double q); - double quantum() const; + void setQuantum (double q); + double quantum () const; - size_t peers() const; + std::chrono::microseconds timeToBeat(); + + size_t peers () const; }; #endif // METRONOME_H diff --git a/Settings.h b/Settings.h index 1f1926c..279a008 100644 --- a/Settings.h +++ b/Settings.h @@ -170,12 +170,16 @@ struct SourceConfig struct MetronomeConfig { + bool start_stop_sync; double tempo; double quantum; + bool sync_tempo; MetronomeConfig() { + start_stop_sync = true; tempo = 120.; quantum = 4.; + sync_tempo = true; } }; diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index badb0dc..a1a80a8 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -1591,7 +1591,7 @@ void UserInterface::RenderMetrics(bool *p_open, int* p_corner, int *p_mode) ICON_FA_TACHOMETER_ALT " Performance\0" ICON_FA_HOURGLASS_HALF " Timers\0" ICON_FA_VECTOR_SQUARE " Source\0" - ICON_FA_USER_CLOCK " Ableton link\0"); + ICON_FA_USER_CLOCK " Metronome\0"); ImGui::SameLine(); if (ImGuiToolkit::IconButton(5,8)) @@ -1603,13 +1603,13 @@ void UserInterface::RenderMetrics(bool *p_open, int* p_corner, int *p_mode) double t = Metronome::manager().tempo(); double p = Metronome::manager().phase(); double q = Metronome::manager().quantum(); - int n = (int) Metronome::manager().peers(); + uint n = (int) Metronome::manager().peers(); + + ImGuiToolkit::PushFont(ImGuiToolkit::FONT_MONO); // tempo char buf[32]; - ImGuiToolkit::PushFont(ImGuiToolkit::FONT_MONO); ImGui::Text("Tempo %.1f BPM ", t); - // network peers indicator ImGui::SameLine(); if ( n < 1) { @@ -1626,17 +1626,14 @@ void UserInterface::RenderMetrics(bool *p_open, int* p_corner, int *p_mode) ImGuiToolkit::ToolTip(buf); } } - // compute and display duration of a phase - double duration = 60.0 / t * q; - guint64 time_phase = GST_SECOND * duration ; + guint64 time_phase = GST_SECOND * (60.0 * q / t) ; ImGui::Text("Phase %s", GstToolkit::time_to_string(time_phase, GstToolkit::TIME_STRING_READABLE).c_str()); - ImGui::PopFont(); - // metronome sprintf(buf, "%d/%d", (int)(p)+1, (int)(q) ); ImGui::ProgressBar(ceil(p)/ceil(q), ImVec2(250.f,0.f), buf); + ImGui::PopFont(); } else if (*p_mode > 1) { ImGuiToolkit::PushFont(ImGuiToolkit::FONT_MONO); @@ -4760,15 +4757,15 @@ void Navigator::RenderMainPannelSettings() // Metronome // ImGuiToolkit::Spacing(); - ImGui::Text("Ableton Link"); + ImGui::Text("Ableton link"); - ImGuiToolkit::HelpMarker("Ableton link enables time synchronization\n " + ImGuiToolkit::HelpMarker("Time synchronization between computers with Ableton link\n " ICON_FA_ANGLE_RIGHT " Tempo is the number of beats per minute (or set by peers).\n " ICON_FA_ANGLE_RIGHT " Quantum is the number of beats in a phase."); ImGui::SameLine(0); ImGui::SetCursorPosX(-1.f * IMGUI_RIGHT_ALIGN); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - int t = (int) Metronome::manager().tempo(); + int t = (int) ceil(Metronome::manager().tempo()); // if no other peers, user can set a tempo if (Metronome::manager().peers() < 1) { if ( ImGui::SliderInt("Tempo", &t, 20, 240, "%d BPM") ) @@ -4786,10 +4783,12 @@ void Navigator::RenderMainPannelSettings() ImGui::SetCursorPosX(-1.f * IMGUI_RIGHT_ALIGN); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - int q = (int) Metronome::manager().quantum(); + int q = (int) ceil(Metronome::manager().quantum()); if ( ImGui::SliderInt("Quantum", &q, 2, 100) ) Metronome::manager().setQuantum((double) q); +// ImGuiToolkit::ButtonSwitch( ICON_FA_USER_CLOCK " Start/stop sync", &Settings::application.metronome.start_stop_sync); + #ifndef NDEBUG ImGui::Text("Expert"); // ImGuiToolkit::ButtonSwitch( IMGUI_TITLE_HISTORY, &Settings::application.widget.history);