, _recordable (true)
, _silent (false)
, _declickable (false)
- , _solo_control (new SoloControllable (X_("solo"), *this))
- , _mute_control (new MuteControllable (X_("mute"), *this))
, _mute_master (new MuteMaster (sess, name))
, _have_internal_generator (false)
, _solo_safe (false)
{
/* add standard controls */
+ _solo_control.reset (new SoloControllable (X_("solo"), shared_from_this ()));
+ _mute_control.reset (new MuteControllable (X_("mute"), shared_from_this ()));
+
_solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
_mute_control->set_flags (Controllable::Flag (_mute_control->flags() | Controllable::Toggle));
break;
}
- if (bufs.count() != (*i)->input_streams()) {
- cerr << _name << " bufs = " << bufs.count()
- << " input for " << (*i)->name() << " = " << (*i)->input_streams()
- << endl;
- }
- assert (bufs.count() == (*i)->input_streams());
-
+#ifndef NDEBUG
+ /* if it has any inputs, make sure they match */
+ if ((*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 ();
+ }
+ }
+#endif
/* should we NOT run plugins here if the route is inactive?
do we catch route != active somewhere higher?
*/
{
assert (processor != _meter);
assert (processor != _main_outs);
+
+ DEBUG_TRACE (DEBUG::Processors, string_compose ("%1 adding processor %2\n", name(), processor->name()));
ChanCount old_pms = processor_max_streams;
if (configure_processors_unlocked (err)) {
pstate.restore ();
configure_processors_unlocked (0); // it worked before we tried to add it ...
- cerr << "configure failed\n";
return -1;
}
}
must_configure = true;
}
_monitor_control->set_state (**niter, Stateful::current_state_version);
+ } else if (prop->value() == "capture") {
+ _capturing_processor.reset (new CapturingProcessor (_session));
} else {
ProcessorList::iterator o;
if (prop->value() == "intsend") {
processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr<Route>(), Delivery::Role (0)));
-
} else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
prop->value() == "lv2" ||
prop->value() == "vst" ||
processor.reset (new UnknownProcessor (_session, **niter));
}
+ /* we have to note the monitor send here, otherwise a new one will be created
+ and the state of this one will be lost.
+ */
+ boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (processor);
+ if (isend && isend->role() == Delivery::Listen) {
+ _monitor_send = isend;
+ }
+
/* it doesn't matter if invisible processors are added here, as they
will be sorted out by setup_invisible_processors () shortly.
*/
}
}
-BufferSet*
-Route::get_return_buffer () const
+void
+Route::add_send_to_internal_return (InternalSend* send)
{
Glib::RWLock::ReaderLock rm (_processor_lock);
boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
if (d) {
- BufferSet* bs = d->get_buffers ();
- return bs;
+ return d->add_send (send);
}
}
-
- return 0;
}
void
-Route::release_return_buffer () const
+Route::remove_send_from_internal_return (InternalSend* send)
{
Glib::RWLock::ReaderLock rm (_processor_lock);
boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
if (d) {
- return d->release_buffers ();
+ return d->remove_send (send);
}
}
}
-/** Add a monitor send, if we don't already have one */
+/** Add a monitor send (if we don't already have one) but don't activate it */
int
Route::listen_via_monitor ()
{
/* make sure we have one */
if (!_monitor_send) {
_monitor_send.reset (new InternalSend (_session, _pannable, _mute_master, _session.monitor_out(), Delivery::Listen));
- _monitor_send->activate ();
_monitor_send->set_display_to_user (false);
}
}
}
-Route::SoloControllable::SoloControllable (std::string name, Route& r)
- : AutomationControl (r.session(), Evoral::Parameter (SoloAutomation),
+Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<Route> r)
+ : AutomationControl (r->session(), Evoral::Parameter (SoloAutomation),
boost::shared_ptr<AutomationList>(), name)
- , route (r)
+ , _route (r)
{
boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
set_list (gl);
Route::SoloControllable::set_value (double val)
{
bool bval = ((val >= 0.5f) ? true: false);
-# if 0
- this is how it should be done
boost::shared_ptr<RouteList> rl (new RouteList);
- rl->push_back (route);
+
+ boost::shared_ptr<Route> r = _route.lock ();
+ if (!r) {
+ return;
+ }
+
+ rl->push_back (r);
if (Config->get_solo_control_is_listen_control()) {
_session.set_listen (rl, bval);
} else {
_session.set_solo (rl, bval);
}
-#else
- route.set_solo (bval, this);
-#endif
}
double
-Route::SoloControllable::get_value (void) const
+Route::SoloControllable::get_value () const
{
+ boost::shared_ptr<Route> r = _route.lock ();
+ if (!r) {
+ return 0;
+ }
+
if (Config->get_solo_control_is_listen_control()) {
- return route.listening_via_monitor() ? 1.0f : 0.0f;
+ return r->listening_via_monitor() ? 1.0f : 0.0f;
} else {
- return route.self_soloed() ? 1.0f : 0.0f;
+ return r->self_soloed() ? 1.0f : 0.0f;
}
}
-Route::MuteControllable::MuteControllable (std::string name, Route& r)
- : AutomationControl (r.session(), Evoral::Parameter (MuteAutomation),
+Route::MuteControllable::MuteControllable (std::string name, boost::shared_ptr<Route> r)
+ : AutomationControl (r->session(), Evoral::Parameter (MuteAutomation),
boost::shared_ptr<AutomationList>(), name)
- , route (r)
+ , _route (r)
{
boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
set_list (gl);
Route::MuteControllable::set_value (double val)
{
bool bval = ((val >= 0.5f) ? true: false);
-# if 0
- this is how it should be done
boost::shared_ptr<RouteList> rl (new RouteList);
- rl->push_back (route);
+
+ boost::shared_ptr<Route> r = _route.lock ();
+ if (!r) {
+ return;
+ }
+
+ rl->push_back (r);
_session.set_mute (rl, bval);
-#else
- route.set_mute (bval, this);
-#endif
}
double
-Route::MuteControllable::get_value (void) const
+Route::MuteControllable::get_value () const
{
- return route.muted() ? 1.0f : 0.0f;
+ boost::shared_ptr<Route> r = _route.lock ();
+ if (!r) {
+ return 0;
+ }
+
+ return r->muted() ? 1.0f : 0.0f;
}
void
void
Route::setup_invisible_processors ()
{
-#ifdef NDEBUG
- Glib::RWLock::WriterLock lm (_processor_lock, Glib::TryLock);
+#ifndef NDEBUG
+ Glib::RWLock::WriterLock lm (_processor_lock, Glib::TRY_LOCK);
assert (!lm.locked ());
#endif
+ if (!_main_outs) {
+ /* too early to be doing this stuff */
+ return;
+ }
+
/* we'll build this new list here and then use it */
ProcessorList new_processors;
new_processors.insert (amp, _meter);
break;
case MeterPostFader:
- assert (!_meter->display_to_user ());
- new_processors.insert (after_amp, _meter);
+ /* do nothing here */
+ break;
+ case MeterOutput:
+ /* do nothing here */
break;
case MeterCustom:
/* the meter is visible, so we don't touch it here */
}
}
-
/* MAIN OUTS */
- if (_main_outs) {
- assert (!_main_outs->display_to_user ());
- new_processors.push_back (_main_outs);
- }
+ assert (_main_outs);
+ assert (!_main_outs->display_to_user ());
+ new_processors.push_back (_main_outs);
+
+ /* iterator for the main outs */
+
+ ProcessorList::iterator main = new_processors.end();
+ --main;
+
+ /* OUTPUT METERING */
+
+ if (_meter && (_meter_point == MeterOutput || _meter_point == MeterPostFader)) {
+ assert (!_meter->display_to_user ());
+
+ /* add the processor just before or just after the main outs */
+
+ ProcessorList::iterator meter_point = main;
+
+ if (_meter_point == MeterOutput) {
+ ++meter_point;
+ }
+ new_processors.insert (meter_point, _meter);
+ }
/* MONITOR SEND */
if (_monitor_send && !is_monitor ()) {
assert (!_monitor_send->display_to_user ());
- switch (Config->get_listen_position ()) {
- case PreFaderListen:
- switch (Config->get_pfl_position ()) {
- case PFLFromBeforeProcessors:
- new_processors.push_front (_monitor_send);
- break;
- case PFLFromAfterProcessors:
- new_processors.insert (amp, _monitor_send);
- break;
- }
- break;
- case AfterFaderListen:
- new_processors.insert (after_amp, _monitor_send);
- break;
- }
+ if (Config->get_solo_control_is_listen_control()) {
+ switch (Config->get_listen_position ()) {
+ case PreFaderListen:
+ switch (Config->get_pfl_position ()) {
+ case PFLFromBeforeProcessors:
+ new_processors.push_front (_monitor_send);
+ break;
+ case PFLFromAfterProcessors:
+ new_processors.insert (amp, _monitor_send);
+ break;
+ }
+ break;
+ case AfterFaderListen:
+ switch (Config->get_afl_position ()) {
+ case AFLFromBeforeProcessors:
+ new_processors.insert (after_amp, _monitor_send);
+ break;
+ case AFLFromAfterProcessors:
+ new_processors.insert (new_processors.end(), _monitor_send);
+ break;
+ }
+ break;
+ }
+ } else {
+ new_processors.insert (new_processors.end(), _monitor_send);
+ }
}
/* MONITOR CONTROL */