Don’t use invalid iterator during cleanup. fixes #6403
[ardour.git] / libs / ardour / session_state.cc
index eca01cbe9995313436d7cdf069217503fb87c3c0..6dc5462d58814f4b2a4839df0e9e0224026f9490 100644 (file)
@@ -142,8 +142,18 @@ Session::pre_engine_init (string fullpath)
        _path = canonical_path(fullpath);
 
        /* is it new ? */
+       if (Profile->get_trx() ) {
+               // Waves TracksLive has a usecase of session replacement with a new one.
+               // We should check session state file (<session_name>.ardour) existance
+               // to determine if the session is new or not
 
-       _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
+               string full_session_name = Glib::build_filename( fullpath, _name );
+               full_session_name += statefile_suffix;
+               
+               _is_new = !Glib::file_test (full_session_name, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
+       } else {
+               _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
+       }
 
        /* finish initialization that can't be done in a normal C++ constructor
           definition.
@@ -271,6 +281,7 @@ Session::post_engine_init ()
                
                Config->map_parameters (ff);
                config.map_parameters (ft);
+                _butler->map_parameters ();
 
                /* Reset all panners */
                
@@ -352,6 +363,18 @@ Session::post_engine_init ()
                state_was_pending = false;
        }
 
+       /* Now, finally, we can fill the playback buffers */
+    
+       BootMessage (_("Filling playback buffers"));
+    
+       boost::shared_ptr<RouteList> rl = routes.reader();
+       for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
+               boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (*r);
+               if (trk && !trk->hidden()) {
+                       trk->seek (_transport_frame, true);
+               }
+       }
+
        return 0;
 }
 
@@ -375,14 +398,7 @@ Session::session_loaded ()
        /* Now, finally, we can fill the playback buffers */
        
        BootMessage (_("Filling playback buffers"));
-       
-       boost::shared_ptr<RouteList> rl = routes.reader();
-       for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
-               boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (*r);
-               if (trk && !trk->hidden()) {
-                       trk->seek (_transport_frame, true);
-               }
-       }
+       force_locate (_transport_frame, false);
 }
 
 string
@@ -559,7 +575,21 @@ Session::create (const string& session_template, BusProfile* bus_profile)
 
        }
 
-       /* set initial start + end point */
+       if (Profile->get_trx()) {
+       
+               /* set initial start + end point : ARDOUR::Session::session_end_shift long.
+                  Remember that this is a brand new session. Sessions
+                  loaded from saved state will get this range from the saved state.
+               */
+               
+               set_session_range_location (0, 0);
+               
+               /* Initial loop location, from absolute zero, length 10 seconds  */
+               
+               Location* loc = new Location (*this, 0, 10.0 * _engine.sample_rate(), _("Loop"),  Location::IsAutoLoop);
+               _locations->add (loc, true);
+               set_auto_loop_location (loc);
+       }
 
        _state_of_the_state = Clean;
 
@@ -1101,6 +1131,7 @@ Session::state (bool full_state)
                XMLNode& locations_state = loc.get_state();
                
                if (ARDOUR::Profile->get_trx() && _locations) {
+                       // For tracks we need stored the Auto Loop Range and all MIDI markers.
                        for (Locations::LocationList::const_iterator i = _locations->list ().begin (); i != _locations->list ().end (); ++i) {
                                if ((*i)->is_mark () || (*i)->is_auto_loop ()) {
                                        locations_state.add_child_nocopy ((*i)->get_state ());
@@ -1908,17 +1939,15 @@ Session::get_sources_as_xml ()
 void
 Session::reset_write_sources (bool mark_write_complete, bool force)
 {
-    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) {
-                       
-                       // block state saving
+       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) {
                        _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
                        tr->reset_write_sources(mark_write_complete, force);
                        _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
-        }
-    }
+               }
+       }
 }
 
 int
@@ -2313,25 +2342,25 @@ Session::get_best_session_directory_for_new_audio ()
 string
 Session::automation_dir () const
 {
-       return Glib::build_filename (_path, "automation");
+       return Glib::build_filename (_path, automation_dir_name);
 }
 
 string
 Session::analysis_dir () const
 {
-       return Glib::build_filename (_path, "analysis");
+       return Glib::build_filename (_path, analysis_dir_name);
 }
 
 string
 Session::plugins_dir () const
 {
-       return Glib::build_filename (_path, "plugins");
+       return Glib::build_filename (_path, plugins_dir_name);
 }
 
 string
 Session::externals_dir () const
 {
-       return Glib::build_filename (_path, "externals");
+       return Glib::build_filename (_path, externals_dir_name);
 }
 
 int
@@ -2859,6 +2888,8 @@ Session::cleanup_sources (CleanupReport& rep)
                                           in the region list.
                                        */
                                        
+                                       std::string fpath = i->second->name ();
+
                                        RegionFactory::remove_regions_using_source (i->second);
                                        sources.erase (i);
                                        
@@ -2866,7 +2897,7 @@ Session::cleanup_sources (CleanupReport& rep)
                                        
                                        for (set<string>::iterator j = all_sources.begin(); j != all_sources.end(); ++j) {
                                                spath = Glib::path_get_basename (*j);
-                                               if ( spath == i->second->name () ) {
+                                               if ( spath == fpath ) {
                                                        all_sources.erase (j);
                                                        break;
                                                }
@@ -3633,6 +3664,8 @@ Session::config_changed (std::string p, bool ours)
                reconnect_ltc_output ();
        } else if (p == "timecode-generator-offset") {
                ltc_tx_parse_offset();
+       } else if (p == "auto-return-target-list") {
+               follow_playhead_priority ();
        }
 
        set_dirty ();
@@ -4425,6 +4458,7 @@ Session::save_as (SaveAs& saveas)
                        if (internal_file_cnt) {
                                for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
                                        ensure_search_path_includes (*s, DataType::AUDIO);
+                                       cerr << "be sure to include " << *s << "  for audio" << endl;
                                }
 
                                /* we do not do this for MIDI because we copy