X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Froute.cc;h=8546c3ce76b9a18ecff7f8f28fbf45f63c64ad27;hb=e0012e1b88a6a26ebaf0038f40975779480b1453;hp=3cb71fad84fb07f6626acd9aab53080fed2372af;hpb=ca1de500041e2739cf623bc94b090ff82ee6052c;p=ardour.git diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 3cb71fad84..8546c3ce76 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -26,6 +26,8 @@ #include #include +#include + #include "pbd/xml++.h" #include "pbd/enumwriter.h" #include "pbd/memento_command.h" @@ -33,40 +35,30 @@ #include "pbd/convert.h" #include "pbd/boost_debug.h" -#include "evoral/Curve.hpp" - #include "ardour/amp.h" -#include "ardour/audio_port.h" +#include "ardour/audio_buffer.h" #include "ardour/audioengine.h" #include "ardour/buffer.h" #include "ardour/buffer_set.h" -#include "ardour/configuration.h" -#include "ardour/cycle_timer.h" +#include "ardour/capturing_processor.h" #include "ardour/debug.h" #include "ardour/delivery.h" -#include "ardour/dB.h" -#include "ardour/internal_send.h" #include "ardour/internal_return.h" -#include "ardour/ladspa_plugin.h" +#include "ardour/internal_send.h" #include "ardour/meter.h" -#include "ardour/mix.h" #include "ardour/monitor_processor.h" #include "ardour/pannable.h" -#include "ardour/panner.h" #include "ardour/panner_shell.h" #include "ardour/plugin_insert.h" #include "ardour/port.h" #include "ardour/port_insert.h" #include "ardour/processor.h" -#include "ardour/profile.h" #include "ardour/route.h" #include "ardour/route_group.h" #include "ardour/send.h" #include "ardour/session.h" -#include "ardour/timestamps.h" -#include "ardour/utils.h" #include "ardour/unknown_processor.h" -#include "ardour/capturing_processor.h" +#include "ardour/utils.h" #include "i18n.h" @@ -74,8 +66,7 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -uint32_t Route::order_key_cnt = 0; -PBD::Signal1 Route::SyncOrderKeys; +PBD::Signal1 Route::SyncOrderKeys; PBD::Signal0 Route::RemoteControlIDChange; Route::Route (Session& sess, string name, Flag flg, DataType default_type) @@ -107,14 +98,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type) , _last_custom_meter_was_at_end (false) { processor_max_streams.reset(); - order_keys[N_("signal")] = order_key_cnt++; - - if (is_master()) { - set_remote_control_id (MasterBusRemoteControlID); - } else if (is_monitor()) { - set_remote_control_id (MonitorBusRemoteControlID); - } - } int @@ -185,7 +168,7 @@ Route::init () { /* run a configure so that the invisible processors get set up */ - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); configure_processors (0); } @@ -205,7 +188,7 @@ Route::~Route () be half-destroyed by now */ - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { (*i)->drop_references (); } @@ -216,6 +199,15 @@ Route::~Route () void Route::set_remote_control_id (uint32_t id, bool notify_class_listeners) { + if (Config->get_remote_model() != UserOrdered) { + return; + } + + if (id < 1) { + error << _("Remote Control ID's start at one, not zero") << endmsg; + return; + } + /* force IDs for master/monitor busses and prevent any other route from accidentally getting these IDs (i.e. legacy sessions) @@ -236,9 +228,10 @@ Route::set_remote_control_id (uint32_t id, bool notify_class_listeners) id += MonitorBusRemoteControlID; } - if (id != _remote_control_id) { + if (id != remote_control_id()) { _remote_control_id = id; RemoteControlIDChanged (); + if (notify_class_listeners) { RemoteControlIDChange (); } @@ -248,88 +241,101 @@ Route::set_remote_control_id (uint32_t id, bool notify_class_listeners) uint32_t Route::remote_control_id() const { + if (is_master()) { + return MasterBusRemoteControlID; + } + + if (is_monitor()) { + return MonitorBusRemoteControlID; + } + return _remote_control_id; } -int32_t -Route::order_key (std::string const & name) const +bool +Route::has_order_key (RouteSortOrderKey key) const { - OrderKeys::const_iterator i = order_keys.find (name); + return (order_keys.find (key) != order_keys.end()); +} + +uint32_t +Route::order_key (RouteSortOrderKey key) const +{ + OrderKeys::const_iterator i = order_keys.find (key); + if (i == order_keys.end()) { - return -1; + return 0; } return i->second; } void -Route::set_order_key (std::string const & name, int32_t n) +Route::sync_order_keys (RouteSortOrderKey base) { - bool changed = false; + /* this is called after changes to 1 or more route order keys have been + * made, and we want to sync up. + */ - /* This method looks more complicated than it should, but - it's important that we don't emit order_key_changed unless - it actually has, as expensive things happen on receipt of that - signal. - */ + OrderKeys::iterator i = order_keys.find (base); - if (order_keys.find(name) == order_keys.end() || order_keys[name] != n) { - order_keys[name] = n; - changed = true; + if (i == order_keys.end()) { + return; } - if (Config->get_sync_all_route_ordering()) { - for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) { - if (x->second != n) { - x->second = n; - changed = true; - } - } - } + for (OrderKeys::iterator k = order_keys.begin(); k != order_keys.end(); ++k) { - if (changed) { - order_key_changed (); /* EMIT SIGNAL */ - _session.set_dirty (); + if (k->first != base) { + DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 set key for %2 to %3 from %4\n", + name(), + enum_2_string (k->first), + i->second, + enum_2_string (base))); + + k->second = i->second; + } } } -/** Set all order keys to be the same as that for `base', if such a key - * exists in this route. - * @param base Base key. - */ void -Route::sync_order_keys (std::string const & base) +Route::set_remote_control_id_from_order_key (RouteSortOrderKey key, uint32_t rid) { - if (order_keys.empty()) { + if (is_master() || is_monitor() || is_hidden()) { + /* hard-coded remote IDs, or no remote ID */ return; } - OrderKeys::iterator i; - int32_t key; - - if ((i = order_keys.find (base)) == order_keys.end()) { - /* key doesn't exist, use the first existing key (during session initialization) */ - i = order_keys.begin(); - key = i->second; - ++i; - } else { - /* key exists - use it and reset all others (actually, itself included) */ - key = i->second; - i = order_keys.begin(); + if (_remote_control_id != rid) { + DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1: set edit-based RID to %2\n", name(), rid)); + _remote_control_id = rid; + RemoteControlIDChanged (); /* EMIT SIGNAL (per-route) */ } - bool changed = false; + /* don't emit the class-level RID signal RemoteControlIDChange here, + leave that to the entity that changed the order key, so that we + don't get lots of emissions for no good reasons (e.g. when changing + all route order keys). - for (; i != order_keys.end(); ++i) { - if (i->second != key) { - i->second = key; - changed = true; - } - } + See Session::sync_remote_id_from_order_keys() for the (primary|only) + spot where that is emitted. + */ +} - if (changed) { - order_key_changed (); /* EMIT SIGNAL */ +void +Route::set_order_key (RouteSortOrderKey key, uint32_t n) +{ + OrderKeys::iterator i = order_keys.find (key); + + if (i != order_keys.end() && i->second == n) { + return; } + + order_keys[key] = n; + + DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 order key %2 set to %3\n", + name(), enum_2_string (key), order_key (key))); + + _session.set_dirty (); } string @@ -433,6 +439,7 @@ Route::process_output_buffers (BufferSet& bufs, /* figure out if we're going to use gain automation */ if (gain_automation_ok) { + _amp->set_gain_automation_buffer (_session.gain_automation_buffer ()); _amp->setup_gain_automation (start_frame, end_frame, nframes); } else { _amp->apply_gain_automation (false); @@ -522,10 +529,13 @@ Route::process_output_buffers (BufferSet& bufs, /* if it has any inputs, make sure they match */ if (boost::dynamic_pointer_cast (*i) == 0 && (*i)->input_streams() != ChanCount::ZERO) { if (bufs.count() != (*i)->input_streams()) { - cerr << _name << " bufs = " << bufs.count() - << " input for " << (*i)->name() << " = " << (*i)->input_streams() - << endl; - abort (); + DEBUG_TRACE ( + DEBUG::Processors, string_compose ( + "%1 bufs = %2 input for %3 = %4\n", + _name, bufs.count(), (*i)->name(), (*i)->input_streams() + ) + ); + continue; } } #endif @@ -875,7 +885,7 @@ dump_processors(const string& name, const list >& p boost::shared_ptr Route::before_processor_for_placement (Placement p) { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); ProcessorList::iterator loc; @@ -900,7 +910,7 @@ Route::before_processor_for_index (int index) return boost::shared_ptr (); } - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); ProcessorList::iterator i = _processors.begin (); int j = 0; @@ -953,7 +963,7 @@ Route::add_processor (boost::shared_ptr processor, boost::shared_ptr< } { - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); ProcessorState pstate (this); boost::shared_ptr pi; @@ -993,7 +1003,7 @@ Route::add_processor (boost::shared_ptr processor, boost::shared_ptr< // configure redirect ports properly, etc. { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); if (configure_processors_unlocked (err)) { pstate.restore (); @@ -1011,7 +1021,7 @@ Route::add_processor (boost::shared_ptr processor, boost::shared_ptr< } - if (activation_allowed) { + if (activation_allowed && !_session.get_disable_all_loaded_plugins()) { processor->activate (); } @@ -1020,6 +1030,7 @@ Route::add_processor (boost::shared_ptr processor, boost::shared_ptr< _output->set_user_latency (0); } + reset_instrument_info (); processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */ set_processor_positions (); @@ -1059,7 +1070,7 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version) if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "lv2" || - prop->value() == "vst" || + prop->value() == "windows-vst" || prop->value() == "lxvst" || prop->value() == "audiounit") { @@ -1121,7 +1132,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr } { - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); ProcessorState pstate (this); for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) { @@ -1143,7 +1154,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr } { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); if (configure_processors_unlocked (err)) { pstate.restore (); configure_processors_unlocked (0); // it worked before we tried to add it ... @@ -1168,6 +1179,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr _output->set_user_latency (0); } + reset_instrument_info (); processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */ set_processor_positions (); @@ -1193,7 +1205,7 @@ Route::placement_range(Placement p, ProcessorList::iterator& start, ProcessorLis void Route::disable_processors (Placement p) { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); ProcessorList::iterator start, end; placement_range(p, start, end); @@ -1210,7 +1222,7 @@ Route::disable_processors (Placement p) void Route::disable_processors () { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { (*i)->deactivate (); @@ -1225,7 +1237,7 @@ Route::disable_processors () void Route::disable_plugins (Placement p) { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); ProcessorList::iterator start, end; placement_range(p, start, end); @@ -1244,7 +1256,7 @@ Route::disable_plugins (Placement p) void Route::disable_plugins () { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { if (boost::dynamic_pointer_cast (*i)) { @@ -1259,7 +1271,7 @@ Route::disable_plugins () void Route::ab_plugins (bool forward) { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); if (forward) { @@ -1318,7 +1330,7 @@ Route::clear_processors (Placement p) } { - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); ProcessorList new_list; ProcessorStreams err; bool seen_amp = false; @@ -1364,7 +1376,7 @@ Route::clear_processors (Placement p) _processors = new_list; { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); configure_processors_unlocked (&err); // this can't fail } } @@ -1374,6 +1386,8 @@ Route::clear_processors (Placement p) processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */ set_processor_positions (); + reset_instrument_info (); + if (!already_deleting) { _session.clear_deletion_in_progress(); } @@ -1382,6 +1396,11 @@ Route::clear_processors (Placement p) int Route::remove_processor (boost::shared_ptr processor, ProcessorStreams* err, bool need_process_lock) { + // TODO once the export point can be configured properly, do something smarter here + if (processor == _capturing_processor) { + _capturing_processor.reset(); + } + /* these can never be removed */ if (processor == _amp || processor == _meter || processor == _main_outs) { @@ -1395,7 +1414,7 @@ Route::remove_processor (boost::shared_ptr processor, ProcessorStream processor_max_streams.reset(); { - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); ProcessorState pstate (this); ProcessorList::iterator i; @@ -1416,12 +1435,7 @@ Route::remove_processor (boost::shared_ptr processor, ProcessorStream boost::shared_ptr iop; if ((iop = boost::dynamic_pointer_cast (*i)) != 0) { - if (iop->input()) { - iop->input()->disconnect (this); - } - if (iop->output()) { - iop->output()->disconnect (this); - } + iop->disconnect (); } i = _processors.erase (i); @@ -1441,7 +1455,7 @@ Route::remove_processor (boost::shared_ptr processor, ProcessorStream } if (need_process_lock) { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); if (configure_processors_unlocked (err)) { pstate.restore (); @@ -1472,6 +1486,7 @@ Route::remove_processor (boost::shared_ptr processor, ProcessorStream } } + reset_instrument_info (); processor->drop_references (); processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */ set_processor_positions (); @@ -1491,7 +1506,7 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* processor_max_streams.reset(); { - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); ProcessorState pstate (this); ProcessorList::iterator i; @@ -1538,7 +1553,7 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* _output->set_user_latency (0); { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); if (configure_processors_unlocked (err)) { pstate.restore (); @@ -1568,12 +1583,22 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* (*i)->drop_references (); } + reset_instrument_info (); processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */ set_processor_positions (); return 0; } +void +Route::reset_instrument_info () +{ + boost::shared_ptr instr = the_instrument(); + if (instr) { + _instrument_info.set_internal_instrument (instr); + } +} + /** Caller must hold process lock */ int Route::configure_processors (ProcessorStreams* err) @@ -1581,7 +1606,7 @@ Route::configure_processors (ProcessorStreams* err) assert (!AudioEngine::instance()->process_lock().trylock()); if (!_in_configure_processors) { - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); return configure_processors_unlocked (err); } @@ -1597,7 +1622,7 @@ Route::input_streams () const list > Route::try_configure_processors (ChanCount in, ProcessorStreams* err) { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); return try_configure_processors_unlocked (in, err); } @@ -1702,7 +1727,7 @@ Route::configure_processors_unlocked (ProcessorStreams* err) void Route::all_visible_processors_active (bool state) { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); if (_processors.empty()) { return; @@ -1733,7 +1758,7 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err */ { - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); ProcessorState pstate (this); ProcessorList::iterator oiter; @@ -1795,7 +1820,7 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err maybe_note_meter_position (); { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); if (configure_processors_unlocked (err)) { pstate.restore (); @@ -1853,9 +1878,9 @@ Route::state(bool full_state) OrderKeys::iterator x = order_keys.begin(); while (x != order_keys.end()) { - order_string += string ((*x).first); + order_string += enum_2_string ((*x).first); order_string += '='; - snprintf (buf, sizeof(buf), "%ld", (*x).second); + snprintf (buf, sizeof(buf), "%" PRId32, (*x).second); order_string += buf; ++x; @@ -2002,7 +2027,6 @@ Route::set_state (const XMLNode& node, int version) processor_state.add_child_copy (*child); } - if (child->name() == X_("Pannable")) { if (_pannable) { _pannable->set_state (*child, version); @@ -2022,6 +2046,9 @@ Route::set_state (const XMLNode& node, int version) set_processor_state (processor_state); + // this looks up the internal instrument in processors + reset_instrument_info(); + if ((prop = node.property ("self-solo")) != 0) { set_self_solo (string_is_affirmative (prop->value())); } @@ -2075,7 +2102,18 @@ Route::set_state (const XMLNode& node, int version) error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) << endmsg; } else { - set_order_key (remaining.substr (0, equal), n); + string keyname = remaining.substr (0, equal); + RouteSortOrderKey sk; + + if (keyname == "signal") { + sk = MixerSort; + } else if (keyname == "editor") { + sk = EditorSort; + } else { + sk = (RouteSortOrderKey) string_2_enum (remaining.substr (0, equal), sk); + } + + set_order_key (sk, n); } } @@ -2091,7 +2129,7 @@ Route::set_state (const XMLNode& node, int version) if ((prop = node.property (X_("processor-after-last-custom-meter"))) != 0) { PBD::ID id (prop->value ()); - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); ProcessorList::const_iterator i = _processors.begin (); while (i != _processors.end() && (*i)->id() != id) { ++i; @@ -2120,6 +2158,8 @@ Route::set_state (const XMLNode& node, int version) } else if (child->name() == Controllable::xml_node_name && (prop = child->property("name")) != 0) { if (prop->value() == "solo") { _solo_control->set_state (*child, version); + } else if (prop->value() == "mute") { + _mute_control->set_state (*child, version); } } else if (child->name() == X_("RemoteControl")) { @@ -2157,7 +2197,9 @@ Route::set_state_2X (const XMLNode& node, int version) } if ((prop = node.property (X_("flags"))) != 0) { - _flags = Flag (string_2_enum (prop->value(), _flags)); + string f = prop->value (); + boost::replace_all (f, "ControlOut", "MonitorOut"); + _flags = Flag (string_2_enum (f, _flags)); } else { _flags = Flag (0); } @@ -2267,7 +2309,18 @@ Route::set_state_2X (const XMLNode& node, int version) error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) << endmsg; } else { - set_order_key (remaining.substr (0, equal), n); + string keyname = remaining.substr (0, equal); + RouteSortOrderKey sk; + + if (keyname == "signal") { + sk = MixerSort; + } else if (keyname == "editor") { + sk = EditorSort; + } else { + sk = (RouteSortOrderKey) string_2_enum (remaining.substr (0, equal), sk); + } + + set_order_key (sk, n); } } @@ -2441,7 +2494,8 @@ Route::set_processor_state (const XMLNode& node) } _monitor_control->set_state (**niter, Stateful::current_state_version); } else if (prop->value() == "capture") { - _capturing_processor.reset (new CapturingProcessor (_session)); + /* CapturingProcessor should never be restored, it's always + added explicitly when needed */ } else { ProcessorList::iterator o; @@ -2466,7 +2520,7 @@ Route::set_processor_state (const XMLNode& node) } else if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "lv2" || - prop->value() == "vst" || + prop->value() == "windows-vst" || prop->value() == "lxvst" || prop->value() == "audiounit") { @@ -2509,11 +2563,11 @@ Route::set_processor_state (const XMLNode& node) } { - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); _processors = new_order; if (must_configure) { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); configure_processors_unlocked (0); } @@ -2532,6 +2586,7 @@ Route::set_processor_state (const XMLNode& node) } } + reset_instrument_info (); processors_changed (RouteProcessorChange ()); set_processor_positions (); } @@ -2546,7 +2601,7 @@ Route::curve_reallocate () void Route::silence (framecnt_t nframes) { - Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); if (!lm.locked()) { return; } @@ -2592,7 +2647,7 @@ Route::add_internal_return () void Route::add_send_to_internal_return (InternalSend* send) { - Glib::RWLock::ReaderLock rm (_processor_lock); + Glib::Threads::RWLock::ReaderLock rm (_processor_lock); for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) { boost::shared_ptr d = boost::dynamic_pointer_cast(*x); @@ -2606,7 +2661,7 @@ Route::add_send_to_internal_return (InternalSend* send) void Route::remove_send_from_internal_return (InternalSend* send) { - Glib::RWLock::ReaderLock rm (_processor_lock); + Glib::Threads::RWLock::ReaderLock rm (_processor_lock); for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) { boost::shared_ptr d = boost::dynamic_pointer_cast(*x); @@ -2646,7 +2701,7 @@ Route::add_aux_send (boost::shared_ptr route, boost::shared_ptr route, boost::shared_ptr listener; { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); listener.reset (new InternalSend (_session, _pannable, _mute_master, route, Delivery::Aux)); } @@ -2684,7 +2739,7 @@ Route::remove_aux_or_listen (boost::shared_ptr route) ProcessorList::iterator tmp; { - Glib::RWLock::ReaderLock rl(_processor_lock); + Glib::Threads::RWLock::ReaderLock rl(_processor_lock); /* have to do this early because otherwise processor reconfig * will put _monitor_send back in the list @@ -2820,11 +2875,7 @@ Route::nonrealtime_handle_transport_stopped (bool /*abort_ignored*/, bool did_lo framepos_t now = _session.transport_frame(); { - Glib::RWLock::ReaderLock lm (_processor_lock); - - if (!did_locate) { - automation_snapshot (now, true); - } + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); Automatable::transport_stopped (now); @@ -2911,7 +2962,7 @@ Route::pans_required () const int Route::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool session_state_changing) { - Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); if (!lm.locked()) { return 0; } @@ -2948,13 +2999,11 @@ Route::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int Route::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& /* need_butler */) { - Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); if (!lm.locked()) { return 0; } - automation_snapshot (_session.transport_frame(), false); - if (n_outputs().n_total() == 0) { return 0; } @@ -2964,7 +3013,7 @@ Route::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, in return 0; } - framecnt_t unused = 0; + framepos_t unused = 0; if ((nframes = check_initial_delay (nframes, unused)) == 0) { return 0; @@ -2991,7 +3040,7 @@ Route::flush_processors () this is called from the RT audio thread. */ - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { (*i)->flush (); @@ -3010,7 +3059,7 @@ Route::set_meter_point (MeterPoint p, bool force) bool meter_was_visible_to_user = _meter->display_to_user (); { - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); maybe_note_meter_position (); @@ -3077,11 +3126,11 @@ void Route::listen_position_changed () { { - Glib::RWLock::WriterLock lm (_processor_lock); + Glib::Threads::RWLock::WriterLock lm (_processor_lock); ProcessorState pstate (this); { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); if (configure_processors_unlocked (0)) { pstate.restore (); @@ -3104,7 +3153,7 @@ Route::add_export_point() _capturing_processor->activate (); { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); configure_processors (0); } @@ -3166,18 +3215,6 @@ Route::set_latency_compensation (framecnt_t longest_session_latency) } } -void -Route::automation_snapshot (framepos_t now, bool force) -{ - if (_pannable) { - _pannable->automation_snapshot (now, force); - } - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - (*i)->automation_snapshot (now, force); - } -} - Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr r) : AutomationControl (r->session(), Evoral::Parameter (SoloAutomation), boost::shared_ptr(), name) @@ -3276,19 +3313,20 @@ Route::protect_automation () (*i)->protect_automation(); } +/** @param declick 1 to set a pending declick fade-in, + * -1 to set a pending declick fade-out + */ void Route::set_pending_declick (int declick) { if (_declickable) { - /* this call is not allowed to turn off a pending declick unless "force" is true */ + /* this call is not allowed to turn off a pending declick */ if (declick) { _pending_declick = declick; } - // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl; } else { _pending_declick = 0; } - } /** Shift automation forwards from a particular place, thereby inserting time. @@ -3329,7 +3367,7 @@ Route::shift (framepos_t pos, framecnt_t frames) /* redirect automation */ { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); for (ProcessorList::iterator i = _processors.begin (); i != _processors.end (); ++i) { set parameters = (*i)->what_can_be_automated(); @@ -3429,7 +3467,7 @@ Route::set_name_in_state (XMLNode& node, string const & name) boost::shared_ptr Route::internal_send_for (boost::shared_ptr target) const { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { boost::shared_ptr send; @@ -3507,13 +3545,14 @@ Route::set_active (bool yn, void* src) _input->set_active (yn); _output->set_active (yn); active_changed (); // EMIT SIGNAL + _session.set_dirty (); } } void Route::meter () { - Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK); + Glib::Threads::RWLock::ReaderLock rm (_processor_lock, Glib::Threads::TRY_LOCK); assert (_meter); @@ -3568,7 +3607,7 @@ Route::get_control (const Evoral::Parameter& param) /* maybe one of our processors does or ... */ - Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK); + Glib::Threads::RWLock::ReaderLock rm (_processor_lock, Glib::Threads::TRY_LOCK); for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { if ((c = boost::dynamic_pointer_cast((*i)->control (param))) != 0) { break; @@ -3590,7 +3629,7 @@ Route::get_control (const Evoral::Parameter& param) boost::shared_ptr Route::nth_plugin (uint32_t n) { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); ProcessorList::iterator i; for (i = _processors.begin(); i != _processors.end(); ++i) { @@ -3607,7 +3646,7 @@ Route::nth_plugin (uint32_t n) boost::shared_ptr Route::nth_send (uint32_t n) { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); ProcessorList::iterator i; for (i = _processors.begin(); i != _processors.end(); ++i) { @@ -3624,7 +3663,7 @@ Route::nth_send (uint32_t n) bool Route::has_io_processor_named (const string& name) { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); ProcessorList::iterator i; for (i = _processors.begin(); i != _processors.end(); ++i) { @@ -3648,7 +3687,7 @@ Route::mute_points () const void Route::set_processor_positions () { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); bool had_amp = false; for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { @@ -3680,7 +3719,7 @@ Route::unknown_processors () const { list p; - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { if (boost::dynamic_pointer_cast (*i)) { p.push_back ((*i)->name ()); @@ -3805,7 +3844,7 @@ void Route::setup_invisible_processors () { #ifndef NDEBUG - Glib::RWLock::WriterLock lm (_processor_lock, Glib::TRY_LOCK); + Glib::Threads::RWLock::WriterLock lm (_processor_lock, Glib::Threads::TRY_LOCK); assert (!lm.locked ()); #endif @@ -3961,8 +4000,8 @@ Route::setup_invisible_processors () void Route::unpan () { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); - Glib::RWLock::ReaderLock lp (_processor_lock); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + Glib::Threads::RWLock::ReaderLock lp (_processor_lock); _pannable.reset (); @@ -4006,7 +4045,7 @@ Route::maybe_note_meter_position () boost::shared_ptr Route::processor_by_id (PBD::ID id) const { - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { if ((*i)->id() == id) { return *i; @@ -4051,3 +4090,33 @@ Route::has_external_redirects () const return false; } +boost::shared_ptr +Route::the_instrument () const +{ + Glib::Threads::RWLock::WriterLock lm (_processor_lock); + for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { + if (boost::dynamic_pointer_cast(*i)) { + if ((*i)->input_streams().n_midi() > 0 && + (*i)->output_streams().n_audio() > 0) { + return (*i); + } + } + } + return boost::shared_ptr(); +} + +void +Route::non_realtime_locate (framepos_t pos) +{ + if (_pannable) { + _pannable->transport_located (pos); + } + + { + Glib::Threads::RWLock::WriterLock lm (_processor_lock); + + for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { + (*i)->transport_located (pos); + } + } +}