X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_state.cc;h=e222de2221624a1df43ea398569179f483840b9a;hb=9e0d03020ff47773f7d1c0414de1c74e6c9e0dac;hp=16cbfd1d3685da4f8d129b00879993ae8946a2c5;hpb=aae367b63c9b619db1e40f27dc334c6987219481;p=ardour.git diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 16cbfd1d36..e222de2221 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -57,6 +57,7 @@ #include "midi++/port.h" #include "pbd/boost_debug.h" +#include "pbd/controllable_descriptor.h" #include "pbd/enumwriter.h" #include "pbd/error.h" #include "pbd/pathscanner.h" @@ -64,6 +65,7 @@ #include "pbd/search_path.h" #include "pbd/stacktrace.h" +#include "ardour/amp.h" #include "ardour/audio_diskstream.h" #include "ardour/audio_track.h" #include "ardour/audioengine.h" @@ -144,10 +146,8 @@ Session::first_stage_init (string fullpath, string snapshot_name) } if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) { - cerr << "Session non-writable based on " << _path << endl; _writable = false; } else { - cerr << "Session writable based on " << _path << endl; _writable = true; } @@ -164,7 +164,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) _base_frame_rate = _current_frame_rate; _tempo_map = new TempoMap (_current_frame_rate); - _tempo_map->StateChanged.connect (*this, boost::bind (&Session::tempo_map_changed, this, _1)); + _tempo_map->StateChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1)); _non_soloed_outs_muted = false; @@ -209,7 +209,6 @@ Session::first_stage_init (string fullpath, string snapshot_name) g_atomic_int_set (&_capture_load_min, 100); _play_range = false; _exporting = false; - _exporting_realtime = false; _gain_automation_buffer = 0; _pan_automation_buffer = 0; _npan_buffers = 0; @@ -266,21 +265,17 @@ Session::first_stage_init (string fullpath, string snapshot_name) delta_accumulator_cnt = 0; _slave_state = Stopped; - _engine.GraphReordered.connect (*this, boost::bind (&Session::graph_reordered, this)); + _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this)); /* These are all static "per-class" signals */ - RegionFactory::CheckNewRegion.connect (*this, boost::bind (&Session::add_region, this, _1)); - SourceFactory::SourceCreated.connect (*this, boost::bind (&Session::add_source, this, _1)); - PlaylistFactory::PlaylistCreated.connect (*this, boost::bind (&Session::add_playlist, this, _1, _2)); - Processor::ProcessorCreated.connect (*this, boost::bind (&Session::add_processor, this, _1)); - NamedSelection::NamedSelectionCreated.connect (*this, boost::bind (&Session::add_named_selection, this, _1)); - AutomationList::AutomationListCreated.connect (*this, boost::bind (&Session::add_automation_list, this, _1)); - - // BOOST SIGNALS - // Controllable::Destroyed.connect (*this, boost::bind (&Session::remove_controllable, this, _1)); - - IO::PortCountChanged.connect (*this, boost::bind (&Session::ensure_buffers, this, _1)); + RegionFactory::CheckNewRegion.connect_same_thread (*this, boost::bind (&Session::add_region, this, _1)); + SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1)); + PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2)); + Processor::ProcessorCreated.connect_same_thread (*this, boost::bind (&Session::add_processor, this, _1)); + AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1)); + Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1)); + IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1)); /* stop IO objects from doing stuff until we're ready for them */ @@ -332,15 +327,15 @@ Session::second_stage_init (bool new_session) _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading); - _locations.changed.connect (*this, boost::bind (&Session::locations_changed, this)); - _locations.added.connect (*this, boost::bind (&Session::locations_added, this, _1)); + _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this)); + _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1)); setup_click_sounds (0); setup_midi_control (); /* Pay attention ... */ - _engine.Halted.connect (*this, boost::bind (&Session::engine_halted, this)); - _engine.Xrun.connect (*this, boost::bind (&Session::xrun_recovery, this)); + _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this)); + _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this)); try { when_engine_running(); @@ -792,7 +787,7 @@ Session::load_state (string snapshot_name) /* there is pending state from a crashed capture attempt */ - if (AskAboutPendingState()) { + if (*AskAboutPendingState()) { state_was_pending = true; } } @@ -1129,7 +1124,7 @@ Session::set_state (const XMLNode& node, int version) _nominal_frame_rate = atoi (prop->value()); if (_nominal_frame_rate != _current_frame_rate) { - if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) { + if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) { return -1; } } @@ -1382,6 +1377,7 @@ Session::XMLRouteFactory (const XMLNode& node, int version) DataType type = DataType::AUDIO; const XMLProperty* prop = node.property("default-type"); + boost::shared_ptr ret; if (prop) { type = DataType(prop->value()); @@ -1392,17 +1388,19 @@ Session::XMLRouteFactory (const XMLNode& node, int version) if (has_diskstream) { if (type == DataType::AUDIO) { AudioTrack* at = new AudioTrack (*this, node, version); - // boost_debug_shared_ptr_mark_interesting (at, typeid (at).name()); - boost::shared_ptr ret (at); - return ret; + boost_debug_shared_ptr_mark_interesting (at, "Track"); + ret.reset (at); + } else { - boost::shared_ptr ret (new MidiTrack (*this, node, version)); - return ret; + ret.reset (new MidiTrack (*this, node, version)); } } else { - boost::shared_ptr ret (new Route (*this, node)); - return ret; + Route* rt = new Route (*this, node); + boost_debug_shared_ptr_mark_interesting (rt, "Route"); + ret.reset (rt); } + + return ret; } int @@ -2290,6 +2288,12 @@ struct RegionCounter { RegionCounter() : count (0) {} }; +int +Session::ask_about_playlist_deletion (boost::shared_ptr p) +{ + return *AskAboutPlaylistDeletion (p); +} + int Session::cleanup_sources (CleanupReport& rep) { @@ -2311,12 +2315,11 @@ Session::cleanup_sources (CleanupReport& rep) /* step 1: consider deleting all unused playlists */ -/* BOOST SIGNALS - if (playlists->maybe_delete_unused (boost::bind (AskAboutPlaylistDeletion, _1)); + if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) { ret = 0; goto out; } -*/ + /* step 2: find all un-used sources */ rep.paths.clear (); @@ -2675,6 +2678,121 @@ Session::controllable_by_id (const PBD::ID& id) return boost::shared_ptr(); } +boost::shared_ptr +Session::controllable_by_descriptor (const ControllableDescriptor& desc) +{ + boost::shared_ptr c; + boost::shared_ptr r; + + switch (desc.top_level_type()) { + case ControllableDescriptor::NamedRoute: + { + std::string str = desc.top_level_name(); + if (str == "master") { + r = _master_out; + } else if (str == "control" || str == "listen") { + r = _control_out; + } else { + r = route_by_name (desc.top_level_name()); + } + break; + } + + case ControllableDescriptor::RemoteControlID: + r = route_by_remote_id (desc.rid()); + break; + } + + if (!r) { + return c; + } + + switch (desc.subtype()) { + case ControllableDescriptor::Gain: + c = r->gain_control (); + break; + + case ControllableDescriptor::Solo: + c = r->solo_control(); + break; + + case ControllableDescriptor::Mute: + c = r->mute_control(); + break; + + case ControllableDescriptor::Recenable: + { + boost::shared_ptr t = boost::dynamic_pointer_cast(r); + + if (t) { + c = t->rec_enable_control (); + } + break; + } + + case ControllableDescriptor::Pan: + /* XXX pan 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; + } + + boost::shared_ptr p = r->nth_plugin (plugin); + + if (p) { + c = boost::dynamic_pointer_cast( + p->data().control(Evoral::Parameter(PluginAutomation, 0, parameter_index))); + } + break; + } + + case ControllableDescriptor::SendGain: + { + uint32_t send = desc.target (0); + + /* revert to zero-based counting */ + + if (send > 0) { + --send; + } + + boost::shared_ptr p = r->nth_send (send); + + if (p) { + boost::shared_ptr s = boost::dynamic_pointer_cast(p); + boost::shared_ptr a = s->amp(); + + if (a) { + c = s->amp()->gain_control(); + } + } + break; + } + + default: + /* relax and return a null pointer */ + break; + } + + return c; +} + void Session::add_instant_xml (XMLNode& node, bool write_to_config) {