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
This commit is contained in:
Carl Hetherington 2010-08-09 16:40:31 +00:00
parent aa9fd33349
commit 5b520324ce
18 changed files with 218 additions and 90 deletions

View file

@ -1135,7 +1135,7 @@ Editor::set_session (Session *t)
Location* loc = _session->locations()->auto_loop_location(); Location* loc = _session->locations()->auto_loop_location();
if (loc == 0) { 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()) { if (loc->start() == loc->end()) {
loc->set_end (loc->start() + 1); loc->set_end (loc->start() + 1);
} }
@ -1148,7 +1148,7 @@ Editor::set_session (Session *t)
loc = _session->locations()->auto_punch_location(); loc = _session->locations()->auto_punch_location();
if (loc == 0) { 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()) { if (loc->start() == loc->end()) {
loc->set_end (loc->start() + 1); loc->set_end (loc->start() + 1);
} }
@ -4602,7 +4602,7 @@ Editor::set_loop_range (nframes64_t start, nframes64_t end, string cmd)
Location* tll; Location* tll;
if ((tll = transport_loop_location()) == 0) { 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(); XMLNode &before = _session->locations()->get_state();
_session->locations()->add (loc, true); _session->locations()->add (loc, true);
_session->set_auto_loop_location (loc); _session->set_auto_loop_location (loc);
@ -4629,7 +4629,7 @@ Editor::set_punch_range (nframes64_t start, nframes64_t end, string cmd)
Location* tpl; Location* tpl;
if ((tpl = transport_punch_location()) == 0) { 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(); XMLNode &before = _session->locations()->get_state();
_session->locations()->add (loc, true); _session->locations()->add (loc, true);
_session->set_auto_loop_location (loc); _session->set_auto_loop_location (loc);

View file

@ -1465,6 +1465,7 @@ public:
void marker_menu_remove (); void marker_menu_remove ();
void marker_menu_rename (); void marker_menu_rename ();
void toggle_marker_menu_lock (); void toggle_marker_menu_lock ();
void toggle_marker_menu_glue ();
void marker_menu_hide (); void marker_menu_hide ();
void marker_menu_loop_range (); void marker_menu_loop_range ();
void marker_menu_select_all_selectables_using_range (); void marker_menu_select_all_selectables_using_range ();

View file

@ -3504,7 +3504,7 @@ RangeMarkerBarDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
Gdk::Cursor* cursor = 0; Gdk::Cursor* cursor = 0;
if (!_editor->temp_location) { if (!_editor->temp_location) {
_editor->temp_location = new Location; _editor->temp_location = new Location (*_editor->session());
} }
switch (_operation) { switch (_operation) {
@ -3625,7 +3625,10 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
flags = Location::IsRangeMarker; flags = Location::IsRangeMarker;
_editor->range_bar_drag_rect->hide(); _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); _editor->session()->locations()->add (newloc, true);
XMLNode &after = _editor->session()->locations()->get_state(); XMLNode &after = _editor->session()->locations()->get_state();
_editor->session()->add_command(new MementoCommand<Locations>(*(_editor->session()->locations()), &before, &after)); _editor->session()->add_command(new MementoCommand<Locations>(*(_editor->session()->locations()), &before, &after));

View file

@ -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)) { if (!is_xrun && !choose_new_marker_name(markername)) {
return; 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")); _session->begin_reversible_command (_("add marker"));
XMLNode &before = _session->locations()->get_state(); XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true); _session->locations()->add (location, true);
@ -628,6 +628,13 @@ Editor::build_marker_menu (bool session_range, Location* loc)
lock_item->set_active (); lock_item->set_active ();
} }
lock_item->signal_activate().connect (sigc::mem_fun (*this, &Editor::toggle_marker_menu_lock)); 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()); items.push_back (SeparatorElem());
@ -867,7 +874,7 @@ Editor::marker_menu_range_to_next ()
string range_name = l->name(); string range_name = l->name();
range_name += "-range"; 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); _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);
}
}

View file

@ -1904,7 +1904,7 @@ Editor::add_location_from_selection ()
nframes64_t end = selection->time[clicked_selection].end; nframes64_t end = selection->time[clicked_selection].end;
_session->locations()->next_available_name(rangename,"selection"); _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")); _session->begin_reversible_command (_("add marker"));
XMLNode &before = _session->locations()->get_state(); XMLNode &before = _session->locations()->get_state();
@ -1925,7 +1925,7 @@ Editor::add_location_mark (nframes64_t where)
if (!choose_new_marker_name(markername)) { if (!choose_new_marker_name(markername)) {
return; 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")); _session->begin_reversible_command (_("add marker"));
XMLNode &before = _session->locations()->get_state(); XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true); _session->locations()->add (location, true);
@ -1958,7 +1958,7 @@ Editor::add_locations_from_audio_region ()
boost::shared_ptr<Region> region = (*i)->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); _session->locations()->add (location, true);
} }
@ -1997,7 +1997,7 @@ Editor::add_location_from_audio_region ()
} }
// single range spanning all selected // 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); _session->locations()->add (location, true);
XMLNode &after = _session->locations()->get_state(); XMLNode &after = _session->locations()->get_state();
@ -2114,7 +2114,7 @@ Editor::set_mark ()
if (!choose_new_marker_name(markername)) { if (!choose_new_marker_name(markername)) {
return; 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 void

View file

@ -829,7 +829,7 @@ LocationUI::add_new_location()
if (_session) { if (_session) {
nframes_t where = _session->audible_frame(); nframes_t where = _session->audible_frame();
_session->locations()->next_available_name(markername,"mark"); _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()) { if (Config->get_name_new_markers()) {
newest_location = location; newest_location = location;
} }
@ -851,7 +851,7 @@ LocationUI::add_new_range()
if (_session) { if (_session) {
nframes_t where = _session->audible_frame(); nframes_t where = _session->audible_frame();
_session->locations()->next_available_name(rangename,"unnamed"); _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")); _session->begin_reversible_command (_("add range marker"));
XMLNode &before = _session->locations()->get_state(); XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true); _session->locations()->add (location, true);

View file

@ -34,10 +34,11 @@
#include "pbd/statefuldestructible.h" #include "pbd/statefuldestructible.h"
#include "ardour/ardour.h" #include "ardour/ardour.h"
#include "ardour/session_handle.h"
namespace ARDOUR { namespace ARDOUR {
class Location : public PBD::StatefulDestructible class Location : public SessionHandleRef, public PBD::StatefulDestructible
{ {
public: public:
enum Flags { enum Flags {
@ -50,26 +51,10 @@ class Location : public PBD::StatefulDestructible
IsSessionRange = 0x40 IsSessionRange = 0x40
}; };
Location (nframes64_t sample_start, Location (Session &);
nframes64_t sample_end, Location (Session &, nframes64_t, nframes64_t, const std::string &, Flags bits = Flags(0));
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 (const Location& other); Location (const Location& other);
Location (const XMLNode&); Location (Session &, const XMLNode&);
Location* operator= (const Location& other); Location* operator= (const Location& other);
bool locked() const { return _locked; } bool locked() const { return _locked; }
@ -80,9 +65,9 @@ class Location : public PBD::StatefulDestructible
nframes64_t end() const { return _end; } nframes64_t end() const { return _end; }
nframes64_t length() const { return _end - _start; } nframes64_t length() const { return _end - _start; }
int set_start (nframes64_t s, bool force = false); int set_start (nframes64_t s, bool force = false, bool allow_bbt_recompute = true);
int set_end (nframes64_t e, bool force = false); int set_end (nframes64_t e, bool force = false, bool allow_bbt_recompute = true);
int set (nframes64_t start, nframes64_t end); int set (nframes64_t start, nframes64_t end, bool allow_bbt_recompute = true);
int move_to (nframes64_t pos); int move_to (nframes64_t pos);
@ -124,23 +109,31 @@ class Location : public PBD::StatefulDestructible
XMLNode& get_state (void); XMLNode& get_state (void);
int set_state (const XMLNode&, int version); 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: private:
std::string _name; std::string _name;
nframes64_t _start; nframes64_t _start;
BBT_Time _bbt_start;
nframes64_t _end; nframes64_t _end;
BBT_Time _bbt_end;
Flags _flags; Flags _flags;
bool _locked; bool _locked;
PositionLockStyle _position_lock_style;
void set_mark (bool yn); void set_mark (bool yn);
bool set_flag_internal (bool yn, Flags flag); 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: public:
typedef std::list<Location *> LocationList; typedef std::list<Location *> LocationList;
Locations (); Locations (Session &);
~Locations (); ~Locations ();
const LocationList& list() { return locations; } const LocationList& list() { return locations; }

View file

@ -334,7 +334,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
/* Locations */ /* Locations */
Locations *locations() { return &_locations; } Locations *locations() { return _locations; }
PBD::Signal1<void,Location*> auto_loop_location_changed; PBD::Signal1<void,Location*> auto_loop_location_changed;
PBD::Signal1<void,Location*> auto_punch_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 set_rf_speed (float speed);
void reset_rf_scale (nframes_t frames_moved); void reset_rf_scale (nframes_t frames_moved);
Locations _locations; Locations* _locations;
void locations_changed (); void locations_changed ();
void locations_added (Location*); void locations_added (Location*);
void handle_locations_changed (Locations::LocationList&); 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 */ /** true if timecode transmission by the transport is suspended, otherwise false */
mutable gint _suspend_timecode_transmission; mutable gint _suspend_timecode_transmission;
void update_locations_after_tempo_map_change (Locations::LocationList &);
}; };
} // namespace ARDOUR } // namespace ARDOUR

View file

@ -52,7 +52,7 @@ ExportProfileManager::ExportProfileManager (Session & s) :
handler (s.get_export_handler()), handler (s.get_export_handler()),
session (s), session (s),
session_range (new Location ()), session_range (new Location (s)),
ranges (new LocationList ()), ranges (new LocationList ()),
single_range_mode (false), single_range_mode (false),
@ -286,7 +286,7 @@ ExportProfileManager::set_selection_range (nframes_t start, nframes_t end)
{ {
if (start || end) { if (start || end) {
selection_range.reset (new Location()); selection_range.reset (new Location (session));
selection_range->set_name (_("Selection")); selection_range->set_name (_("Selection"));
selection_range->set (start, end); selection_range->set (start, end);
} else { } else {
@ -303,7 +303,7 @@ ExportProfileManager::set_single_range (nframes_t start, nframes_t end, Glib::us
{ {
single_range_mode = true; single_range_mode = true;
single_range.reset (new Location()); single_range.reset (new Location (session));
single_range->set_name (name); single_range->set_name (name);
single_range->set (start, end); single_range->set (start, end);

View file

@ -25,7 +25,6 @@
#include <ctime> #include <ctime>
#include <list> #include <list>
#include "pbd/stl_delete.h" #include "pbd/stl_delete.h"
#include "pbd/xml++.h" #include "pbd/xml++.h"
#include "pbd/enumwriter.h" #include "pbd/enumwriter.h"
@ -33,6 +32,7 @@
#include "ardour/location.h" #include "ardour/location.h"
#include "ardour/session.h" #include "ardour/session.h"
#include "ardour/audiofilesource.h" #include "ardour/audiofilesource.h"
#include "ardour/tempo.h"
#include "i18n.h" #include "i18n.h"
@ -42,19 +42,47 @@ using namespace std;
using namespace ARDOUR; using namespace ARDOUR;
using namespace PBD; 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) Location::Location (const Location& other)
: StatefulDestructible(), : SessionHandleRef (other._session)
_name (other._name), , StatefulDestructible()
_start (other._start), , _name (other._name)
_end (other._end), , _start (other._start)
_flags (other._flags) , _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 */ /* copy is not locked even if original was */
_locked = false; _locked = false;
} }
Location::Location (const XMLNode& node) Location::Location (Session& s, const XMLNode& node)
: SessionHandleRef (s)
{ {
if (set_state (node, Stateful::loading_state_version)) { if (set_state (node, Stateful::loading_state_version)) {
throw failed_constructor (); throw failed_constructor ();
@ -70,8 +98,11 @@ Location::operator= (const Location& other)
_name = other._name; _name = other._name;
_start = other._start; _start = other._start;
_bbt_start = other._bbt_start;
_end = other._end; _end = other._end;
_bbt_end = other._bbt_end;
_flags = other._flags; _flags = other._flags;
_position_lock_style = other._position_lock_style;
/* copy is not locked even if original was */ /* copy is not locked even if original was */
@ -85,9 +116,10 @@ Location::operator= (const Location& other)
/** Set start position. /** Set start position.
* @param s New start. * @param s New start.
* @param force true to force setting, even if the given new start is after the current 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 start time from the new given start time.
*/ */
int int
Location::set_start (nframes64_t s, bool force) Location::set_start (nframes64_t s, bool force, bool allow_bbt_recompute)
{ {
if (_locked) { if (_locked) {
return -1; return -1;
@ -103,6 +135,9 @@ Location::set_start (nframes64_t s, bool force)
if (_start != s) { if (_start != s) {
_start = s; _start = s;
_end = s; _end = s;
if (allow_bbt_recompute) {
recompute_bbt_from_frames ();
}
start_changed (this); /* EMIT SIGNAL */ start_changed (this); /* EMIT SIGNAL */
end_changed (this); /* EMIT SIGNAL */ end_changed (this); /* EMIT SIGNAL */
} }
@ -111,6 +146,9 @@ Location::set_start (nframes64_t s, bool force)
if (s != _start) { if (s != _start) {
_start = s; _start = s;
if (allow_bbt_recompute) {
recompute_bbt_from_frames ();
}
start_changed (this); /* EMIT SIGNAL */ start_changed (this); /* EMIT SIGNAL */
if (is_session_range ()) { if (is_session_range ()) {
Session::StartTimeChanged (); /* EMIT SIGNAL */ Session::StartTimeChanged (); /* EMIT SIGNAL */
@ -124,9 +162,10 @@ Location::set_start (nframes64_t s, bool force)
/** Set end position. /** Set end position.
* @param s New end. * @param s New end.
* @param force true to force setting, even if the given new start is after the current 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 int
Location::set_end (nframes64_t e, bool force) Location::set_end (nframes64_t e, bool force, bool allow_bbt_recompute)
{ {
if (_locked) { if (_locked) {
return -1; return -1;
@ -142,6 +181,9 @@ Location::set_end (nframes64_t e, bool force)
if (_start != e) { if (_start != e) {
_start = e; _start = e;
_end = e; _end = e;
if (allow_bbt_recompute) {
recompute_bbt_from_frames ();
}
start_changed (this); /* EMIT SIGNAL */ start_changed (this); /* EMIT SIGNAL */
end_changed (this); /* EMIT SIGNAL */ end_changed (this); /* EMIT SIGNAL */
} }
@ -150,6 +192,9 @@ Location::set_end (nframes64_t e, bool force)
if (e != _end) { if (e != _end) {
_end = e; _end = e;
if (allow_bbt_recompute) {
recompute_bbt_from_frames ();
}
end_changed(this); /* EMIT SIGNAL */ end_changed(this); /* EMIT SIGNAL */
if (is_session_range()) { if (is_session_range()) {
@ -161,7 +206,7 @@ Location::set_end (nframes64_t e, bool force)
} }
int int
Location::set (nframes64_t start, nframes64_t end) Location::set (nframes64_t start, nframes64_t end, bool allow_bbt_recompute)
{ {
/* check validity */ /* check validity */
if (((is_auto_punch() || is_auto_loop()) && start >= end) || (!is_mark() && start > end)) { 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 */ /* now we know these values are ok, so force-set them */
int const s = set_start (start, true); int const s = set_start (start, true, allow_bbt_recompute);
int const e = set_end (end, true); int const e = set_end (end, true, allow_bbt_recompute);
return (s == 0 && e == 0) ? 0 : -1; return (s == 0 && e == 0) ? 0 : -1;
} }
@ -185,6 +230,7 @@ Location::move_to (nframes64_t pos)
if (_start != pos) { if (_start != pos) {
_start = pos; _start = pos;
_end = _start + length(); _end = _start + length();
recompute_bbt_from_frames ();
changed (this); /* EMIT SIGNAL */ changed (this); /* EMIT SIGNAL */
} }
@ -291,7 +337,7 @@ Location::cd_info_node(const string & name, const string & value)
XMLNode& XMLNode&
Location::get_state (void) Location::get_state ()
{ {
XMLNode *node = new XMLNode ("Location"); XMLNode *node = new XMLNode ("Location");
char buf[64]; 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; 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; current_location = 0;
} }
@ -426,7 +508,6 @@ Locations::~Locations ()
int int
Locations::set_current (Location *loc, bool want_lock) Locations::set_current (Location *loc, bool want_lock)
{ {
int ret; int ret;
@ -658,7 +739,7 @@ Locations::set_state (const XMLNode& node, int version)
Location* session_range_location = 0; Location* session_range_location = 0;
if (version < 3000) { 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); locations.push_back (session_range_location);
} }
@ -670,7 +751,7 @@ Locations::set_state (const XMLNode& node, int version)
try { try {
Location *loc = new Location (**niter); Location *loc = new Location (_session, **niter);
bool add = true; bool add = true;

View file

@ -133,7 +133,7 @@ bool
LocationImporter::_prepare_move () LocationImporter::_prepare_move ()
{ {
try { try {
Location const original (xml_location); Location const original (session, xml_location);
location = new Location (original); // Updates id location = new Location (original); // Updates id
} catch (failed_constructor& err) { } catch (failed_constructor& err) {
throw std::runtime_error (X_("Error in session file!")); throw std::runtime_error (X_("Error in session file!"));

View file

@ -157,6 +157,8 @@ Session::Session (AudioEngine &eng,
_have_rec_enabled_track (false), _have_rec_enabled_track (false),
_suspend_timecode_transmission (0) _suspend_timecode_transmission (0)
{ {
_locations = new Locations (*this);
playlists.reset (new SessionPlaylists); playlists.reset (new SessionPlaylists);
interpolation.add_channel_to (0, 0); interpolation.add_channel_to (0, 0);
@ -313,6 +315,8 @@ Session::destroy ()
boost_debug_list_ptrs (); boost_debug_list_ptrs ();
delete _locations;
DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n"); DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
} }
@ -871,7 +875,7 @@ Session::set_auto_punch_location (Location* location)
{ {
Location* existing; Location* existing;
if ((existing = _locations.auto_punch_location()) != 0 && existing != location) { if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
punch_connections.drop_connections(); punch_connections.drop_connections();
existing->set_auto_punch (false, this); existing->set_auto_punch (false, this);
remove_event (existing->start(), SessionEvent::PunchIn); remove_event (existing->start(), SessionEvent::PunchIn);
@ -908,7 +912,7 @@ Session::set_auto_loop_location (Location* location)
{ {
Location* existing; Location* existing;
if ((existing = _locations.auto_loop_location()) != 0 && existing != location) { if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
loop_connections.drop_connections (); loop_connections.drop_connections ();
existing->set_auto_loop (false, this); existing->set_auto_loop (false, this);
remove_event (existing->end(), SessionEvent::AutoLoop); remove_event (existing->end(), SessionEvent::AutoLoop);
@ -954,7 +958,7 @@ Session::locations_added (Location *)
void void
Session::locations_changed () Session::locations_changed ()
{ {
_locations.apply (*this, &Session::handle_locations_changed); _locations->apply (*this, &Session::handle_locations_changed);
} }
void void
@ -3262,9 +3266,19 @@ Session::tempo_map_changed (const PropertyChange&)
playlists->update_after_tempo_map_change (); playlists->update_after_tempo_map_change ();
_locations->apply (*this, &Session::update_locations_after_tempo_map_change);
set_dirty (); 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 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
* the given count with the current block size. * the given count with the current block size.
*/ */
@ -3968,8 +3982,8 @@ Session::current_end_frame () const
void void
Session::add_session_range_location (nframes_t start, nframes_t end) Session::add_session_range_location (nframes_t start, nframes_t end)
{ {
_session_range_location = new Location (start, end, _("session"), Location::IsSessionRange); _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
_locations.add (_session_range_location); _locations->add (_session_range_location);
} }
/** Called when one of our routes' order keys has changed */ /** Called when one of our routes' order keys has changed */

View file

@ -103,13 +103,13 @@ Session::memento_command_factory(XMLNode *n)
return new MementoCommand<Source>(*sources[id], before, after); return new MementoCommand<Source>(*sources[id], before, after);
} else if (obj_T == "ARDOUR::Location") { } else if (obj_T == "ARDOUR::Location") {
Location* loc = _locations.get_location_by_id(id); Location* loc = _locations->get_location_by_id(id);
if (loc) { if (loc) {
return new MementoCommand<Location>(*loc, before, after); return new MementoCommand<Location>(*loc, before, after);
} }
} else if (obj_T == "ARDOUR::Locations") { } 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") { } else if (obj_T == "ARDOUR::TempoMap") {
return new MementoCommand<TempoMap>(*_tempo_map, before, after); return new MementoCommand<TempoMap>(*_tempo_map, before, after);

View file

@ -608,7 +608,7 @@ Session::track_slave_state (float slave_speed, nframes_t slave_transport_frame,
_slave_state = Running; _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())) { if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
// cancel looping // cancel looping

View file

@ -325,8 +325,8 @@ Session::second_stage_init ()
_state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading); _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
_locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this)); _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->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
setup_click_sounds (0); setup_click_sounds (0);
setup_midi_control (); setup_midi_control ();
@ -1094,12 +1094,12 @@ Session::state(bool full_state)
} }
if (full_state) { if (full_state) {
node->add_child_nocopy (_locations.get_state()); node->add_child_nocopy (_locations->get_state());
} else { } else {
// for a template, just create a new Locations, populate it // for a template, just create a new Locations, populate it
// with the default start and end, and get the state for that. // with the default start and end, and get the state for that.
Locations loc; Locations loc (*this);
Location* range = new Location (0, 0, _("session"), Location::IsSessionRange); Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
range->set (max_frames, 0); range->set (max_frames, 0);
loc.add (range); loc.add (range);
node->add_child_nocopy (loc.get_state()); 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) { if ((child = find_named_node (node, "Locations")) == 0) {
error << _("Session: XML state has no locations section") << endmsg; error << _("Session: XML state has no locations section") << endmsg;
goto out; goto out;
} else if (_locations.set_state (*child, version)) { } else if (_locations->set_state (*child, version)) {
goto out; goto out;
} }
Location* location; Location* location;
if ((location = _locations.auto_loop_location()) != 0) { if ((location = _locations->auto_loop_location()) != 0) {
set_auto_loop_location (location); set_auto_loop_location (location);
} }
if ((location = _locations.auto_punch_location()) != 0) { if ((location = _locations->auto_punch_location()) != 0) {
set_auto_punch_location (location); set_auto_punch_location (location);
} }
if ((location = _locations.session_range_location()) != 0) { if ((location = _locations->session_range_location()) != 0) {
delete _session_range_location; delete _session_range_location;
_session_range_location = location; _session_range_location = location;
} }
@ -3165,7 +3165,7 @@ Session::config_changed (std::string p, bool ours)
Location* location; Location* location;
if ((location = _locations.auto_punch_location()) != 0) { if ((location = _locations->auto_punch_location()) != 0) {
if (config.get_punch_in ()) { if (config.get_punch_in ()) {
replace_event (SessionEvent::PunchIn, location->start()); replace_event (SessionEvent::PunchIn, location->start());
@ -3178,7 +3178,7 @@ Session::config_changed (std::string p, bool ours)
Location* location; Location* location;
if ((location = _locations.auto_punch_location()) != 0) { if ((location = _locations->auto_punch_location()) != 0) {
if (config.get_punch_out()) { if (config.get_punch_out()) {
replace_event (SessionEvent::PunchOut, location->end()); replace_event (SessionEvent::PunchOut, location->end());

View file

@ -142,7 +142,7 @@ void
Session::request_play_loop (bool yn, bool leave_rolling) Session::request_play_loop (bool yn, bool leave_rolling)
{ {
SessionEvent* ev; SessionEvent* ev;
Location *location = _locations.auto_loop_location(); Location *location = _locations->auto_loop_location();
if (location == 0 && yn) { if (location == 0 && yn) {
error << _("Cannot loop - no loop range defined") 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()) { if (!synced_to_jack()) {
Location *location = _locations.auto_loop_location(); Location *location = _locations->auto_loop_location();
if (location != 0) { if (location != 0) {
_transport_frame = location->start(); _transport_frame = location->start();
@ -653,7 +653,7 @@ Session::set_play_loop (bool yn)
Location *loc; 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 */ /* nothing to do, or can't change loop status while recording */
return; 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 */ /* cancel looped playback if transport pos outside of loop range */
if (play_loop) { 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())) { if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
// cancel looping directly, this is called from event handling context // cancel looping directly, this is called from event handling context

View file

@ -95,7 +95,7 @@ void
BasicUI::add_marker () BasicUI::add_marker ()
{ {
nframes_t when = session->audible_frame(); 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 void

View file

@ -1601,7 +1601,7 @@ MackieControlProtocol::marker_press (Button &)
string markername; string markername;
nframes_t where = session->audible_frame(); nframes_t where = session->audible_frame();
session->locations()->next_available_name(markername,"mcu"); 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")); session->begin_reversible_command (_("add marker"));
XMLNode &before = session->locations()->get_state(); XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true); session->locations()->add (location, true);