From 5b520324ceab2559723b4ef5127301fa61ff4846 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 9 Aug 2010 16:40:31 +0000 Subject: [PATCH] Allow markers to be glued to bar/beat time. Fixes #1815. git-svn-id: svn://localhost/ardour2/branches/3.0@7573 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor.cc | 8 +- gtk2_ardour/editor.h | 1 + gtk2_ardour/editor_drag.cc | 7 +- gtk2_ardour/editor_markers.cc | 38 +++++- gtk2_ardour/editor_ops.cc | 10 +- gtk2_ardour/location_ui.cc | 4 +- libs/ardour/ardour/location.h | 43 +++---- libs/ardour/ardour/session.h | 6 +- libs/ardour/export_profile_manager.cc | 6 +- libs/ardour/location.cc | 119 +++++++++++++++--- libs/ardour/location_importer.cc | 2 +- libs/ardour/session.cc | 24 +++- libs/ardour/session_command.cc | 4 +- libs/ardour/session_process.cc | 2 +- libs/ardour/session_state.cc | 22 ++-- libs/ardour/session_transport.cc | 8 +- libs/surfaces/control_protocol/basic_ui.cc | 2 +- .../mackie/mackie_control_protocol.cc | 2 +- 18 files changed, 218 insertions(+), 90 deletions(-) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 28d9ee543a..5080636db2 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1135,7 +1135,7 @@ Editor::set_session (Session *t) Location* loc = _session->locations()->auto_loop_location(); if (loc == 0) { - loc = new Location (0, _session->current_end_frame(), _("Loop"),(Location::Flags) (Location::IsAutoLoop | Location::IsHidden)); + loc = new Location (*_session, 0, _session->current_end_frame(), _("Loop"),(Location::Flags) (Location::IsAutoLoop | Location::IsHidden)); if (loc->start() == loc->end()) { loc->set_end (loc->start() + 1); } @@ -1148,7 +1148,7 @@ Editor::set_session (Session *t) loc = _session->locations()->auto_punch_location(); if (loc == 0) { - loc = new Location (0, _session->current_end_frame(), _("Punch"), (Location::Flags) (Location::IsAutoPunch | Location::IsHidden)); + loc = new Location (*_session, 0, _session->current_end_frame(), _("Punch"), (Location::Flags) (Location::IsAutoPunch | Location::IsHidden)); if (loc->start() == loc->end()) { loc->set_end (loc->start() + 1); } @@ -4602,7 +4602,7 @@ Editor::set_loop_range (nframes64_t start, nframes64_t end, string cmd) Location* tll; if ((tll = transport_loop_location()) == 0) { - Location* loc = new Location (start, end, _("Loop"), Location::IsAutoLoop); + Location* loc = new Location (*_session, start, end, _("Loop"), Location::IsAutoLoop); XMLNode &before = _session->locations()->get_state(); _session->locations()->add (loc, true); _session->set_auto_loop_location (loc); @@ -4629,7 +4629,7 @@ Editor::set_punch_range (nframes64_t start, nframes64_t end, string cmd) Location* tpl; if ((tpl = transport_punch_location()) == 0) { - Location* loc = new Location (start, end, _("Loop"), Location::IsAutoPunch); + Location* loc = new Location (*_session, start, end, _("Loop"), Location::IsAutoPunch); XMLNode &before = _session->locations()->get_state(); _session->locations()->add (loc, true); _session->set_auto_loop_location (loc); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 27e20e698b..ecd13778a1 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1465,6 +1465,7 @@ public: void marker_menu_remove (); void marker_menu_rename (); void toggle_marker_menu_lock (); + void toggle_marker_menu_glue (); void marker_menu_hide (); void marker_menu_loop_range (); void marker_menu_select_all_selectables_using_range (); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 58bccf68d4..09a1573829 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -3504,7 +3504,7 @@ RangeMarkerBarDrag::start_grab (GdkEvent* event, Gdk::Cursor *) Gdk::Cursor* cursor = 0; if (!_editor->temp_location) { - _editor->temp_location = new Location; + _editor->temp_location = new Location (*_editor->session()); } switch (_operation) { @@ -3625,7 +3625,10 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred) flags = Location::IsRangeMarker; _editor->range_bar_drag_rect->hide(); } - newloc = new Location(_editor->temp_location->start(), _editor->temp_location->end(), rangename, (Location::Flags) flags); + newloc = new Location ( + *_editor->session(), _editor->temp_location->start(), _editor->temp_location->end(), rangename, (Location::Flags) flags + ); + _editor->session()->locations()->add (newloc, true); XMLNode &after = _editor->session()->locations()->get_state(); _editor->session()->add_command(new MementoCommand(*(_editor->session()->locations()), &before, &after)); diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index 87bc4b5138..23332047bd 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -413,7 +413,7 @@ Editor::mouse_add_new_marker (nframes64_t where, bool is_cd, bool is_xrun) if (!is_xrun && !choose_new_marker_name(markername)) { return; } - Location *location = new Location (where, where, markername, (Location::Flags) flags); + Location *location = new Location (*_session, where, where, markername, (Location::Flags) flags); _session->begin_reversible_command (_("add marker")); XMLNode &before = _session->locations()->get_state(); _session->locations()->add (location, true); @@ -628,6 +628,13 @@ Editor::build_marker_menu (bool session_range, Location* loc) lock_item->set_active (); } lock_item->signal_activate().connect (sigc::mem_fun (*this, &Editor::toggle_marker_menu_lock)); + + items.push_back (CheckMenuElem (_("Glue to Bars and Beats"))); + CheckMenuItem* glue_item = static_cast (&items.back()); + if (loc->position_lock_style() == MusicTime) { + glue_item->set_active (); + } + glue_item->signal_activate().connect (sigc::mem_fun (*this, &Editor::toggle_marker_menu_glue)); items.push_back (SeparatorElem()); @@ -867,7 +874,7 @@ Editor::marker_menu_range_to_next () string range_name = l->name(); range_name += "-range"; - Location* newrange = new Location (marker->position(), end, range_name, Location::IsRangeMarker); + Location* newrange = new Location (*_session, marker->position(), end, range_name, Location::IsRangeMarker); _session->locations()->add (newrange); } } @@ -1243,3 +1250,30 @@ Editor::goto_nth_marker (int n) } } } + +void +Editor::toggle_marker_menu_glue () +{ + Marker* marker; + + if ((marker = reinterpret_cast (marker_menu_item->get_data ("marker"))) == 0) { + fatal << _("programming error: marker canvas item has no marker object pointer!") << endmsg; + /*NOTREACHED*/ + } + + Location* loc; + bool ignored; + + loc = find_location_from_marker (marker, ignored); + + if (!loc) { + return; + } + + if (loc->position_lock_style() == MusicTime) { + loc->set_position_lock_style (AudioTime); + } else { + loc->set_position_lock_style (MusicTime); + } + +} diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index cb76fcb1ec..2eb3987b89 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -1904,7 +1904,7 @@ Editor::add_location_from_selection () nframes64_t end = selection->time[clicked_selection].end; _session->locations()->next_available_name(rangename,"selection"); - Location *location = new Location (start, end, rangename, Location::IsRangeMarker); + Location *location = new Location (*_session, start, end, rangename, Location::IsRangeMarker); _session->begin_reversible_command (_("add marker")); XMLNode &before = _session->locations()->get_state(); @@ -1925,7 +1925,7 @@ Editor::add_location_mark (nframes64_t where) if (!choose_new_marker_name(markername)) { return; } - Location *location = new Location (where, where, markername, Location::IsMark); + Location *location = new Location (*_session, where, where, markername, Location::IsMark); _session->begin_reversible_command (_("add marker")); XMLNode &before = _session->locations()->get_state(); _session->locations()->add (location, true); @@ -1958,7 +1958,7 @@ Editor::add_locations_from_audio_region () boost::shared_ptr region = (*i)->region (); - Location *location = new Location (region->position(), region->last_frame(), region->name(), Location::IsRangeMarker); + Location *location = new Location (*_session, region->position(), region->last_frame(), region->name(), Location::IsRangeMarker); _session->locations()->add (location, true); } @@ -1997,7 +1997,7 @@ Editor::add_location_from_audio_region () } // single range spanning all selected - Location *location = new Location (rs.start(), rs.end_frame(), markername, Location::IsRangeMarker); + Location *location = new Location (*_session, rs.start(), rs.end_frame(), markername, Location::IsRangeMarker); _session->locations()->add (location, true); XMLNode &after = _session->locations()->get_state(); @@ -2114,7 +2114,7 @@ Editor::set_mark () if (!choose_new_marker_name(markername)) { return; } - _session->locations()->add (new Location (pos, 0, markername, Location::IsMark), true); + _session->locations()->add (new Location (*_session, pos, 0, markername, Location::IsMark), true); } void diff --git a/gtk2_ardour/location_ui.cc b/gtk2_ardour/location_ui.cc index fda29be193..fb30450a54 100644 --- a/gtk2_ardour/location_ui.cc +++ b/gtk2_ardour/location_ui.cc @@ -829,7 +829,7 @@ LocationUI::add_new_location() if (_session) { nframes_t where = _session->audible_frame(); _session->locations()->next_available_name(markername,"mark"); - Location *location = new Location (where, where, markername, Location::IsMark); + Location *location = new Location (*_session, where, where, markername, Location::IsMark); if (Config->get_name_new_markers()) { newest_location = location; } @@ -851,7 +851,7 @@ LocationUI::add_new_range() if (_session) { nframes_t where = _session->audible_frame(); _session->locations()->next_available_name(rangename,"unnamed"); - Location *location = new Location (where, where, rangename, Location::IsRangeMarker); + Location *location = new Location (*_session, where, where, rangename, Location::IsRangeMarker); _session->begin_reversible_command (_("add range marker")); XMLNode &before = _session->locations()->get_state(); _session->locations()->add (location, true); diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h index 24387cdaef..cafcf38494 100644 --- a/libs/ardour/ardour/location.h +++ b/libs/ardour/ardour/location.h @@ -34,10 +34,11 @@ #include "pbd/statefuldestructible.h" #include "ardour/ardour.h" +#include "ardour/session_handle.h" namespace ARDOUR { -class Location : public PBD::StatefulDestructible +class Location : public SessionHandleRef, public PBD::StatefulDestructible { public: enum Flags { @@ -50,26 +51,10 @@ class Location : public PBD::StatefulDestructible IsSessionRange = 0x40 }; - Location (nframes64_t sample_start, - nframes64_t sample_end, - const std::string &name, - Flags bits = Flags(0)) - - : _name (name), - _start (sample_start), - _end (sample_end), - _flags (bits), - _locked (false) { } - - Location () { - _start = 0; - _end = 0; - _flags = Flags (0); - _locked = false; - } - + Location (Session &); + Location (Session &, nframes64_t, nframes64_t, const std::string &, Flags bits = Flags(0)); Location (const Location& other); - Location (const XMLNode&); + Location (Session &, const XMLNode&); Location* operator= (const Location& other); bool locked() const { return _locked; } @@ -80,9 +65,9 @@ class Location : public PBD::StatefulDestructible nframes64_t end() const { return _end; } nframes64_t length() const { return _end - _start; } - int set_start (nframes64_t s, bool force = false); - int set_end (nframes64_t e, bool force = false); - int set (nframes64_t start, nframes64_t end); + int set_start (nframes64_t s, bool force = false, bool allow_bbt_recompute = true); + int set_end (nframes64_t e, bool force = false, bool allow_bbt_recompute = true); + int set (nframes64_t start, nframes64_t end, bool allow_bbt_recompute = true); int move_to (nframes64_t pos); @@ -124,23 +109,31 @@ class Location : public PBD::StatefulDestructible XMLNode& get_state (void); int set_state (const XMLNode&, int version); + PositionLockStyle position_lock_style() const { return _position_lock_style; } + void set_position_lock_style (PositionLockStyle ps); + void recompute_frames_from_bbt (); + private: std::string _name; nframes64_t _start; + BBT_Time _bbt_start; nframes64_t _end; + BBT_Time _bbt_end; Flags _flags; bool _locked; + PositionLockStyle _position_lock_style; void set_mark (bool yn); bool set_flag_internal (bool yn, Flags flag); + void recompute_bbt_from_frames (); }; -class Locations : public PBD::StatefulDestructible +class Locations : public SessionHandleRef, public PBD::StatefulDestructible { public: typedef std::list LocationList; - Locations (); + Locations (Session &); ~Locations (); const LocationList& list() { return locations; } diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 7d822e64bc..5a7a692691 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -334,7 +334,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* Locations */ - Locations *locations() { return &_locations; } + Locations *locations() { return _locations; } PBD::Signal1 auto_loop_location_changed; PBD::Signal1 auto_punch_location_changed; @@ -1024,7 +1024,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void set_rf_speed (float speed); void reset_rf_scale (nframes_t frames_moved); - Locations _locations; + Locations* _locations; void locations_changed (); void locations_added (Location*); void handle_locations_changed (Locations::LocationList&); @@ -1428,6 +1428,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /** true if timecode transmission by the transport is suspended, otherwise false */ mutable gint _suspend_timecode_transmission; + + void update_locations_after_tempo_map_change (Locations::LocationList &); }; } // namespace ARDOUR diff --git a/libs/ardour/export_profile_manager.cc b/libs/ardour/export_profile_manager.cc index 53e6338a12..521f72747f 100644 --- a/libs/ardour/export_profile_manager.cc +++ b/libs/ardour/export_profile_manager.cc @@ -52,7 +52,7 @@ ExportProfileManager::ExportProfileManager (Session & s) : handler (s.get_export_handler()), session (s), - session_range (new Location ()), + session_range (new Location (s)), ranges (new LocationList ()), single_range_mode (false), @@ -286,7 +286,7 @@ ExportProfileManager::set_selection_range (nframes_t start, nframes_t end) { if (start || end) { - selection_range.reset (new Location()); + selection_range.reset (new Location (session)); selection_range->set_name (_("Selection")); selection_range->set (start, end); } else { @@ -303,7 +303,7 @@ ExportProfileManager::set_single_range (nframes_t start, nframes_t end, Glib::us { single_range_mode = true; - single_range.reset (new Location()); + single_range.reset (new Location (session)); single_range->set_name (name); single_range->set (start, end); diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc index 6fba55e16f..5828c57f65 100644 --- a/libs/ardour/location.cc +++ b/libs/ardour/location.cc @@ -25,7 +25,6 @@ #include #include - #include "pbd/stl_delete.h" #include "pbd/xml++.h" #include "pbd/enumwriter.h" @@ -33,6 +32,7 @@ #include "ardour/location.h" #include "ardour/session.h" #include "ardour/audiofilesource.h" +#include "ardour/tempo.h" #include "i18n.h" @@ -42,19 +42,47 @@ using namespace std; using namespace ARDOUR; using namespace PBD; +Location::Location (Session& s) + : SessionHandleRef (s) + , _start (0) + , _end (0) + , _flags (Flags (0)) + , _locked (false) + , _position_lock_style (AudioTime) +{ + +} + +Location::Location (Session& s, nframes64_t sample_start, nframes64_t sample_end, const std::string &name, Flags bits) + : SessionHandleRef (s) + , _name (name) + , _start (sample_start) + , _end (sample_end) + , _flags (bits) + , _locked (false) + , _position_lock_style (AudioTime) +{ + recompute_bbt_from_frames (); +} + Location::Location (const Location& other) - : StatefulDestructible(), - _name (other._name), - _start (other._start), - _end (other._end), - _flags (other._flags) + : SessionHandleRef (other._session) + , StatefulDestructible() + , _name (other._name) + , _start (other._start) + , _bbt_start (other._bbt_start) + , _end (other._end) + , _bbt_end (other._bbt_end) + , _flags (other._flags) + , _position_lock_style (other._position_lock_style) { /* copy is not locked even if original was */ _locked = false; } -Location::Location (const XMLNode& node) +Location::Location (Session& s, const XMLNode& node) + : SessionHandleRef (s) { if (set_state (node, Stateful::loading_state_version)) { throw failed_constructor (); @@ -70,8 +98,11 @@ Location::operator= (const Location& other) _name = other._name; _start = other._start; + _bbt_start = other._bbt_start; _end = other._end; + _bbt_end = other._bbt_end; _flags = other._flags; + _position_lock_style = other._position_lock_style; /* copy is not locked even if original was */ @@ -85,9 +116,10 @@ Location::operator= (const Location& other) /** Set start position. * @param s New start. * @param force true to force setting, even if the given new start is after the current end. + * @param allow_bbt_recompute True to recompute BBT start time from the new given start time. */ int -Location::set_start (nframes64_t s, bool force) +Location::set_start (nframes64_t s, bool force, bool allow_bbt_recompute) { if (_locked) { return -1; @@ -103,6 +135,9 @@ Location::set_start (nframes64_t s, bool force) if (_start != s) { _start = s; _end = s; + if (allow_bbt_recompute) { + recompute_bbt_from_frames (); + } start_changed (this); /* EMIT SIGNAL */ end_changed (this); /* EMIT SIGNAL */ } @@ -111,6 +146,9 @@ Location::set_start (nframes64_t s, bool force) if (s != _start) { _start = s; + if (allow_bbt_recompute) { + recompute_bbt_from_frames (); + } start_changed (this); /* EMIT SIGNAL */ if (is_session_range ()) { Session::StartTimeChanged (); /* EMIT SIGNAL */ @@ -124,9 +162,10 @@ Location::set_start (nframes64_t s, bool force) /** Set end position. * @param s New end. * @param force true to force setting, even if the given new start is after the current end. + * @param allow_bbt_recompute True to recompute BBT end time from the new given end time. */ int -Location::set_end (nframes64_t e, bool force) +Location::set_end (nframes64_t e, bool force, bool allow_bbt_recompute) { if (_locked) { return -1; @@ -142,6 +181,9 @@ Location::set_end (nframes64_t e, bool force) if (_start != e) { _start = e; _end = e; + if (allow_bbt_recompute) { + recompute_bbt_from_frames (); + } start_changed (this); /* EMIT SIGNAL */ end_changed (this); /* EMIT SIGNAL */ } @@ -150,6 +192,9 @@ Location::set_end (nframes64_t e, bool force) if (e != _end) { _end = e; + if (allow_bbt_recompute) { + recompute_bbt_from_frames (); + } end_changed(this); /* EMIT SIGNAL */ if (is_session_range()) { @@ -161,7 +206,7 @@ Location::set_end (nframes64_t e, bool force) } int -Location::set (nframes64_t start, nframes64_t end) +Location::set (nframes64_t start, nframes64_t end, bool allow_bbt_recompute) { /* check validity */ if (((is_auto_punch() || is_auto_loop()) && start >= end) || (!is_mark() && start > end)) { @@ -169,8 +214,8 @@ Location::set (nframes64_t start, nframes64_t end) } /* now we know these values are ok, so force-set them */ - int const s = set_start (start, true); - int const e = set_end (end, true); + int const s = set_start (start, true, allow_bbt_recompute); + int const e = set_end (end, true, allow_bbt_recompute); return (s == 0 && e == 0) ? 0 : -1; } @@ -185,6 +230,7 @@ Location::move_to (nframes64_t pos) if (_start != pos) { _start = pos; _end = _start + length(); + recompute_bbt_from_frames (); changed (this); /* EMIT SIGNAL */ } @@ -291,7 +337,7 @@ Location::cd_info_node(const string & name, const string & value) XMLNode& -Location::get_state (void) +Location::get_state () { XMLNode *node = new XMLNode ("Location"); char buf[64]; @@ -401,15 +447,51 @@ Location::set_state (const XMLNode& node, int /*version*/) } - changed(this); /* EMIT SIGNAL */ + recompute_bbt_from_frames (); + + changed (this); /* EMIT SIGNAL */ return 0; } +void +Location::set_position_lock_style (PositionLockStyle ps) +{ + if (_position_lock_style == ps) { + return; + } + + _position_lock_style = ps; + + recompute_bbt_from_frames (); +} + +void +Location::recompute_bbt_from_frames () +{ + if (_position_lock_style != MusicTime) { + return; + } + + _session.tempo_map().bbt_time (_start, _bbt_start); + _session.tempo_map().bbt_time (_end, _bbt_end); +} + +void +Location::recompute_frames_from_bbt () +{ + if (_position_lock_style != MusicTime) { + return; + } + + TempoMap& map (_session.tempo_map()); + set (map.frame_time (_bbt_start), map.frame_time (_bbt_end), false); +} + /*---------------------------------------------------------------------- */ -Locations::Locations () - +Locations::Locations (Session& s) + : SessionHandleRef (s) { current_location = 0; } @@ -426,7 +508,6 @@ Locations::~Locations () int Locations::set_current (Location *loc, bool want_lock) - { int ret; @@ -658,7 +739,7 @@ Locations::set_state (const XMLNode& node, int version) Location* session_range_location = 0; if (version < 3000) { - session_range_location = new Location (0, 0, _("session"), Location::IsSessionRange); + session_range_location = new Location (_session, 0, 0, _("session"), Location::IsSessionRange); locations.push_back (session_range_location); } @@ -670,7 +751,7 @@ Locations::set_state (const XMLNode& node, int version) try { - Location *loc = new Location (**niter); + Location *loc = new Location (_session, **niter); bool add = true; diff --git a/libs/ardour/location_importer.cc b/libs/ardour/location_importer.cc index 8d6af300ca..1674616096 100644 --- a/libs/ardour/location_importer.cc +++ b/libs/ardour/location_importer.cc @@ -133,7 +133,7 @@ bool LocationImporter::_prepare_move () { try { - Location const original (xml_location); + Location const original (session, xml_location); location = new Location (original); // Updates id } catch (failed_constructor& err) { throw std::runtime_error (X_("Error in session file!")); diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 7978123695..2989e14afa 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -157,6 +157,8 @@ Session::Session (AudioEngine &eng, _have_rec_enabled_track (false), _suspend_timecode_transmission (0) { + _locations = new Locations (*this); + playlists.reset (new SessionPlaylists); interpolation.add_channel_to (0, 0); @@ -313,6 +315,8 @@ Session::destroy () boost_debug_list_ptrs (); + delete _locations; + DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n"); } @@ -871,7 +875,7 @@ Session::set_auto_punch_location (Location* location) { Location* existing; - if ((existing = _locations.auto_punch_location()) != 0 && existing != location) { + if ((existing = _locations->auto_punch_location()) != 0 && existing != location) { punch_connections.drop_connections(); existing->set_auto_punch (false, this); remove_event (existing->start(), SessionEvent::PunchIn); @@ -908,7 +912,7 @@ Session::set_auto_loop_location (Location* location) { Location* existing; - if ((existing = _locations.auto_loop_location()) != 0 && existing != location) { + if ((existing = _locations->auto_loop_location()) != 0 && existing != location) { loop_connections.drop_connections (); existing->set_auto_loop (false, this); remove_event (existing->end(), SessionEvent::AutoLoop); @@ -954,7 +958,7 @@ Session::locations_added (Location *) void Session::locations_changed () { - _locations.apply (*this, &Session::handle_locations_changed); + _locations->apply (*this, &Session::handle_locations_changed); } void @@ -3262,9 +3266,19 @@ Session::tempo_map_changed (const PropertyChange&) playlists->update_after_tempo_map_change (); + _locations->apply (*this, &Session::update_locations_after_tempo_map_change); + set_dirty (); } +void +Session::update_locations_after_tempo_map_change (Locations::LocationList& loc) +{ + for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) { + (*i)->recompute_frames_from_bbt (); + } +} + /** Ensures that all buffers (scratch, send, silent, etc) are allocated for * the given count with the current block size. */ @@ -3968,8 +3982,8 @@ Session::current_end_frame () const void Session::add_session_range_location (nframes_t start, nframes_t end) { - _session_range_location = new Location (start, end, _("session"), Location::IsSessionRange); - _locations.add (_session_range_location); + _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange); + _locations->add (_session_range_location); } /** Called when one of our routes' order keys has changed */ diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc index dc918dfe1c..8d3ce793bc 100644 --- a/libs/ardour/session_command.cc +++ b/libs/ardour/session_command.cc @@ -103,13 +103,13 @@ Session::memento_command_factory(XMLNode *n) return new MementoCommand(*sources[id], before, after); } else if (obj_T == "ARDOUR::Location") { - Location* loc = _locations.get_location_by_id(id); + Location* loc = _locations->get_location_by_id(id); if (loc) { return new MementoCommand(*loc, before, after); } } else if (obj_T == "ARDOUR::Locations") { - return new MementoCommand(_locations, before, after); + return new MementoCommand(*_locations, before, after); } else if (obj_T == "ARDOUR::TempoMap") { return new MementoCommand(*_tempo_map, before, after); diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index f4f2c5ad0e..6889e714fd 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -608,7 +608,7 @@ Session::track_slave_state (float slave_speed, nframes_t slave_transport_frame, _slave_state = Running; - Location* al = _locations.auto_loop_location(); + Location* al = _locations->auto_loop_location(); if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) { // cancel looping diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 94ea4bb2a1..a2dc6ced68 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -325,8 +325,8 @@ Session::second_stage_init () _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading); - _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this)); - _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1)); + _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this)); + _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1)); setup_click_sounds (0); setup_midi_control (); @@ -1094,12 +1094,12 @@ Session::state(bool full_state) } if (full_state) { - node->add_child_nocopy (_locations.get_state()); + node->add_child_nocopy (_locations->get_state()); } else { // for a template, just create a new Locations, populate it // with the default start and end, and get the state for that. - Locations loc; - Location* range = new Location (0, 0, _("session"), Location::IsSessionRange); + Locations loc (*this); + Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange); range->set (max_frames, 0); loc.add (range); node->add_child_nocopy (loc.get_state()); @@ -1278,21 +1278,21 @@ Session::set_state (const XMLNode& node, int version) if ((child = find_named_node (node, "Locations")) == 0) { error << _("Session: XML state has no locations section") << endmsg; goto out; - } else if (_locations.set_state (*child, version)) { + } else if (_locations->set_state (*child, version)) { goto out; } Location* location; - if ((location = _locations.auto_loop_location()) != 0) { + if ((location = _locations->auto_loop_location()) != 0) { set_auto_loop_location (location); } - if ((location = _locations.auto_punch_location()) != 0) { + if ((location = _locations->auto_punch_location()) != 0) { set_auto_punch_location (location); } - if ((location = _locations.session_range_location()) != 0) { + if ((location = _locations->session_range_location()) != 0) { delete _session_range_location; _session_range_location = location; } @@ -3165,7 +3165,7 @@ Session::config_changed (std::string p, bool ours) Location* location; - if ((location = _locations.auto_punch_location()) != 0) { + if ((location = _locations->auto_punch_location()) != 0) { if (config.get_punch_in ()) { replace_event (SessionEvent::PunchIn, location->start()); @@ -3178,7 +3178,7 @@ Session::config_changed (std::string p, bool ours) Location* location; - if ((location = _locations.auto_punch_location()) != 0) { + if ((location = _locations->auto_punch_location()) != 0) { if (config.get_punch_out()) { replace_event (SessionEvent::PunchOut, location->end()); diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index b722bc04a7..64f9d1e616 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -142,7 +142,7 @@ void Session::request_play_loop (bool yn, bool leave_rolling) { SessionEvent* ev; - Location *location = _locations.auto_loop_location(); + Location *location = _locations->auto_loop_location(); if (location == 0 && yn) { error << _("Cannot loop - no loop range defined") @@ -503,7 +503,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) if (!synced_to_jack()) { - Location *location = _locations.auto_loop_location(); + Location *location = _locations->auto_loop_location(); if (location != 0) { _transport_frame = location->start(); @@ -653,7 +653,7 @@ Session::set_play_loop (bool yn) Location *loc; - if (yn == play_loop || (actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) { + if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) { /* nothing to do, or can't change loop status while recording */ return; } @@ -873,7 +873,7 @@ Session::locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool /* cancel looped playback if transport pos outside of loop range */ if (play_loop) { - Location* al = _locations.auto_loop_location(); + Location* al = _locations->auto_loop_location(); if (al && (_transport_frame < al->start() || _transport_frame > al->end())) { // cancel looping directly, this is called from event handling context diff --git a/libs/surfaces/control_protocol/basic_ui.cc b/libs/surfaces/control_protocol/basic_ui.cc index 2c3305e66f..2bea3b529c 100644 --- a/libs/surfaces/control_protocol/basic_ui.cc +++ b/libs/surfaces/control_protocol/basic_ui.cc @@ -95,7 +95,7 @@ void BasicUI::add_marker () { nframes_t when = session->audible_frame(); - session->locations()->add (new Location (when, when, _("unnamed"), Location::IsMark)); + session->locations()->add (new Location (*session, when, when, _("unnamed"), Location::IsMark)); } void diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index e9f3223796..72827e9fc9 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -1601,7 +1601,7 @@ MackieControlProtocol::marker_press (Button &) string markername; nframes_t where = session->audible_frame(); session->locations()->next_available_name(markername,"mcu"); - Location *location = new Location (where, where, markername, Location::IsMark); + Location *location = new Location (*session, where, where, markername, Location::IsMark); session->begin_reversible_command (_("add marker")); XMLNode &before = session->locations()->get_state(); session->locations()->add (location, true);