summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-05-09 20:48:21 +0000
committerCarl Hetherington <carl@carlh.net>2010-05-09 20:48:21 +0000
commit792e3de1d4cb291a02c5c31dad54028049bafed9 (patch)
treee65183deeb01752110a59a5b834e06deef811dab
parentacfc44f3889704587ff281c6348523b2811e7c2e (diff)
Create the session range location as and when the session first gets some content. Allows both the beginning and end of the range to expand to contain the actual session contents.
git-svn-id: svn://localhost/ardour2/branches/3.0@7087 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/editor.cc6
-rw-r--r--gtk2_ardour/editor.h2
-rw-r--r--gtk2_ardour/editor_canvas.cc12
-rw-r--r--gtk2_ardour/editor_drag.cc6
-rw-r--r--gtk2_ardour/editor_keyboard.cc2
-rw-r--r--gtk2_ardour/editor_mouse.cc2
-rw-r--r--gtk2_ardour/editor_ops.cc5
-rw-r--r--gtk2_ardour/editor_summary.cc6
-rw-r--r--libs/ardour/ardour/playlist.h4
-rw-r--r--libs/ardour/ardour/session.h25
-rw-r--r--libs/ardour/ardour/session_configuration_vars.h1
-rw-r--r--libs/ardour/audiofilesource.cc2
-rw-r--r--libs/ardour/auditioner.cc2
-rw-r--r--libs/ardour/location.cc2
-rw-r--r--libs/ardour/playlist.cc50
-rw-r--r--libs/ardour/session.cc133
-rw-r--r--libs/ardour/session_state.cc19
-rw-r--r--libs/ardour/session_transport.cc34
18 files changed, 175 insertions, 138 deletions
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 45e77a6e96..2cc64ae612 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -4251,8 +4251,6 @@ Editor::post_zoom ()
}
}
- leftmost_frame = (nframes64_t) floor (_horizontal_position * frames_per_unit);
-
ZoomChanged (); /* EMIT_SIGNAL */
//reset_scrolling_region ();
@@ -4313,7 +4311,7 @@ Editor::idle_visual_changer ()
VisualChange::Type p = pending_visual_change.pending;
pending_visual_change.pending = (VisualChange::Type) 0;
- double last_time_origin = _horizontal_position;
+ double last_time_origin = horizontal_position ();
if (p & VisualChange::ZoomLevel) {
set_frames_per_unit (pending_visual_change.frames_per_unit);
@@ -4330,7 +4328,7 @@ Editor::idle_visual_changer ()
vertical_adjustment.set_value (pending_visual_change.y_origin);
}
- if (last_time_origin == _horizontal_position) {
+ if (last_time_origin == horizontal_position ()) {
/* changed signal not emitted */
update_fixed_rulers ();
redisplay_tempo (true);
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index a772d9eef9..153fbe5651 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -898,7 +898,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Gtk::Table edit_packer;
Gtk::Adjustment vertical_adjustment;
- double _horizontal_position;
Gtk::Layout controls_layout;
bool control_layout_scroll (GdkEventScroll* ev);
@@ -936,6 +935,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
double last_trackview_group_vertical_offset;
void tie_vertical_scrolling ();
void set_horizontal_position (double);
+ double horizontal_position () const;
void scroll_canvas_vertically ();
struct VisualChange {
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index 52e381b032..b072a2779e 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -780,20 +780,18 @@ Editor::tie_vertical_scrolling ()
void
Editor::set_horizontal_position (double p)
{
- _horizontal_position = p;
-
/* horizontal scrolling only */
double x1, y1, x2, y2, x_delta;
_master_group->get_bounds (x1, y1, x2, y2);
- x_delta = - (x1 + _horizontal_position);
+ x_delta = - (x1 + p);
_master_group->move (x_delta, 0);
timebar_group->move (x_delta, 0);
time_line_group->move (x_delta, 0);
cursor_group->move (x_delta, 0);
- leftmost_frame = (nframes64_t) floor (_horizontal_position * frames_per_unit);
+ leftmost_frame = (nframes64_t) floor (p * frames_per_unit);
update_fixed_rulers ();
redisplay_tempo (true);
@@ -921,3 +919,9 @@ Editor::update_canvas_now ()
track_canvas->update_now ();
}
}
+
+double
+Editor::horizontal_position () const
+{
+ return frame_to_unit (leftmost_frame);
+}
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index f1ad6e773a..a35357884a 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -560,7 +560,7 @@ RegionMotionDrag::compute_x_delta (GdkEvent const * event, nframes64_t* pending_
rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
rv->get_canvas_frame()->i2w (ix1, iy1);
- if (-x_delta > ix1 + _editor->_horizontal_position) {
+ if (-x_delta > ix1 + _editor->horizontal_position()) {
x_delta = 0;
*pending_region_position = _last_frame_position;
break;
@@ -3321,7 +3321,7 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
break;
}
- if (event->button.x >= _editor->_horizontal_position + _editor->_canvas_width) {
+ if (event->button.x >= _editor->horizontal_position() + _editor->_canvas_width) {
_editor->start_canvas_autoscroll (1, 0);
}
@@ -3478,7 +3478,7 @@ RangeMarkerBarDrag::motion (GdkEvent* event, bool first_move)
}
}
- if (event->button.x >= _editor->_horizontal_position + _editor->_canvas_width) {
+ if (event->button.x >= _editor->horizontal_position() + _editor->_canvas_width) {
_editor->start_canvas_autoscroll (1, 0);
}
diff --git a/gtk2_ardour/editor_keyboard.cc b/gtk2_ardour/editor_keyboard.cc
index bb047a1440..da6fadfe16 100644
--- a/gtk2_ardour/editor_keyboard.cc
+++ b/gtk2_ardour/editor_keyboard.cc
@@ -66,7 +66,7 @@ Editor::kbd_driver (sigc::slot<void,GdkEvent*> theslot, bool use_track_canvas, b
}
track_canvas->window_to_world (x, y, worldx, worldy);
- worldx += _horizontal_position;
+ worldx += horizontal_position();
worldy += vertical_adjustment.get_value();
ev.type = GDK_BUTTON_PRESS;
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 551183d205..dfdb3c811a 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -2005,7 +2005,7 @@ Editor::show_verbose_time_cursor (nframes64_t frame, double offset, double xpos,
if (xpos >= 0 && ypos >=0) {
set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset);
} else {
- set_verbose_canvas_cursor (buf, _drags->current_pointer_x() + offset - _horizontal_position, _drags->current_pointer_y() + offset - vertical_adjustment.get_value() + canvas_timebars_vsize);
+ set_verbose_canvas_cursor (buf, _drags->current_pointer_x() + offset - horizontal_position(), _drags->current_pointer_y() + offset - vertical_adjustment.get_value() + canvas_timebars_vsize);
}
show_verbose_canvas_cursor ();
}
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 2e5055e755..25e0b0016b 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -2227,7 +2227,8 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
}
void
-Editor::insert_route_list_drag (boost::shared_ptr<Route> route, int x, int y) {
+Editor::insert_route_list_drag (boost::shared_ptr<Route> route, int x, int y)
+{
double wx, wy;
double cx, cy;
nframes_t where;
@@ -2235,7 +2236,7 @@ Editor::insert_route_list_drag (boost::shared_ptr<Route> route, int x, int y) {
RouteTimeAxisView *source_rtv = 0;
track_canvas->window_to_world (x, y, wx, wy);
- wx += _horizontal_position;
+ wx += horizontal_position ();
wy += vertical_adjustment.get_value();
GdkEvent event;
diff --git a/gtk2_ardour/editor_summary.cc b/gtk2_ardour/editor_summary.cc
index fd4422bc08..5c2135ac43 100644
--- a/gtk2_ardour/editor_summary.cc
+++ b/gtk2_ardour/editor_summary.cc
@@ -153,7 +153,11 @@ EditorSummary::render (cairo_t* cr)
max_height = max (max_height, t);
}
- _x_scale = static_cast<double> (_width) / (_end - _start);
+ if (_end != _start) {
+ _x_scale = static_cast<double> (_width) / (_end - _start);
+ } else {
+ _x_scale = 1;
+ }
_y_scale = static_cast<double> (_height) / h;
/* tallest a region should ever be in the summary, in pixels */
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index c5b79644c6..d13789fa38 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -126,7 +126,7 @@ class Playlist : public SessionObject
bool hidden() const { return _hidden; }
bool empty() const;
uint32_t n_regions() const;
- framecnt_t get_maximum_extent () const;
+ std::pair<framecnt_t, framecnt_t> get_extent () const;
layer_t top_layer() const;
EditMode get_edit_mode() const { return _edit_mode; }
@@ -334,7 +334,7 @@ class Playlist : public SessionObject
void copy_regions (RegionList&) const;
void partition_internal (framepos_t start, framepos_t end, bool cutting, RegionList& thawlist);
- framecnt_t _get_maximum_extent() const;
+ std::pair<framecnt_t, framecnt_t> _get_extent() const;
boost::shared_ptr<Playlist> cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(framepos_t, framecnt_t, bool),
std::list<AudioRange>& ranges, bool result_is_hidden);
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 4182ce1ea1..0f5a73a280 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -270,7 +270,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
PBD::Signal0<void> TransportStateChange; /* generic */
PBD::Signal1<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */
- PBD::Signal0<void> DurationChanged;
PBD::Signal1<void,nframes64_t> Xrun;
PBD::Signal0<void> TransportLooped;
@@ -291,10 +290,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
bool get_play_loop () const { return play_loop; }
nframes_t last_transport_start() const { return _last_roll_location; }
- void goto_end () { request_locate (_session_range_location->end(), false);}
- void goto_start () { request_locate (_session_range_location->start(), false); }
- void set_session_start (nframes_t start) { _session_range_location->set_start(start); }
- void set_session_end (nframes_t end) { _session_range_location->set_end(end); config.set_end_marker_is_free (false); }
+ void goto_end ();
+ void goto_start ();
+ void set_session_start (nframes_t);
+ void set_session_end (nframes_t);
void use_rf_shuttle_speed ();
void allow_auto_play (bool yn);
void request_transport_speed (double speed);
@@ -307,9 +306,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
int wipe ();
- nframes_t get_maximum_extent () const;
- nframes_t current_end_frame() const { return _session_range_location->end(); }
- nframes_t current_start_frame() const { return _session_range_location->start(); }
+ std::pair<nframes_t, nframes_t> get_extent () const;
+ nframes_t current_end_frame () const;
+ nframes_t current_start_frame () const;
/// "actual" sample rate of session, set by current audioengine rate, pullup/down etc.
nframes_t frame_rate() const { return _current_frame_rate; }
/// "native" sample rate of session, regardless of current audioengine rate, pullup/down etc
@@ -805,11 +804,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void update_latency_compensation (bool, bool);
private:
- int create (const std::string& mix_template, nframes_t initial_length, BusProfile*);
+ int create (const std::string& mix_template, BusProfile*);
void destroy ();
- nframes_t compute_initial_length ();
-
enum SubState {
PendingDeclickIn = 0x1,
PendingDeclickOut = 0x2,
@@ -836,7 +833,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
int transport_sub_state;
mutable gint _record_status;
volatile nframes64_t _transport_frame;
- Location* _session_range_location;
+ Location* _session_range_location; ///< session range, or 0 if there is nothing in the session yet
Slave* _slave;
bool _silent;
@@ -1056,7 +1053,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void first_stage_init (std::string path, std::string snapshot_name);
int second_stage_init ();
- void find_current_end ();
+ void update_session_range_location_marker ();
void remove_empty_sounds ();
void setup_midi_control ();
@@ -1442,6 +1439,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
/** temporary list of Diskstreams used only during load of 2.X sessions */
std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;
+
+ void add_session_range_location (nframes_t, nframes_t);
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/session_configuration_vars.h b/libs/ardour/ardour/session_configuration_vars.h
index 2776787271..df76057e0b 100644
--- a/libs/ardour/ardour/session_configuration_vars.h
+++ b/libs/ardour/ardour/session_configuration_vars.h
@@ -37,7 +37,6 @@ CONFIG_VARIABLE (TimecodeFormat, timecode_format, "timecode-format", timecode_30
CONFIG_VARIABLE_SPECIAL(Glib::ustring, raid_path, "raid-path", "", path_expand)
CONFIG_VARIABLE (std::string, bwf_country_code, "bwf-country-code", "US")
CONFIG_VARIABLE (std::string, bwf_organization_code, "bwf-organization-code", "US")
-CONFIG_VARIABLE (bool, end_marker_is_free, "end-marker-is-free", true)
CONFIG_VARIABLE (LayerModel, layer_model, "layer-model", MoveAddHigher)
CONFIG_VARIABLE (std::string, auditioner_output_left, "auditioner-output-left", "default")
CONFIG_VARIABLE (std::string, auditioner_output_right, "auditioner-output-right", "default")
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
index 0e498c3d59..1973678359 100644
--- a/libs/ardour/audiofilesource.cc
+++ b/libs/ardour/audiofilesource.cc
@@ -222,7 +222,7 @@ AudioFileSource::old_peak_path (ustring audio_path)
#ifdef __APPLE__
snprintf (buf, sizeof (buf), "%u-%u-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel);
#else
- snprintf (buf, sizeof (buf), "%ld-%ld-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel);
+ snprintf (buf, sizeof (buf), "%lld-%lld-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel);
#endif
ustring res = peak_dir;
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index 8b8f850f8b..45a836582d 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -127,7 +127,7 @@ Auditioner::audition_current_playlist ()
Glib::Mutex::Lock lm (lock);
_diskstream->seek (0);
- length = _diskstream->playlist()->get_maximum_extent();
+ length = _diskstream->playlist()->get_extent().second;
current_frame = 0;
/* force a panner reset now that we have all channels */
diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc
index f855cb75cf..7202e1ef03 100644
--- a/libs/ardour/location.cc
+++ b/libs/ardour/location.cc
@@ -548,6 +548,8 @@ Locations::clear_ranges ()
void
Locations::add (Location *loc, bool make_current)
{
+ assert (loc);
+
{
Glib::Mutex::Lock lm (lock);
locations.push_back (loc);
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 649d549b86..a5e662f4d0 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -452,7 +452,7 @@ void
Playlist::delay_notifications ()
{
g_atomic_int_inc (&block_notifications);
- freeze_length = _get_maximum_extent();
+ freeze_length = _get_extent().second;
}
void
@@ -574,7 +574,7 @@ Playlist::flush_notifications ()
if (!pending_bounds.empty() || !pending_removes.empty() || !pending_adds.empty()) {
regions_changed = true;
if (!pending_length) {
- old_length = _get_maximum_extent ();
+ old_length = _get_extent ().second;
check_length = true;
}
}
@@ -608,13 +608,13 @@ Playlist::flush_notifications ()
}
if (check_length) {
- if (old_length != _get_maximum_extent()) {
+ if (old_length != _get_extent().second) {
pending_length = true;
// cerr << _name << " length has changed\n";
}
}
- if (pending_length || (freeze_length != _get_maximum_extent())) {
+ if (pending_length || (freeze_length != _get_extent().second)) {
pending_length = false;
// cerr << _name << " sends LengthChanged\n";
LengthChanged(); /* EMIT SIGNAL */
@@ -737,7 +737,7 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, framepos_t posi
framecnt_t old_length = 0;
if (!holding_state()) {
- old_length = _get_maximum_extent();
+ old_length = _get_extent().second;
}
if (!first_set_state) {
@@ -767,7 +767,7 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, framepos_t posi
check_dependents (region, false);
- if (old_length != _get_maximum_extent()) {
+ if (old_length != _get_extent().second) {
notify_length_changed ();
}
}
@@ -808,7 +808,7 @@ Playlist::remove_region_internal (boost::shared_ptr<Region> region)
int ret = -1;
if (!holding_state()) {
- old_length = _get_maximum_extent();
+ old_length = _get_extent().second;
}
if (!in_set_state) {
@@ -832,7 +832,7 @@ Playlist::remove_region_internal (boost::shared_ptr<Region> region)
relayer ();
remove_dependents (region);
- if (old_length != _get_maximum_extent()) {
+ if (old_length != _get_extent().second) {
notify_length_changed ();
}
}
@@ -1203,7 +1203,7 @@ Playlist::copy (framepos_t start, framecnt_t cnt, bool result_is_hidden)
new_name += '.';
new_name += buf;
- cnt = min (_get_maximum_extent() - start, cnt);
+ cnt = min (_get_extent().second - start, cnt);
return PlaylistFactory::create (shared_from_this(), start, cnt, new_name, result_is_hidden);
}
@@ -1216,11 +1216,11 @@ Playlist::paste (boost::shared_ptr<Playlist> other, framepos_t position, float t
RegionLock rl1 (this);
RegionLock rl2 (other.get());
- framecnt_t old_length = _get_maximum_extent();
+ framecnt_t const old_length = _get_extent().second;
int itimes = (int) floor (times);
framepos_t pos = position;
- framecnt_t shift = other->_get_maximum_extent();
+ framecnt_t const shift = other->_get_extent().second;
layer_t top_layer = regions.size();
while (itimes--) {
@@ -1240,7 +1240,7 @@ Playlist::paste (boost::shared_ptr<Playlist> other, framepos_t position, float t
/* XXX shall we handle fractional cases at some point? */
- if (old_length != _get_maximum_extent()) {
+ if (old_length != _get_extent().second) {
notify_length_changed ();
}
@@ -2280,27 +2280,29 @@ Playlist::n_regions() const
return regions.size();
}
-framecnt_t
-Playlist::get_maximum_extent () const
+pair<framecnt_t, framecnt_t>
+Playlist::get_extent () const
{
RegionLock rlock (const_cast<Playlist *>(this), false);
- return _get_maximum_extent ();
+ return _get_extent ();
}
-framecnt_t
-Playlist::_get_maximum_extent () const
+pair<framecnt_t, framecnt_t>
+Playlist::_get_extent () const
{
- RegionList::const_iterator i;
- framecnt_t max_extent = 0;
- framepos_t end = 0;
+ pair<framecnt_t, framecnt_t> ext (max_frames, 0);
- for (i = regions.begin(); i != regions.end(); ++i) {
- if ((end = (*i)->position() + (*i)->length()) > max_extent) {
- max_extent = end;
+ for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+ pair<framecnt_t, framecnt_t> const e ((*i)->position(), (*i)->position() + (*i)->length());
+ if (e.first < ext.first) {
+ ext.first = e.first;
+ }
+ if (e.second > ext.second) {
+ ext.second = e.second;
}
}
- return max_extent;
+ return ext;
}
string
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 2d4aefd388..a5443a1797 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -172,7 +172,7 @@ Session::Session (AudioEngine &eng,
_is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
if (_is_new) {
- if (create (mix_template, compute_initial_length(), bus_profile)) {
+ if (create (mix_template, bus_profile)) {
destroy ();
throw failed_constructor ();
}
@@ -700,13 +700,7 @@ Session::hookup_io ()
void
Session::playlist_length_changed ()
{
- /* we can't just increase session_range_location->end() if pl->get_maximum_extent()
- if larger. if the playlist used to be the longest playlist,
- and its now shorter, we have to decrease session_range_location->end(). hence,
- we have to iterate over all diskstreams and check the
- playlists currently in use.
- */
- find_current_end ();
+ update_session_range_location_marker ();
}
void
@@ -723,8 +717,7 @@ Session::track_playlist_changed (boost::weak_ptr<Track> wp)
playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
}
- /* see comment in playlist_length_changed () */
- find_current_end ();
+ update_session_range_location_marker ();
}
bool
@@ -2082,7 +2075,7 @@ Session::remove_route (shared_ptr<Route> route)
}
update_route_solo_state ();
- find_current_end ();
+ update_session_range_location_marker ();
// We need to disconnect the route's inputs and outputs
@@ -2396,43 +2389,64 @@ Session::route_by_remote_id (uint32_t id)
return shared_ptr<Route> ((Route*) 0);
}
+/** If either end of the session range location marker lies inside the current
+ * session extent, move it to the corresponding session extent.
+ */
void
-Session::find_current_end ()
+Session::update_session_range_location_marker ()
{
if (_state_of_the_state & Loading) {
return;
}
- nframes_t max = get_maximum_extent ();
+ pair<nframes_t, nframes_t> const ext = get_extent ();
- if (max > _session_range_location->end()) {
- _session_range_location->set_end (max);
- set_dirty();
- DurationChanged(); /* EMIT SIGNAL */
+ if (_session_range_location == 0) {
+ /* we don't have a session range yet; use this one (provided it is valid) */
+ if (ext.first != max_frames) {
+ add_session_range_location (ext.first, ext.second);
+ }
+ } else {
+ /* update the existing session range */
+ if (ext.first < _session_range_location->start()) {
+ _session_range_location->set_start (ext.first);
+ set_dirty ();
+ }
+
+ if (ext.second > _session_range_location->end()) {
+ _session_range_location->set_end (ext.second);
+ set_dirty ();
+ }
+
}
}
-nframes_t
-Session::get_maximum_extent () const
+/** @return Extent of the session's contents; if the session is empty, the first value of
+ * the pair will equal max_frames.
+ */
+pair<nframes_t, nframes_t>
+Session::get_extent () const
{
- nframes_t max = 0;
- nframes_t me;
+ pair<nframes_t, nframes_t> ext (max_frames, 0);
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (!tr || tr->destructive()) {
- //ignore tape tracks when getting max extents
+ // ignore tape tracks when getting extents
continue;
}
-
- boost::shared_ptr<Playlist> pl = tr->playlist();
- if ((me = pl->get_maximum_extent()) > max) {
- max = me;
+
+ pair<nframes_t, nframes_t> e = tr->playlist()->get_extent ();
+ if (e.first < ext.first) {
+ ext.first = e.first;
+ }
+ if (e.second > ext.second) {
+ ext.second = e.second;
}
}
- return max;
+ return ext;
}
/* Region management */
@@ -3693,12 +3707,6 @@ Session::add_automation_list(AutomationList *al)
automation_lists[al->id()] = al;
}
-nframes_t
-Session::compute_initial_length ()
-{
- return _engine.frame_rate() * 60 * 5;
-}
-
void
Session::sync_order_keys (std::string const & base)
{
@@ -3838,3 +3846,62 @@ Session::get_routes_with_regions_at (nframes64_t const p) const
return rl;
}
+
+void
+Session::goto_end ()
+{
+ if (_session_range_location) {
+ request_locate (_session_range_location->end(), false);
+ } else {
+ request_locate (0, false);
+ }
+}
+
+void
+Session::goto_start ()
+{
+ if (_session_range_location) {
+ request_locate (_session_range_location->start(), false);
+ } else {
+ request_locate (0, false);
+ }
+}
+
+void
+Session::set_session_start (nframes_t start)
+{
+ if (_session_range_location) {
+ _session_range_location->set_start (start);
+ } else {
+ add_session_range_location (start, start);
+ }
+}
+
+void
+Session::set_session_end (nframes_t end)
+{
+ if (_session_range_location) {
+ _session_range_location->set_end (end);
+ } else {
+ add_session_range_location (end, end);
+ }
+}
+
+nframes_t
+Session::current_start_frame () const
+{
+ return _session_range_location ? _session_range_location->start() : 0;
+}
+
+nframes_t
+Session::current_end_frame () const
+{
+ return _session_range_location ? _session_range_location->end() : 0;
+}
+
+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);
+}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index a0e61d547a..ee7e88caaa 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -179,7 +179,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
transport_sub_state = 0;
_transport_frame = 0;
_requested_return_frame = -1;
- _session_range_location = new Location (0, 0, _("session"), Location::IsSessionRange);
+ _session_range_location = 0;
g_atomic_int_set (&_record_status, Disabled);
loop_changing = false;
play_loop = false;
@@ -365,8 +365,6 @@ Session::second_stage_init ()
ControlProtocolManager::instance().set_session (this);
- config.set_end_marker_is_free (_is_new);
-
_state_of_the_state = Clean;
DirtyChanged (); /* EMIT SIGNAL */
@@ -491,7 +489,7 @@ Session::ensure_subdirs ()
}
int
-Session::create (const string& mix_template, nframes_t initial_length, BusProfile* bus_profile)
+Session::create (const string& mix_template, BusProfile* bus_profile)
{
if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
@@ -540,9 +538,6 @@ Session::create (const string& mix_template, nframes_t initial_length, BusProfil
/* set initial start + end point */
- _session_range_location->set (0, initial_length);
- _locations.add (_session_range_location);
-
_state_of_the_state = Clean;
/* set up Master Out and Control Out if necessary */
@@ -1051,7 +1046,7 @@ Session::state(bool full_state)
// with the default start and end, and get the state for that.
Locations loc;
Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
- range->set (0, compute_initial_length ());
+ range->set (max_frames, 0);
loc.add (range);
node->add_child_nocopy (loc.get_state());
}
@@ -1242,14 +1237,14 @@ Session::set_state (const XMLNode& node, int version)
set_auto_punch_location (location);
}
- if ((location = _locations.session_range_location()) == 0) {
- _locations.add (_session_range_location);
- } else {
+ if ((location = _locations.session_range_location()) != 0) {
delete _session_range_location;
_session_range_location = location;
}
- AudioFileSource::set_header_position_offset (_session_range_location->start());
+ if (_session_range_location) {
+ AudioFileSource::set_header_position_offset (_session_range_location->start());
+ }
if ((child = find_named_node (node, "Sources")) == 0) {
error << _("Session: XML state has no sources section") << endmsg;
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 6d7d3b4521..7a378e1a01 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -408,36 +408,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
if (did_record) {
begin_reversible_command ("capture");
-
- Location* loc = _locations.session_range_location();
- bool change_end = false;
-
- if (_transport_frame < loc->end()) {
-
- /* stopped recording before current end */
-
- if (config.get_end_marker_is_free()) {
-
- /* first capture for this session, move end back to where we are */
-
- change_end = true;
- }
-
- } else if (_transport_frame > loc->end()) {
-
- /* stopped recording after the current end, extend it */
-
- change_end = true;
- }
-
- if (change_end) {
- XMLNode &before = loc->get_state();
- loc->set_end(_transport_frame);
- XMLNode &after = loc->get_state();
- add_command (new MementoCommand<Location>(*loc, &before, &after));
- }
-
- config.set_end_marker_is_free (false);
_have_captured = true;
}
@@ -587,10 +557,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
save_state (_current_snapshot_name);
}
- if (ptw & PostTransportDuration) {
- DurationChanged (); /* EMIT SIGNAL */
- }
-
if (ptw & PostTransportStop) {
_play_range = false;
play_loop = false;