remove reference to PluginState in VST code, for real this time
[ardour.git] / libs / ardour / session_state.cc
index 9d3ce2822552abf0bdb2f1578bb7ada4e18303bb..8a49636941e5c4327cff48bae548caf58019c31c 100644 (file)
@@ -84,6 +84,8 @@
 #include <ardour/region_factory.h>
 #include <ardour/source_factory.h>
 
+#include <control_protocol/control_protocol.h>
+
 #include "i18n.h"
 #include <locale.h>
 
@@ -159,7 +161,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        mmc = 0;
        session_send_mmc = false;
        session_send_mtc = false;
-       session_midi_feedback = false;
        post_transport_work = PostTransportWork (0);
        g_atomic_int_set (&butler_should_do_transport_work, 0);
        g_atomic_int_set (&butler_active, 0);
@@ -176,12 +177,14 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        pending_abort = false;
        destructive_index = 0;
        current_trans = 0;
-       
+       first_file_data_format_reset = true;
+       first_file_header_format_reset = true;
+
        AudioDiskstream::allocate_working_buffers();
        
        /* default short fade = 15ms */
 
-       Crossfade::set_short_xfade_length ((jack_nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
+       Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
        DestructiveFileSource::setup_standard_crossfades (frame_rate());
 
        last_mmc_step.tv_sec = 0;
@@ -240,8 +243,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
         Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
         AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
 
-       Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
-       Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
+       Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
 
        IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
 
@@ -433,7 +435,7 @@ Session::setup_raid_path (string path)
 }
 
 int
-Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
+Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
 {
        string dir;
 
@@ -725,19 +727,26 @@ Session::load_options (const XMLNode& node)
        return 0;
 }
 
+bool
+Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
+{
+       const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
+               (ConfigVariableBase::Session|ConfigVariableBase::Interface);
+
+       return owner & modified_by_session_or_user;
+}
+
 XMLNode&
 Session::get_options () const
 {
        XMLNode* child;
        LocaleGuard lg (X_("POSIX"));
 
-       XMLNode& option_root = Config->get_partial_state (ConfigVariableBase::Interface);
+       XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
 
        child = option_root.add_child ("end-marker-is-free");
        child->add_property ("val", _end_location_is_free ? "yes" : "no");
 
-       child = option_root.add_child ("full-xfades-unmuted");
-
        return option_root;
 }
 
@@ -958,6 +967,8 @@ Session::state(bool full_state)
 
        node->add_child_nocopy (_tempo_map->get_state());
 
+       node->add_child_nocopy (get_control_protocol_state());
+
        if (_extra_xml) {
                node->add_child_copy (*_extra_xml);
        }
@@ -965,6 +976,25 @@ Session::state(bool full_state)
        return *node;
 }
 
+XMLNode&
+Session::get_control_protocol_state ()
+{
+       ControlProtocolManager& cpm (ControlProtocolManager::instance());
+       XMLNode* node = new XMLNode (X_("ControlProtocols"));
+
+       cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
+       
+       return *node;
+}
+
+void
+Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
+{
+       if (cpi->protocol) {
+               node->add_child_nocopy (cpi->protocol->get_state());
+       }
+}
+
 int
 Session::set_state (const XMLNode& node)
 {
@@ -980,8 +1010,6 @@ Session::set_state (const XMLNode& node)
                return -1;
        }
 
-       StateManager::prohibit_save ();
-
        if ((prop = node.property ("name")) != 0) {
                _name = prop->value ();
        }
@@ -1021,6 +1049,7 @@ Session::set_state (const XMLNode& node)
        EditGroups
        MixGroups
        Click
+       ControlProtocols
        */
 
        if (use_config_midi_ports ()) {
@@ -1116,8 +1145,6 @@ Session::set_state (const XMLNode& node)
                start_location = location;
        }
 
-       _locations.save_state (_("initial state"));
-
        if ((child = find_named_node (node, "EditGroups")) == 0) {
                error << _("Session: XML state has no edit groups section") << endmsg;
                goto out;
@@ -1152,14 +1179,16 @@ Session::set_state (const XMLNode& node)
                _click_io->set_state (*child);
        }
        
+       if ((child = find_named_node (node, "ControlProtocols")) != 0) {
+               ControlProtocolManager::instance().set_protocol_states (*child);
+       }
+
        /* here beginneth the second phase ... */
 
        StateReady (); /* EMIT SIGNAL */
 
        _state_of_the_state = Clean;
 
-       StateManager::allow_save (_("initial state"), true);
-
        if (state_was_pending) {
                save_state (_current_snapshot_name);
                remove_pending_capture_state ();
@@ -1169,8 +1198,6 @@ Session::set_state (const XMLNode& node)
        return 0;
 
   out:
-       /* we failed, re-enable state saving but don't actually save internal state */
-       StateManager::allow_save (X_("ignored"), false);
        return ret;
 }
 
@@ -1256,6 +1283,11 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
                nchans = atoi (prop->value().c_str());
        }
 
+
+       if ((prop = node.property ("name")) == 0) {
+               cerr << "no name for this region\n";
+               abort ();
+       }
        
        if ((prop = node.property (X_("source-0"))) == 0) {
                if ((prop = node.property ("source")) == 0) {
@@ -2394,13 +2426,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                delete *x;
        }
 
-       /* step 2: clear the undo/redo history for all playlists */
-
-       for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
-               (*x)->drop_all_states ();
-       }
-
-       /* step 3: find all un-referenced sources */
+       /* step 2: find all un-referenced sources */
 
        rep.paths.clear ();
        rep.space = 0;
@@ -2430,7 +2456,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                i = tmp;
        }
 
-       /* Step 4: get rid of all regions in the region list that use any dead sources
+       /* Step 3: get rid of all regions in the region list that use any dead sources
           in case the sources themselves don't go away (they might be referenced in
           other snapshots).
        */
@@ -2710,7 +2736,7 @@ void
 Session::add_controllable (Controllable* c)
 {
        Glib::Mutex::Lock lm (controllables_lock);
-       controllables.push_back (c);
+       controllables.insert (c);
 }
 
 void
@@ -2721,7 +2747,12 @@ Session::remove_controllable (Controllable* c)
        }
 
        Glib::Mutex::Lock lm (controllables_lock);
-       controllables.remove (c);
+
+       Controllables::iterator x = controllables.find (c);
+
+       if (x != controllables.end()) {
+               controllables.erase (x);
+       }
 }      
 
 Controllable*
@@ -2818,41 +2849,39 @@ Session::restore_history (string snapshot_name)
 
     /* replace history */
     history.clear();
-    for (XMLNodeConstIterator it  = tree.root()->children().begin();
-         it != tree.root()->children().end();
-         it++)
-    {
-        XMLNode *t = *it;
-        UndoTransaction* ut = new UndoTransaction ();
-        struct timeval tv;
-
-        ut->set_name(t->property("name")->value());
-        stringstream ss(t->property("tv_sec")->value());
-        ss >> tv.tv_sec;
-        ss.str(t->property("tv_usec")->value());
-        ss >> tv.tv_usec;
-        ut->set_timestamp(tv);
-
-        for (XMLNodeConstIterator child_it  = t->children().begin();
-             child_it != t->children().end();
-             child_it++)
-        {
-            XMLNode *n = *child_it;
-            Command *c;
-            if (n->name() == "MementoCommand" ||
-                n->name() == "MementoUndoCommand" ||
-                n->name() == "MementoRedoCommand")
-            {
-                c = memento_command_factory(n);
-                if (c)
-                    ut->add_command(c);
-            }
-            else
-            {
-                error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
-            }
-        }
-        history.add(ut);
+
+    for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
+           
+           XMLNode *t = *it;
+           UndoTransaction* ut = new UndoTransaction ();
+           struct timeval tv;
+           
+           ut->set_name(t->property("name")->value());
+           stringstream ss(t->property("tv_sec")->value());
+           ss >> tv.tv_sec;
+           ss.str(t->property("tv_usec")->value());
+           ss >> tv.tv_usec;
+           ut->set_timestamp(tv);
+           
+           for (XMLNodeConstIterator child_it  = t->children().begin();
+                child_it != t->children().end();
+                child_it++)
+           {
+                   XMLNode *n = *child_it;
+                   Command *c;
+       
+                   if (n->name() == "MementoCommand" ||
+                       n->name() == "MementoUndoCommand" ||
+                       n->name() == "MementoRedoCommand") {
+                           if ((c = memento_command_factory(n))) {
+                                   ut->add_command(c);
+                           }
+                   } else {
+                           error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
+                   }
+           }
+
+           history.add (ut);
     }
 
     return 0;
@@ -2871,7 +2900,7 @@ Session::config_changed (const char* parameter_name)
                
        } else if (PARAM_IS ("auto-input")) {
 
-               if (Config->get_use_hardware_monitoring() && transport_rolling()) {
+               if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
                        /* auto-input only makes a difference if we're rolling */
                        
                        boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
@@ -3006,6 +3035,25 @@ Session::config_changed (const char* parameter_name)
                        session_midi_feedback = Config->get_midi_feedback();
                }
 
+       } else if (PARAM_IS ("jack-time-master")) {
+
+               engine().reset_timebase ();
+
+       } else if (PARAM_IS ("native-file-header-format")) {
+
+               if (!first_file_header_format_reset) {
+                       reset_native_file_format ();
+               }
+
+               first_file_header_format_reset = false;
+
+       } else if (PARAM_IS ("native-file-data-format")) {
+
+               if (!first_file_data_format_reset) {
+                       reset_native_file_format ();
+               }
+
+               first_file_data_format_reset = false;
        }
                
        set_dirty ();