#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/utils.h"
#include "ardour/graph.h"
#include "ardour/unknown_processor.h"
+#include "ardour/capturing_processor.h"
#include "i18n.h"
int
Route::init ()
{
- /* add standard controls */
+ /* add standard controls */
_solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
_mute_control->set_flags (Controllable::Flag (_mute_control->flags() | Controllable::Toggle));
add_control (_solo_control);
add_control (_mute_control);
+ /* panning */
+
+ _pannable.reset (new Pannable (_session));
+
/* input and output objects */
_input.reset (new IO (_session, _name, IO::Input, _default_type));
add_processor (_meter, PostFader);
- _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main));
+ _main_outs.reset (new Delivery (_session, _output, _pannable, _mute_master, _name, Delivery::Main));
add_processor (_main_outs, PostFader);
/* no panning on the monitor main outs */
+#ifdef PANNER_HACKS
_main_outs->panner()->set_bypassed (true);
+#endif
}
if (is_master() || is_monitor() || is_hidden()) {
}
}
- _route_group->apply (&Route::inc_gain, factor, _route_group);
+ _route_group->foreach_route (boost::bind (&Route::inc_gain, _1, factor, _route_group));
} else {
- _route_group->apply (&Route::set_gain, val, _route_group);
+ _route_group->foreach_route (boost::bind (&Route::set_gain, _1, val, _route_group));
}
return;
}
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) {
- _route_group->apply (&Route::set_solo, yn, _route_group);
+ _route_group->foreach_route (boost::bind (&Route::set_solo, _1, yn, _route_group));
return;
}
}
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) {
- _route_group->apply (&Route::set_solo_isolated, yn, _route_group);
+ _route_group->foreach_route (boost::bind (&Route::set_solo_isolated, _1, yn, _route_group));
return;
}
Route::set_mute (bool yn, void *src)
{
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_mute()) {
- _route_group->apply (&Route::set_mute, yn, _route_group);
+ _route_group->foreach_route (boost::bind (&Route::set_mute, _1, yn, _route_group));
return;
}
} else {
- processor.reset (new PortInsert (_session, _mute_master));
+ processor.reset (new PortInsert (_session, _pannable, _mute_master));
}
}
} else if (node.name() == "Send") {
- processor.reset (new Send (_session, _mute_master));
+ processor.reset (new Send (_session, _pannable, _mute_master));
} else {
cmt->add_content (_comment);
}
+ node->add_child_nocopy (_pannable->state (full_state));
+
for (i = _processors.begin(); i != _processors.end(); ++i) {
node->add_child_nocopy((*i)->state (full_state));
}
if (child->name() == X_("Processor")) {
processor_state.add_child_copy (*child);
}
+
+
+ if (child->name() == X_("Pannable")) {
+ _pannable->set_state (*child, version);
+ }
}
set_processor_state (processor_state);
if ((prop = node.property (X_("active"))) != 0) {
bool yn = string_is_affirmative (prop->value());
_active = !yn; // force switch
- set_active (yn);
+ set_active (yn, this);
}
if ((prop = node.property (X_("meter-point"))) != 0) {
MeterPoint mp = MeterPoint (string_2_enum (prop->value (), _meter_point));
- set_meter_point (mp);
+ set_meter_point (mp, true);
if (_meter) {
_meter->set_display_to_user (_meter_point == MeterCustom);
}
if ((prop = child->property (X_("active"))) != 0) {
bool yn = string_is_affirmative (prop->value());
_active = !yn; // force switch
- set_active (yn);
+ set_active (yn, this);
}
if ((prop = child->property (X_("gain"))) != 0) {
io_child = *io_niter;
if (io_child->name() == X_("Panner")) {
- _main_outs->panner()->set_state(*io_child, version);
+ _main_outs->panner_shell()->set_state(*io_child, version);
} else if (io_child->name() == X_("Automation")) {
/* IO's automation is for the fader */
_amp->set_automation_xml_state (*io_child, Evoral::Parameter (GainAutomation));
if (prop->value() == "intsend") {
- processor.reset (new InternalSend (_session, _mute_master, boost::shared_ptr<Route>(), Delivery::Role (0)));
+ 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" ||
} else if (prop->value() == "port") {
- processor.reset (new PortInsert (_session, _mute_master));
+ processor.reset (new PortInsert (_session, _pannable, _mute_master));
} else if (prop->value() == "send") {
- processor.reset (new Send (_session, _mute_master));
+ processor.reset (new Send (_session, _pannable, _mute_master));
} else {
error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
/* master never sends to control outs */
return 0;
} else {
- listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
+ listener.reset (new InternalSend (_session, _pannable, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
}
} else {
- listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
+ listener.reset (new InternalSend (_session, _pannable, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
}
} catch (failed_constructor& err) {
_monitor_send = listener;
}
- if (placement == PostFader) {
- /* put it *really* at the end, not just after the panner (main outs)
- */
- add_processor (listener, _processors.end());
- } else {
- add_processor (listener, PreFader);
- }
+
+ if (aux) {
+
+ add_processor (listener, placement);
+
+ } else {
+
+ if (placement == PostFader) {
+ /* put it *really* at the end, not just after the panner (main outs)
+ */
+ add_processor (listener, _processors.end());
+ } else {
+ add_processor (listener, PreFader);
+ }
+
+ }
return 0;
}
}
void
-Route::set_meter_point (MeterPoint p)
+Route::set_meter_point (MeterPoint p, bool force)
{
/* CAN BE CALLED FROM PROCESS CONTEXT */
- if (_meter_point == p) {
+ if (_meter_point == p && !force) {
return;
}
_meter->reflect_inputs (m_in);
_processors.insert (loc, _meter);
-
+
/* we do not need to reconfigure the processors, because the meter
(a) is always ready to handle processor_max_streams
(b) is always an N-in/N-out processor, and thus moving
_session.set_dirty ();
}
+boost::shared_ptr<CapturingProcessor>
+Route::add_export_point()
+{
+ // Check if it exists already
+ boost::shared_ptr<CapturingProcessor> processor;
+ if ((processor = boost::dynamic_pointer_cast<CapturingProcessor> (*_processors.begin()))) {
+ return processor;
+ }
+
+ // ...else add it
+ processor.reset (new CapturingProcessor (_session));
+ add_processor (processor, _processors.begin());
+ return processor;
+}
+
framecnt_t
Route::update_total_latency ()
{
void
Route::automation_snapshot (framepos_t now, bool force)
{
- panner()->automation_snapshot (now, force);
-
+ _pannable->automation_snapshot (now, force);
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
(*i)->automation_snapshot (now, force);
}
/* pan automation */
{
- boost::shared_ptr<AutomationControl> pc;
- uint32_t npans = _main_outs->panner()->npanners();
-
- for (uint32_t p = 0; p < npans; ++p) {
- pc = _main_outs->panner()->pan_control (0, p);
+ ControlSet::Controls& c (_pannable->controls());
+
+ for (ControlSet::Controls::const_iterator ci = c.begin(); ci != c.end(); ++ci) {
+ boost::shared_ptr<AutomationControl> pc = boost::dynamic_pointer_cast<AutomationControl> (ci->second);
if (pc) {
boost::shared_ptr<AutomationList> al = pc->alist();
XMLNode& before = al->get_state ();
}
void
-Route::set_active (bool yn)
+Route::set_active (bool yn, void* src)
{
+ if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_route_active()) {
+ _route_group->foreach_route (boost::bind (&Route::set_active, _1, yn, _route_group));
+ return;
+ }
+
if (_active != yn) {
_active = yn;
_input->set_active (yn);
}
}
+boost::shared_ptr<Pannable>
+Route::pannable() const
+{
+ return _pannable;
+}
+
boost::shared_ptr<Panner>
Route::panner() const
{
- return _main_outs->panner();
+ /* may be null ! */
+ return _main_outs->panner_shell()->panner();
+}
+
+boost::shared_ptr<PannerShell>
+Route::panner_shell() const
+{
+ return _main_outs->panner_shell();
}
boost::shared_ptr<AutomationControl>