Add option to limit automatable control parmaters
[ardour.git] / libs / ardour / session_state.cc
index ebb2b99cc1406eb8bebe068e6b041feef0eea170..34a6a4348061b84773c07536a5afd271daceb298 100644 (file)
@@ -85,7 +85,6 @@
 #include "ardour/automation_control.h"
 #include "ardour/boost_debug.h"
 #include "ardour/butler.h"
-#include "ardour/controllable_descriptor.h"
 #include "ardour/control_protocol_manager.h"
 #include "ardour/directory_names.h"
 #include "ardour/disk_reader.h"
 #include "ardour/template_utils.h"
 #include "ardour/tempo.h"
 #include "ardour/ticker.h"
+#include "ardour/transport_master_manager.h"
 #include "ardour/types_convert.h"
 #include "ardour/user_bundle.h"
 #include "ardour/vca.h"
@@ -183,7 +183,6 @@ Session::pre_engine_init (string fullpath)
        g_atomic_int_set (&_capture_load, 100);
        set_next_event ();
        _all_route_group->set_active (true, this);
-       interpolation.add_channel ();
 
        if (config.get_use_video_sync()) {
                waiting_for_sync_offset = true;
@@ -751,6 +750,8 @@ Session::remove_state (string snapshot_name)
                error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
                                xml_path, g_strerror (errno)) << endmsg;
        }
+
+       StateSaved (snapshot_name); /* EMIT SIGNAL */
 }
 
 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
@@ -875,6 +876,32 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
                }
        }
 
+       //Mixbus auto-backup mechanism
+       if(Profile->get_mixbus()) {
+               if (pending) {  //"pending" save means it's a backup, or some other non-user-initiated save;  a good time to make a backup
+                       // make a serialized safety backup
+                       // (will make one periodically but only one per hour is left on disk)
+                       // these backup files go into a separated folder
+                       char timebuf[128];
+                       time_t n;
+                       struct tm local_time;
+                       time (&n);
+                       localtime_r (&n, &local_time);
+                       strftime (timebuf, sizeof(timebuf), "%y-%m-%d.%H", &local_time);
+                       std::string save_path(session_directory().backup_path());
+                       save_path += G_DIR_SEPARATOR;
+                       save_path += legalize_for_path(_current_snapshot_name);
+                       save_path += "-";
+                       save_path += timebuf;
+                       save_path += statefile_suffix;
+                       if ( !tree.write (save_path) )
+                                       error << string_compose(_("Could not save backup file at path \"%1\" (%2)"),
+                                                       save_path, g_strerror (errno)) << endmsg;
+               }
+
+               StateSaved (snapshot_name); /* EMIT SIGNAL */
+       }
+
        if (!pending && !for_archive) {
 
                save_history (snapshot_name);
@@ -1453,12 +1480,7 @@ Session::state (bool save_template, snapshot_t snapshot_type, bool only_used_ass
                gain_child->add_child_nocopy (_click_gain->get_state ());
        }
 
-       if (_ltc_input) {
-               XMLNode* ltc_input_child = node->add_child ("LTC-In");
-               ltc_input_child->add_child_nocopy (_ltc_input->get_state ());
-       }
-
-       if (_ltc_input) {
+       if (_ltc_output) {
                XMLNode* ltc_output_child = node->add_child ("LTC-Out");
                ltc_output_child->add_child_nocopy (_ltc_output->get_state ());
        }
@@ -1497,8 +1519,7 @@ Session::state (bool save_template, snapshot_t snapshot_type, bool only_used_ass
 XMLNode&
 Session::get_control_protocol_state ()
 {
-       ControlProtocolManager& cpm (ControlProtocolManager::instance());
-       return cpm.get_state();
+       return ControlProtocolManager::instance().get_state ();
 }
 
 int
@@ -1708,7 +1729,7 @@ Session::set_state (const XMLNode& node, int version)
        }
 
        if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
-               ControlProtocolManager::instance().set_state (*child, version);
+               ControlProtocolManager::instance().set_state (*child, 1 /* here: session-specific state */);
        }
 
        if ((child = find_named_node (node, "Script"))) {
@@ -3648,7 +3669,7 @@ Session::set_dirty ()
        }
 
        /* never mark session dirty during loading */
-       if (_state_of_the_state & Loading) {
+       if (_state_of_the_state & (Loading | Deletion)) {
                return;
        }
 
@@ -3731,143 +3752,6 @@ Session::automation_control_by_id (const PBD::ID& id)
        return boost::dynamic_pointer_cast<AutomationControl> (controllable_by_id (id));
 }
 
-boost::shared_ptr<Controllable>
-Session::controllable_by_descriptor (const ControllableDescriptor& desc)
-{
-       boost::shared_ptr<Controllable> c;
-       boost::shared_ptr<Stripable> s;
-       boost::shared_ptr<Route> r;
-
-       switch (desc.top_level_type()) {
-       case ControllableDescriptor::NamedRoute:
-       {
-               std::string str = desc.top_level_name();
-
-               if (str == "Master" || str == "master") {
-                       s = _master_out;
-               } else if (str == "control" || str == "listen" || str == "monitor" || str == "Monitor") {
-                       s = _monitor_out;
-               } else if (str == "auditioner") {
-                       s = auditioner;
-               } else {
-                       s = route_by_name (desc.top_level_name());
-               }
-
-               break;
-       }
-
-       case ControllableDescriptor::PresentationOrderRoute:
-               s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Route);
-               break;
-
-       case ControllableDescriptor::PresentationOrderTrack:
-               s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Track);
-               break;
-
-       case ControllableDescriptor::PresentationOrderBus:
-               s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Bus);
-               break;
-
-       case ControllableDescriptor::PresentationOrderVCA:
-               s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::VCA);
-               break;
-
-       case ControllableDescriptor::SelectionCount:
-               s = route_by_selected_count (desc.selection_id());
-               break;
-       }
-
-       if (!s) {
-               return c;
-       }
-
-       r = boost::dynamic_pointer_cast<Route> (s);
-
-       switch (desc.subtype()) {
-       case ControllableDescriptor::Gain:
-               c = s->gain_control ();
-               break;
-
-       case ControllableDescriptor::Trim:
-               c = s->trim_control ();
-               break;
-
-       case ControllableDescriptor::Solo:
-               c = s->solo_control();
-               break;
-
-       case ControllableDescriptor::Mute:
-               c = s->mute_control();
-               break;
-
-       case ControllableDescriptor::Recenable:
-               c = s->rec_enable_control ();
-               break;
-
-       case ControllableDescriptor::PanDirection:
-               c = s->pan_azimuth_control();
-               break;
-
-       case ControllableDescriptor::PanWidth:
-               c = s->pan_width_control();
-               break;
-
-       case ControllableDescriptor::PanElevation:
-               c = s->pan_elevation_control();
-               break;
-
-       case ControllableDescriptor::Balance:
-               /* XXX simple pan control */
-               break;
-
-       case ControllableDescriptor::PluginParameter:
-       {
-               uint32_t plugin = desc.target (0);
-               uint32_t parameter_index = desc.target (1);
-
-               /* revert to zero based counting */
-
-               if (plugin > 0) {
-                       --plugin;
-               }
-
-               if (parameter_index > 0) {
-                       --parameter_index;
-               }
-
-               if (!r) {
-                       return c;
-               }
-
-               boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
-
-               if (p) {
-                       c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
-                               p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
-               }
-               break;
-       }
-
-       case ControllableDescriptor::SendGain: {
-               uint32_t send = desc.target (0);
-               if (send > 0) {
-                       --send;
-               }
-               if (!r) {
-                       return c;
-               }
-               c = r->send_level_controllable (send);
-               break;
-       }
-
-       default:
-               /* relax and return a null pointer */
-               break;
-       }
-
-       return c;
-}
-
 void
 Session::add_instant_xml (XMLNode& node, bool write_to_config)
 {
@@ -4214,11 +4098,7 @@ Session::config_changed (std::string p, bool ours)
                first_file_data_format_reset = false;
 
        } else if (p == "external-sync") {
-               if (!config.get_external_sync()) {
-                       drop_sync_source ();
-               } else {
-                       switch_to_sync_source (Config->get_sync_source());
-               }
+               request_sync_source (TransportMasterManager::instance().current());
        }  else if (p == "denormal-model") {
                setup_fpu ();
        } else if (p == "history-depth") {
@@ -4249,8 +4129,6 @@ Session::config_changed (std::string p, bool ours)
                last_timecode_valid = false;
        } else if (p == "playback-buffer-seconds") {
                AudioSource::allocate_working_buffers (sample_rate());
-       } else if (p == "ltc-source-port") {
-               reconnect_ltc_input ();
        } else if (p == "ltc-sink-port") {
                reconnect_ltc_output ();
        } else if (p == "timecode-generator-offset") {