Media player synchronicity to beat or phase

Metronome synched play, rewind and step. saving in xml.
This commit is contained in:
Bruno Herbelin
2021-11-26 12:22:39 +01:00
parent e123d139e4
commit 1b4849f214
6 changed files with 41 additions and 22 deletions

View File

@@ -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<void()> 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<void()> 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<void()> 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

View File

@@ -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
* */

View File

@@ -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

View File

@@ -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);

View File

@@ -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");

View File

@@ -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);