full compilation and linking (coding not finished, will not run)
[ardour.git] / libs / ardour / session_state.cc
index 1389d1ac165d153e0515287fd220aa6400e3a76d..cae3b9720acf7233030d13206066a4617a45de63 100644 (file)
@@ -54,7 +54,7 @@
 #include <glib/gstdio.h>
 
 #include <glibmm.h>
-#include <glibmm/thread.h>
+#include <glibmm/threads.h>
 
 #include <boost/algorithm/string.hpp>
 
@@ -72,7 +72,6 @@
 #include "pbd/file_utils.h"
 #include "pbd/pathscanner.h"
 #include "pbd/pthread_utils.h"
-#include "pbd/search_path.h"
 #include "pbd/stacktrace.h"
 #include "pbd/convert.h"
 #include "pbd/clear_dir.h"
@@ -94,7 +93,6 @@
 #include "ardour/midi_region.h"
 #include "ardour/midi_source.h"
 #include "ardour/midi_track.h"
-#include "ardour/named_selection.h"
 #include "ardour/pannable.h"
 #include "ardour/playlist_factory.h"
 #include "ardour/port.h"
 #include "ardour/session_metadata.h"
 #include "ardour/session_playlists.h"
 #include "ardour/session_state_utils.h"
-#include "ardour/session_utils.h"
 #include "ardour/silentfilesource.h"
 #include "ardour/sndfilesource.h"
 #include "ardour/source_factory.h"
@@ -139,7 +136,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
 
        char buf[PATH_MAX+1];
        if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
-               error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
+               error << string_compose(_("Could not use path %1 (%2)"), buf, strerror(errno)) << endmsg;
                destroy ();
                throw failed_constructor();
        }
@@ -158,7 +155,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
 
        set_history_depth (Config->get_history_depth());
 
-       _current_frame_rate = _engine.frame_rate ();
+       _current_frame_rate = _engine.sample_rate ();
        _nominal_frame_rate = _current_frame_rate;
        _base_frame_rate = _current_frame_rate;
 
@@ -209,6 +206,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        _play_range = false;
        _exporting = false;
        pending_abort = false;
+       _adding_routes_in_progress = false;
        destructive_index = 0;
        first_file_data_format_reset = true;
        first_file_header_format_reset = true;
@@ -369,6 +367,7 @@ Session::second_stage_init ()
 
        MIDI::Name::MidiPatchManager::instance().set_session (this);
 
+       ltc_tx_initialize();
        /* initial program change will be delivered later; see ::config_changed() */
 
        _state_of_the_state = Clean;
@@ -579,7 +578,7 @@ Session::create (const string& session_template, BusProfile* bus_profile)
                        // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
 #endif
                        {
-                               Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+                               Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
                                r->input()->ensure_io (count, false, this);
                                r->output()->ensure_io (count, false, this);
                        }
@@ -686,7 +685,7 @@ Session::remove_state (string snapshot_name)
 
        // and delete it
        if (g_remove (xml_path.c_str()) != 0) {
-               error << string_compose(_("Could not remove state file at path \"%1\" (%2)"),
+               error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
                                xml_path, g_strerror (errno)) << endmsg;
        }
 }
@@ -695,7 +694,7 @@ Session::remove_state (string snapshot_name)
 void
 Session::jack_session_event (jack_session_event_t * event)
 {
-        char timebuf[128];
+        char timebuf[128], *tmp;
         time_t n;
         struct tm local_time;
 
@@ -703,6 +702,8 @@ Session::jack_session_event (jack_session_event_t * event)
         localtime_r (&n, &local_time);
         strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
 
+        while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
+
         if (event->type == JackSessionSaveTemplate)
         {
                 if (save_template( timebuf )) {
@@ -735,7 +736,15 @@ Session::jack_session_event (jack_session_event_t * event)
                 }
         }
 
-       jack_session_reply (_engine.jack(), event);
+       /* this won't be called if the port engine in use is not JACK, so we do 
+          not have to worry about the type of PortEngine::private_handle()
+       */
+
+       jack_client_t* jack_client = (jack_client_t*) AudioEngine::instance()->port_engine().private_handle();
+       
+       if (jack_client) {
+               jack_session_reply (jack_client, event);
+       }
 
        if (event->type == JackSessionSaveAndQuit) {
                Quit (); /* EMIT SIGNAL */
@@ -773,6 +782,8 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
                }
        }
 
+       SaveSession (); /* EMIT SIGNAL */
+
        tree.set_root (&get_state());
 
        if (snapshot_name.empty()) {
@@ -808,7 +819,7 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
        if (!tree.write (tmp_path)) {
                error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
                if (g_remove (tmp_path.c_str()) != 0) {
-                       error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
+                       error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
                                        tmp_path, g_strerror (errno)) << endmsg;
                }
                return -1;
@@ -819,7 +830,7 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
                        error << string_compose (_("could not rename temporary session file %1 to %2"),
                                        tmp_path, xml_path) << endmsg;
                        if (g_remove (tmp_path.c_str()) != 0) {
-                               error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
+                               error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
                                                tmp_path, g_strerror (errno)) << endmsg;
                        }
                        return -1;
@@ -884,7 +895,7 @@ Session::load_state (string snapshot_name)
        if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
                xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
                if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
-                        error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
+                        error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
                         return 1;
                 }
         }
@@ -896,7 +907,7 @@ Session::load_state (string snapshot_name)
        _writable = exists_and_writable (xmlpath);
 
        if (!state_tree->read (xmlpath)) {
-               error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
+               error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
                delete state_tree;
                state_tree = 0;
                return -1;
@@ -939,9 +950,7 @@ Session::load_state (string snapshot_name)
 
                if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
                        
-                       info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
-                                               xmlpath, backup_path, PROGRAM_NAME)
-                            << endmsg;
+                       VersionMismatch (xmlpath, backup_path);
                        
                        if (!copy_file (xmlpath, backup_path)) {;
                                return -1;
@@ -1046,7 +1055,7 @@ Session::state (bool full_state)
        child = node->add_child ("Sources");
 
        if (full_state) {
-               Glib::Mutex::Lock sl (source_lock);
+               Glib::Threads::Mutex::Lock sl (source_lock);
 
                for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
 
@@ -1073,13 +1082,17 @@ Session::state (bool full_state)
        child = node->add_child ("Regions");
 
        if (full_state) {
-               Glib::Mutex::Lock rl (region_lock);
+               Glib::Threads::Mutex::Lock rl (region_lock);
                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
                         boost::shared_ptr<Region> r = i->second;
                         /* only store regions not attached to playlists */
                         if (r->playlist() == 0) {
-                                child->add_child_nocopy (r->state ());
+                               if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
+                                       child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
+                               } else {
+                                       child->add_child_nocopy (r->get_state ());
+                               }
                         }
                 }
 
@@ -1138,7 +1151,7 @@ Session::state (bool full_state)
                 }
 
                for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
-                       if (!(*i)->is_hidden()) {
+                       if (!(*i)->is_auditioner()) {
                                if (full_state) {
                                        child->add_child_nocopy ((*i)->get_state());
                                } else {
@@ -1161,13 +1174,14 @@ Session::state (bool full_state)
                gain_child->add_child_nocopy (_click_gain->state (full_state));
        }
 
-       if (full_state) {
-               XMLNode* ns_child = node->add_child ("NamedSelections");
-               for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
-                       if (full_state) {
-                               ns_child->add_child_nocopy ((*i)->get_state());
-                       }
-               }
+       if (_ltc_input) {
+               XMLNode* ltc_input_child = node->add_child ("LTC-In");
+               ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
+       }
+
+       if (_ltc_input) {
+               XMLNode* ltc_output_child = node->add_child ("LTC-Out");
+               ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
        }
 
         node->add_child_nocopy (_speakers->get_state());
@@ -1329,12 +1343,6 @@ Session::set_state (const XMLNode& node, int version)
                }
        }
 
-       if ((child = find_named_node (node, "NamedSelections")) != 0) {
-               if (load_named_selections (*child)) {
-                       goto out;
-               }
-       }
-
        if (version >= 3000) {
                if ((child = find_named_node (node, "Bundles")) == 0) {
                        warning << _("Session: XML state has no bundles section") << endmsg;
@@ -1404,8 +1412,8 @@ Session::set_state (const XMLNode& node, int version)
                }
        }
 
-       if ((child = find_named_node (node, "ControlProtocols")) != 0) {
-               ControlProtocolManager::instance().set_protocol_states (*child);
+       if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
+               ControlProtocolManager::instance().set_state (*child, version);
        }
 
        update_have_rec_enabled_track ();
@@ -1665,7 +1673,7 @@ Session::load_nested_sources (const XMLNode& node)
 
                        XMLProperty* prop = (*niter)->property (X_("id"));
                        if (!prop) {
-                               error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
+                               error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
                                continue;
                        }
 
@@ -1897,7 +1905,7 @@ Session::get_sources_as_xml ()
 
 {
        XMLNode* node = new XMLNode (X_("Sources"));
-       Glib::Mutex::Lock lm (source_lock);
+       Glib::Threads::Mutex::Lock lm (source_lock);
 
        for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
                node->add_child_nocopy (i->second->get_state());
@@ -2082,9 +2090,9 @@ Session::save_template (string template_name)
 void
 Session::refresh_disk_space ()
 {
-#if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
+#if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
        
-       Glib::Mutex::Lock lm (space_lock);
+       Glib::Threads::Mutex::Lock lm (space_lock);
 
        /* get freespace on every FS that is part of the session path */
 
@@ -2191,7 +2199,8 @@ Session::get_best_session_directory_for_new_source ()
                        }
 
                        if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
-                               if (create_session_directory ((*i).path)) {
+                               SessionDirectory sdir(i->path);
+                               if (sdir.create ()) {
                                        result = (*i).path;
                                        last_rr_session_dir = i;
                                        return result;
@@ -2213,7 +2222,8 @@ Session::get_best_session_directory_for_new_source ()
                sort (sorted.begin(), sorted.end(), cmp);
 
                for (i = sorted.begin(); i != sorted.end(); ++i) {
-                       if (create_session_directory ((*i).path)) {
+                       SessionDirectory sdir(i->path);
+                       if (sdir.create ()) {
                                result = (*i).path;
                                last_rr_session_dir = i;
                                return result;
@@ -2224,39 +2234,6 @@ Session::get_best_session_directory_for_new_source ()
        return result;
 }
 
-int
-Session::load_named_selections (const XMLNode& node)
-{
-       XMLNodeList nlist;
-       XMLNodeConstIterator niter;
-       NamedSelection *ns;
-
-       nlist = node.children();
-
-       set_dirty();
-
-       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-
-               if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
-                       error << _("Session: cannot create Named Selection from XML description.") << endmsg;
-               }
-       }
-
-       return 0;
-}
-
-NamedSelection *
-Session::XMLNamedSelectionFactory (const XMLNode& node)
-{
-       try {
-               return new NamedSelection (*this, node);
-       }
-
-       catch (failed_constructor& err) {
-               return 0;
-       }
-}
-
 string
 Session::automation_dir () const
 {
@@ -2295,7 +2272,7 @@ Session::load_bundles (XMLNode const & node)
                } else if ((*niter)->name() == "OutputBundle") {
                        add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
                } else {
-                       error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
+                       error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
                        return -1;
                }
        }
@@ -2622,7 +2599,7 @@ Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_th
                ripped = ripped.substr (0, ripped.length() - 1);
        }
 
-       state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
+       state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
 
        if (state_files == 0) {
                /* impossible! */
@@ -3052,7 +3029,7 @@ Session::add_controllable (boost::shared_ptr<Controllable> c)
           as part of the session.
        */
 
-       Glib::Mutex::Lock lm (controllables_lock);
+       Glib::Threads::Mutex::Lock lm (controllables_lock);
        controllables.insert (c);
 }
 
@@ -3065,7 +3042,7 @@ Session::remove_controllable (Controllable* c)
                return;
        }
 
-       Glib::Mutex::Lock lm (controllables_lock);
+       Glib::Threads::Mutex::Lock lm (controllables_lock);
 
        Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
 
@@ -3077,7 +3054,7 @@ Session::remove_controllable (Controllable* c)
 boost::shared_ptr<Controllable>
 Session::controllable_by_id (const PBD::ID& id)
 {
-       Glib::Mutex::Lock lm (controllables_lock);
+       Glib::Threads::Mutex::Lock lm (controllables_lock);
 
        for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
                if ((*i)->id() == id) {
@@ -3201,7 +3178,7 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc)
                if (p) {
                        boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
                        boost::shared_ptr<Amp> a = s->amp();
-
+                       
                        if (a) {
                                c = s->amp()->gain_control();
                        }
@@ -3436,7 +3413,7 @@ Session::config_changed (std::string p, bool ours)
 
        } else if (p == "edit-mode") {
 
-               Glib::Mutex::Lock lm (playlists->lock);
+               Glib::Threads::Mutex::Lock lm (playlists->lock);
 
                for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
                        (*i)->set_edit_mode (Config->get_edit_mode ());
@@ -3549,16 +3526,32 @@ Session::config_changed (std::string p, bool ours)
                if (!config.get_external_sync()) {
                        drop_sync_source ();
                } else {
-                       switch_to_sync_source (config.get_sync_source());
+                       switch_to_sync_source (Config->get_sync_source());
                }
-       } else if (p == "remote-model") {
-               set_remote_control_ids ();
        }  else if (p == "denormal-model") {
                setup_fpu ();
        } else if (p == "history-depth") {
                set_history_depth (Config->get_history_depth());
+       } else if (p == "remote-model") {
+               /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
+                  TO SET REMOTE ID'S
+               */
        } else if (p == "sync-all-route-ordering") {
-               sync_order_keys ("session");
+
+               /* sync to editor order unless mixer is used for remote IDs 
+                */
+
+               switch (Config->get_remote_model()) {
+               case UserOrdered:
+                       sync_order_keys (EditorSort);
+                       break;
+               case EditorOrdered:
+                       sync_order_keys (EditorSort);
+                       break;
+               case MixerOrdered:
+                       sync_order_keys (MixerSort);
+               }
+                       
        } else if (p == "initial-program-change") {
 
                if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
@@ -3581,6 +3574,12 @@ Session::config_changed (std::string p, bool ours)
                AudioSource::allocate_working_buffers (frame_rate());
        } else if (p == "automation-thinning-factor") {
                Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
+       } else if (p == "ltc-source-port") {
+               reconnect_ltc_input ();
+       } else if (p == "ltc-sink-port") {
+               reconnect_ltc_output ();
+       } else if (p == "timecode-generator-offset") {
+               ltc_tx_parse_offset();
        }
 
        set_dirty ();