diff --git a/MediaPlayer.cpp b/MediaPlayer.cpp index 6ea5a1e..af3282a 100644 --- a/MediaPlayer.cpp +++ b/MediaPlayer.cpp @@ -646,12 +646,17 @@ void MediaPlayer::play(bool on) return; // Metronome - if (metro_sync_) { - // busy with this play() + if (metro_sync_ > Metronome::SYNC_NONE) { + // busy with this delayed action pending_ = true; - // Execute: sync to Metronome if active - Metronome::manager().executeAtBeat( std::bind([](MediaPlayer *p, bool o) { - p->execute_play_command(o); p->pending_=false; }, this, on) ); + // delayed execution function + std::function playlater = std::bind([](MediaPlayer *p, bool o) { + p->execute_play_command(o); p->pending_=false; }, this, on); + // Execute: sync to Metronome + if (metro_sync_ > Metronome::SYNC_BEAT) + Metronome::manager().executeAtPhase( playlater ); + else + Metronome::manager().executeAtBeat( playlater ); } else // execute immediately @@ -702,11 +707,16 @@ void MediaPlayer::rewind(bool force) // Metronome if (metro_sync_) { - // busy with this play() + // busy with this delayed action pending_ = true; - // Execute: sync to Metronome if active - Metronome::manager().executeAtBeat( std::bind([](MediaPlayer *p, GstClockTime t, bool f) { - p->execute_seek_command( t, f ); p->pending_=false; }, this, target, force) ); + // delayed execution function + std::function rewindlater = std::bind([](MediaPlayer *p, GstClockTime t, bool f) { + p->execute_seek_command( t, f ); p->pending_=false; }, this, target, force); + // Execute: sync to Metronome + if (metro_sync_ > Metronome::SYNC_BEAT) + Metronome::manager().executeAtPhase( rewindlater ); + else + Metronome::manager().executeAtBeat( rewindlater ); } else // execute immediately @@ -729,11 +739,17 @@ void MediaPlayer::step() // Metronome if (metro_sync_) { - // busy with this play() + // busy with this delayed action pending_ = true; - // Execute: sync to Metronome if active - Metronome::manager().executeAtBeat( std::bind([](MediaPlayer *p, GstEvent *e) { - gst_element_send_event(p->pipeline_, e); p->pending_=false; }, this, stepevent) ); + // delayed execution function + std::function steplater = std::bind([](MediaPlayer *p, GstEvent *e) { + gst_element_send_event(p->pipeline_, e); p->pending_=false; }, this, stepevent) ; + // Execute: sync to Metronome + if (metro_sync_ > Metronome::SYNC_BEAT) + Metronome::manager().executeAtPhase( steplater ); + else + Metronome::manager().executeAtBeat( steplater ); + } else // execute immediately diff --git a/MediaPlayer.h b/MediaPlayer.h index 43409be..9ccd397 100644 --- a/MediaPlayer.h +++ b/MediaPlayer.h @@ -269,7 +269,7 @@ public: * Option to synchronize with metronome * */ inline void setSyncToMetronome(Metronome::Synchronicity s) { metro_sync_ = s; } - inline Metronome::Synchronicity synchedToMetronome() const { return metro_sync_; } + inline Metronome::Synchronicity syncToMetronome() const { return metro_sync_; } /** * Accept visitors * */ diff --git a/Metronome.cpp b/Metronome.cpp index f638798..9136fba 100644 --- a/Metronome.cpp +++ b/Metronome.cpp @@ -75,8 +75,9 @@ namespace ableton std::chrono::microseconds timeNextPhase() const { auto sessionState = mLink.captureAppSessionState(); - double beat = ceil(sessionState.phaseAtTime(now(), mQuantum)); - return sessionState.timeAtBeat(beat, mQuantum); + double phase = ceil(sessionState.phaseAtTime(now(), mQuantum)); + double beat = ceil(sessionState.beatAtTime(now(), mQuantum)); + return sessionState.timeAtBeat(beat + (mQuantum-phase), mQuantum); } double tempo() const diff --git a/SessionCreator.cpp b/SessionCreator.cpp index 943b3cf..71f8ec6 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -726,6 +726,10 @@ void SessionLoader::visit(MediaPlayer &n) mediaplayerNode->QueryBoolAttribute("rewind_on_disabled", &rewind_on_disabled); n.setRewindOnDisabled(rewind_on_disabled); + int sync_to_metronome = 0; + mediaplayerNode->QueryIntAttribute("sync_to_metronome", &sync_to_metronome); + n.setSyncToMetronome( (Metronome::Synchronicity) sync_to_metronome); + bool play = true; mediaplayerNode->QueryBoolAttribute("play", &play); n.play(play); diff --git a/SessionVisitor.cpp b/SessionVisitor.cpp index 982f150..044d175 100644 --- a/SessionVisitor.cpp +++ b/SessionVisitor.cpp @@ -354,6 +354,7 @@ void SessionVisitor::visit(MediaPlayer &n) newelement->SetAttribute("speed", n.playSpeed()); newelement->SetAttribute("software_decoding", n.softwareDecodingForced()); newelement->SetAttribute("rewind_on_disabled", n.rewindOnDisabled()); + newelement->SetAttribute("sync_to_metronome", (int) n.syncToMetronome()); // timeline XMLElement *timelineelement = xmlDoc_->NewElement("Timeline"); diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 785209d..1deee74 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -104,11 +104,8 @@ void SetNextWindowVisible(ImVec2 pos, ImVec2 size, float margin = 180.f); std::string readable_date_time_string(std::string date){ if (date.length()<12) return ""; - std::string s = date.substr(0, 12); - s.insert(10, ":"); - s.insert(8, " "); - s.insert(6, "/"); - s.insert(4, "/"); + std::string s = date.substr(6, 2) + "/" + date.substr(4, 2) + "/" + date.substr(0, 4); + s += " @ " + date.substr(8, 2) + ":" + date.substr(10, 2); return s; } @@ -2472,7 +2469,7 @@ void SourceController::Render() if (ImGui::BeginMenu(ICON_FA_CLOCK " Metronome")) { - Metronome::Synchronicity sync = mediaplayer_active_->synchedToMetronome(); + Metronome::Synchronicity sync = mediaplayer_active_->syncToMetronome(); bool active = sync == Metronome::SYNC_NONE; if (ImGuiToolkit::MenuItemIcon(5, 13, " Not synchronized", active )) mediaplayer_active_->setSyncToMetronome(Metronome::SYNC_NONE);