X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_state.cc;h=5b10389a3f620f0a058db2719f4d91adacf3e8b3;hb=e0ff70cf86c01c42f98faf8b0eaf1a8ccf867946;hp=95eb36c07f4ec6fb617d12f20b214a8fac01f438;hpb=b2149de37b8a55fb69d1da65ea321d93e40e5e7c;p=ardour.git diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 95eb36c07f..5b10389a3f 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -61,7 +61,6 @@ #include "evoral/SMF.hpp" -#include "pbd/boost_debug.h" #include "pbd/basename.h" #include "pbd/controllable_descriptor.h" #include "pbd/debug.h" @@ -83,6 +82,7 @@ #include "ardour/audiofilesource.h" #include "ardour/audioregion.h" #include "ardour/automation_control.h" +#include "ardour/boost_debug.h" #include "ardour/butler.h" #include "ardour/control_protocol_manager.h" #include "ardour/directory_names.h" @@ -119,6 +119,8 @@ #include "ardour/tempo.h" #include "ardour/ticker.h" #include "ardour/user_bundle.h" +#include "ardour/vca.h" +#include "ardour/vca_manager.h" #include "control_protocol/control_protocol.h" @@ -171,6 +173,7 @@ Session::pre_engine_init (string fullpath) set_next_event (); _all_route_group->set_active (true, this); interpolation.add_channel_to (0, 0); + _vca_manager = new VCAManager (*this); if (config.get_use_video_sync()) { waiting_for_sync_offset = true; @@ -248,9 +251,11 @@ Session::post_engine_init () delete _tempo_map; _tempo_map = new TempoMap (_current_frame_rate); _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1)); + _tempo_map->MetricPositionChanged.connect_same_thread (*this, boost::bind (&Session::gui_tempo_map_changed, this)); /* MidiClock requires a tempo map */ + delete midi_clock; midi_clock = new MidiClockTicker (); midi_clock->set_session (this); @@ -623,7 +628,7 @@ Session::create (const string& session_template, BusProfile* bus_profile) _state_of_the_state = Clean; - /* set up Master Out and Control Out if necessary */ + /* set up Master Out and Monitor Out if necessary */ if (bus_profile) { @@ -632,14 +637,14 @@ Session::create (const string& session_template, BusProfile* bus_profile) // Waves Tracks: always create master bus for Tracks if (ARDOUR::Profile->get_trx() || bus_profile->master_out_channels) { - boost::shared_ptr r (new Route (*this, _("Master"), Route::MasterOut, DataType::AUDIO)); + boost::shared_ptr r (new Route (*this, _("Master"), PresentationInfo::MasterOut, DataType::AUDIO)); if (r->init ()) { return -1; } -#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - // boost_debug_shared_ptr_mark_interesting (r.get(), "Route"); -#endif - { + + BOOST_MARK_ROUTE(r); + + { Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); r->input()->ensure_io (count, false, this); r->output()->ensure_io (count, false, this); @@ -653,7 +658,7 @@ Session::create (const string& session_template, BusProfile* bus_profile) } if (!rl.empty()) { - add_routes (rl, false, false, false); + add_routes (rl, false, false, false, PresentationInfo::max_order); } // Waves Tracks: Skip this. Always use autoconnection for Tracks @@ -758,6 +763,8 @@ Session::remove_state (string snapshot_name) int Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot, bool template_only) { + DEBUG_TRACE (DEBUG::Locale, string_compose ("Session::save_state locale '%1'\n", setlocale (LC_NUMERIC, NULL))); + XMLTree tree; std::string xml_path(_session_dir->root_path()); @@ -948,7 +955,7 @@ Session::load_state (string snapshot_name) return -1; } - XMLNode& root (*state_tree->root()); + XMLNode const & root (*state_tree->root()); if (root.name() != X_("Session")) { error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg; @@ -957,7 +964,7 @@ Session::load_state (string snapshot_name) return -1; } - const XMLProperty* prop; + XMLProperty const * prop; if ((prop = root.property ("version")) == 0) { /* no version implies very old version of Ardour */ @@ -1001,7 +1008,7 @@ Session::load_state (string snapshot_name) int Session::load_options (const XMLNode& node) { - LocaleGuard lg (X_("C")); + LocaleGuard lg; config.set_variables (node); return 0; } @@ -1034,6 +1041,7 @@ Session::get_template() XMLNode& Session::state (bool full_state) { + LocaleGuard lg; XMLNode* node = new XMLNode("Session"); XMLNode* child; @@ -1092,6 +1100,11 @@ Session::state (bool full_state) snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter()); node->add_property ("event-counter", buf); + /* save the VCA counter */ + + snprintf (buf, sizeof (buf), "%" PRIu32, VCA::get_next_vca_number()); + node->add_property ("vca-counter", buf); + /* various options */ list midi_port_nodes = _midi_ports->get_midi_port_states(); @@ -1206,6 +1219,8 @@ Session::state (bool full_state) } } + node->add_child_nocopy (_vca_manager->get_state()); + child = node->add_child ("Routes"); { boost::shared_ptr r = routes.reader (); @@ -1295,9 +1310,10 @@ Session::get_control_protocol_state () int Session::set_state (const XMLNode& node, int version) { + LocaleGuard lg; XMLNodeList nlist; XMLNode* child; - const XMLProperty* prop; + XMLProperty const * prop; int ret = -1; _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave); @@ -1349,6 +1365,14 @@ Session::set_state (const XMLNode& node, int version) Evoral::init_event_id_counter (atoi (prop->value())); } + if ((prop = node.property (X_("vca-counter"))) != 0) { + uint32_t x; + sscanf (prop->value().c_str(), "%" PRIu32, &x); + VCA::set_next_vca_number (x); + } else { + VCA::set_next_vca_number (1); + } + if ((child = find_named_node (node, "MIDIPorts")) != 0) { _midi_ports->set_midi_port_states (child->children()); } @@ -1451,6 +1475,10 @@ Session::set_state (const XMLNode& node, int version) } } + if ((child = find_named_node (node, VCAManager::xml_node_name)) != 0) { + _vca_manager->set_state (*child, version); + } + if ((child = find_named_node (node, "Routes")) == 0) { error << _("Session: XML state has no routes section") << endmsg; goto out; @@ -1458,6 +1486,10 @@ Session::set_state (const XMLNode& node, int version) goto out; } + /* Now that we have Routes and masters loaded, connect them if appropriate */ + + Slavable::Assign (_vca_manager); /* EMIT SIGNAL */ + /* our diskstreams list is no longer needed as they are now all owned by their Route */ _diskstreams_2X.clear (); @@ -1561,7 +1593,7 @@ Session::load_routes (const XMLNode& node, int version) BootMessage (_("Tracks/busses loaded; Adding to Session")); - add_routes (new_routes, false, false, false); + add_routes (new_routes, false, false, false, PresentationInfo::max_order); BootMessage (_("Finished adding tracks/busses")); @@ -1580,7 +1612,7 @@ Session::XMLRouteFactory (const XMLNode& node, int version) XMLNode* ds_child = find_named_node (node, X_("Diskstream")); DataType type = DataType::AUDIO; - const XMLProperty* prop = node.property("default-type"); + XMLProperty const * prop = node.property("default-type"); if (prop) { type = DataType (prop->value()); @@ -1606,24 +1638,15 @@ Session::XMLRouteFactory (const XMLNode& node, int version) return ret; } -#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - // boost_debug_shared_ptr_mark_interesting (track.get(), "Track"); -#endif + BOOST_MARK_TRACK (track); ret = track; } else { - enum Route::Flag flags = Route::Flag(0); - const XMLProperty* prop = node.property("flags"); - if (prop) { - flags = Route::Flag (string_2_enum (prop->value(), flags)); - } - + PresentationInfo::Flag flags = PresentationInfo::get_flags (node); boost::shared_ptr r (new Route (*this, X_("toBeResetFroXML"), flags)); if (r->init () == 0 && r->set_state (node, version) == 0) { -#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - // boost_debug_shared_ptr_mark_interesting (r.get(), "Route"); -#endif + BOOST_MARK_ROUTE (r); ret = r; } } @@ -1646,7 +1669,7 @@ Session::XMLRouteFactory_2X (const XMLNode& node, int version) } DataType type = DataType::AUDIO; - const XMLProperty* prop = node.property("default-type"); + XMLProperty const * prop = node.property("default-type"); if (prop) { type = DataType (prop->value()); @@ -1684,24 +1707,15 @@ Session::XMLRouteFactory_2X (const XMLNode& node, int version) track->set_diskstream (*i); -#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - // boost_debug_shared_ptr_mark_interesting (track.get(), "Track"); -#endif + BOOST_MARK_TRACK (track); ret = track; } else { - enum Route::Flag flags = Route::Flag(0); - const XMLProperty* prop = node.property("flags"); - if (prop) { - flags = Route::Flag (string_2_enum (prop->value(), flags)); - } - + PresentationInfo::Flag flags = PresentationInfo::get_flags (node); boost::shared_ptr r (new Route (*this, X_("toBeResetFroXML"), flags)); if (r->init () == 0 && r->set_state (node, version) == 0) { -#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - // boost_debug_shared_ptr_mark_interesting (r.get(), "Route"); -#endif + BOOST_MARK_ROUTE (r); ret = r; } } @@ -1723,7 +1737,7 @@ Session::load_regions (const XMLNode& node) for (niter = nlist.begin(); niter != nlist.end(); ++niter) { if ((region = XMLRegionFactory (**niter, false)) == 0) { error << _("Session: cannot create Region from XML description."); - const XMLProperty *name = (**niter).property("name"); + XMLProperty const * name = (**niter).property("name"); if (name) { error << " " << string_compose (_("Can not load state for region '%1'"), name->value()); @@ -1741,7 +1755,7 @@ Session::load_compounds (const XMLNode& node) { XMLNodeList calist = node.children(); XMLNodeConstIterator caiter; - XMLProperty *caprop; + XMLProperty const * caprop; for (caiter = calist.begin(); caiter != calist.end(); ++caiter) { XMLNode* ca = *caiter; @@ -1788,7 +1802,7 @@ Session::load_nested_sources (const XMLNode& node) /* it may already exist, so don't recreate it unnecessarily */ - XMLProperty* prop = (*niter)->property (X_("id")); + XMLProperty const * prop = (*niter)->property (X_("id")); if (!prop) { error << _("Nested source has no ID info in session file! (ignored)") << endmsg; continue; @@ -1812,7 +1826,7 @@ Session::load_nested_sources (const XMLNode& node) boost::shared_ptr Session::XMLRegionFactory (const XMLNode& node, bool full) { - const XMLProperty* type = node.property("type"); + XMLProperty const * type = node.property("type"); try { @@ -1841,7 +1855,7 @@ Session::XMLRegionFactory (const XMLNode& node, bool full) boost::shared_ptr Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/) { - const XMLProperty* prop; + XMLProperty const * prop; boost::shared_ptr source; boost::shared_ptr as; SourceList sources; @@ -1960,7 +1974,7 @@ Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/) boost::shared_ptr Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/) { - const XMLProperty* prop; + XMLProperty const * prop; boost::shared_ptr source; boost::shared_ptr ms; SourceList sources; @@ -2792,7 +2806,7 @@ Session::find_all_sources (string path, set& result) for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - XMLProperty* prop; + XMLProperty const * prop; if ((prop = (*niter)->property (X_("type"))) == 0) { continue; @@ -3399,7 +3413,7 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc) } case ControllableDescriptor::RemoteControlID: - r = route_by_remote_id (desc.rid()); + r = get_remote_nth_route (desc.rid()); break; case ControllableDescriptor::SelectionCount: @@ -3855,7 +3869,7 @@ Session::config_changed (std::string p, bool ours) } else if (p == "solo-control-is-listen-control") { solo_control_mode_changed (); } else if (p == "solo-mute-gain") { - _solo_cut_control->Changed(); + _solo_cut_control->Changed (true, Controllable::NoGroup); } else if (p == "timecode-offset" || p == "timecode-offset-negative") { last_timecode_valid = false; } else if (p == "playback-buffer-seconds") { @@ -4229,27 +4243,29 @@ Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFo /* sample rate */ - const XMLProperty* prop; - if ((prop = tree.root()->property (X_("sample-rate"))) != 0) { + XMLProperty const * prop; + XMLNode const * root (tree.root()); + + if ((prop = root->property (X_("sample-rate"))) != 0) { sample_rate = atoi (prop->value()); found_sr = true; } - const XMLNodeList& children (tree.root()->children()); + const XMLNodeList& children (root->children()); for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) { const XMLNode* child = *c; if (child->name() == "Config") { const XMLNodeList& options (child->children()); for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) { - const XMLNode* option = *oc; - const XMLProperty* name = option->property("name"); + XMLNode const * option = *oc; + XMLProperty const * name = option->property("name"); if (!name) { continue; } if (name->value() == "native-file-data-format") { - const XMLProperty* value = option->property ("value"); + XMLProperty const * value = option->property ("value"); if (value) { SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt); data_format = fmt; @@ -4281,7 +4297,7 @@ Session::get_snapshot_from_instant (const std::string& session_dir) return ""; } - const XMLProperty* prop; + XMLProperty const * prop; XMLNode *last_used_snapshot = tree.root()->child("LastUsedSnapshot"); if (last_used_snapshot && (prop = last_used_snapshot->property ("name")) != 0) { return prop->value();