Create the session range location as and when the session first gets some content...
authorCarl Hetherington <carl@carlh.net>
Sun, 9 May 2010 20:48:21 +0000 (20:48 +0000)
committerCarl Hetherington <carl@carlh.net>
Sun, 9 May 2010 20:48:21 +0000 (20:48 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@7087 d708f5d6-7413-0410-9779-e7cbd77b26cf

18 files changed:
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_keyboard.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_summary.cc
libs/ardour/ardour/playlist.h
libs/ardour/ardour/session.h
libs/ardour/ardour/session_configuration_vars.h
libs/ardour/audiofilesource.cc
libs/ardour/auditioner.cc
libs/ardour/location.cc
libs/ardour/playlist.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/ardour/session_transport.cc

index 45e77a6e9618ca038610af1b2d9a54943af80757..2cc64ae6129c376700166dda56815f0c6745ac0b 100644 (file)
@@ -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);
index a772d9eef90fed2d9ca78f9b821fa98140e5690a..153fbe565148b6d0401c0dd63f06a4eeceea8ff9 100644 (file)
@@ -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 {
index 52e381b032625b31b2365e3bf5c08124c38c3ee8..b072a2779e13d49d8c4feabb31a920a27ae406eb 100644 (file)
@@ -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);
+}
index f1ad6e773a5baa3f06bd66caeed254bcb90d5fd9..a35357884a04c90e96bcf5d1fa91104b6ba3e836 100644 (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()->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);
        }
 
index bb047a1440df99d1f5c693669afeab73592ae85c..da6fadfe16bb4db7b5e93a3502669b087ca61b71 100644 (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);
-               worldx += _horizontal_position;
+               worldx += horizontal_position();
                worldy += vertical_adjustment.get_value();
 
                ev.type = GDK_BUTTON_PRESS;
index 551183d205f61811790b09e081afaa33a82cf42d..dfdb3c811a76835878902d6c66c528e86df62515 100644 (file)
@@ -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 ();
 }
index 2e5055e755258f4c726da924a3ed478fef31b616..25e0b0016bb0f74632130784eba5e5c4080ede4e 100644 (file)
@@ -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;
index fd4422bc08f62f56a4f3135c9b1fd201003e6c72..5c2135ac43ac45d8dbedae624f3f29ba8956720c 100644 (file)
@@ -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 */
index c5b79644c65fb0f6fd2e23ce19d005cf282b3517..d13789fa380daf4998bca37e577ccc2c11925cef 100644 (file)
@@ -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);
index 4182ce1ea1dc9dabde494d658136742a1e2c9243..0f5a73a28032df055e40272cbf2ddc8f20b5398c 100644 (file)
@@ -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
index 2776787271b6d491c29506c4126729b002bd2fe2..df76057e0bd0ad9818237f1d078bf95d0e5f3a8b 100644 (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 (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")
index 0e498c3d59a418d88bae2dab270474e43bd34009..1973678359c4c7ff86b46f800f20af00b7e9e1ff 100644 (file)
@@ -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;
index 8b8f850f8bd6dfde0cff7c973e65dbfae1bda18c..45a836582df7bea7bdde2ba4bd0b5a9f4e0943a5 100644 (file)
@@ -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 */
index f855cb75cffff6c67248eaf0befb18d3461b714d..7202e1ef035def7603447ef8fe9ca5630ac9887e 100644 (file)
@@ -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);
index 649d549b8658d9ec13a7f31949ecfc09a47396f1..a5e662f4d024790de6d45b2c4ce61d664e6a22fb 100644 (file)
@@ -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
index 2d4aefd3888fe9642e5164378a5999abe10304cb..a5443a179773a9dfe2c3790ba56814f07def278c 100644 (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));
 
        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);
+}
index a0e61d547a1d2b83802d572b147e88b19120a6e9..ee7e88caaa489868f732193a82dabb81e212f629 100644 (file)
@@ -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;
index 6d7d3b4521c9abdea1c1d1018e8d685081b53685..7a378e1a01be6b64a5586ded867510fb8e03f740 100644 (file)
@@ -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;