diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 27ca9b6c78..48ddeb55d2 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -2110,18 +2110,24 @@ CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c) if (_cursor == _editor->playhead_cursor) { _editor->_dragging_playhead = true; - if (_editor->session()) { + Session* s = _editor->session (); + + if (s) { if (_was_rolling && _stop) { - _editor->session()->request_stop (); + s->request_stop (); } - if (_editor->session()->is_auditioning()) { - _editor->session()->cancel_audition (); + if (s->is_auditioning()) { + s->cancel_audition (); } - nframes64_t const f = _editor->playhead_cursor->current_frame; - _editor->session()->send_mmc_locate (f); - _editor->session()->send_full_time_code (f); + s->request_suspend_timecode_transmission (); + + if (s->timecode_transmission_suspended ()) { + nframes64_t const f = _editor->playhead_cursor->current_frame; + s->send_mmc_locate (f); + s->send_full_time_code (f); + } } } @@ -2143,10 +2149,11 @@ CursorDrag::motion (GdkEvent* event, bool) _editor->show_verbose_time_cursor (_cursor->current_frame, 10); - if (_editor->session() && _item == &_editor->playhead_cursor->canvas_item) { + Session* s = _editor->session (); + if (s && _item == &_editor->playhead_cursor->canvas_item && s->timecode_transmission_suspended ()) { nframes64_t const f = _editor->playhead_cursor->current_frame; - _editor->session()->send_mmc_locate (f); - _editor->session()->send_full_time_code (f); + s->send_mmc_locate (f); + s->send_full_time_code (f); } @@ -2168,9 +2175,11 @@ CursorDrag::finished (GdkEvent* event, bool movement_occurred) motion (event, false); if (_item == &_editor->playhead_cursor->canvas_item) { - if (_editor->session()) { - _editor->session()->request_locate (_editor->playhead_cursor->current_frame, _was_rolling); + Session* s = _editor->session (); + if (s) { + s->request_locate (_editor->playhead_cursor->current_frame, _was_rolling); _editor->_pending_locate_request = true; + s->request_resume_timecode_transmission (); } } } @@ -2178,7 +2187,11 @@ CursorDrag::finished (GdkEvent* event, bool movement_occurred) void CursorDrag::aborted () { - _editor->_dragging_playhead = false; + if (_editor->_dragging_playhead) { + _editor->session()->request_resume_timecode_transmission (); + _editor->_dragging_playhead = false; + } + _cursor->set_position (adjusted_frame (grab_frame (), 0, false)); } diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 98bf0145c2..7d822e64bc 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -780,6 +780,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi bool step_editing() const { return (_step_editors > 0); } + void request_suspend_timecode_transmission (); + void request_resume_timecode_transmission (); + bool timecode_transmission_suspended () const; + protected: friend class AudioEngine; void set_block_size (nframes_t nframes); @@ -1421,6 +1425,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void step_edit_status_change (bool); uint32_t _step_editors; + + /** true if timecode transmission by the transport is suspended, otherwise false */ + mutable gint _suspend_timecode_transmission; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/session_event.h b/libs/ardour/ardour/session_event.h index e2027298fb..396f4e778b 100644 --- a/libs/ardour/ardour/session_event.h +++ b/libs/ardour/ardour/session_event.h @@ -36,6 +36,7 @@ struct SessionEvent { RealTimeOperation, AdjustPlaybackBuffering, AdjustCaptureBuffering, + SetTimecodeTransmission, /* only one of each of these events can be queued at any one time */ diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 3bee1bc49e..6e557e6d49 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -154,8 +154,8 @@ Session::Session (AudioEngine &eng, click_emphasis_data (0), main_outs (0), _metadata (new SessionMetadata()), - _have_rec_enabled_track (false) - + _have_rec_enabled_track (false), + _suspend_timecode_transmission (0) { playlists.reset (new SessionPlaylists); @@ -4006,3 +4006,4 @@ Session::step_edit_status_change (bool yn) StepEditStatusChange (val); } } + diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 546963516e..f4f2c5ad0e 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -311,7 +311,7 @@ Session::process_with_events (nframes_t nframes) return; } - if (!_exporting) { + if (!_exporting && !timecode_transmission_suspended()) { send_midi_time_code_for_cycle (nframes); } @@ -762,7 +762,7 @@ Session::process_without_events (nframes_t nframes) return; } - if (!_exporting) { + if (!_exporting && !timecode_transmission_suspended()) { send_midi_time_code_for_cycle (nframes); } @@ -1099,6 +1099,10 @@ Session::process_event (SessionEvent* ev) schedule_capture_buffering_adjustment (); break; + case SessionEvent::SetTimecodeTransmission: + g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1); + break; + default: fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg; /*NOTREACHED*/ diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 2897c5cd8f..b722bc04a7 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -1568,3 +1568,27 @@ Session::send_mmc_locate (nframes64_t t) timecode_time_subframes (t, time); MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time)); } + +/** Ask the transport to not send timecode until further notice. The suspension + * will come into effect some finite time after this call, and timecode_transmission_suspended() + * should be checked by the caller to find out when. + */ +void +Session::request_suspend_timecode_transmission () +{ + SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false); + queue_event (ev); +} + +void +Session::request_resume_timecode_transmission () +{ + SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true); + queue_event (ev); +} + +bool +Session::timecode_transmission_suspended () const +{ + return g_atomic_int_get (&_suspend_timecode_transmission) == 1; +}