diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/location.h | 43 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 6 | ||||
-rw-r--r-- | libs/ardour/export_profile_manager.cc | 6 | ||||
-rw-r--r-- | libs/ardour/location.cc | 119 | ||||
-rw-r--r-- | libs/ardour/location_importer.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session.cc | 24 | ||||
-rw-r--r-- | libs/ardour/session_command.cc | 4 | ||||
-rw-r--r-- | libs/ardour/session_process.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 22 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 8 |
10 files changed, 163 insertions, 73 deletions
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<Location *> 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<void,Location*> auto_loop_location_changed; PBD::Signal1<void,Location*> 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 <ctime> #include <list> - #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; + } -Locations::Locations () + _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 (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<Source>(*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<Location>(*loc, before, after); } } else if (obj_T == "ARDOUR::Locations") { - return new MementoCommand<Locations>(_locations, before, after); + return new MementoCommand<Locations>(*_locations, before, after); } else if (obj_T == "ARDOUR::TempoMap") { return new MementoCommand<TempoMap>(*_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 |