void
Route::process_output_buffers (BufferSet& bufs,
sframes_t start_frame, sframes_t end_frame, nframes_t nframes,
- bool with_processors, int declick)
+ bool /*with_processors*/, int declick)
{
bool monitor;
if (placement == PreFader) {
/* generic pre-fader: insert immediately before the amp */
- loc = find(_processors.begin(), _processors.end(), _amp);
+ loc = find (_processors.begin(), _processors.end(), _amp);
} else {
- /* generic post-fader: insert at end */
- loc = _processors.end();
-
- if (processor->visible() && !_processors.empty()) {
- /* check for invisible processors stacked at the end and leave them there */
- ProcessorList::iterator p;
- p = _processors.end();
- --p;
- while (!(*p)->visible() && p != _processors.begin()) {
- --p;
- }
- ++p;
- loc = p;
- }
+ /* generic post-fader: insert right before the main outs */
+ loc = find (_processors.begin(), _processors.end(), _main_outs);
}
return add_processor (processor, loc, err);
}
// XXX: do we want to emit the signal here ? change call order.
- if (!boost::dynamic_pointer_cast<InternalSend>(processor)) {
- processor->activate ();
- }
+ processor->activate ();
processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false));
_output->set_user_latency (0);
return 0;
}
-bool
-Route::add_processor_from_xml (const XMLNode& node, Placement placement)
-{
- ProcessorList::iterator loc;
-
- if (placement == PreFader) {
- /* generic pre-fader: insert immediately before the amp */
- loc = find(_processors.begin(), _processors.end(), _amp);
- } else {
- /* generic post-fader: insert at end */
- loc = _processors.end();
- }
-
- return add_processor_from_xml (node, loc);
-}
-
bool
Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter)
{
const XMLProperty *prop;
- // legacy sessions use a different node name for sends
- if (node.name() == "Send") {
-
- try {
- boost::shared_ptr<Send> send (new Send (_session, _mute_master, node));
- add_processor (send, iter);
- return true;
- }
-
- catch (failed_constructor &err) {
- error << _("Send construction failed") << endmsg;
- return false;
- }
-
- } else if (node.name() == "Processor") {
+ if (node.name() != "Processor") {
+ return false;
+ }
- try {
- if ((prop = node.property ("type")) != 0) {
-
- boost::shared_ptr<Processor> processor;
+ try {
+ if ((prop = node.property ("type")) != 0) {
+
+ boost::shared_ptr<Processor> processor;
- if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
- prop->value() == "lv2" ||
- prop->value() == "vst" ||
- prop->value() == "audiounit") {
+ if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
+ prop->value() == "lv2" ||
+ prop->value() == "vst" ||
+ prop->value() == "audiounit") {
- processor.reset (new PluginInsert(_session, node));
+ processor.reset (new PluginInsert(_session, node));
- } else if (prop->value() == "port") {
+ } else if (prop->value() == "port") {
- processor.reset (new PortInsert (_session, _mute_master, node));
+ processor.reset (new PortInsert (_session, _mute_master, node));
- } else if (prop->value() == "send") {
-
- processor.reset (new Send (_session, _mute_master, node));
-
- } else if (prop->value() == "meter") {
+ } else if (prop->value() == "send") {
- if (_meter) {
- if (_meter->set_state (node)) {
- return false;
- } else {
- return true;
- }
- }
+ processor.reset (new Send (_session, _mute_master, node));
- _meter.reset (new PeakMeter (_session, node));
- processor = _meter;
-
- } else if (prop->value() == "amp") {
+ } else if (prop->value() == "meter") {
- /* amp always exists */
-
- processor = _amp;
- if (processor->set_state (node)) {
+ if (_meter) {
+ if (_meter->set_state (node)) {
return false;
} else {
- /* never any reason to add it */
return true;
}
-
- } else if (prop->value() == "listen" || prop->value() == "deliver") {
+ }
- /* XXX need to generalize */
+ _meter.reset (new PeakMeter (_session, node));
+ processor = _meter;
+
+ } else if (prop->value() == "amp") {
- } else if (prop->value() == "intsend") {
+ /* amp always exists */
+
+ processor = _amp;
+ if (processor->set_state (node)) {
+ return false;
+ } else {
+ /* never any reason to add it */
+ return true;
+ }
+
+ } else if (prop->value() == "intsend") {
- processor.reset (new InternalSend (_session, _mute_master, node));
+ processor.reset (new InternalSend (_session, _mute_master, node));
- } else if (prop->value() == "intreturn") {
+ } else if (prop->value() == "intreturn") {
- if (_intreturn) {
- if (_intreturn->set_state (node)) {
- return false;
- } else {
- return true;
- }
+ if (_intreturn) {
+ if (_intreturn->set_state (node)) {
+ return false;
+ } else {
+ return true;
}
- _intreturn.reset (new InternalReturn (_session, node));
- processor = _intreturn;
+ }
+ _intreturn.reset (new InternalReturn (_session, node));
+ processor = _intreturn;
- } else if (prop->value() == "main-outs") {
+ } else if (prop->value() == "main-outs") {
- if (_main_outs) {
- if (_main_outs->set_state (node)) {
- return false;
- } else {
- return true;
- }
+ if (_main_outs) {
+ if (_main_outs->set_state (node)) {
+ return false;
+ } else {
+ return true;
}
+ }
- _main_outs.reset (new Delivery (_session, _output, _mute_master, node));
- processor = _main_outs;
+ _main_outs.reset (new Delivery (_session, _output, _mute_master, node));
+ processor = _main_outs;
- } else {
- error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
- }
+ } else {
+ error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
+ return false;
+ }
- if (iter == _processors.end() && processor->visible() && !_processors.empty()) {
- /* check for invisible processors stacked at the end and leave them there */
- ProcessorList::iterator p;
- p = _processors.end();
+ if (iter == _processors.end() && processor->visible() && !_processors.empty()) {
+ /* check for invisible processors stacked at the end and leave them there */
+ ProcessorList::iterator p;
+ p = _processors.end();
+ --p;
+ while (!(*p)->visible() && p != _processors.begin()) {
--p;
- while (!(*p)->visible() && p != _processors.begin()) {
- --p;
- }
- ++p;
- iter = p;
}
-
- return (add_processor (processor, iter) == 0);
-
- } else {
- error << _("Processor XML node has no type property") << endmsg;
+ ++p;
+ iter = p;
}
- }
- catch (failed_constructor &err) {
- warning << _("processor could not be created. Ignored.") << endmsg;
+ return (add_processor (processor, iter) == 0);
+
+ } else {
+ error << _("Processor XML node has no type property") << endmsg;
return false;
}
}
- return false;
+
+ catch (failed_constructor &err) {
+ warning << _("processor could not be created. Ignored.") << endmsg;
+ return false;
+ }
}
int
-Route::add_processors (const ProcessorList& others, Placement placement, ProcessorStreams* err)
+Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> before, ProcessorStreams* err)
{
ProcessorList::iterator loc;
- if (placement == PreFader) {
- /* generic pre-fader: insert immediately before the amp */
- loc = find(_processors.begin(), _processors.end(), _amp);
- } else {
- /* generic post-fader: insert at end */
- loc = _processors.end();
- if (!_processors.empty()) {
- /* check for invisible processors stacked at the end and leave them there */
- ProcessorList::iterator p;
- p = _processors.end();
- --p;
- cerr << "Let's check " << (*p)->name() << " vis ? " << (*p)->visible() << endl;
- while (!(*p)->visible() && p != _processors.begin()) {
- --p;
- }
- ++p;
- loc = p;
- }
+ if (before) {
+ loc = find(_processors.begin(), _processors.end(), before);
+ } else {
+ /* nothing specified - at end but before main outs */
+ loc = find (_processors.begin(), _processors.end(), _main_outs);
}
return add_processors (others, loc, err);
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
pi->set_count (1);
- ChanCount m = max(pi->input_streams(), pi->output_streams());
- if (m > potential_max_streams)
+ ChanCount m = max (pi->input_streams(), pi->output_streams());
+
+ if (m > potential_max_streams) {
potential_max_streams = m;
+ }
}
_processors.insert (iter, *i);
Glib::RWLock::WriterLock lm (_processor_lock);
ProcessorList new_list;
ProcessorStreams err;
+ bool seen_amp = false;
- ProcessorList::iterator amp_loc = find(_processors.begin(), _processors.end(), _amp);
- if (p == PreFader) {
- // Get rid of PreFader processors
- for (ProcessorList::iterator i = _processors.begin(); i != amp_loc; ++i) {
- (*i)->drop_references ();
- }
- // Keep the rest
- for (ProcessorList::iterator i = amp_loc; i != _processors.end(); ++i) {
- new_list.push_back (*i);
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+
+ if (*i == _amp) {
+ seen_amp = true;
}
- } else {
- // Keep PreFader processors
- for (ProcessorList::iterator i = _processors.begin(); i != amp_loc; ++i) {
+
+ if ((*i) == _amp || (*i) == _meter || (*i) == _main_outs) {
+
+ /* you can't remove these */
+
new_list.push_back (*i);
- }
- new_list.push_back (_amp);
- // Get rid of PostFader processors
- for (ProcessorList::iterator i = amp_loc; i != _processors.end(); ++i) {
- (*i)->drop_references ();
+
+ } else {
+ if (seen_amp) {
+
+ switch (p) {
+ case PreFader:
+ new_list.push_back (*i);
+ break;
+ case PostFader:
+ (*i)->drop_references ();
+ break;
+ }
+
+ } else {
+
+ switch (p) {
+ case PreFader:
+ (*i)->drop_references ();
+ break;
+ case PostFader:
+ new_list.push_back (*i);
+ break;
+ }
+ }
}
}
return 0;
}
+int
+Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* err)
+{
+ ProcessorList deleted;
+ ProcessorList as_we_were;
+
+ if (!_session.engine().connected()) {
+ return 1;
+ }
+
+ processor_max_streams.reset();
+
+ {
+ Glib::RWLock::WriterLock lm (_processor_lock);
+ ProcessorList::iterator i;
+ boost::shared_ptr<Processor> processor;
+
+ as_we_were = _processors;
+
+ for (i = _processors.begin(); i != _processors.end(); ) {
+
+ processor = *i;
+
+ /* these can never be removed */
+
+ if (processor == _amp || processor == _meter || processor == _main_outs) {
+ ++i;
+ continue;
+ }
+
+ /* see if its in the list of processors to delete */
+
+ if (find (to_be_deleted.begin(), to_be_deleted.end(), processor) == to_be_deleted.end()) {
+ ++i;
+ continue;
+ }
+
+ /* stop IOProcessors that send to JACK ports
+ from causing noise as a result of no longer being
+ run.
+ */
+
+ boost::shared_ptr<IOProcessor> iop;
+
+ if ((iop = boost::dynamic_pointer_cast<IOProcessor> (processor)) != 0) {
+ iop->disconnect ();
+ }
+
+ deleted.push_back (processor);
+ i = _processors.erase (i);
+ }
+
+ if (deleted.empty()) {
+ /* none of those in the requested list were found */
+ return 0;
+ }
+
+ _output->set_user_latency (0);
+
+ if (configure_processors_unlocked (err)) {
+ /* get back to where we where */
+ _processors = as_we_were;
+ /* we know this will work, because it worked before :) */
+ configure_processors_unlocked (0);
+ return -1;
+ }
+
+ _have_internal_generator = false;
+
+ for (i = _processors.begin(); i != _processors.end(); ++i) {
+ boost::shared_ptr<PluginInsert> pi;
+
+ if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
+ if (pi->is_generator()) {
+ _have_internal_generator = true;
+ break;
+ }
+ }
+ }
+ }
+
+ /* now try to do what we need to so that those that were removed will be deleted */
+
+ for (ProcessorList::iterator i = deleted.begin(); i != deleted.end(); ++i) {
+ (*i)->drop_references ();
+ }
+
+ processors_changed (); /* EMIT SIGNAL */
+
+ return 0;
+}
+
+
int
Route::configure_processors (ProcessorStreams* err)
{
// Ensure route outputs match last processor's outputs
if (out != _output->n_ports ()) {
+ cerr << "For " << _name << " out/last mismatch - out = " << out << " vs. " << _output->n_ports() << endl;
_output->ensure_io (out, false, this);
}
_session.set_dirty ();
}
+bool
+Route::processor_is_prefader (boost::shared_ptr<Processor> p)
+{
+ bool pre_fader = true;
+ Glib::RWLock::ReaderLock lm (_processor_lock);
+
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+
+ /* semantic note: if p == amp, we want to return true, so test
+ for equality before checking if this is the amp
+ */
+
+ if ((*i) == p) {
+ break;
+ }
+
+ if ((*i) == _amp) {
+ pre_fader = false;
+ break;
+ }
+ }
+
+ return pre_fader;
+}
+
int
-Route::reorder_processors (const ProcessorList& new_order, Placement placement, ProcessorStreams* err)
+Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err)
{
/* "new_order" is an ordered list of processors to be positioned according to "placement".
NOTE: all processors in "new_order" MUST be marked as visible. There maybe additional
ProcessorList::const_iterator niter;
ProcessorList as_it_was_before = _processors;
ProcessorList as_it_will_be;
- ProcessorList::iterator start, end;
-
- placement_range (placement, start, end);
- oiter = start;
+ oiter = _processors.begin();
niter = new_order.begin();
while (niter != new_order.end()) {
its been deleted. If its there, append it to the temp list.
*/
- if (oiter == end) {
+ if (oiter == _processors.end()) {
/* no more elements in the old list, so just stick the rest of
the new order onto the temp list.
as_it_will_be.insert (as_it_will_be.end(), niter, new_order.end());
while (niter != new_order.end()) {
- (*niter)->set_placement (placement);
++niter;
}
break;
if (!(*oiter)->visible()) {
as_it_will_be.push_back (*oiter);
- (*oiter)->set_placement (placement);
} else {
} else {
/* ignore this one, and add the next item from the new order instead */
as_it_will_be.push_back (*niter);
- (*niter)->set_placement (placement);
++niter;
}
}
}
int
-Route::_set_state (const XMLNode& node, bool call_base)
+Route::_set_state (const XMLNode& node, bool /*call_base*/)
{
XMLNodeList nlist;
}
int
-Route::listen_via (boost::shared_ptr<Route> route, bool active)
+Route::listen_via (boost::shared_ptr<Route> route, Placement placement, bool /*active*/, bool aux)
{
vector<string> ports;
vector<string>::const_iterator i;
boost::shared_ptr<InternalSend> listener;
try {
- listener.reset (new InternalSend (_session, _mute_master, route));
+ listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
} catch (failed_constructor& err) {
return -1;
_control_outs = listener;
}
- add_processor (listener, (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader));
+ add_processor (listener, placement);
return 0;
}
}
void
-Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_processors)
+Route::handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool can_flush_processors)
{
nframes_t now = _session.transport_frame();
}
void
-Route::input_change_handler (IOChange change, void *src)
+Route::input_change_handler (IOChange change, void * /*src*/)
{
if ((change & ConfigurationChanged)) {
configure_processors (0);
}
void
-Route::output_change_handler (IOChange change, void *src)
+Route::output_change_handler (IOChange change, void * /*src*/)
{
if ((change & ConfigurationChanged)) {
int
Route::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
- bool session_state_changing, bool can_record, bool rec_monitors_input)
+ bool session_state_changing, bool /*can_record*/, bool /*rec_monitors_input*/)
{
if (n_outputs().n_total() == 0) {
return 0;
int
Route::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int declick,
- bool can_record, bool rec_monitors_input)
+ bool /*can_record*/, bool /*rec_monitors_input*/)
{
{
// automation snapshot can also be called from the non-rt context
}
int
-Route::silent_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
- bool can_record, bool rec_monitors_input)
+Route::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
+ bool /*can_record*/, bool /*rec_monitors_input*/)
{
silence (nframes);
return 0;
*/
void
-Route::shift (nframes64_t pos, nframes64_t frames)
+Route::shift (nframes64_t /*pos*/, nframes64_t /*frames*/)
{
#ifdef THIS_NEEDS_FIXING_FOR_V3
Route::meter ()
{
Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
+
+ assert (_meter);
+
_meter->meter ();
+
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+
+ boost::shared_ptr<Send> s;
+ boost::shared_ptr<Return> r;
+
+ if ((s = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
+ s->meter()->meter();
+ } else if ((r = boost::dynamic_pointer_cast<Return> (*i)) != 0) {
+ r->meter()->meter ();
+ }
+ }
}
boost::shared_ptr<Panner>