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
This commit is contained in:
Carl Hetherington 2010-05-09 20:48:21 +00:00
parent acfc44f388
commit 792e3de1d4
18 changed files with 175 additions and 138 deletions

View file

@ -4251,8 +4251,6 @@ Editor::post_zoom ()
} }
} }
leftmost_frame = (nframes64_t) floor (_horizontal_position * frames_per_unit);
ZoomChanged (); /* EMIT_SIGNAL */ ZoomChanged (); /* EMIT_SIGNAL */
//reset_scrolling_region (); //reset_scrolling_region ();
@ -4313,7 +4311,7 @@ Editor::idle_visual_changer ()
VisualChange::Type p = pending_visual_change.pending; VisualChange::Type p = pending_visual_change.pending;
pending_visual_change.pending = (VisualChange::Type) 0; pending_visual_change.pending = (VisualChange::Type) 0;
double last_time_origin = _horizontal_position; double last_time_origin = horizontal_position ();
if (p & VisualChange::ZoomLevel) { if (p & VisualChange::ZoomLevel) {
set_frames_per_unit (pending_visual_change.frames_per_unit); 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); 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 */ /* changed signal not emitted */
update_fixed_rulers (); update_fixed_rulers ();
redisplay_tempo (true); redisplay_tempo (true);

View file

@ -898,7 +898,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Gtk::Table edit_packer; Gtk::Table edit_packer;
Gtk::Adjustment vertical_adjustment; Gtk::Adjustment vertical_adjustment;
double _horizontal_position;
Gtk::Layout controls_layout; Gtk::Layout controls_layout;
bool control_layout_scroll (GdkEventScroll* ev); 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; double last_trackview_group_vertical_offset;
void tie_vertical_scrolling (); void tie_vertical_scrolling ();
void set_horizontal_position (double); void set_horizontal_position (double);
double horizontal_position () const;
void scroll_canvas_vertically (); void scroll_canvas_vertically ();
struct VisualChange { struct VisualChange {

View file

@ -780,20 +780,18 @@ Editor::tie_vertical_scrolling ()
void void
Editor::set_horizontal_position (double p) Editor::set_horizontal_position (double p)
{ {
_horizontal_position = p;
/* horizontal scrolling only */ /* horizontal scrolling only */
double x1, y1, x2, y2, x_delta; double x1, y1, x2, y2, x_delta;
_master_group->get_bounds (x1, y1, x2, y2); _master_group->get_bounds (x1, y1, x2, y2);
x_delta = - (x1 + _horizontal_position); x_delta = - (x1 + p);
_master_group->move (x_delta, 0); _master_group->move (x_delta, 0);
timebar_group->move (x_delta, 0); timebar_group->move (x_delta, 0);
time_line_group->move (x_delta, 0); time_line_group->move (x_delta, 0);
cursor_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 (); update_fixed_rulers ();
redisplay_tempo (true); redisplay_tempo (true);
@ -921,3 +919,9 @@ Editor::update_canvas_now ()
track_canvas->update_now (); track_canvas->update_now ();
} }
} }
double
Editor::horizontal_position () const
{
return frame_to_unit (leftmost_frame);
}

View file

@ -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()->get_bounds (ix1, iy1, ix2, iy2);
rv->get_canvas_frame()->i2w (ix1, iy1); rv->get_canvas_frame()->i2w (ix1, iy1);
if (-x_delta > ix1 + _editor->_horizontal_position) { if (-x_delta > ix1 + _editor->horizontal_position()) {
x_delta = 0; x_delta = 0;
*pending_region_position = _last_frame_position; *pending_region_position = _last_frame_position;
break; break;
@ -3321,7 +3321,7 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
break; 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); _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); _editor->start_canvas_autoscroll (1, 0);
} }

View file

@ -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); track_canvas->window_to_world (x, y, worldx, worldy);
worldx += _horizontal_position; worldx += horizontal_position();
worldy += vertical_adjustment.get_value(); worldy += vertical_adjustment.get_value();
ev.type = GDK_BUTTON_PRESS; ev.type = GDK_BUTTON_PRESS;

View file

@ -2005,7 +2005,7 @@ Editor::show_verbose_time_cursor (nframes64_t frame, double offset, double xpos,
if (xpos >= 0 && ypos >=0) { if (xpos >= 0 && ypos >=0) {
set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset); set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset);
} else { } 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 (); show_verbose_canvas_cursor ();
} }

View file

@ -2227,7 +2227,8 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
} }
void 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 wx, wy;
double cx, cy; double cx, cy;
nframes_t where; 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; RouteTimeAxisView *source_rtv = 0;
track_canvas->window_to_world (x, y, wx, wy); track_canvas->window_to_world (x, y, wx, wy);
wx += _horizontal_position; wx += horizontal_position ();
wy += vertical_adjustment.get_value(); wy += vertical_adjustment.get_value();
GdkEvent event; GdkEvent event;

View file

@ -153,7 +153,11 @@ EditorSummary::render (cairo_t* cr)
max_height = max (max_height, t); 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; _y_scale = static_cast<double> (_height) / h;
/* tallest a region should ever be in the summary, in pixels */ /* tallest a region should ever be in the summary, in pixels */

View file

@ -126,7 +126,7 @@ class Playlist : public SessionObject
bool hidden() const { return _hidden; } bool hidden() const { return _hidden; }
bool empty() const; bool empty() const;
uint32_t n_regions() 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; layer_t top_layer() const;
EditMode get_edit_mode() const { return _edit_mode; } EditMode get_edit_mode() const { return _edit_mode; }
@ -334,7 +334,7 @@ class Playlist : public SessionObject
void copy_regions (RegionList&) const; void copy_regions (RegionList&) const;
void partition_internal (framepos_t start, framepos_t end, bool cutting, RegionList& thawlist); 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), 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); std::list<AudioRange>& ranges, bool result_is_hidden);

View file

@ -270,7 +270,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
PBD::Signal0<void> TransportStateChange; /* generic */ PBD::Signal0<void> TransportStateChange; /* generic */
PBD::Signal1<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */ PBD::Signal1<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */
PBD::Signal0<void> DurationChanged;
PBD::Signal1<void,nframes64_t> Xrun; PBD::Signal1<void,nframes64_t> Xrun;
PBD::Signal0<void> TransportLooped; PBD::Signal0<void> TransportLooped;
@ -291,10 +290,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
bool get_play_loop () const { return play_loop; } bool get_play_loop () const { return play_loop; }
nframes_t last_transport_start() const { return _last_roll_location; } nframes_t last_transport_start() const { return _last_roll_location; }
void goto_end () { request_locate (_session_range_location->end(), false);} void goto_end ();
void goto_start () { request_locate (_session_range_location->start(), false); } void goto_start ();
void set_session_start (nframes_t start) { _session_range_location->set_start(start); } void set_session_start (nframes_t);
void set_session_end (nframes_t end) { _session_range_location->set_end(end); config.set_end_marker_is_free (false); } void set_session_end (nframes_t);
void use_rf_shuttle_speed (); void use_rf_shuttle_speed ();
void allow_auto_play (bool yn); void allow_auto_play (bool yn);
void request_transport_speed (double speed); void request_transport_speed (double speed);
@ -307,9 +306,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
int wipe (); int wipe ();
nframes_t get_maximum_extent () const; std::pair<nframes_t, nframes_t> get_extent () const;
nframes_t current_end_frame() const { return _session_range_location->end(); } nframes_t current_end_frame () const;
nframes_t current_start_frame() const { return _session_range_location->start(); } nframes_t current_start_frame () const;
/// "actual" sample rate of session, set by current audioengine rate, pullup/down etc. /// "actual" sample rate of session, set by current audioengine rate, pullup/down etc.
nframes_t frame_rate() const { return _current_frame_rate; } nframes_t frame_rate() const { return _current_frame_rate; }
/// "native" sample rate of session, regardless of current audioengine rate, pullup/down etc /// "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); void update_latency_compensation (bool, bool);
private: private:
int create (const std::string& mix_template, nframes_t initial_length, BusProfile*); int create (const std::string& mix_template, BusProfile*);
void destroy (); void destroy ();
nframes_t compute_initial_length ();
enum SubState { enum SubState {
PendingDeclickIn = 0x1, PendingDeclickIn = 0x1,
PendingDeclickOut = 0x2, PendingDeclickOut = 0x2,
@ -836,7 +833,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
int transport_sub_state; int transport_sub_state;
mutable gint _record_status; mutable gint _record_status;
volatile nframes64_t _transport_frame; 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; Slave* _slave;
bool _silent; 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); void first_stage_init (std::string path, std::string snapshot_name);
int second_stage_init (); int second_stage_init ();
void find_current_end (); void update_session_range_location_marker ();
void remove_empty_sounds (); void remove_empty_sounds ();
void setup_midi_control (); 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 */ /** temporary list of Diskstreams used only during load of 2.X sessions */
std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X; std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;
void add_session_range_location (nframes_t, nframes_t);
}; };
} // namespace ARDOUR } // namespace ARDOUR

View file

@ -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_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_country_code, "bwf-country-code", "US")
CONFIG_VARIABLE (std::string, bwf_organization_code, "bwf-organization-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 (LayerModel, layer_model, "layer-model", MoveAddHigher)
CONFIG_VARIABLE (std::string, auditioner_output_left, "auditioner-output-left", "default") CONFIG_VARIABLE (std::string, auditioner_output_left, "auditioner-output-left", "default")
CONFIG_VARIABLE (std::string, auditioner_output_right, "auditioner-output-right", "default") CONFIG_VARIABLE (std::string, auditioner_output_right, "auditioner-output-right", "default")

View file

@ -222,7 +222,7 @@ AudioFileSource::old_peak_path (ustring audio_path)
#ifdef __APPLE__ #ifdef __APPLE__
snprintf (buf, sizeof (buf), "%u-%u-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel); snprintf (buf, sizeof (buf), "%u-%u-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel);
#else #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 #endif
ustring res = peak_dir; ustring res = peak_dir;

View file

@ -127,7 +127,7 @@ Auditioner::audition_current_playlist ()
Glib::Mutex::Lock lm (lock); Glib::Mutex::Lock lm (lock);
_diskstream->seek (0); _diskstream->seek (0);
length = _diskstream->playlist()->get_maximum_extent(); length = _diskstream->playlist()->get_extent().second;
current_frame = 0; current_frame = 0;
/* force a panner reset now that we have all channels */ /* force a panner reset now that we have all channels */

View file

@ -548,6 +548,8 @@ Locations::clear_ranges ()
void void
Locations::add (Location *loc, bool make_current) Locations::add (Location *loc, bool make_current)
{ {
assert (loc);
{ {
Glib::Mutex::Lock lm (lock); Glib::Mutex::Lock lm (lock);
locations.push_back (loc); locations.push_back (loc);

View file

@ -452,7 +452,7 @@ void
Playlist::delay_notifications () Playlist::delay_notifications ()
{ {
g_atomic_int_inc (&block_notifications); g_atomic_int_inc (&block_notifications);
freeze_length = _get_maximum_extent(); freeze_length = _get_extent().second;
} }
void void
@ -574,7 +574,7 @@ Playlist::flush_notifications ()
if (!pending_bounds.empty() || !pending_removes.empty() || !pending_adds.empty()) { if (!pending_bounds.empty() || !pending_removes.empty() || !pending_adds.empty()) {
regions_changed = true; regions_changed = true;
if (!pending_length) { if (!pending_length) {
old_length = _get_maximum_extent (); old_length = _get_extent ().second;
check_length = true; check_length = true;
} }
} }
@ -608,13 +608,13 @@ Playlist::flush_notifications ()
} }
if (check_length) { if (check_length) {
if (old_length != _get_maximum_extent()) { if (old_length != _get_extent().second) {
pending_length = true; pending_length = true;
// cerr << _name << " length has changed\n"; // 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; pending_length = false;
// cerr << _name << " sends LengthChanged\n"; // cerr << _name << " sends LengthChanged\n";
LengthChanged(); /* EMIT SIGNAL */ LengthChanged(); /* EMIT SIGNAL */
@ -737,7 +737,7 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, framepos_t posi
framecnt_t old_length = 0; framecnt_t old_length = 0;
if (!holding_state()) { if (!holding_state()) {
old_length = _get_maximum_extent(); old_length = _get_extent().second;
} }
if (!first_set_state) { if (!first_set_state) {
@ -767,7 +767,7 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, framepos_t posi
check_dependents (region, false); check_dependents (region, false);
if (old_length != _get_maximum_extent()) { if (old_length != _get_extent().second) {
notify_length_changed (); notify_length_changed ();
} }
} }
@ -808,7 +808,7 @@ Playlist::remove_region_internal (boost::shared_ptr<Region> region)
int ret = -1; int ret = -1;
if (!holding_state()) { if (!holding_state()) {
old_length = _get_maximum_extent(); old_length = _get_extent().second;
} }
if (!in_set_state) { if (!in_set_state) {
@ -832,7 +832,7 @@ Playlist::remove_region_internal (boost::shared_ptr<Region> region)
relayer (); relayer ();
remove_dependents (region); remove_dependents (region);
if (old_length != _get_maximum_extent()) { if (old_length != _get_extent().second) {
notify_length_changed (); notify_length_changed ();
} }
} }
@ -1203,7 +1203,7 @@ Playlist::copy (framepos_t start, framecnt_t cnt, bool result_is_hidden)
new_name += '.'; new_name += '.';
new_name += buf; 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); 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 rl1 (this);
RegionLock rl2 (other.get()); RegionLock rl2 (other.get());
framecnt_t old_length = _get_maximum_extent(); framecnt_t const old_length = _get_extent().second;
int itimes = (int) floor (times); int itimes = (int) floor (times);
framepos_t pos = position; 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(); layer_t top_layer = regions.size();
while (itimes--) { 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? */ /* XXX shall we handle fractional cases at some point? */
if (old_length != _get_maximum_extent()) { if (old_length != _get_extent().second) {
notify_length_changed (); notify_length_changed ();
} }
@ -2280,27 +2280,29 @@ Playlist::n_regions() const
return regions.size(); return regions.size();
} }
framecnt_t pair<framecnt_t, framecnt_t>
Playlist::get_maximum_extent () const Playlist::get_extent () const
{ {
RegionLock rlock (const_cast<Playlist *>(this), false); RegionLock rlock (const_cast<Playlist *>(this), false);
return _get_maximum_extent (); return _get_extent ();
} }
framecnt_t pair<framecnt_t, framecnt_t>
Playlist::_get_maximum_extent () const Playlist::_get_extent () const
{ {
RegionList::const_iterator i; pair<framecnt_t, framecnt_t> ext (max_frames, 0);
framecnt_t max_extent = 0;
framepos_t end = 0;
for (i = regions.begin(); i != regions.end(); ++i) { for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
if ((end = (*i)->position() + (*i)->length()) > max_extent) { pair<framecnt_t, framecnt_t> const e ((*i)->position(), (*i)->position() + (*i)->length());
max_extent = end; if (e.first < ext.first) {
ext.first = e.first;
}
if (e.second > ext.second) {
ext.second = e.second;
} }
} }
return max_extent; return ext;
} }
string string

View file

@ -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)); _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
if (_is_new) { if (_is_new) {
if (create (mix_template, compute_initial_length(), bus_profile)) { if (create (mix_template, bus_profile)) {
destroy (); destroy ();
throw failed_constructor (); throw failed_constructor ();
} }
@ -700,13 +700,7 @@ Session::hookup_io ()
void void
Session::playlist_length_changed () Session::playlist_length_changed ()
{ {
/* we can't just increase session_range_location->end() if pl->get_maximum_extent() update_session_range_location_marker ();
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 ();
} }
void 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)); playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
} }
/* see comment in playlist_length_changed () */ update_session_range_location_marker ();
find_current_end ();
} }
bool bool
@ -2082,7 +2075,7 @@ Session::remove_route (shared_ptr<Route> route)
} }
update_route_solo_state (); update_route_solo_state ();
find_current_end (); update_session_range_location_marker ();
// We need to disconnect the route's inputs and outputs // 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); 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 void
Session::find_current_end () Session::update_session_range_location_marker ()
{ {
if (_state_of_the_state & Loading) { if (_state_of_the_state & Loading) {
return; return;
} }
nframes_t max = get_maximum_extent (); pair<nframes_t, nframes_t> const ext = get_extent ();
if (max > _session_range_location->end()) { if (_session_range_location == 0) {
_session_range_location->set_end (max); /* we don't have a session range yet; use this one (provided it is valid) */
set_dirty(); if (ext.first != max_frames) {
DurationChanged(); /* EMIT SIGNAL */ 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 /** @return Extent of the session's contents; if the session is empty, the first value of
Session::get_maximum_extent () const * the pair will equal max_frames.
*/
pair<nframes_t, nframes_t>
Session::get_extent () const
{ {
nframes_t max = 0; pair<nframes_t, nframes_t> ext (max_frames, 0);
nframes_t me;
boost::shared_ptr<RouteList> rl = routes.reader (); boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i); boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (!tr || tr->destructive()) { if (!tr || tr->destructive()) {
//ignore tape tracks when getting max extents // ignore tape tracks when getting extents
continue; continue;
} }
boost::shared_ptr<Playlist> pl = tr->playlist(); pair<nframes_t, nframes_t> e = tr->playlist()->get_extent ();
if ((me = pl->get_maximum_extent()) > max) { if (e.first < ext.first) {
max = me; ext.first = e.first;
}
if (e.second > ext.second) {
ext.second = e.second;
} }
} }
return max; return ext;
} }
/* Region management */ /* Region management */
@ -3693,12 +3707,6 @@ Session::add_automation_list(AutomationList *al)
automation_lists[al->id()] = al; automation_lists[al->id()] = al;
} }
nframes_t
Session::compute_initial_length ()
{
return _engine.frame_rate() * 60 * 5;
}
void void
Session::sync_order_keys (std::string const & base) 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; 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);
}

View file

@ -179,7 +179,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
transport_sub_state = 0; transport_sub_state = 0;
_transport_frame = 0; _transport_frame = 0;
_requested_return_frame = -1; _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); g_atomic_int_set (&_record_status, Disabled);
loop_changing = false; loop_changing = false;
play_loop = false; play_loop = false;
@ -365,8 +365,6 @@ Session::second_stage_init ()
ControlProtocolManager::instance().set_session (this); ControlProtocolManager::instance().set_session (this);
config.set_end_marker_is_free (_is_new);
_state_of_the_state = Clean; _state_of_the_state = Clean;
DirtyChanged (); /* EMIT SIGNAL */ DirtyChanged (); /* EMIT SIGNAL */
@ -491,7 +489,7 @@ Session::ensure_subdirs ()
} }
int 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) { 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 */ /* set initial start + end point */
_session_range_location->set (0, initial_length);
_locations.add (_session_range_location);
_state_of_the_state = Clean; _state_of_the_state = Clean;
/* set up Master Out and Control Out if necessary */ /* 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. // with the default start and end, and get the state for that.
Locations loc; Locations loc;
Location* range = new Location (0, 0, _("session"), Location::IsSessionRange); Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
range->set (0, compute_initial_length ()); 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());
} }
@ -1242,14 +1237,14 @@ Session::set_state (const XMLNode& node, int version)
set_auto_punch_location (location); set_auto_punch_location (location);
} }
if ((location = _locations.session_range_location()) == 0) { if ((location = _locations.session_range_location()) != 0) {
_locations.add (_session_range_location);
} else {
delete _session_range_location; delete _session_range_location;
_session_range_location = 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) { if ((child = find_named_node (node, "Sources")) == 0) {
error << _("Session: XML state has no sources section") << endmsg; error << _("Session: XML state has no sources section") << endmsg;

View file

@ -408,36 +408,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
if (did_record) { if (did_record) {
begin_reversible_command ("capture"); 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; _have_captured = true;
} }
@ -587,10 +557,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
save_state (_current_snapshot_name); save_state (_current_snapshot_name);
} }
if (ptw & PostTransportDuration) {
DurationChanged (); /* EMIT SIGNAL */
}
if (ptw & PostTransportStop) { if (ptw & PostTransportStop) {
_play_range = false; _play_range = false;
play_loop = false; play_loop = false;