summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-08-09 16:40:31 +0000
committerCarl Hetherington <carl@carlh.net>2010-08-09 16:40:31 +0000
commit5b520324ceab2559723b4ef5127301fa61ff4846 (patch)
tree13850a356fabdcbd55ca527fc5faf2fda63cb209
parentaa9fd3334976ceae7e164c3fabc87e55fc921dff (diff)
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
-rw-r--r--gtk2_ardour/editor.cc8
-rw-r--r--gtk2_ardour/editor.h1
-rw-r--r--gtk2_ardour/editor_drag.cc7
-rw-r--r--gtk2_ardour/editor_markers.cc38
-rw-r--r--gtk2_ardour/editor_ops.cc10
-rw-r--r--gtk2_ardour/location_ui.cc4
-rw-r--r--libs/ardour/ardour/location.h43
-rw-r--r--libs/ardour/ardour/session.h6
-rw-r--r--libs/ardour/export_profile_manager.cc6
-rw-r--r--libs/ardour/location.cc119
-rw-r--r--libs/ardour/location_importer.cc2
-rw-r--r--libs/ardour/session.cc24
-rw-r--r--libs/ardour/session_command.cc4
-rw-r--r--libs/ardour/session_process.cc2
-rw-r--r--libs/ardour/session_state.cc22
-rw-r--r--libs/ardour/session_transport.cc8
-rw-r--r--libs/surfaces/control_protocol/basic_ui.cc2
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc2
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<Locations>(*(_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<CheckMenuItem*> (&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 *> (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> 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<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
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);