#include "ardour/midi_port.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"
using namespace ARDOUR;
using namespace PBD;
-PBD::Signal1<void,RouteSortOrderKey> Route::SyncOrderKeys;
+PBD::Signal0<void> Route::SyncOrderKeys;
PBD::Signal0<void> Route::RemoteControlIDChange;
Route::Route (Session& sess, string name, Flag flg, DataType default_type)
, _have_internal_generator (false)
, _solo_safe (false)
, _default_type (default_type)
+ , _order_key (0)
+ , _has_order_key (false)
, _remote_control_id (0)
, _in_configure_processors (false)
, _initial_io_setup (false)
Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
{
- /* run a configure so that the invisible processors get set up */
- Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
configure_processors (0);
}
}
bool
-Route::has_order_key (RouteSortOrderKey key) const
+Route::has_order_key () const
{
- return (order_keys.find (key) != order_keys.end());
+ return _has_order_key;
}
uint32_t
-Route::order_key (RouteSortOrderKey key) const
+Route::order_key () const
{
- OrderKeys::const_iterator i = order_keys.find (key);
-
- if (i == order_keys.end()) {
- return 0;
- }
-
- return i->second;
-}
-
-void
-Route::sync_order_keys (RouteSortOrderKey base)
-{
- /* this is called after changes to 1 or more route order keys have been
- * made, and we want to sync up.
- */
-
- OrderKeys::iterator i = order_keys.find (base);
-
- if (i == order_keys.end()) {
- return;
- }
-
- for (OrderKeys::iterator k = order_keys.begin(); k != order_keys.end(); ++k) {
-
- 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;
- }
- }
+ return _order_key;
}
void
-Route::set_remote_control_id_from_order_key (RouteSortOrderKey /*key*/, uint32_t rid)
+Route::set_remote_control_id_explicit (uint32_t rid)
{
if (is_master() || is_monitor() || is_auditioner()) {
/* hard-coded remote IDs, or no remote ID */
}
void
-Route::set_order_key (RouteSortOrderKey key, uint32_t n)
+Route::set_order_key (uint32_t n)
{
- OrderKeys::iterator i = order_keys.find (key);
+ _has_order_key = true;
- if (i != order_keys.end() && i->second == n) {
+ if (_order_key == n) {
return;
}
- order_keys[key] = n;
+ _order_key = n;
- DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 order key %2 set to %3\n",
- name(), enum_2_string (key), order_key (key)));
+ DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 order key set to %2\n",
+ name(), order_key ()));
_session.set_dirty ();
}
framepos_t start_frame, framepos_t end_frame, pframes_t nframes,
int declick, bool gain_automation_ok)
{
- bufs.set_is_silent (false);
+ /* Caller must hold process lock */
+ assert (!AudioEngine::instance()->process_lock().trylock());
+
+ Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
+ assert(lm.locked());
/* figure out if we're going to use gain automation */
if (gain_automation_ok) {
{
assert (is_monitor());
BufferSet& bufs (_session.get_route_buffers (n_process_buffers()));
+ fill_buffers_with_input (bufs, _input, nframes);
passthru (bufs, start_frame, end_frame, nframes, declick);
}
}
{
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
ProcessorState pstate (this);
// configure redirect ports properly, etc.
{
- 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 ...
} else if (node.name() == "Send") {
- processor.reset (new Send (_session, _pannable, _mute_master));
+ boost::shared_ptr<Pannable> sendpan (new Pannable (_session));
+ processor.reset (new Send (_session, sendpan, _mute_master));
} else {
}
{
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
ProcessorState pstate (this);
(*i)->activate ();
}
+ /* Think: does this really need to be called for every processor in the loop? */
{
- 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 ...
}
{
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
ProcessorList new_list;
ProcessorStreams err;
}
_processors = new_list;
-
- {
- Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
- configure_processors_unlocked (&err); // this can't fail
- }
+ configure_processors_unlocked (&err); // this can't fail
}
processor_max_streams.reset();
{
// TODO once the export point can be configured properly, do something smarter here
if (processor == _capturing_processor) {
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
+ if (need_process_lock) {
+ lx.acquire();
+ }
+
_capturing_processor.reset();
+
+ if (need_process_lock) {
+ lx.release();
+ }
}
/* these can never be removed */
processor_max_streams.reset();
{
- Glib::Threads::RWLock::WriterLock lm (_processor_lock);
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
+ if (need_process_lock) {
+ lx.acquire();
+ }
+
+ /* Caller must hold process lock */
+ assert (!AudioEngine::instance()->process_lock().trylock());
+
+ Glib::Threads::RWLock::WriterLock lm (_processor_lock); // XXX deadlock after export
+
ProcessorState pstate (this);
ProcessorList::iterator i;
return 1;
}
- if (need_process_lock) {
- Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
- if (configure_processors_unlocked (err)) {
- pstate.restore ();
- /* we know this will work, because it worked before :) */
- configure_processors_unlocked (0);
- return -1;
- }
- } else {
- if (configure_processors_unlocked (err)) {
- pstate.restore ();
- /* we know this will work, because it worked before :) */
- configure_processors_unlocked (0);
- return -1;
- }
+ if (configure_processors_unlocked (err)) {
+ pstate.restore ();
+ /* we know this will work, because it worked before :) */
+ configure_processors_unlocked (0);
+ return -1;
}
_have_internal_generator = false;
}
}
}
+ if (need_process_lock) {
+ lx.release();
+ }
}
reset_instrument_info ();
processor_max_streams.reset();
{
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
ProcessorState pstate (this);
_output->set_user_latency (0);
- {
- Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
- if (configure_processors_unlocked (err)) {
- pstate.restore ();
- /* we know this will work, because it worked before :) */
- configure_processors_unlocked (0);
- return -1;
- }
+ if (configure_processors_unlocked (err)) {
+ pstate.restore ();
+ /* we know this will work, because it worked before :) */
+ configure_processors_unlocked (0);
+ return -1;
}
+ //lx.unlock();
_have_internal_generator = false;
int
Route::configure_processors (ProcessorStreams* err)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
if (!_in_configure_processors) {
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
int
Route::configure_processors_unlocked (ProcessorStreams* err)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
if (_in_configure_processors) {
return 0;
*/
{
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
ProcessorState pstate (this);
/* If the meter is in a custom position, find it and make a rough note of its position */
maybe_note_meter_position ();
- {
- Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
- if (configure_processors_unlocked (err)) {
- pstate.restore ();
- return -1;
- }
+ if (configure_processors_unlocked (err)) {
+ pstate.restore ();
+ return -1;
}
}
node->add_property("route-group", _route_group->name());
}
- string order_string;
- OrderKeys::iterator x = order_keys.begin();
-
- while (x != order_keys.end()) {
- order_string += enum_2_string ((*x).first);
- order_string += '=';
- snprintf (buf, sizeof(buf), "%" PRId32, (*x).second);
- order_string += buf;
-
- ++x;
-
- if (x == order_keys.end()) {
- break;
- }
-
- order_string += ':';
- }
- node->add_property ("order-keys", order_string);
+ snprintf (buf, sizeof (buf), "%d", _order_key);
+ node->add_property ("order-key", buf);
node->add_property ("self-solo", (_self_solo ? "yes" : "no"));
snprintf (buf, sizeof (buf), "%d", _soloed_by_others_upstream);
node->add_property ("soloed-by-upstream", buf);
set_active (yn, this);
}
- if ((prop = node.property (X_("order-keys"))) != 0) {
+ if ((prop = node.property (X_("order-key"))) != 0) { // New order key (no separate mixer/editor ordering)
+ set_order_key (atoi(prop->value()));
+ }
+
+ if ((prop = node.property (X_("order-keys"))) != 0) { // Deprecated order keys
int32_t n;
<< endmsg;
} else {
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);
+ if ((keyname == "EditorSort") || (keyname == "editor")) {
+ cerr << "Setting " << name() << " order key to " << n << " using saved Editor order." << endl;
+ set_order_key (n);
}
-
- set_order_key (sk, n);
}
}
<< endmsg;
} else {
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);
+ if (keyname == "EditorSort" || keyname == "editor") {
+ info << string_compose(_("Converting deprecated order key for %1 using Editor order %2"), name (), n) << endmsg;
+ set_order_key (n);
}
-
- set_order_key (sk, n);
}
}
if (prop->value() == "intsend") {
- processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr<Route>(), Delivery::Role (0)));
+ processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr<Route>(), Delivery::Aux, true));
} else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
prop->value() == "lv2" ||
} else if (prop->value() == "send") {
- processor.reset (new Send (_session, _pannable, _mute_master));
+ processor.reset (new Send (_session, _pannable, _mute_master, Delivery::Send, true));
} else {
error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
}
{
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
_processors = new_order;
if (must_configure) {
- Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
configure_processors_unlocked (0);
}
/* master never sends to monitor section via the normal mechanism */
assert (!is_master ());
+ assert (!is_monitor ());
/* make sure we have one */
if (!_monitor_send) {
{
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
- listener.reset (new InternalSend (_session, _pannable, _mute_master, route, Delivery::Aux));
+ boost::shared_ptr<Pannable> sendpan (new Pannable (_session));
+ listener.reset (new InternalSend (_session, sendpan, _mute_master, route, Delivery::Aux));
}
add_processor (listener, before);
{
const FedBy& fed_by (other->fed_by());
- for (FedBy::iterator f = fed_by.begin(); f != fed_by.end(); ++f) {
+ for (FedBy::const_iterator f = fed_by.begin(); f != fed_by.end(); ++f) {
boost::shared_ptr<Route> sr = f->r.lock();
if (sr && (sr.get() == this)) {
bool meter_was_visible_to_user = _meter->display_to_user ();
{
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
maybe_note_meter_position ();
Route::listen_position_changed ()
{
{
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
ProcessorState pstate (this);
- {
- Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
- if (configure_processors_unlocked (0)) {
- pstate.restore ();
- configure_processors_unlocked (0); // it worked before we tried to add it ...
- return;
- }
+ if (configure_processors_unlocked (0)) {
+ pstate.restore ();
+ configure_processors_unlocked (0); // it worked before we tried to add it ...
+ return;
}
}
boost::shared_ptr<CapturingProcessor>
Route::add_export_point()
{
+ Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
if (!_capturing_processor) {
+ lm.release();
+ Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
+ Glib::Threads::RWLock::WriterLock lw (_processor_lock);
_capturing_processor.reset (new CapturingProcessor (_session));
_capturing_processor->activate ();
- {
- Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
- configure_processors (0);
- }
+ configure_processors_unlocked (0);
}
boost::shared_ptr<Processor>
Route::the_instrument () const
{
- Glib::Threads::RWLock::WriterLock lm (_processor_lock);
+ Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
return the_instrument_unlocked ();
}
}
{
- Glib::Threads::RWLock::WriterLock lm (_processor_lock);
+ //Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
+ Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
(*i)->transport_located (pos);